apiKeys
The methods of pd.apiKeys. Inputs and outputs are described in Conventions; every method can also fail as described in Errors.
Methods
pd.apiKeys.list(input, init?)
List a workspace's API keys
GET /api/workspaces/{workspaceId}/api-keys
Needs api_keys.read. Never returns the key itself: only its prefix, role and lifecycle dates. Revoked and expired keys stay listed (check revokedAt and expiresAt), in no guaranteed order. A revoked or expired key whose role was deleted is listed with roleId null.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspaceId |
path | string (uuid) |
yes | Id of the workspace the request works in. The caller must be a member of it, or hold an API key issued by it. For anyone else, an unknown id and an id they do not belong to both answer 404 RESOURCE_NOT_FOUND, so membership cannot be probed. |
init |
init | { signal?: AbortSignal; timeoutMs?: number } |
no | The second argument: signal aborts the call, timeoutMs overrides the client's per-attempt timeout. |
Returns 200 OK
| Field | Type | Required | Description |
|---|---|---|---|
apiKeys |
object[] |
yes | Every key of the workspace, revoked and expired ones included. |
apiKeys[].id |
string (uuid) |
yes | Id of the key, used to revoke or rotate it. |
apiKeys[].label |
string |
yes | The name given to the key, to tell keys apart. |
apiKeys[].prefix |
string |
yes | The first 16 characters of the key (pd_live_ and the start of the secret), to recognise it by. Not enough to use it. |
apiKeys[].roleId |
string (uuid) | null |
yes | The key acts with this role's permissions. null once the role was deleted (only a revoked or expired key loses its role): the key can no longer be used, and stays in the list so what it did stays attributed to it. |
apiKeys[].createdAt |
string (date-time) |
yes | When the key was created, as an ISO 8601 timestamp. |
apiKeys[].lastUsedAt |
string (date-time) | null |
yes | When a request last authenticated with the key; null if it never has. |
apiKeys[].expiresAt |
string (date-time) | null |
yes | When the key stops working; null for a key that does not expire. |
apiKeys[].revokedAt |
string (date-time) | null |
yes | When the key was revoked or rotated away; null while it can still be used. |
Errors 400 invalid input, 401 missing or invalid key, 403 the key's roles lack the permission, 404 not found, 429 rate limited or out of quota. See Errors.
Example
import { PrismDraft } from "@prism-draft/sdk";
const pd = new PrismDraft({ apiKey: process.env.PRISMDRAFT_API_KEY! });
const result = await pd.apiKeys.list({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);
pd.apiKeys.create(input, init?)
Create an API key
POST /api/workspaces/{workspaceId}/api-keys
Needs api_keys.create. The key is returned once, in this response, and cannot be retrieved again: only a hash of it is stored, so a lost key is replaced, not recovered. It looks like pd_live_ followed by a secret and is sent as Authorization: Bearer <key>. It acts with the permissions of the role it carries, inside this workspace, until it expires or is revoked. A key cannot carry a role that holds a permission the caller lacks: 403 FORBIDDEN, with those permissions in details.permissions. Records an api_keys.created audit entry and answers 201. 409 CONFLICT with details.reason role_deleted when the role is deleted while the key is being made.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspaceId |
path | string (uuid) |
yes | Id of the workspace the request works in. The caller must be a member of it, or hold an API key issued by it. For anyone else, an unknown id and an id they do not belong to both answer 404 RESOURCE_NOT_FOUND, so membership cannot be probed. |
body |
body | object |
yes | |
body.label |
body | string |
yes | Name for the key, 1 to 120 characters, to tell keys apart in the list. It need not be unique. |
body.roleId |
body | string (uuid) |
yes | Id of the role the key acts with (GET .../roles): requests made with the key can do what that role grants, in this workspace only, and follow later edits to the role. It must belong to this workspace, else 400 INVALID_REQUEST, and it may only hold permissions the caller holds, else 403 FORBIDDEN. |
body.expiresAt |
body | string (date-time) |
no | When the key stops working, an ISO 8601 date-time such as 2027-01-31T00:00:00Z. Omitted: the key does not expire. The date is not checked against the clock, so a date in the past gives a key that is already expired. |
init |
init | { signal?: AbortSignal; timeoutMs?: number } |
no | The second argument: signal aborts the call, timeoutMs overrides the client's per-attempt timeout. |
Returns 201 Created
| Field | Type | Required | Description |
|---|---|---|---|
apiKey |
object |
yes | The key's record, without the secret. |
apiKey.id |
string (uuid) |
yes | Id of the new key, as listed by GET .../api-keys. |
apiKey.prefix |
string |
yes | The first 16 characters of key, to recognise it by. |
apiKey.label |
string |
yes | The name given to the key, to tell keys apart in GET .../api-keys. |
key |
string |
yes | The raw API key. It is returned once, in this response, and cannot be retrieved again. |
Errors 400 invalid input, 401 missing or invalid key, 403 the key's roles lack the permission, 404 not found, 429 rate limited or out of quota. See Errors.
Example
import { PrismDraft } from "@prism-draft/sdk";
const pd = new PrismDraft({ apiKey: process.env.PRISMDRAFT_API_KEY! });
const result = await pd.apiKeys.create({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
body: {
label: "example",
roleId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
},
});
console.log(result);
pd.apiKeys.revoke(input, init?)
Revoke an API key
DELETE /api/workspaces/{workspaceId}/api-keys/{keyId}
Needs api_keys.revoke. The key stops authenticating at once; this cannot be undone (create a new key instead). The key stays in the list with revokedAt set. 404 RESOURCE_NOT_FOUND when the key is unknown or already revoked. Records an api_keys.revoked audit entry.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspaceId |
path | string (uuid) |
yes | Id of the workspace the request works in. The caller must be a member of it, or hold an API key issued by it. For anyone else, an unknown id and an id they do not belong to both answer 404 RESOURCE_NOT_FOUND, so membership cannot be probed. |
keyId |
path | string (uuid) |
yes | Id of an API key of this workspace, as id in GET .../api-keys (not the key itself). A key of another workspace answers 404 RESOURCE_NOT_FOUND. |
init |
init | { signal?: AbortSignal; timeoutMs?: number } |
no | The second argument: signal aborts the call, timeoutMs overrides the client's per-attempt timeout. |
Returns 200 OK
| Field | Type | Required | Description |
|---|---|---|---|
ok |
true |
yes | Always true: the change was made. A failure answers an error. |
Errors 400 invalid input, 401 missing or invalid key, 403 the key's roles lack the permission, 404 not found, 429 rate limited or out of quota. See Errors.
Example
import { PrismDraft } from "@prism-draft/sdk";
const pd = new PrismDraft({ apiKey: process.env.PRISMDRAFT_API_KEY! });
const result = await pd.apiKeys.revoke({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
keyId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);
pd.apiKeys.rotate(input, init?)
Rotate an API key
POST /api/workspaces/{workspaceId}/api-keys/{keyId}/rotate
Needs both api_keys.create and api_keys.revoke. Issues a new key with the same label, role and expiry and revokes the old one, in one transaction: the old key stops working at once, with no overlap, so deploy the new one right away. The new key is returned once, in this response. The expiry is carried over, not extended. The same rule as creating applies to the key's role: 403 FORBIDDEN when it holds a permission the caller lacks, and the old key is left as it was. 404 RESOURCE_NOT_FOUND when the key is unknown or already revoked; an expired key answers 400 INVALID_REQUEST and is left as it was, and a key whose role was deleted answers 409 CONFLICT with details.reason role_deleted. Records api_keys.created and api_keys.revoked audit entries. Answers 201.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspaceId |
path | string (uuid) |
yes | Id of the workspace the request works in. The caller must be a member of it, or hold an API key issued by it. For anyone else, an unknown id and an id they do not belong to both answer 404 RESOURCE_NOT_FOUND, so membership cannot be probed. |
keyId |
path | string (uuid) |
yes | Id of an API key of this workspace, as id in GET .../api-keys (not the key itself). A key of another workspace answers 404 RESOURCE_NOT_FOUND. |
init |
init | { signal?: AbortSignal; timeoutMs?: number } |
no | The second argument: signal aborts the call, timeoutMs overrides the client's per-attempt timeout. |
Returns 201 Created
| Field | Type | Required | Description |
|---|---|---|---|
apiKey |
object |
yes | The key's record, without the secret. |
apiKey.id |
string (uuid) |
yes | Id of the new key, as listed by GET .../api-keys. |
apiKey.prefix |
string |
yes | The first 16 characters of key, to recognise it by. |
apiKey.label |
string |
yes | The name given to the key, to tell keys apart in GET .../api-keys. |
key |
string |
yes | The raw API key. It is returned once, in this response, and cannot be retrieved again. |
Errors 400 invalid input, 401 missing or invalid key, 403 the key's roles lack the permission, 404 not found, 429 rate limited or out of quota. See Errors.
Example
import { PrismDraft } from "@prism-draft/sdk";
const pd = new PrismDraft({ apiKey: process.env.PRISMDRAFT_API_KEY! });
const result = await pd.apiKeys.rotate({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
keyId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);