SDKsTypeScript SDKAdmin API
Service Accounts
Manage service accounts and API keys for machine-to-machine authentication with the TypeScript SDK.
Service Accounts
Service accounts represent non-human identities (backend services, CI/CD pipelines, scripts). Each service account has API keys for authentication and scoped permissions.
createServiceAccount()
client.admin.createServiceAccount(params: CreateServiceAccountParams): Promise<ServiceAccount>Parameters
| Name | Type | Required | Description |
|---|---|---|---|
name | string | yes | Display name (e.g., "CI/CD Pipeline") |
description | string | no | Description of the service account's purpose |
organizationId | string | yes | Organization this service account belongs to |
scopes | string[] | yes | Permission scopes (e.g., ["users:read", "webhooks:write"]) |
ownerId | string | yes | Human owner responsible for this service account |
Basic usage
const sa = await client.admin.createServiceAccount({
name: "GitHub Actions Deploy",
description: "Used by CI/CD to sync users on deploy",
organizationId: "org_abc123",
scopes: ["users:read", "users:write"],
ownerId: "usr_jane",
});
console.log(sa.id); // "sa_abc123"
console.log(sa.name); // "GitHub Actions Deploy"
console.log(sa.status); // "active"createApiKey()
Generate an API key for a service account. The full key is returned only once.
client.admin.createApiKey(params: CreateApiKeyParams): Promise<ApiKey>Parameters
| Name | Type | Required | Description |
|---|---|---|---|
serviceAccountId | string | yes | Service account ID |
name | string | yes | Key name (e.g., "production-key") |
expiresIn | number | no | TTL in seconds (default: no expiry) |
scopes | string[] | no | Subset of the service account's scopes |
Returns
interface ApiKey {
id: string; // Key ID
key: string; // Full API key (shown ONCE -- starts with "ak_live_")
prefix: string; // Key prefix for identification (e.g., "ak_live_abc1")
name: string; // Display name
scopes: string[]; // Granted scopes
expiresAt: string | null;
createdAt: string;
}Basic usage
const apiKey = await client.admin.createApiKey({
serviceAccountId: "sa_abc123",
name: "production-key",
expiresIn: 90 * 24 * 3600, // 90 days
scopes: ["users:read"], // Subset of SA's scopes
});
console.log("Save this key -- it will not be shown again:");
console.log(apiKey.key); // "ak_live_abc123def456..."rotateApiKey()
Rotate an API key with a grace period during which both old and new keys are valid.
client.admin.rotateApiKey(params: RotateApiKeyParams): Promise<ApiKey>Parameters
| Name | Type | Required | Description |
|---|---|---|---|
apiKeyId | string | yes | ID of the key to rotate |
gracePeriodHours | number | no | Hours both keys are valid (default: 24) |
Basic usage
const newKey = await client.admin.rotateApiKey({
apiKeyId: "key_abc123",
gracePeriodHours: 48,
});
console.log("New key:", newKey.key);
console.log("Old key remains valid for 48 hours.");listServiceAccounts()
const result = await client.admin.listServiceAccounts({
organizationId: "org_abc123",
pageSize: 25,
});
for (const sa of result.serviceAccounts) {
console.log(sa.id, sa.name, sa.status, sa.lastUsedAt);
}Common errors
| Error class | HTTP status | When |
|---|---|---|
NotFoundError | 404 | Service account or key not found |
ForbiddenError | 403 | Insufficient permissions |
DuplicateError | 409 | Key name already exists |
See also
- Client credentials -- M2M token flow
- Users -- User management