For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
WebsiteDashboardGet API key
  • Get Started
    • Welcome
    • Quickstart
    • Agent onboarding
    • Service keys
    • Core Concepts
  • Guides
    • Hosted Mode
    • Webhook Mode
    • Audio Mode
    • SMS and Conversations
    • Compliance and Consent
    • Billing and Usage
    • Voice zones
    • SMS zones
  • Reference
    • Authentication
    • API Overview
    • Errors and Testing
  • API Reference
      • GETList child API keys
      • POSTMint a child API key
      • GETGet a child API key
      • DELRevoke a child API key
      • PATCHUpdate a child API key
      • POSTAtomically rotate a child API key
  • Changelog
    • Cloudflare Insights CSP
    • Agent-native key management
    • Postpaid auto-charge
    • Cents-honest pricing
    • Stripe payments foundation
    • Hosted/webhook mode rename
    • Upgrading to v0.5.7.0
LogoLogo
WebsiteDashboardGet API key
API ReferenceKeys

Mint a child API key

POST
https://saperly.com/api/v1/keys
POST
/api/v1/keys
1const url = 'https://saperly.com/api/v1/keys';
2const options = {
3 method: 'POST',
4 headers: {
5 'Idempotency-Key': 'Idempotency-Key',
6 Authorization: 'Bearer <token>',
7 'Content-Type': 'application/json'
8 },
9 body: '{"name":"string"}'
10};
11
12try {
13 const response = await fetch(url, options);
14 const data = await response.json();
15 console.log(data);
16} catch (error) {
17 console.error(error);
18}
1{
2 "key": {
3 "id": "string",
4 "key_prefix": "sk_live_abc",
5 "environment": "live",
6 "name": "string",
7 "agent_label": "string",
8 "line_id": "string",
9 "permissions": "full",
10 "monthly_cap_cents": 1,
11 "monthly_spend_cents": 1,
12 "created_at": "2024-01-15T09:30:00Z",
13 "revoked_at": "2024-01-15T09:30:00Z",
14 "last_used_at": "2024-01-15T09:30:00Z",
15 "rotated_from": "string",
16 "created_by_service_key_id": "string",
17 "plaintext_key": "sk_live_abc123def456..."
18 }
19}
Mints a new child API key (`sk_test_*` / `sk_live_*`) using the authenticated service key as the parent. The plaintext key is returned in the `plaintext_key` field of the response and is shown EXACTLY ONCE — store it immediately. Idempotency replays within 12 hours return the redacted row (no `plaintext_key`). Service-key environment determines the new key's environment by default; passing a mismatched `environment` returns 422. Binding the key to a `line_id` requires the line to exist, belong to the parent service key's user, match the environment, and not be released — a 404 on the line is returned without sticky-caching so retries succeed once the customer fixes the binding. Rate-limited to 60 requests per hour per service key.
Was this page helpful?
Previous

Get a child API key

Next
Built with

Mints a new child API key (sk_test_* / sk_live_*) using the authenticated service key as the parent. The plaintext key is returned in the plaintext_key field of the response and is shown EXACTLY ONCE — store it immediately. Idempotency replays within 12 hours return the redacted row (no plaintext_key).

Service-key environment determines the new key’s environment by default; passing a mismatched environment returns 422. Binding the key to a line_id requires the line to exist, belong to the parent service key’s user, match the environment, and not be released — a 404 on the line is returned without sticky-caching so retries succeed once the customer fixes the binding.

Rate-limited to 60 requests per hour per service key.

Authentication

AuthorizationBearer

Service keys (sk_svc_*) authenticate the /v1/keys/* management plane. Send as Authorization: Bearer <service-key>. Service keys are minted only from the portal (Settings → Service Keys); there is no API path to mint another service key.

Headers

Idempotency-KeystringRequired

Required. Mints are sticky-cached for 12 hours per (service key, method, path, Idempotency-Key) tuple. Reusing the same key with a different body returns 409 idempotency_key_reused; reusing it while the original request is still in-flight returns 409 idempotency_in_progress.

Request

This endpoint expects an object.
namestringRequired1-64 characters

Human-readable name for the key

agent_labelstringOptionalformat: "^[a-z0-9][a-z0-9:_.-]{0,127}$"

Stable identifier for the agent identity holding this key. Lowercase, 1-128 chars.

line_idstringOptionalformat: "uuid"

Scope the key to a single line. Omit (or set to null on PATCH) for an account-wide key.

permissionsenumOptionalDefaults to full

Permission tier. The backfill-only legacy_full tier cannot be set via the API.

Allowed values:
monthly_cap_centsintegerOptional1-1000000
Monthly spend cap in cents.
environmentenumOptional
Allowed values:

Response

Child API key created
keyobject

Returned by POST /v1/keys and POST /v1/keys/{id}/rotate on the FIRST call only. Idempotency replays within the 12-hour TTL return the same row WITHOUT the plaintext_key field — the plaintext is never re-disclosable.

Errors

400
Bad Request Error
401
Unauthorized Error
404
Not Found Error
409
Conflict Error
422
Unprocessable Entity Error
429
Too Many Requests Error