Manage service accounts, Credits limits, long-lived keys, and short-lived tokens.
About this document
Service accounts let applications and automation use Qoder without creating an organization member or occupying a member seat. Enable the service account capability for your organization before using these APIs.
Read Conventions and Get API Key first. Base URL: https://api.qoder.com. Replace all example IDs with real resource UUIDs from your organization; the example UUIDs do not identify existing resources.
Requirements
| Operation | Bearer credential |
|---|---|
| Manage accounts and long-lived keys | Organization API key belonging to the organization in the path |
| Issue a short-lived token | Valid long-lived key belonging to the service account in the path |
Authorization: Bearer <credential>. An organization API key or short-lived token cannot replace the service account's own long-lived key when issuing a token.
API list
1. Create service account
POST /v1/organizations/{organization_id}/service-accounts
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
organization_id | string | Yes | Organization ID |
Request body
Create requires name.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Trimmed; 1–100 characters; unique within the organization |
description | string | No | Optional, trimmed, up to 500 characters; an empty string clears it on update |
limitAmount | float64 | No | Optional: -1 means no independent limit; 0 freezes new Credits consumption; a finite positive value caps consumption. Defaults to -1 on create |
Success response (201 Created)
Response fields
| Field | Type | Description |
|---|---|---|
id, organizationId | string | Account UUID and organization UUID |
name | string | Account name, unique within the organization |
description | string | Optional; omitted when empty |
status | string | active or archived |
tokenValidAfter | string | Optional token validity boundary, UTC RFC 3339 |
createdBy | string | ID of the creating principal |
createdAt, updatedAt | string | UTC RFC 3339 timestamps |
activeKeyCount | int32 | Number of active, unexpired long-lived keys |
lastUsedAt | string | Last successful use; omitted if never used |
limitAmount | float64 | Credits limit for the current organization billing period |
usedAmount | float64 | Credits used in that billing period |
2. List service accounts
GET /v1/organizations/{organization_id}/service-accounts
The response contains serviceAccounts (array of account objects), maxResults (int32), and optional nextToken. Empty results use []. A final page may contain records; stop when nextToken is absent, not when the array is empty.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
organization_id | string | Yes | Organization ID |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
status | string | No | active or archived; omit to include either status |
keyword | string | No | Case-insensitive keyword search across name and description; trimmed, up to 500 characters; Default: None |
maxResults | integer | No | Page size, maximum 100; Default: 20 |
nextToken | string | No | Cursor from the previous response; Default: None |
periodStart and periodEnd, the API selects the latest available period. When a period is available, the list includes an archived account only if its usage was greater than zero in the selected period. See List service accounts for a usage period.
Success response (200 OK)
3. Get service account details
GET /v1/organizations/{organization_id}/service-accounts/{service_account_id}
Get returns 404 if the account does not exist or belongs to another organization.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
organization_id | string | Yes | Organization ID |
service_account_id | string | Yes | Service account ID |
Success response (200 OK)
Returns a service account object. See Create service account for the response example and fields.
4. Update service account
PUT /v1/organizations/{organization_id}/service-accounts/{service_account_id}
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
organization_id | string | Yes | Organization ID |
service_account_id | string | Yes | Service account ID |
Request body
Update requires at least one of name, description, or limitAmount; omitted fields retain their values.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No | Trimmed; 1–100 characters; unique within the organization |
description | string | No | Optional, trimmed, up to 500 characters; an empty string clears it on update |
limitAmount | float64 | No | Optional: -1 means no independent limit; 0 freezes new Credits consumption; a finite positive value caps consumption. Defaults to -1 on create |
Success response (200 OK)
Returns a service account object. See Create service account for the response example and fields.
5. Archive service account
POST /v1/organizations/{organization_id}/service-accounts/{service_account_id}/archive
Archive requires no body, changes status to archived, and revokes all remaining long-lived keys. Archived accounts cannot create or rotate keys. There is no unarchive operation. Repeated archive calls succeed without repeating the state change. Historical usage remains queryable.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
organization_id | string | Yes | Organization ID |
service_account_id | string | Yes | Service account ID |
Success response (200 OK)
Returns the archived service account object: status is archived, activeKeyCount is 0, and tokenValidAfter is the archive time. See Create service account for the remaining field definitions.
6. Create long-lived key
POST /v1/organizations/{organization_id}/service-accounts/{service_account_id}/keys
Plaintext token is returned only when a key is created or rotated. Save it in a server-side secret store immediately; never put it in URLs, logs, source code, or error messages. Lists return only tokenDisplay.
Default limits are 100 active accounts per organization, 5 active unexpired keys per account, and 500 active unexpired keys per organization. Organization configuration can override these limits; revoked or expired keys do not count.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
organization_id | string | Yes | Organization ID |
service_account_id | string | Yes | Service account ID |
Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Trimmed; 1–100 characters |
scope | string | Yes | Space-separated scopes; no empty or duplicate scopes; up to 20 scopes, each up to 100 characters. Confirm available scopes with the Qoder implementation team |
expiresAt | string | No | RFC 3339 timestamp strictly later than the current time |
Success response (201 Created)
Response fields
| Field | Type | Description |
|---|---|---|
id, organizationId, serviceAccountId | string | Key, organization, and account UUIDs |
name, scope | string | Key name and space-separated permissions |
tokenDisplay | string | Masked value; cannot authenticate requests |
status | string | active or revoked |
expiresAt | string | Optional expiration timestamp; omitted when unset |
lastUsedAt | string | Optional last successful use timestamp; omitted if never used |
createdBy | string | ID of the creating principal |
createdAt, updatedAt | string | UTC RFC 3339 timestamps |
isExpired | boolean | Whether the key has expired |
token | string | Returned only on create or rotate |
status=active does not guarantee usability: a key with isExpired=true cannot authenticate.
7. List long-lived keys
GET /v1/organizations/{organization_id}/service-accounts/{service_account_id}/keys
List accepts optional status (active or revoked, all by default), maxResults (default 20, max 100), and nextToken. It returns keys (array of key resources without token), maxResults, and optional nextToken; an empty list is [].
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
organization_id | string | Yes | Organization ID |
service_account_id | string | Yes | Service account ID |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
status | string | No | active / revoked; all by default |
maxResults | integer | No | Default 20, maximum 100 |
nextToken | string | No | Cursor from the preceding response |
Success response (200 OK)
8. Rotate long-lived key
POST /v1/organizations/{organization_id}/service-accounts/{service_account_id}/keys/{key_id}/rotate
Rotate requires no body. It creates a key inheriting the original name, scopes, and expiration, revokes the old key, and returns the new plaintext token once. Revoked or expired keys cannot rotate. For an overlap during migration, create a separate key, switch callers, then revoke the old key.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
organization_id | string | Yes | Organization ID |
service_account_id | string | Yes | Service account ID |
key_id | string | Yes | Key ID |
Success response (201 Created)
Returns a new key object with its one-time plaintext token. See Create long-lived key for the response example and fields.
9. Revoke long-lived key
DELETE /v1/organizations/{organization_id}/service-accounts/{service_account_id}/keys/{key_id}
Revoke requires no body and returns 204 No Content; repeating it for the same key succeeds. Revoked keys cannot authenticate or rotate.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
organization_id | string | Yes | Organization ID |
service_account_id | string | Yes | Service account ID |
key_id | string | Yes | Key ID |
Success response (204 No Content)
Returns 204 No Content with no response body.
10. Issue short-lived token
POST /v1/organizations/{organization_id}/service-accounts/{service_account_id}/tokens
Authenticate with the target account's own long-lived key:
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
organization_id | string | Yes | Organization ID |
service_account_id | string | Yes | Service account ID |
Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
scope | string | Yes | Nonempty, space-separated subset of the source key's scopes; at most 2,048 characters and 20 distinct scopes, each up to 100 characters |
expirationSeconds | integer | No | Omitted or 0: default 3,600 seconds. Otherwise 1–43,200 seconds, capped by the source key's remaining lifetime |
customId | string | No | 1–128 ASCII characters; first character alphanumeric, subsequent characters alphanumeric or ._:/@+-; used for audit attribution |
null, and incorrect types are rejected.
Success response (200 OK)
accessToken, tokenType, and expiresAt are strings; expiresIn is an integer in seconds. Success includes Cache-Control: no-store and Pragma: no-cache. Each successful call issues a new token and is not idempotent. Use the token as an opaque credential; do not parse its internals or log it.
Revoking the source key or archiving the account invalidates its credentials. Already-issued tokens may remain accepted until the gateway's credential-status cache refreshes, or until token expiry, whichever comes first. Do not assume instantaneous token revocation; confirm the cache interval for your deployment.
Usage examples
Create service account
List service accounts
Get service account details
Update service account
Archive service account
Create long-lived key
List long-lived keys
Rotate long-lived key
Revoke long-lived key
Issue short-lived token
Error codes
Errors contain requestId, code, and message, with optional details:
| HTTP | Example codes | Meaning |
|---|---|---|
400 | BadRequest, ServiceAccountLimitAmountInvalid, ServiceAccountArchived, ServiceAccountKeyScopeUnsupported, ServiceAccountKeyLimitExceeded, OrganizationServiceAccountKeyLimitExceeded | Invalid fields, state, scope, or configured limit |
401 | Unauthorized | Missing, invalid, or expired credential |
403 | Forbidden, OrganizationPlanCapabilityForbidden | Wrong credential principal, organization, scope, or disabled capability |
404 | NotFound | Account or key absent or outside the organization |
409 | ServiceAccountNameAlreadyExists, ServiceAccountKeyAlreadyExists | Account name or key conflict |
500 | InternalError | Internal failure |
503 | InternalError or a dependency-specific code | Token issuer or dependency unavailable |
code; do not assume every validation error is BadRequest or every conflict is AlreadyExists.
Use Usage API for historical events and net Credits.