Child keys
Child keys let your backend mint bounded, revocable API keys for your own end customers, so each customer can call the gateway directly, from a server or straight from a browser, without you proxying their traffic. One code you sell, one key you mint, one budget that never resets.
Minting is enabled per account. If your account key returns
403 admin_scope_required, write to hashim@straitly.ai and we turn it on.- Mint a key
- POST https://api.straitly.ai/v1/admin/keys
- List your keys
- GET https://api.straitly.ai/v1/admin/keys
- Read one key's spend
- GET https://api.straitly.ai/v1/admin/keys/{key_hash}/spend
- Revoke a key
- DELETE https://api.straitly.ai/v1/admin/keys/{key_hash}
- Auth
- Authorization: Bearer sk-… (your account key, on every call)
Minting
Every field is optional. The raw key is returned once and never stored. Persist it (or hand it to your customer) immediately; key_hash is the id you manage it by afterwards.
curl https://api.straitly.ai/v1/admin/keys \
-H "Authorization: Bearer $STRAITLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"label": "code-ABC123",
"total_cap_usd": 5,
"allowed_origins": ["https://yourapp.com"]
}'
# 201
# {
# "key": "sk-...", <- shown exactly once
# "key_hash": "0a1c6d9b...", <- manage the key by this
# "label": "code-ABC123",
# "total_cap_usd": 5,
# "allowed_origins": ["https://yourapp.com"],
# "disabled": false
# }curlWhat a child key is
- A real gateway key: same base URL, same endpoints, same models. It bills into your prepaid balance, and its requests appear in your Activity ledger like any other key's.
total_cap_usdis a lifetimebudget, not a daily one. When the key's all-time billed spend reaches it, the key returns429 budget_exhaustedforever. No daily refresh, no rollover. The boundary you sold is the boundary that holds.daily_cap_usdandrpm_limitwork too, if you want them. A child key's rate limit is its own window: one customer going over does not throttle the others.- It cannot mint keys of its own.
Calling from a browser
Set allowed_origins and pages on those origins can call the inference endpoints directly: the gateway answers the preflight and stamps Access-Control-Allow-Origin on responses to listed origins only. Keys without the field stay server-only.
// runs on https://yourapp.com, no proxy in between
const resp = await fetch("https://api.straitly.ai/v1/messages", {
method: "POST",
headers: {
"Authorization": "Bearer sk-CHILD_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "claude-sonnet-5",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello" }],
}),
});javascriptInspection and revocation
curl https://api.straitly.ai/v1/admin/keys/KEY_HASH/spend \
-H "Authorization: Bearer $STRAITLY_API_KEY"
# {"spent_usd": 3.4021, "total_cap_usd": 5, "remaining_usd": 1.5979, "disabled": false}
curl -X DELETE https://api.straitly.ai/v1/admin/keys/KEY_HASH \
-H "Authorization: Bearer $STRAITLY_API_KEY"
# {"key_hash": "...", "revoked": true}curlspent_usdis the key's all-time billed spend: the same dollars your ledger shows, read live.- Revocation is immediate and permanent: the key returns
401from then on. You can only revoke keys you minted. - Budgets are enforced from a tally that refreshes about once a minute plus a live counter for charges still settling, so a key racing its boundary can carry at most about a minute of its own burn past the figure. Bound that with the cap you choose.
