Zuplo API v4
Zuplo Developer API

A consumer is one credential: an API key and the keys that replace it when it is rolled. Every API key belongs to a consumer, and every consumer is created under what holds it:

  • the bucket, for API key authentication on any gateway, such as a customer or a partner, and for AI apps: …/consumers. Link a consumer to an AI app, one per client or environment, with its ID: POST …/ai/apps/{appId}/consumers with its consumerId. The app returns its linked consumers in consumers.
  • a person in an AI user app, for example one per laptop: …/ai/user-apps/{userAppId}/users/{userId}/consumers.

A consumer is then addressed by its ID, /v4/buckets/{bucketId}/consumers/{consumerId}, whatever holds it. What holds it is not a property of the consumer. Create a consumer with ?include[]=apiKey to get its first key in the same response.

When a key of a consumer in the bucket authenticates a request, the API key authentication policy sets request.user.sub to the consumer's name and request.user.data to its metadata. The consumers of apps and people get a generated name.

A consumer the bucket holds can have managers: the people who see and roll its keys in your developer portal. They sign in to the developer portal, not to Zuplo, so they are listed by email, with their portal sub once they have signed in. They are set with the consumer and have no URLs of their own. The consumers of apps and people have no managers.

Who manages consumers. A person's consumers in a user app are managed by the person and the user app's admins (see User Apps). Every other consumer in the bucket, linked to an app or not, and its keys are managed by the people who can change the bucket: for a project's bucket, project admins (and developers, on a preview or development bucket) and account admins; for a custom bucket, account admins. They list, create, change, link, unlink, roll and delete them. The members of a pool, its admins included, read the consumers linked to the pool's apps (include[]=consumers on the app) and their masked keys, but cannot create, link, change, roll or delete them. Everyone else gets 403.


POST
https://dev-api-v4-main-a471234.zuplo.app
/v4/buckets/{bucketId}/ai/apps/{appId}/consumers

Links a consumer in the bucket to the app, so the consumer's keys call the app. Create the consumer first with POST …/consumers, with include[]=apiKey for its first key. The app then lists it in its consumers. Returns 201 when the consumer was linked and 200 when it already was, so sending the same request again changes nothing. Unlink it with DELETE …/ai/apps/{appId}/consumers/{consumerId}.

A consumer is linked to at most one app. Fails with 409 when another app holds it, when it is a person's consumer in a user app, or when it has managers (an app's consumers have none: remove them first), and with 404 when the app is not in the bucket. A consumerId that is not in the bucket is a 400. Only people who manage the bucket's consumers can link one; pool admins get 403.

bucketId
​string · maxLength: 64 · required

The bucket ID (bckt_…). Everything in a bucket is addressed under it.

appId
​string · maxLength: 64 · required

The app ID (config_…).

The consumer to link to the app.
consumerId
​string · maxLength: 64 · required

A consumer in the app's bucket. It cannot be a person's consumer or one another app holds.

Example: csmr_brw0leTAVw478VFKD4F6OqVI

The consumer was already linked to the app.

The link between an app and a consumer in its bucket. The consumer's keys call the app.
appId
​string · required

The app.

Example: config_Kx7gDiGsr1c2tOOUW5kpmXZn
consumerId
​string · required

The consumer.

Example: csmr_brw0leTAVw478VFKD4F6OqVI
createdOn
​string · date-time · required

When the consumer was linked to the app.


GET
https://dev-api-v4-main-a471234.zuplo.app
/v4/buckets/{bucketId}/ai/apps/{appId}/consumers/{consumerId}

Returns the link between the app and one of its consumers. Read the consumer itself at …/consumers/{consumerId}. Fails with 404 when the consumer is not linked to the app. People who manage the bucket's consumers and the members of the app's pool can read it.

bucketId
​string · maxLength: 64 · required

The bucket ID (bckt_…). Everything in a bucket is addressed under it.

appId
​string · maxLength: 64 · required

The app ID (config_…).

consumerId
​string · maxLength: 64 · required

The consumer ID (csmr_…).

The link.

The link between an app and a consumer in its bucket. The consumer's keys call the app.
appId
​string · required

The app.

Example: config_Kx7gDiGsr1c2tOOUW5kpmXZn
consumerId
​string · required

The consumer.

Example: csmr_brw0leTAVw478VFKD4F6OqVI
createdOn
​string · date-time · required

When the consumer was linked to the app.


DELETE
https://dev-api-v4-main-a471234.zuplo.app
/v4/buckets/{bucketId}/ai/apps/{appId}/consumers/{consumerId}

Unlinks the consumer from the app. The consumer stays in the bucket with its keys, which no longer call the app, so it can be linked again. Delete it at …/consumers/{consumerId} to revoke its keys. A repeated unlink returns 404, which clients should treat as success. Only people who manage the bucket's consumers can unlink one; pool admins get 403.

bucketId
​string · maxLength: 64 · required

The bucket ID (bckt_…). Everything in a bucket is addressed under it.

appId
​string · maxLength: 64 · required

The app ID (config_…).

consumerId
​string · maxLength: 64 · required

The consumer ID (csmr_…).

The consumer was unlinked.

No data returned

List a person's consumers

GET
https://dev-api-v4-main-a471234.zuplo.app
/v4/buckets/{bucketId}/ai/user-apps/{userAppId}/users/{userId}/consumers

Lists one person's consumers in the user app, oldest first, for example one per laptop. People list their own with their own userId. User app admins can list anyone's.

List a person's consumers › path Parameters

bucketId
​string · maxLength: 64 · required

The bucket ID (bckt_…). Everything in a bucket is addressed under it.

userAppId
​string · maxLength: 64 · required

The user app ID (config_…).

userId
​UserId · maxLength: 64 · required

The 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.

Example: user_Jm5tR8wQz2KcX7vB4nLp9HdS

List a person's consumers › query Parameters

limit
​integer · min: 1 · max: 100

The maximum number of items to return.

Default: 10
offset
​integer · min: 0

The number of items to skip before the first item returned.

Default: 0

List a person's consumers › Responses

A page of the person's consumers.

A page of consumers.
​Consumer[] · required

The consumers on this page.

limit
​integer · required

The page size that was applied.

offset
​integer · required

The number of items skipped before this page.

total
​integer · required

The number of items in the whole collection.

hasMore
​boolean · required

Whether there are more items after this page.

next
​string | null · required

The relative URL of the next page, or null on the last page.


Create a personal consumer

POST
https://dev-api-v4-main-a471234.zuplo.app
/v4/buckets/{bucketId}/ai/user-apps/{userAppId}/users/{userId}/consumers

Creates a consumer for one person in the user app, for example for Claude Code on their laptop. People create their own with their own userId. A user app admin can create one for anyone who can use the user app, one request per person. Fails with 404 when the person cannot use the user app.

With include[]=apiKey it also issues the consumer's first key, and the response contains the key's secret. The person can read it again at …/api-keys/{apiKeyId}/secret, so a key an admin issued reaches them without the admin handing it over.

Create a personal consumer › path Parameters

bucketId
​string · maxLength: 64 · required

The bucket ID (bckt_…). Everything in a bucket is addressed under it.

userAppId
​string · maxLength: 64 · required

The user app ID (config_…).

userId
​UserId · maxLength: 64 · required

The 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.

Example: user_Jm5tR8wQz2KcX7vB4nLp9HdS

Create a personal consumer › query Parameters

include[]
​string[] · maxItems: 1 · unique · style: form · explode: true

What else to return. apiKey also issues the consumer's first API key, without a description or expiry, and returns it with its secret in apiKey, which is null otherwise. Change the key afterwards at …/api-keys/{apiKeyId}.

Enum values:
apiKey

Create a personal consumer › Request Body

A new consumer for a person in a user app.
description
​string | null · maxLength: 512

Where the person uses the consumer's keys, for example their laptop.

Create a personal consumer › Responses

The consumer was created, with its first key when include[] had apiKey.

A newly created consumer, with its first key and that key's secret when `include[]` had `apiKey`.
id
​string · required

The consumer ID.

Example: csmr_brw0leTAVw478VFKD4F6OqVI
bucketId
​string · required

The bucket the consumer belongs to.

Example: bckt_Y40ypGODCDP3S7iZxNwCAbIe
name
​string · required

The consumer's name, unique in the bucket.

Example: acme-corp
description
​string | null · required

Who or what the consumer is.

​object · required

Key-value pairs to organize and find consumers. Empty when there are none.

​object · required

Your data for your own code, passed to your gateway as request.user.data. Any JSON values, at most 3 KB (3,072 bytes) as JSON. Empty when there is none.

​ConsumerManager[] · required

The people who manage the consumer's keys in your developer portal, by email. Empty when there are none, and always empty for the consumers of apps and people.

createdOn
​string · date-time · required

When the consumer was created.

updatedOn
​string · date-time · required

When the consumer was last changed.

​required

The consumer's first key, with its secret, which is shown only once. Null unless include[] had apiKey.


List consumers

GET
https://dev-api-v4-main-a471234.zuplo.app
/v4/buckets/{bucketId}/consumers

Lists the consumers the bucket holds, oldest first: those of API key authentication on any gateway, such as customers and partners, and those linked to AI apps. Filter by name to find one consumer, or by managerEmail to list the consumers a person manages. People's consumers are listed under them. Only people who manage the bucket's consumers can list them; others get 403.

List consumers › path Parameters

bucketId
​string · maxLength: 64 · required

The bucket ID (bckt_…). Everything in a bucket is addressed under it.

List consumers › query Parameters

name
​string · maxLength: 128

Only return consumers with this name, exactly as it is stored. Names are unique for consumers created through v4, but consumers created before v4 can share a name or use other characters, so the list can hold more than one.

managerEmail
​string · email · maxLength: 320

Only return the consumers this person manages, by the email address in their managers entry (case-insensitive).

limit
​integer · min: 1 · max: 100

The maximum number of items to return.

Default: 10
offset
​integer · min: 0

The number of items to skip before the first item returned.

Default: 0

List consumers › Responses

A page of consumers.

A page of consumers.
​Consumer[] · required

The consumers on this page.

limit
​integer · required

The page size that was applied.

offset
​integer · required

The number of items skipped before this page.

total
​integer · required

The number of items in the whole collection.

hasMore
​boolean · required

Whether there are more items after this page.

next
​string | null · required

The relative URL of the next page, or null on the last page.


Create a consumer

POST
https://dev-api-v4-main-a471234.zuplo.app
/v4/buckets/{bucketId}/consumers

Creates a consumer in the bucket. Its name is unique in the bucket and cannot be changed later. With include[]=apiKey it also issues the consumer's first key. The response then contains the key's secret, the only time it is returned. Link it to an AI app with POST …/ai/apps/{appId}/consumers. Fails with 409 when the bucket already has a consumer with this name, including people's consumers, which are not listed here. Only people who manage the bucket's consumers can create one; others, pool admins included, get 403.

managers lists the people who manage the consumer's keys in your developer portal, by email. They see its keys there once they sign in with that address. A consumer you will link to an app has no managers, because linking a consumer that has managers fails with 409.

Create a consumer › path Parameters

bucketId
​string · maxLength: 64 · required

The bucket ID (bckt_…). Everything in a bucket is addressed under it.

Create a consumer › query Parameters

include[]
​string[] · maxItems: 1 · unique · style: form · explode: true

What else to return. apiKey also issues the consumer's first API key, without a description or expiry, and returns it with its secret in apiKey, which is null otherwise. Change the key afterwards at …/api-keys/{apiKeyId}.

Enum values:
apiKey

Create a consumer › Request Body

A new consumer.
name
​string · minLength: 1 · maxLength: 128 · pattern: ^[a-z0-9-]+$ · required

A name, unique in the bucket, that cannot be changed later: lowercase letters, digits and hyphens. The API key authentication policy sets request.user.sub to it.

description
​string | null · maxLength: 512

Who or what the consumer is.

​object · maxProps: 5

Up to five key-value pairs to organize and find consumers. Keys are at most 64 characters.

​object · maxProps: 50

Your data for your own code: the API key authentication policy passes it to your gateway as request.user.data. Any JSON values, at most 3 KB (3,072 bytes) as JSON. Keys are at most 64 characters.

​ConsumerManagerInput[] · maxItems: 100

The people who manage the consumer's keys in your developer portal, by email, at most 100. They see its keys there once they sign in with that address.

Create a consumer › Responses

The consumer was created, with its first key when include[] had apiKey.

A newly created consumer, with its first key and that key's secret when `include[]` had `apiKey`.
id
​string · required

The consumer ID.

Example: csmr_brw0leTAVw478VFKD4F6OqVI
bucketId
​string · required

The bucket the consumer belongs to.

Example: bckt_Y40ypGODCDP3S7iZxNwCAbIe
name
​string · required

The consumer's name, unique in the bucket.

Example: acme-corp
description
​string | null · required

Who or what the consumer is.

​object · required

Key-value pairs to organize and find consumers. Empty when there are none.

​object · required

Your data for your own code, passed to your gateway as request.user.data. Any JSON values, at most 3 KB (3,072 bytes) as JSON. Empty when there is none.

​ConsumerManager[] · required

The people who manage the consumer's keys in your developer portal, by email. Empty when there are none, and always empty for the consumers of apps and people.

createdOn
​string · date-time · required

When the consumer was created.

updatedOn
​string · date-time · required

When the consumer was last changed.

​required

The consumer's first key, with its secret, which is shown only once. Null unless include[] had apiKey.


Get a consumer

GET
https://dev-api-v4-main-a471234.zuplo.app
/v4/buckets/{bucketId}/consumers/{consumerId}

Returns a consumer, whether an app, a person or the bucket holds it. List its keys at …/consumers/{consumerId}/api-keys. People who manage the bucket's consumers read any consumer that is not a person's. The person and the user app's admins read a person's consumer, and the members of a pool read the consumers linked to the pool's apps.

Get a consumer › path Parameters

bucketId
​string · maxLength: 64 · required

The bucket ID (bckt_…). Everything in a bucket is addressed under it.

consumerId
​string · maxLength: 64 · required

The consumer ID (csmr_…).

Get a consumer › Responses

The consumer.

One credential, held by an app, a person in a user app or the bucket. Its keys are the versions of that credential.
id
​string · required

The consumer ID.

Example: csmr_brw0leTAVw478VFKD4F6OqVI
bucketId
​string · required

The bucket the consumer belongs to.

Example: bckt_Y40ypGODCDP3S7iZxNwCAbIe
name
​string · required

The consumer's name, unique in the bucket. For a consumer the bucket holds, the API key authentication policy sets request.user.sub to it. Generated for the consumers of apps and people.

Example: acme-corp
description
​string | null · required

Who or what the consumer is.

Example: Acme Corp
​object · required

Key-value pairs to organize and find consumers. Empty when there are none.

Example: {"plan":"gold"}
​object · required

Your data for your own code: the API key authentication policy passes it to your gateway as request.user.data. Any JSON values, at most 3 KB (3,072 bytes) as JSON. Empty when there is none.

Example: {"customerId":"cus_9s6XKzkNRiz8i3","plan":"gold","seats":25}
​ConsumerManager[] · required

The people who manage the consumer's keys in your developer portal, by email. Empty when there are none, and always empty for the consumers of apps and people.

createdOn
​string · date-time · required

When the consumer was created.

updatedOn
​string · date-time · required

When the consumer was last changed.


Update a consumer

PATCH
https://dev-api-v4-main-a471234.zuplo.app
/v4/buckets/{bucketId}/consumers/{consumerId}

Updates a consumer with JSON Merge Patch semantics: omitted properties are unchanged and null clears a property. tags are merged key by key and metadata as a JSON Merge Patch, and a key set to null is removed. managers replaces all of the consumer's managers, so send the complete list; [] removes them all. A consumer's name and what holds it cannot be changed.

Only a consumer the bucket holds has managers: managers on a consumer linked to an app, or on a person's consumer, is a 400.

The person and the user app's admins change a person's consumer. Any other consumer is changed only by people who manage the bucket's consumers, not by pool admins. Others get 403.

Update a consumer › path Parameters

bucketId
​string · maxLength: 64 · required

The bucket ID (bckt_…). Everything in a bucket is addressed under it.

consumerId
​string · maxLength: 64 · required

The consumer ID (csmr_…).

Update a consumer › Request Body

Changes to a consumer (JSON Merge Patch).
description
​string | null · maxLength: 512

Who or what the consumer is. Null clears it.

​object | null · maxProps: 5

Tags to set, merged key by key. A key set to null is removed, and null removes every tag. A consumer has at most five tags.

​object | null · maxProps: 50

Metadata to set, merged as a JSON Merge Patch. A key set to null is removed, an object is merged into the object it replaces, any other value replaces the key's value, and null removes all metadata. The result is at most 3 KB (3,072 bytes) as JSON.

​ConsumerManagerInput[] · maxItems: 100

All of the consumer's managers, replacing the current ones: send the complete list, and [] to remove them all. Only a consumer the bucket holds has managers; on any other consumer this is a 400.

Update a consumer › Responses

The updated consumer.

One credential, held by an app, a person in a user app or the bucket. Its keys are the versions of that credential.
id
​string · required

The consumer ID.

Example: csmr_brw0leTAVw478VFKD4F6OqVI
bucketId
​string · required

The bucket the consumer belongs to.

Example: bckt_Y40ypGODCDP3S7iZxNwCAbIe
name
​string · required

The consumer's name, unique in the bucket. For a consumer the bucket holds, the API key authentication policy sets request.user.sub to it. Generated for the consumers of apps and people.

Example: acme-corp
description
​string | null · required

Who or what the consumer is.

Example: Acme Corp
​object · required

Key-value pairs to organize and find consumers. Empty when there are none.

Example: {"plan":"gold"}
​object · required

Your data for your own code: the API key authentication policy passes it to your gateway as request.user.data. Any JSON values, at most 3 KB (3,072 bytes) as JSON. Empty when there is none.

Example: {"customerId":"cus_9s6XKzkNRiz8i3","plan":"gold","seats":25}
​ConsumerManager[] · required

The people who manage the consumer's keys in your developer portal, by email. Empty when there are none, and always empty for the consumers of apps and people.

createdOn
​string · date-time · required

When the consumer was created.

updatedOn
​string · date-time · required

When the consumer was last changed.


Delete a consumer

DELETE
https://dev-api-v4-main-a471234.zuplo.app
/v4/buckets/{bucketId}/consumers/{consumerId}

Deletes a consumer, with its managers, and revokes all of its API keys. A repeated delete returns 404, which clients should treat as success. Who can delete it is who can change it (PATCH); others get 403. A consumer that holds a subscription (API monetization) cannot be deleted and gets 409.

Delete a consumer › path Parameters

bucketId
​string · maxLength: 64 · required

The bucket ID (bckt_…). Everything in a bucket is addressed under it.

consumerId
​string · maxLength: 64 · required

The consumer ID (csmr_…).

Delete a consumer › Responses

The consumer was deleted.

No data returned