User Apps
A user app gives every person in the account their own personal API keys and
personal budget for the AI Gateway. That covers coding agents like Claude Code
or Cursor, scripts, and notebooks. Its policies work like an app's, and its
metering policy's per-person rule (budgetBy: expression on
request.user.sub) sets the limits every person gets.
Every gateway has exactly one user app, created with the gateway. It is listed, read and changed, but never created or deleted.
Everything about one person in the user app is under
…/ai/user-apps/{userAppId}/users/{userId}:
consumers: their API keys, for example one consumer per laptop,budget: their own limits, which replace the per-person defaults, for example a higher daily spend for one engineer,usage: their current usage against their limits.
…/users lists the people who can use the user app. A person has no ID of their
own in it: they are identified by the user app and their userId.
People who can edit the user app are its admins. Everyone who can use the
user app manages their own consumers and keys, and reads their own budget and
usage, with their own userId. Admins can do the same for anyone: issue each
person a key, one request per person, revoke it, see their usage, and set
their budget.
List user apps
Lists the gateway's user apps. Every gateway has exactly one, created with the gateway.
path Parameters
bucketIdThe bucket ID (bckt_…). Everything in a bucket is addressed under it.
query Parameters
limitThe maximum number of items to return.
offsetThe number of items to skip before the first item returned.
List user apps › Responses
A page of user apps.
The user apps on this page.
limitThe page size that was applied.
offsetThe number of items skipped before this page.
totalThe number of items in the whole collection.
hasMoreWhether there are more items after this page.
nextThe relative URL of the next page, or null on the last page.
Get a user app
Returns a user app and its policies, which set everyone's personal limits.
path Parameters
bucketIdThe bucket ID (bckt_…). Everything in a bucket is addressed under it.
userAppIdThe user app ID (config_…).
Get a user app › Responses
The user app.
idThe user app ID.
bucketIdThe bucket (gateway) the user app belongs to.
nameThe user app's display name.
baseUrlWhere personal-key clients (Claude Code, Cursor, scripts) send requests. Null until the gateway is deployed.
The policies every personal-key request runs, in order. The metering
policy's per-person rule (budgetBy: expression on request.user.sub)
sets the limits every person gets. A person's budget changes them for that
person.
createdOnWhen the user app was created.
updatedOnWhen the user app was last changed.
Update a user app
Updates a user app with JSON Merge Patch semantics. policies is replaced as
a whole. Changing the metering policy's per-person rule changes the limits
of everyone without limits of their own. Fails with 409 when it removes a
limit that a person's budget still changes.
path Parameters
bucketIdThe bucket ID (bckt_…). Everything in a bucket is addressed under it.
userAppIdThe user app ID (config_…).
Update a user app › Request Body
nameThe user app's display name.
Replaces all of the user app's policies, in the order they run. Keep the
metering policy's per-person rule to keep personal limits: removing a
limit that a person's budget still changes fails with 409.
Update a user app › Responses
The updated user app.
idThe user app ID.
bucketIdThe bucket (gateway) the user app belongs to.
nameThe user app's display name.
baseUrlWhere personal-key clients (Claude Code, Cursor, scripts) send requests. Null until the gateway is deployed.
The policies every personal-key request runs, in order. The metering
policy's per-person rule (budgetBy: expression on request.user.sub)
sets the limits every person gets. A person's budget changes them for that
person.
createdOnWhen the user app was created.
updatedOnWhen the user app was last changed.
List the people in a user app
Lists the people who can use the user app, by email address. Add
include[]=budget for each person's budget. Filter by hasBudgetOverride
to see who has limits of their own. User app admins see everyone. Everyone
else sees only themselves.
path Parameters
bucketIdThe bucket ID (bckt_…). Everything in a bucket is addressed under it.
userAppIdThe user app ID (config_…).
query Parameters
hasBudgetOverrideOnly return the people who have limits of their own (true), or only those on the defaults (false).
include[]What else to return with each person. budget returns their limits, as
…/users/{userId}/budget does, in budget, which is null otherwise.
limitThe maximum number of items to return.
offsetThe number of items to skip before the first item returned.
List the people in a user app › Responses
A page of the people in the user app.
The people on this page.
limitThe page size that was applied.
offsetThe number of items skipped before this page.
totalThe number of items in the whole collection.
hasMoreWhether there are more items after this page.
nextThe relative URL of the next page, or null on the last page.
Get a person in a user app
Returns one person who can use the user app, and with include[]=budget
their budget. Their budget, usage and consumers are under this URL, where
the budget is also set. 404 when the person cannot use the user app.
path Parameters
bucketIdThe bucket ID (bckt_…). Everything in a bucket is addressed under it.
userAppIdThe user app ID (config_…).
userIdThe user ID of an account member (user_…).
A person, identified by their Zuplo user ID (user_…). Zuplo assigns it when
the person is first added to an account, before they ever sign in, and it
never changes. Every userId and ownerId in v4 is one.
query Parameters
include[]What else to return with each person. budget returns their limits, as
…/users/{userId}/budget does, in budget, which is null otherwise.
Get a person in a user app › Responses
The person.
userAppIdThe user app.
userIdA person, identified by their Zuplo user ID (user_…). Zuplo assigns it when
the person is first added to an account, before they ever sign in, and it
never changes. Every userId and ownerId in v4 is one.
emailThe person's email address.
nameThe person's display name, if they set one.
hasBudgetOverrideWhether the person has limits of their own (…/users/{userId}/budget) instead of the user app's defaults.
The person's limits, as GET …/users/{userId}/budget returns them. Null unless include[] has budget.
Get a person's budget
Returns one person's own limits in the user app, which replace the user app's
per-person defaults. limits is empty when the defaults apply. People read
their own. User app admins can read anyone's.
path Parameters
bucketIdThe bucket ID (bckt_…). Everything in a bucket is addressed under it.
userAppIdThe user app ID (config_…).
userIdThe user ID of an account member (user_…).
A person, identified by their Zuplo user ID (user_…). Zuplo assigns it when
the person is first added to an account, before they ever sign in, and it
never changes. Every userId and ownerId in v4 is one.
Get a person's budget › Responses
The person's budget.
userAppIdThe user app.
userIdA person, identified by their Zuplo user ID (user_…). Zuplo assigns it when
the person is first added to an account, before they ever sign in, and it
never changes. Every userId and ownerId in v4 is one.
The person's own limits. Empty when the defaults apply. Limits that are not listed keep the defaults.
updatedOnWhen the limits were last set, or null if they never were.
Set a person's budget
Sets one person's own limits, replacing the ones they had, so sending the same
request again changes nothing. Send the complete list. limits: [] puts the
person back on the user app's defaults. Only cost limits with action block
that exist in the user app's per-person budget rule can be set, and only user
app admins can set them.
Returns 201 when the person had no limits of their own and now has, and
200 otherwise. Fails with 409 when the gateway's budget rules, not the user
app, hold the per-person rule.
path Parameters
bucketIdThe bucket ID (bckt_…). Everything in a bucket is addressed under it.
userAppIdThe user app ID (config_…).
userIdThe user ID of an account member (user_…).
A person, identified by their Zuplo user ID (user_…). Zuplo assigns it when
the person is first added to an account, before they ever sign in, and it
never changes. Every userId and ownerId in v4 is one.
Set a person's budget › Request Body
Replaces the person's own limits. Each must match a cost limit with action block in the user app's per-person budget rule. [] puts the person back on the defaults.
Set a person's budget › Responses
The person's limits were replaced.
userAppIdThe user app.
userIdA person, identified by their Zuplo user ID (user_…). Zuplo assigns it when
the person is first added to an account, before they ever sign in, and it
never changes. Every userId and ownerId in v4 is one.
The person's own limits. Empty when the defaults apply. Limits that are not listed keep the defaults.
updatedOnWhen the limits were last set, or null if they never were.
Get a person's usage
Returns one person's current usage against their limits. People read their own. User app admins can read anyone's.
path Parameters
bucketIdThe bucket ID (bckt_…). Everything in a bucket is addressed under it.
userAppIdThe user app ID (config_…).
userIdThe user ID of an account member (user_…).
A person, identified by their Zuplo user ID (user_…). Zuplo assigns it when
the person is first added to an account, before they ever sign in, and it
never changes. Every userId and ownerId in v4 is one.
Get a person's usage › Responses
The person's usage.
userAppIdThe user app.
userIdA person, identified by their Zuplo user ID (user_…). Zuplo assigns it when
the person is first added to an account, before they ever sign in, and it
never changes. Every userId and ownerId in v4 is one.
Usage per limit.
measuredOnHow fresh the numbers are. Usage is aggregated asynchronously and can lag by a few seconds.