Skip to main content

Account Management

An account is the tenant boundary: every credential, project, executor and job belongs to exactly one account, identified by the X-Account-ID header. On the hosted service accounts are created and managed for you by the dashboard. The endpoints on this page exist for self-hosted operators who administer accounts directly.

Who can call these endpoints​

Everything under /accounts and /account requires either:

  • a credential carrying the admin scope, or
  • HTTP Basic Auth with the server's operator username/password plus the header X-Peer: cmd.

Ordinary read/write/execute credentials receive 403. An admin credential can only address its own account ({id} must equal X-Account-ID, otherwise 403); operator Basic Auth can address any account.

Two related endpoints are not operator-only and are documented elsewhere: GET /features (read scope) and GET /async-tasks/{id} (read scope).

Account object​

{
"id": 42,
"name": "Acme Corp",
"features": [
{ "accountId": 42, "featureId": 3, "feature": "increased_retry_max_by_five" }
],
"dateCreated": "2026-01-01T00:00:00Z",
"dateModified": null
}

Endpoints​

MethodPathNotes
POST/accountsCreate → 201
GET/accounts/{id}Read
PUT/accounts/{id}Rename
GET/accounts/{id}/execution-countRemaining execution allowance
PUT/accounts/{id}/execution-countAdd to the allowance
GET/accounts/{id}/ai/usageAI request quota usage
GET/accounts/{id}/tokensToken balance
PUT/accounts/{id}/tokens/addAdd tokens
PUT/accounts/{id}/featureEnable a feature → 201
DELETE/accounts/{id}/featureDisable a feature → 204
PUT/accounts/{id}/features/allEnable every feature
DELETE/accounts/{id}/features/allDisable every feature
POST/account/rotate-secretRe-encrypt stored secrets after changing the server key
GET/featuresFeature catalog (read scope)

The examples below use operator Basic Auth. Substitute the three API-key headers if you are using an admin credential.

Create, read, rename​

curl -X POST "https://scheduler.example.com/api/v1/accounts" \
-u "$SCHEDULER0_USER:$SCHEDULER0_PASSWORD" -H "X-Peer: cmd" \
-H "Content-Type: application/json" \
-d '{"name": "Acme Corp"}'

curl "https://scheduler.example.com/api/v1/accounts/42" \
-u "$SCHEDULER0_USER:$SCHEDULER0_PASSWORD" -H "X-Peer: cmd"

curl -X PUT "https://scheduler.example.com/api/v1/accounts/42" \
-u "$SCHEDULER0_USER:$SCHEDULER0_PASSWORD" -H "X-Peer: cmd" \
-H "Content-Type: application/json" \
-d '{"name": "Acme Corporation"}'

name is required and must be non-empty. A new account starts with no features and the default execution allowance. To let the account call the API, create a credential for it (see Credentials); only an admin/operator can create a credential with the admin scope.

Execution count​

Each account has a monthly execution allowance: 1,000 executions by default, 100,000 with the increased_number_of_job_executions_100_k_per_month feature. Every job run decrements executionCount; when it reaches zero all of the account's jobs are set to inactive and stop firing until the allowance is topped up (account 1 is exempt). nextResetDate records when the current period ends.

curl "https://scheduler.example.com/api/v1/accounts/42/execution-count" \
-u "$SCHEDULER0_USER:$SCHEDULER0_PASSWORD" -H "X-Peer: cmd"
{
"success": true,
"data": {
"id": 7,
"accountId": 42,
"executionCount": 850,
"tokens": 0,
"dateCreated": "2026-01-01T00:00:00Z",
"dateModified": "2026-01-15T10:00:00Z",
"nextResetDate": "2026-02-01T00:00:00Z"
}
}

Add to the allowance:

curl -X PUT "https://scheduler.example.com/api/v1/accounts/42/execution-count" \
-u "$SCHEDULER0_USER:$SCHEDULER0_PASSWORD" -H "X-Peer: cmd" \
-H "Content-Type: application/json" \
-d '{"count": 1000}'
{ "success": true, "data": { "newExecutionCount": 1850 } }

count must be greater than 0. After topping up, re-activate jobs that were paused (PUT /jobs/{id} with status: "active", see Jobs).

AI usage​

Returns the account's monthly AI request quotas (see AI quotas).

curl "https://scheduler.example.com/api/v1/accounts/42/ai/usage" \
-u "$SCHEDULER0_USER:$SCHEDULER0_PASSWORD" -H "X-Peer: cmd"
{
"success": true,
"data": {
"accountId": 42,
"periodStart": "2026-01-01T00:00:00Z",
"nextResetDate": "2026-02-01T00:00:00Z",
"prompt": { "limit": 1000, "used": 120, "remaining": 880 },
"classify": { "limit": 1000, "used": 300, "remaining": 700 },
"estimatedCostUsd": 0.42
}
}

prompt covers POST /ai/prompt and POST /ai/schedule; classify covers POST /ai/prompt/classify and POST /ai/suggestions/analyze. Limits rise to 100,000 with the increased_number_of_prompt_requests_100_k_per_month and increased_number_of_classify_requests_100_k_per_month features. estimatedCostUsd is the sum of model cost estimates recorded in the prompt request log for the period.

Tokens​

A numeric balance stored alongside the execution count.

curl "https://scheduler.example.com/api/v1/accounts/42/tokens" \
-u "$SCHEDULER0_USER:$SCHEDULER0_PASSWORD" -H "X-Peer: cmd"
# → { "success": true, "data": { "tokens": 500 } }

curl -X PUT "https://scheduler.example.com/api/v1/accounts/42/tokens/add" \
-u "$SCHEDULER0_USER:$SCHEDULER0_PASSWORD" -H "X-Peer: cmd" \
-H "Content-Type: application/json" \
-d '{"amount": 500}'
# → { "success": true, "data": { "newBalance": 1000 } }

amount must be greater than 0.

Features​

Features are server-defined flags that raise an account's limits.

NameEffect
increased_retry_max_by_fiveJob retryMax limit 3 → 15
increased_job_payload_size_to_1mbJob data limit 3,072 bytes → 1 MB
increased_number_of_job_executions_100_k_per_monthExecution allowance 1,000 → 100,000 per month
increased_execution_logs_90_days_retentionMarks the account for 90-day rather than 30-day execution-log retention. The server currently has no automatic retention sweep; logs are only removed by POST /executions/cleanup-old-logs, which takes its own retentionMonths.
increased_number_of_prompt_requests_100_k_per_monthPrompt quota 1,000 → 100,000 per month
increased_number_of_classify_requests_100_k_per_monthClassify quota 1,000 → 100,000 per month

List the catalog (any credential with read scope):

curl "https://scheduler.example.com/api/v1/features" \
-H "X-API-Key: YOUR_API_KEY" \
-H "X-Secret-Key: YOUR_SECRET_KEY" \
-H "X-Account-ID: YOUR_ACCOUNT_ID"
{
"success": true,
"data": [
{ "id": 1, "name": "increased_retry_max_by_five", "dateCreated": "2026-01-01T00:00:00Z", "dateModified": null }
]
}

Enable or disable one feature by id, or all at once:

curl -X PUT "https://scheduler.example.com/api/v1/accounts/42/feature" \
-u "$SCHEDULER0_USER:$SCHEDULER0_PASSWORD" -H "X-Peer: cmd" \
-H "Content-Type: application/json" \
-d '{"featureId": 1}'
# → 201 { "success": true, "data": { "featureId": 1 } }

curl -X DELETE "https://scheduler.example.com/api/v1/accounts/42/feature" \
-u "$SCHEDULER0_USER:$SCHEDULER0_PASSWORD" -H "X-Peer: cmd" \
-H "Content-Type: application/json" \
-d '{"featureId": 1}'
# → 204

curl -X PUT "https://scheduler.example.com/api/v1/accounts/42/features/all" -u "$SCHEDULER0_USER:$SCHEDULER0_PASSWORD" -H "X-Peer: cmd"
curl -X DELETE "https://scheduler.example.com/api/v1/accounts/42/features/all" -u "$SCHEDULER0_USER:$SCHEDULER0_PASSWORD" -H "X-Peer: cmd"
# → 200 { "success": true, "data": { "message": "..." } }

Removing increased_number_of_job_executions_100_k_per_month does not reduce an allowance already granted.

Rotating the server secret key​

The server encrypts credential secrets, executor cloud keys and webhook secrets, and AI provider keys with its SecretKey. To rotate it:

  1. Generate a new key: scheduler0 accounts generate-secret-key.
  2. Update SecretKey in the server's secrets source and reload or restart the server so the new key is loaded.
  3. Call the endpoint with the previous key so existing rows can be decrypted and re-encrypted:
curl -X POST "https://scheduler.example.com/api/v1/account/rotate-secret" \
-u "$SCHEDULER0_USER:$SCHEDULER0_PASSWORD" -H "X-Peer: cmd" \
-H "Content-Type: application/json" \
-d '{"oldSecretKey": "<previous-hex-key>"}'
{ "success": true, "data": { "credentialsRotated": 12, "executorsRotated": 4, "aiSettingsRotated": 1 } }

Equivalent CLI: scheduler0 accounts rotate-secret --old-secret-key <previous-key>. API keys are unchanged by rotation, so clients keep working. oldSecretKey is required.