curl -X POST https://api.tracklysms.com/api/v2/accounts/children/1042/api-keys \
-H "X-Api-Key: trk_your_parent_key" \
-H "Content-Type: application/json" \
-d '{ "name": "prod", "permissions": ["api.full"] }'
import requests
resp = requests.post(
"https://api.tracklysms.com/api/v2/accounts/children/1042/api-keys",
headers={"X-Api-Key": "trk_your_parent_key"},
json={"name": "prod", "permissions": ["api.full"]},
)
key = resp.json()["apiKey"]["key"] # store this now — shown once
{
"apiKey": {
"id": "66b0f7c84a1d4b2e9c3a1f2e",
"accountId": 1042,
"name": "prod",
"key": "trk_ab12cd34ef56gh78ij90kl12mn34op56",
"keyPrefix": "trk_ab12",
"status": "active",
"permissions": ["api.full"],
"resourceConstraints": {},
"expiresAt": null,
"allowedIps": [],
"rateLimitOverride": null,
"sandbox": false,
"graceUntil": null,
"rotatedFrom": null,
"lastUsedIp": null,
"createdAt": "2026-07-26T14:05:00.000000",
"lastUsedAt": null
},
"message": "Store the plaintext key now — it cannot be retrieved later."
}
Partner Accounts (v2)
Create API Key
Mint a scoped API key for a child account. The plaintext key is returned exactly once.
POST
/
v2
/
accounts
/
children
/
{child_id}
/
api-keys
curl -X POST https://api.tracklysms.com/api/v2/accounts/children/1042/api-keys \
-H "X-Api-Key: trk_your_parent_key" \
-H "Content-Type: application/json" \
-d '{ "name": "prod", "permissions": ["api.full"] }'
import requests
resp = requests.post(
"https://api.tracklysms.com/api/v2/accounts/children/1042/api-keys",
headers={"X-Api-Key": "trk_your_parent_key"},
json={"name": "prod", "permissions": ["api.full"]},
)
key = resp.json()["apiKey"]["key"] # store this now — shown once
{
"apiKey": {
"id": "66b0f7c84a1d4b2e9c3a1f2e",
"accountId": 1042,
"name": "prod",
"key": "trk_ab12cd34ef56gh78ij90kl12mn34op56",
"keyPrefix": "trk_ab12",
"status": "active",
"permissions": ["api.full"],
"resourceConstraints": {},
"expiresAt": null,
"allowedIps": [],
"rateLimitOverride": null,
"sandbox": false,
"graceUntil": null,
"rotatedFrom": null,
"lastUsedIp": null,
"createdAt": "2026-07-26T14:05:00.000000",
"lastUsedAt": null
},
"message": "Store the plaintext key now — it cannot be retrieved later."
}
Mints a new API key for a child. Use your parent key with
Also
accounts.write. The child then authenticates its own requests with the returned key.
The server rechecks parent authority when it creates the key. If the parent credential, account ownership, or child key capacity changes concurrently, creation returns 409 create_key_conflict; reload the current configuration before trying again. If creation cannot be confirmed, 409 api_key_outcome_unknown returns no plaintext and includes retryable: false. Do not repeat the mint; contact support with its supportReference.
Path Parameters
integer
required
The child account’s
accountId.Body Parameters
string
required
A label for the key (e.g.
prod, staging). Max 255 characters.array
default:["api.full"]
A list of
resource.action permission strings. The requested set must be a subset of the calling parent key’s own permissions. Sensitive resources (admin, system, billing, account, accounts, users, keys, api_keys, internal, root, super) and the wildcard * can never be granted.object
Send restrictions for the key.
list_numbers (array of up to 200 E.164 strings) limits the key to those sending lists; a send from any other list, or a schedule whose source lists include another list, is refused with 403 list_not_allowed_for_key. Numbers are normalized to E.164 on save. list_numbers is the only key accepted here; omit it or pass an empty list for no restriction.integer
Maximum live sends per UTC day through the
/v2/send family of endpoints for this key (positive integer, max 1,000,000); omit or null for no cap. Once reached, sends are refused with 429 daily_cap_exceeded until the next UTC day. Sandbox, scheduled, and OTP sends do not count. The key’s current usage is visible on Who Am I as send_policy.sends_today.A parent key with active list restrictions, a
dailySendCap, an IP allowlist, or required send approval cannot mint or rotate child keys (403 constrained_key_cannot_delegate). An otherwise unrestricted parent may delegate when list_numbers is omitted, null, or an empty list. Malformed or unsupported stored constraints block delegation. Rotation preserves the child’s cap, list restriction, and confirmation setting; both keys share one daily counter.Partner-minted keys are live keys. To get a sandbox key, create one from the dashboard (see Sandbox & Testing).
boolean
default:false
Require human approval for SMS sends. Direct SMS/raw SMS, email, OTP, and send-enabling operations are blocked; use pending sends for SMS. A parent with this restriction cannot mint or rotate child keys (
403 constrained_key_cannot_delegate). The response includes requireSendConfirmation.Response Fields
object
The created key. Includes
id, accountId, name, key (plaintext, once), keyPrefix, status, permissions, resourceConstraints, expiresAt, allowedIps, rateLimitOverride, sandbox, graceUntil, rotatedFrom, lastUsedIp, createdAt, and lastUsedAt.string
A reminder to store the plaintext key now.
Examples
curl -X POST https://api.tracklysms.com/api/v2/accounts/children/1042/api-keys \
-H "X-Api-Key: trk_your_parent_key" \
-H "Content-Type: application/json" \
-d '{ "name": "prod", "permissions": ["api.full"] }'
import requests
resp = requests.post(
"https://api.tracklysms.com/api/v2/accounts/children/1042/api-keys",
headers={"X-Api-Key": "trk_your_parent_key"},
json={"name": "prod", "permissions": ["api.full"]},
)
key = resp.json()["apiKey"]["key"] # store this now — shown once
{
"apiKey": {
"id": "66b0f7c84a1d4b2e9c3a1f2e",
"accountId": 1042,
"name": "prod",
"key": "trk_ab12cd34ef56gh78ij90kl12mn34op56",
"keyPrefix": "trk_ab12",
"status": "active",
"permissions": ["api.full"],
"resourceConstraints": {},
"expiresAt": null,
"allowedIps": [],
"rateLimitOverride": null,
"sandbox": false,
"graceUntil": null,
"rotatedFrom": null,
"lastUsedIp": null,
"createdAt": "2026-07-26T14:05:00.000000",
"lastUsedAt": null
},
"message": "Store the plaintext key now — it cannot be retrieved later."
}
Error Codes
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | missing_name | name is required. |
| 400 | name_too_long | name exceeds 255 characters. |
| 400 | invalid_permission | A permission is malformed, not a subset of the caller’s grant, or references a reserved resource. |
| 400 | key_cap_exceeded | The child has hit its active-key cap. The cap defaults to 25 and can vary by environment. |
| 403 | constrained_key_cannot_delegate | The calling key has IP restrictions, active or invalid resource constraints, or a daily cap. |
| 403 | api_key_has_no_owner | The calling key has no owning user to attribute the mint to. |
| 404 | child_not_found | No child with that ID under this parent. |
| 409 | child_deleted | The child has been deleted. |
| 409 | create_key_conflict | Parent authority, account ownership, or child key capacity changed concurrently. Reload the current configuration before minting. |
| 409 | api_key_outcome_unknown | Creation could not be confirmed. No plaintext is returned. Do not retry; contact support with the response’s supportReference. |
| 502 | create_key_failed | Key creation failed before a confirmed outcome; retry only when the response uses this code. |
| 503 | api_key_lineage_unavailable | The parent’s key history could not be validated. Contact support before retrying. |
403 not_a_parent_account / insufficient_scope / sandbox_read_only.