curl -X POST https://api.tracklysms.com/api/v2/accounts/children \
-H "X-Api-Key: trk_your_parent_key" \
-H "Idempotency-Key: create-child-loc-west-0001" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme West",
"externalIds": { "partnerId": "p_1", "businessId": "b_9", "locationId": "loc_west" },
"paidIntent": true,
"billedByParent": true
}'
import requests
resp = requests.post(
"https://api.tracklysms.com/api/v2/accounts/children",
headers={
"X-Api-Key": "trk_your_parent_key",
"Idempotency-Key": "create-child-loc-west-0001",
},
json={
"name": "Acme West",
"externalIds": {"partnerId": "p_1", "businessId": "b_9", "locationId": "loc_west"},
"paidIntent": True,
"billedByParent": True,
},
)
child = resp.json()["child"]
print(child["accountId"])
{
"child": {
"accountId": 1042,
"name": "Acme West",
"status": "active",
"plan": "paid",
"externalIds": { "partnerId": "p_1", "businessId": "b_9", "locationId": "loc_west" },
"billedByParent": true,
"createdAt": "2026-07-26T14:03:11.123456"
}
}
{
"error": "A child with locationId 'loc_west' already exists",
"code": "duplicate_location",
"existingAccountId": 1042
}
Partner Accounts (v2)
Create Child Account
Provision a new child account under your parent, optionally keyed to your own identifiers and pooled to the parent’s billing.
POST
/
v2
/
accounts
/
children
curl -X POST https://api.tracklysms.com/api/v2/accounts/children \
-H "X-Api-Key: trk_your_parent_key" \
-H "Idempotency-Key: create-child-loc-west-0001" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme West",
"externalIds": { "partnerId": "p_1", "businessId": "b_9", "locationId": "loc_west" },
"paidIntent": true,
"billedByParent": true
}'
import requests
resp = requests.post(
"https://api.tracklysms.com/api/v2/accounts/children",
headers={
"X-Api-Key": "trk_your_parent_key",
"Idempotency-Key": "create-child-loc-west-0001",
},
json={
"name": "Acme West",
"externalIds": {"partnerId": "p_1", "businessId": "b_9", "locationId": "loc_west"},
"paidIntent": True,
"billedByParent": True,
},
)
child = resp.json()["child"]
print(child["accountId"])
{
"child": {
"accountId": 1042,
"name": "Acme West",
"status": "active",
"plan": "paid",
"externalIds": { "partnerId": "p_1", "businessId": "b_9", "locationId": "loc_west" },
"billedByParent": true,
"createdAt": "2026-07-26T14:03:11.123456"
}
}
{
"error": "A child with locationId 'loc_west' already exists",
"code": "duplicate_location",
"existingAccountId": 1042
}
Creates a child account under your parent. Use your parent key. Requires the
Only
Authenticated requests can also fail with
accounts.write scope (or an unscoped grandfathered key). See Accounts & Hierarchy for the model.
This endpoint is idempotent: send an
Idempotency-Key header to make retries safe. Duplicate businesses are separately prevented by externalIds.locationId uniqueness.Body Parameters
string
required
Display name for the child account. Max 255 characters.
object
Your own identifiers for this account. Each value is a non-empty printable-ASCII string, max 128 characters, and immutable once set. Unknown keys are rejected.
boolean
default:"false"
Whether this child should be a paid account. When
false, the child is created on the free plan and self-pays, and billedByParent is ignored.boolean
default:"true"
Whether the parent pools this child’s billing. Only honored when
paidIntent is true. When honored, the child is created on the paid plan and the parent must have a payment method on file.Response Fields
object
The created child.
Show child
Show child
integer
The new account’s ID — use it in the child-scoped account endpoints.
string
Display name.
string
active.string
paid or free, per the billing fields above.object
The external IDs you supplied.
boolean
Whether billing pools to the parent.
string
ISO-8601 creation time.
boolean
Present only if the requested paid/pooled state was downgraded (e.g. parent had no payment method path); indicates the child was created self-paying instead.
Examples
curl -X POST https://api.tracklysms.com/api/v2/accounts/children \
-H "X-Api-Key: trk_your_parent_key" \
-H "Idempotency-Key: create-child-loc-west-0001" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme West",
"externalIds": { "partnerId": "p_1", "businessId": "b_9", "locationId": "loc_west" },
"paidIntent": true,
"billedByParent": true
}'
import requests
resp = requests.post(
"https://api.tracklysms.com/api/v2/accounts/children",
headers={
"X-Api-Key": "trk_your_parent_key",
"Idempotency-Key": "create-child-loc-west-0001",
},
json={
"name": "Acme West",
"externalIds": {"partnerId": "p_1", "businessId": "b_9", "locationId": "loc_west"},
"paidIntent": True,
"billedByParent": True,
},
)
child = resp.json()["child"]
print(child["accountId"])
{
"child": {
"accountId": 1042,
"name": "Acme West",
"status": "active",
"plan": "paid",
"externalIds": { "partnerId": "p_1", "businessId": "b_9", "locationId": "loc_west" },
"billedByParent": true,
"createdAt": "2026-07-26T14:03:11.123456"
}
}
{
"error": "A child with locationId 'loc_west' already exists",
"code": "duplicate_location",
"existingAccountId": 1042
}
code is contractual — error message text may change.
Error Codes
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | missing_name | name is required. |
| 400 | name_too_long | name exceeds 255 characters. |
| 400 | invalid_external_ids | An external ID is malformed, too long, empty, or an unknown key was supplied. |
| 400 | invalid_paid_intent | paidIntent is not a boolean. |
| 400 | invalid_billed_by_parent | billedByParent is not a boolean. |
| 400 | children_cap_exceeded | The parent has reached its 100-children limit. |
| 400 | invalid_body | The request body is not a JSON object. |
| 403 | not_a_parent_account | The calling key belongs to a child account. |
| 403 | sandbox_read_only | Sandbox keys cannot create children. |
| 403 | insufficient_scope | The key lacks the accounts.write scope. |
| 409 | duplicate_location | externalIds.locationId is already in use (see existingAccountId). |
| 409 | parent_payment_method_required | A pooled paid child needs a parent payment method on file. |
| 429 | rate_limited | Child-creation rate limit (100/hour) hit; see the Retry-After header. |
401 invalid_credentials, 403 account_suspended, and rare 502 link_failed / 503 rate_limiter_unavailable transients.
Next Steps
Mint an API key
Issue a scoped key for the new child.
Register a webhook
Receive signed events for this child.