Secrets
A secret is a named value on a product, such as DATABASE_URL, with its own version history in each environment the product is deployed to. Reads return non-production values only. Production values reach a deployment through a pull with a vault key, or once in the response that generated them.
The Secret object
A named value on a product with one version history per environment. Production values never appear.
Attributes
idstringRequiredUnique ID of the secret.
namestringRequiredLetters, digits and underscores, starting with a letter or underscore, at most 255 characters and unique on the product, such as DATABASE_URL.
createdAtstringRequiredWhen the secret was created, as an ISO 8601 timestamp.
productobjectRequiredThe product the secret belongs to.
environmentsarray of objectsRequiredThe active environments the product is deployed to, in the order it was deployed.
valuesmap of objectsRequiredThe current version in each of those environments, keyed by environment slug.
{ "id": "Sc4VnJ7qTr2X", "name": "DATABASE_URL", "createdAt": "2026-10-01T16:20:00.000Z", "product": { "id": "Pr4GtY9sLm3B", "slug": "storefront", "name": "Storefront", "type": "website" }, "environments": [ { "id": "En8RqZ2vKp5D", "slug": "staging", "name": "Staging", "class": "non-production" }, { "id": "En1MwX6cTb7F", "slug": "production", "name": "Production", "class": "production" } ], "values": { "staging": { "version": 3, "isSet": true, "generator": null, "publicKey": null, "restoredFrom": null, "createdAt": "2026-10-14T09:05:12.000Z", "actor": { "id": "Us3NfP8kLq2V", "type": "user", "name": "Maya Patel" }, "value": "postgres://storefront@db.staging.acme.dev:5432/storefront" }, "production": { "version": 2, "isSet": true, "generator": null, "publicKey": null, "restoredFrom": null, "createdAt": "2026-10-01T16:20:00.000Z", "actor": { "id": "Us3NfP8kLq2V", "type": "user", "name": "Maya Patel" } } }}List every product's secrets
GET/Returns each active product with the environments it is deployed to and each secret's current version there. Non-production values are included; production values never are.
Path parameters
slugstringRequiredThe workspace's slug or ID, such as acme.
Returns
Returns an array of objects with these fields. Status 200.
Every active product in the workspace.
idstringRequiredUnique ID of the product.
workspaceIdstringRequiredUnique ID of the workspace the product belongs to.
namestringRequiredThe product's display name.
slugstringRequiredThe product's slug, such as storefront.
typestringRequiredWhat kind of software the product is.
websiteapiclimobile_appdesktop_appagentdescriptionnullable stringRequiredA short description, or null.
repositorynullable stringRequiredThe source repository, such as acme/storefront, or null.
archivedAtnullable stringRequiredAlways null: the vault lists only active products.
createdAtstringRequiredWhen the product was created, as an ISO 8601 timestamp.
updatedAtstringRequiredWhen the product last changed, as an ISO 8601 timestamp.
environmentsarray of objectsRequiredThe active environments the product is deployed to, in the order it was deployed.
secretsarray of objectsRequiredThe product's secrets.
Errors
- 400
InvalidInputThe request is malformed, or a value is not allowed.- 401
UnauthorizedThe request has no valid API key.- 403
ForbiddenThe key's user or role may not do this.- 404
NotFoundThe workspace or object does not exist, or the caller cannot see it.- 409
ConflictThe change conflicts with current data, such as a slug that is already in use.- 500
InternalClanker Ship failed to handle the request. Retry, or report the response's x-request-id.
curl https://api.qa.clankership.net/v1/workspaces/acme/vault \ -H "Authorization: Bearer $CLANKER_API_KEY"[ { "id": "Pr4GtY9sLm3B", "workspaceId": "Wk7Qm2RtXa9L", "name": "Storefront", "slug": "storefront", "type": "website", "description": "The customer-facing shop.", "repository": "acme/storefront", "archivedAt": null, "createdAt": "2026-10-01T16:20:00.000Z", "updatedAt": "2026-10-14T09:05:12.000Z", "environments": [ { "id": "En8RqZ2vKp5D", "slug": "staging", "name": "Staging", "class": "non-production" }, { "id": "En1MwX6cTb7F", "slug": "production", "name": "Production", "class": "production" } ], "secrets": [ { "id": "Sc4VnJ7qTr2X", "name": "DATABASE_URL", "values": { "staging": { "isSet": true, "version": 3, "value": "postgres://storefront@db.staging.acme.dev:5432/storefront" }, "production": { "isSet": true, "version": 2 } } } ] }]List a product's secrets
GET/Returns the product's secrets with their current version in each environment the product is deployed to. Non-production values are included; production values never are. Fails with NotFound when the product does not exist or is archived.
Path parameters
slugstringRequiredThe workspace's slug or ID, such as acme.
productSlugstringRequiredThe product's slug, such as storefront.
Returns
Returns an array of objects with these fields. Status 200.
The product's secrets.
idstringRequiredUnique ID of the secret.
namestringRequiredLetters, digits and underscores, starting with a letter or underscore, at most 255 characters and unique on the product, such as DATABASE_URL.
valuesmap of objectsRequiredThe current version in each environment the product is deployed to, keyed by environment slug.
Errors
- 400
InvalidInputThe request is malformed, or a value is not allowed.- 401
UnauthorizedThe request has no valid API key.- 403
ForbiddenThe key's user or role may not do this.- 404
NotFoundThe workspace or object does not exist, or the caller cannot see it.- 409
ConflictThe change conflicts with current data, such as a slug that is already in use.- 500
InternalClanker Ship failed to handle the request. Retry, or report the response's x-request-id.
curl https://api.qa.clankership.net/v1/workspaces/acme/products/{productSlug}/secrets \ -H "Authorization: Bearer $CLANKER_API_KEY"[ { "id": "Sc4VnJ7qTr2X", "name": "DATABASE_URL", "values": { "staging": { "isSet": true, "version": 3, "value": "postgres://storefront@db.staging.acme.dev:5432/storefront" }, "production": { "isSet": true, "version": 2 } } }]Create a secret
POST/Adds a secret name to the product and sets any values sent, returning one result per value. Viewers cannot create secrets, a member's production values come back skipped, and a name already on the product fails with Conflict.
Path parameters
slugstringRequiredThe workspace's slug or ID, such as acme.
productSlugstringRequiredThe product's slug, such as storefront.
Body parameters
namestringRequiredLetters, digits and underscores, starting with a letter or underscore, at most 255 characters and unique on the product, such as DATABASE_URL.
valuesmap of stringsFirst values keyed by environment slug, each at most 64 KiB. The product must be deployed to each environment. null or an empty string records it as unset.
requestIdstringYour own ID for this request, up to 100 characters, stored with each first value. Unlike other secret writes, a retry fails with Conflict once the first attempt has created the name.
Returns
Returns an array of objects with these fields. Status 200.
One result per product and environment, sorted by product and then environment slug.
productstringRequiredThe product's slug, such as storefront.
environmentstringRequiredThe environment's slug, such as staging.
statusstringRequiredwritten when the environment holds the value, or skipped when the caller's role may not write there, such as a member writing production.
writtenskippedversionintegerThe version that holds the value. A retry with the same requestId returns the first write's version. Absent when skipped.
publicKeystringThe SPKI PEM public key, present when the value is an Ed25519 key pair.
valuestringThe generated value. Present only when a generation sends reveal: true, and never on a retry.
Errors
- 400
InvalidInputThe request is malformed, or a value is not allowed.- 401
UnauthorizedThe request has no valid API key.- 403
ForbiddenThe key's user or role may not do this.- 404
NotFoundThe workspace or object does not exist, or the caller cannot see it.- 409
ConflictThe change conflicts with current data, such as a slug that is already in use.- 500
InternalClanker Ship failed to handle the request. Retry, or report the response's x-request-id.
curl -X POST https://api.qa.clankership.net/v1/workspaces/acme/products/{productSlug}/secrets \ -H "Authorization: Bearer $CLANKER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "DATABASE_URL", "values": { "staging": "postgres://storefront@db.staging.acme.dev:5432/storefront" }, "requestId": "5b0e8f3a-2c41-4d9e-9a7b-61f2c3d4e5a6" }'[ { "product": "storefront", "environment": "staging", "status": "written", "version": 4 }]Get a secret
GET/Returns the secret with its product, the environments the product is deployed to, and the current version in each. The plaintext value appears only for non-production environments. Fails with Conflict while the product is archived.
Path parameters
slugstringRequiredThe workspace's slug or ID, such as acme.
productSlugstringRequiredThe product's slug, such as storefront.
namestringRequiredThe secret's name, such as DATABASE_URL.
Returns
Returns the Secret object. Status 200.
Errors
- 400
InvalidInputThe request is malformed, or a value is not allowed.- 401
UnauthorizedThe request has no valid API key.- 403
ForbiddenThe key's user or role may not do this.- 404
NotFoundThe workspace or object does not exist, or the caller cannot see it.- 409
ConflictThe change conflicts with current data, such as a slug that is already in use.- 500
InternalClanker Ship failed to handle the request. Retry, or report the response's x-request-id.
curl https://api.qa.clankership.net/v1/workspaces/acme/products/{productSlug}/secrets/{name} \ -H "Authorization: Bearer $CLANKER_API_KEY"{ "id": "Sc4VnJ7qTr2X", "name": "DATABASE_URL", "createdAt": "2026-10-01T16:20:00.000Z", "product": { "id": "Pr4GtY9sLm3B", "slug": "storefront", "name": "Storefront", "type": "website" }, "environments": [ { "id": "En8RqZ2vKp5D", "slug": "staging", "name": "Staging", "class": "non-production" }, { "id": "En1MwX6cTb7F", "slug": "production", "name": "Production", "class": "production" } ], "values": { "staging": { "version": 3, "isSet": true, "generator": null, "publicKey": null, "restoredFrom": null, "createdAt": "2026-10-14T09:05:12.000Z", "actor": { "id": "Us3NfP8kLq2V", "type": "user", "name": "Maya Patel" }, "value": "postgres://storefront@db.staging.acme.dev:5432/storefront" }, "production": { "version": 2, "isSet": true, "generator": null, "publicKey": null, "restoredFrom": null, "createdAt": "2026-10-01T16:20:00.000Z", "actor": { "id": "Us3NfP8kLq2V", "type": "user", "name": "Maya Patel" } } }}Update a secret
PATCH/Renames the secret, sets or clears values, or both, in one transaction, and returns one result per value sent. Viewers cannot update secrets, and a member's production values come back skipped. A taken name, a stale expectedVersions entry or a requestId already used for a different write fails with Conflict, and nothing is saved.
Path parameters
slugstringRequiredThe workspace's slug or ID, such as acme.
productSlugstringRequiredThe product's slug, such as storefront.
namestringRequiredThe secret's name, such as DATABASE_URL.
Body parameters
newNamestringA new name for the secret, unique on the product.
valuesmap of stringsNew values keyed by environment slug, each at most 64 KiB. null or an empty string clears a value, and environments left out keep theirs.
expectedVersionsmap of integersThe version you last saw in each environment you are changing, keyed by environment slug, with 0 for one that has no version. If any has changed since, nothing is saved and the request fails with Conflict.
requestIdstringYour own ID for this request, up to 100 characters. Sending the same ID again returns the first result instead of writing twice.
Returns
Returns an array of objects with these fields. Status 200.
One result per product and environment, sorted by product and then environment slug.
productstringRequiredThe product's slug, such as storefront.
environmentstringRequiredThe environment's slug, such as staging.
statusstringRequiredwritten when the environment holds the value, or skipped when the caller's role may not write there, such as a member writing production.
writtenskippedversionintegerThe version that holds the value. A retry with the same requestId returns the first write's version. Absent when skipped.
publicKeystringThe SPKI PEM public key, present when the value is an Ed25519 key pair.
valuestringThe generated value. Present only when a generation sends reveal: true, and never on a retry.
Errors
- 400
InvalidInputThe request is malformed, or a value is not allowed.- 401
UnauthorizedThe request has no valid API key.- 403
ForbiddenThe key's user or role may not do this.- 404
NotFoundThe workspace or object does not exist, or the caller cannot see it.- 409
ConflictThe change conflicts with current data, such as a slug that is already in use.- 500
InternalClanker Ship failed to handle the request. Retry, or report the response's x-request-id.
curl -X PATCH https://api.qa.clankership.net/v1/workspaces/acme/products/{productSlug}/secrets/{name} \ -H "Authorization: Bearer $CLANKER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "values": { "staging": "postgres://storefront@db-2.staging.acme.dev:5432/storefront" }, "expectedVersions": { "staging": 3 }, "requestId": "5b0e8f3a-2c41-4d9e-9a7b-61f2c3d4e5a6" }'[ { "product": "storefront", "environment": "staging", "status": "written", "version": 4 }]Delete a secret
DELETE/Deletes the secret and every version of it in every environment. Viewers cannot delete secrets, and only admins and owners can delete one that has a production value.
Path parameters
slugstringRequiredThe workspace's slug or ID, such as acme.
productSlugstringRequiredThe product's slug, such as storefront.
namestringRequiredThe secret's name, such as DATABASE_URL.
Returns
Returns an object with these fields. Status 200.
okbooleanRequiredAlways true: the change was made.
trueErrors
- 400
InvalidInputThe request is malformed, or a value is not allowed.- 401
UnauthorizedThe request has no valid API key.- 403
ForbiddenThe key's user or role may not do this.- 404
NotFoundThe workspace or object does not exist, or the caller cannot see it.- 409
ConflictThe change conflicts with current data, such as a slug that is already in use.- 500
InternalClanker Ship failed to handle the request. Retry, or report the response's x-request-id.
curl -X DELETE https://api.qa.clankership.net/v1/workspaces/acme/products/{productSlug}/secrets/{name} \ -H "Authorization: Bearer $CLANKER_API_KEY"{ "ok": true}Set a secret across products and environments
POST/Writes one value to every product and environment pair, up to 200 pairs, in one transaction, and creates the secret name on any product that lacks it. Every pair must be a deployment whose product and environment are active. Viewers cannot assign values, and a member's production pairs come back skipped.
Path parameters
slugstringRequiredThe workspace's slug or ID, such as acme.
Body parameters
productsarray of stringsRequiredSlugs of the products to write, such as storefront.
environmentsarray of stringsRequiredSlugs of the environments to write, such as staging. Each product must be deployed to each of them.
namestringRequiredLetters, digits and underscores, starting with a letter or underscore, at most 255 characters and unique on the product, such as DATABASE_URL.
valuenullable stringRequiredThe value to set, at most 64 KiB. null or an empty string clears it.
requestIdstringYour own ID for this request, up to 100 characters. Sending the same ID again returns the first result instead of writing twice.
Returns
Returns an array of objects with these fields. Status 200.
One result per product and environment, sorted by product and then environment slug.
productstringRequiredThe product's slug, such as storefront.
environmentstringRequiredThe environment's slug, such as staging.
statusstringRequiredwritten when the environment holds the value, or skipped when the caller's role may not write there, such as a member writing production.
writtenskippedversionintegerThe version that holds the value. A retry with the same requestId returns the first write's version. Absent when skipped.
publicKeystringThe SPKI PEM public key, present when the value is an Ed25519 key pair.
valuestringThe generated value. Present only when a generation sends reveal: true, and never on a retry.
Errors
- 400
InvalidInputThe request is malformed, or a value is not allowed.- 401
UnauthorizedThe request has no valid API key.- 403
ForbiddenThe key's user or role may not do this.- 404
NotFoundThe workspace or object does not exist, or the caller cannot see it.- 409
ConflictThe change conflicts with current data, such as a slug that is already in use.- 500
InternalClanker Ship failed to handle the request. Retry, or report the response's x-request-id.
curl -X POST https://api.qa.clankership.net/v1/workspaces/acme/vault/assignments \ -H "Authorization: Bearer $CLANKER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "products": [ "storefront" ], "environments": [ "staging" ], "name": "LOG_LEVEL", "value": "debug", "requestId": "5b0e8f3a-2c41-4d9e-9a7b-61f2c3d4e5a6" }'[ { "product": "storefront", "environment": "staging", "status": "written", "version": 4 }]Generate a secret value
POST/Generates one value per environment on the server and writes it to every selected product there, so products share a value within an environment and no value crosses environments. Targets, limits and roles work as when setting a secret across products. Values come back only with reveal: true, and a retry with the same requestId returns the first versions without values.
Path parameters
slugstringRequiredThe workspace's slug or ID, such as acme.
Body parameters
productsarray of stringsRequiredSlugs of the products to write, such as storefront.
environmentsarray of stringsRequiredSlugs of the environments to write, such as staging. Each product must be deployed to each of them.
namestringRequiredLetters, digits and underscores, starting with a letter or underscore, at most 255 characters and unique on the product, such as DATABASE_URL.
generatorobjectRequiredWhat to generate. Options left out use their defaults.
revealbooleanReturn each generated value in this response. Defaults to false.
requestIdstringYour own ID for this request, up to 100 characters. Sending the same ID again returns the first result instead of writing twice.
Returns
Returns an array of objects with these fields. Status 200.
One result per product and environment, sorted by product and then environment slug.
productstringRequiredThe product's slug, such as storefront.
environmentstringRequiredThe environment's slug, such as staging.
statusstringRequiredwritten when the environment holds the value, or skipped when the caller's role may not write there, such as a member writing production.
writtenskippedversionintegerThe version that holds the value. A retry with the same requestId returns the first write's version. Absent when skipped.
publicKeystringThe SPKI PEM public key, present when the value is an Ed25519 key pair.
valuestringThe generated value. Present only when a generation sends reveal: true, and never on a retry.
Errors
- 400
InvalidInputThe request is malformed, or a value is not allowed.- 401
UnauthorizedThe request has no valid API key.- 403
ForbiddenThe key's user or role may not do this.- 404
NotFoundThe workspace or object does not exist, or the caller cannot see it.- 409
ConflictThe change conflicts with current data, such as a slug that is already in use.- 500
InternalClanker Ship failed to handle the request. Retry, or report the response's x-request-id.
curl -X POST https://api.qa.clankership.net/v1/workspaces/acme/vault/generations \ -H "Authorization: Bearer $CLANKER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "products": [ "storefront" ], "environments": [ "staging", "production" ], "name": "SESSION_SECRET", "generator": { "type": "token", "bytes": 32 }, "requestId": "5b0e8f3a-2c41-4d9e-9a7b-61f2c3d4e5a6" }'[ { "product": "storefront", "environment": "staging", "status": "written", "version": 4 }]List a secret's versions
GET/Returns up to 100 versions of the secret in one environment, newest first, with who wrote each. Send the oldest version you have as before to get the next page. values=true fails with Forbidden for a production environment.
Path parameters
slugstringRequiredThe workspace's slug or ID, such as acme.
productSlugstringRequiredThe product's slug, such as storefront.
namestringRequiredThe secret's name, such as DATABASE_URL.
environmentSlugstringRequiredThe environment's slug, such as staging.
Query parameters
valuesstringtrue adds each version's plaintext value. Production environments refuse it.
truefalsebeforestringReturn only versions older than this version number, to fetch the next page.
Returns
Returns an array of objects with these fields. Status 200.
Up to 100 versions, newest first.
versionintegerRequiredThe version number. Each write to an environment adds one, starting at 1.
isSetbooleanRequiredFalse when this version cleared the value.
generatornullable objectRequiredHow the value was generated, or null when it was set by hand.
publicKeynullable stringRequiredThe SPKI PEM public key of a generated Ed25519 key pair, or null. It is not secret, so production versions show it too.
restoredFromnullable integerRequiredThe earlier version this version restored, or null.
createdAtstringRequiredWhen the version was written, as an ISO 8601 timestamp.
actornullable objectRequiredWho wrote the version, or null when they can no longer be found.
valuenullable stringThe plaintext value, or null for a version that cleared it. Present only when the request sends values=true.
Errors
- 400
InvalidInputThe request is malformed, or a value is not allowed.- 401
UnauthorizedThe request has no valid API key.- 403
ForbiddenThe key's user or role may not do this.- 404
NotFoundThe workspace or object does not exist, or the caller cannot see it.- 409
ConflictThe change conflicts with current data, such as a slug that is already in use.- 500
InternalClanker Ship failed to handle the request. Retry, or report the response's x-request-id.
curl https://api.qa.clankership.net/v1/workspaces/acme/products/{productSlug}/secrets/{name}/environments/{environmentSlug}/versions \ -H "Authorization: Bearer $CLANKER_API_KEY"[ { "version": 3, "isSet": true, "generator": null, "publicKey": null, "restoredFrom": null, "createdAt": "2026-10-14T09:05:12.000Z", "actor": { "id": "Us3NfP8kLq2V", "type": "user", "name": "Maya Patel" }, "value": "postgres://storefront@db.staging.acme.dev:5432/storefront" }]Restore a secret version
POST/Writes a new version with an earlier version's value, generator and public key, and records which version it restored. Restoring a version that cleared the value clears it again. Viewers cannot restore, and members cannot restore production versions.
Path parameters
slugstringRequiredThe workspace's slug or ID, such as acme.
productSlugstringRequiredThe product's slug, such as storefront.
namestringRequiredThe secret's name, such as DATABASE_URL.
environmentSlugstringRequiredThe environment's slug, such as staging.
Body parameters
versionintegerRequiredThe version to restore.
requestIdstringYour own ID for this request, up to 100 characters. Sending the same ID again returns the first result instead of writing twice.
Returns
Returns an array of objects with these fields. Status 200.
One result per product and environment, sorted by product and then environment slug.
productstringRequiredThe product's slug, such as storefront.
environmentstringRequiredThe environment's slug, such as staging.
statusstringRequiredwritten when the environment holds the value, or skipped when the caller's role may not write there, such as a member writing production.
writtenskippedversionintegerThe version that holds the value. A retry with the same requestId returns the first write's version. Absent when skipped.
publicKeystringThe SPKI PEM public key, present when the value is an Ed25519 key pair.
valuestringThe generated value. Present only when a generation sends reveal: true, and never on a retry.
Errors
- 400
InvalidInputThe request is malformed, or a value is not allowed.- 401
UnauthorizedThe request has no valid API key.- 403
ForbiddenThe key's user or role may not do this.- 404
NotFoundThe workspace or object does not exist, or the caller cannot see it.- 409
ConflictThe change conflicts with current data, such as a slug that is already in use.- 500
InternalClanker Ship failed to handle the request. Retry, or report the response's x-request-id.
curl -X POST https://api.qa.clankership.net/v1/workspaces/acme/products/{productSlug}/secrets/{name}/environments/{environmentSlug}/restore \ -H "Authorization: Bearer $CLANKER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "version": 2, "requestId": "5b0e8f3a-2c41-4d9e-9a7b-61f2c3d4e5a6" }'[ { "product": "storefront", "environment": "staging", "status": "written", "version": 4 }]Pull an environment's secrets
GET/Returns the current value of every set secret for one deployment, keyed by secret name; the product and environment must be active. Production pulls need a vault key (ctvk_…) scoped to the product and environment, and every attempt is recorded in the vault audit log. Non-production pulls take a user API key, account API key or CLI login for the workspace and refuse vault keys.
Path parameters
slugstringRequiredThe workspace's slug or ID, such as acme.
productSlugstringRequiredThe product's slug, such as storefront.
environmentSlugstringRequiredThe environment's slug, such as staging.
Returns
Returns a map of strings. Status 200.
Each set secret's current value, keyed by secret name. Unset secrets are left out.
Errors
- 400
InvalidInputThe request is malformed, or a value is not allowed.- 401
UnauthorizedThe request has no valid API key.- 403
ForbiddenThe key's user or role may not do this.- 404
NotFoundThe workspace or object does not exist, or the caller cannot see it.- 409
ConflictThe change conflicts with current data, such as a slug that is already in use.- 500
InternalClanker Ship failed to handle the request. Retry, or report the response's x-request-id.
curl https://api.qa.clankership.net/v1/workspaces/acme/products/{productSlug}/environments/{environmentSlug}/secrets/pull \ -H "Authorization: Bearer $CLANKER_API_KEY"{ "DATABASE_URL": "postgres://storefront@db.staging.acme.dev:5432/storefront", "LOG_LEVEL": "debug"}