Skip to main content
A partner integration is a two-level hierarchy: your parent account owns a set of child accounts. Each child is a full Trackly SMS account — typically one per business, brand, or location that you manage. The parent creates children, issues their API keys, controls their lifecycle (suspend / reactivate), and can read messages and billing across the whole portfolio.

The parent account

Your parent account is a normal account that has children attached to it. Parent-level operations require a parent key and are refused for a key that belongs to a child (403 not_a_parent_account). A child account cannot itself have children — the hierarchy is exactly one level deep.
Sandbox (test) keys are read-only for the hierarchy: any write — creating a child, minting a key, suspending — is refused with 403 sandbox_read_only. Provision your fleet with a live parent key.

External IDs

Every child carries an optional externalIds object so you can key Trackly accounts to your own system without maintaining a separate mapping table: Rules:
  • Each value is a non-empty printable-ASCII string, ≤128 characters.
  • locationId is unique per parent. Creating a second child with a locationId already in use returns 409 duplicate_location (with the conflicting existingAccountId), so you can safely retry provisioning without creating duplicates.
  • External IDs are immutable once set. You may backfill a field that was never set via update, but changing or clearing a value that already exists returns 409 external_id_immutable.
External IDs flow through the rest of the API: you can filter message reads by external_location_id, and they are included on the webhook envelope so your receiver can route an event to the right tenant.

Billing model

How a child pays is decided at creation from two fields:
Because billedByParent only takes effect when paidIntent is true, always send paidIntent: true explicitly when you want the parent to pool a child’s billing. A child created without paidIntent is a free, self-paying account regardless of billedByParent.
For a pooled child, cost is managed entirely by the parent: preflight returns estimated_cost: null for pooled children, and portfolio spend is read from the usage & billing endpoints on the parent.

API keys

Each child gets its own API key(s), minted by the parent. Keys are scoped: you grant a list of resource.action permissions, and a child key can never exceed the grant of the parent key that created it. A set of sensitive resources (admin, billing, account, accounts, users, keys, and others) can never be granted, and the wildcard * is reserved.
  • The plaintext key is returned exactly once, at creation or rotation. Store it immediately — it cannot be retrieved later, only rotated or revoked.
  • Rotation on the child-key management surface is immediate: the replacement is minted and the old key is revoked with no grace window. (The separate webhook signing-secret rotation does keep a 24-hour grace window — that’s a different secret.)
  • A key carrying IP allow-lists or resource constraints cannot mint further keys (403 constrained_key_cannot_delegate).
See Manage API keys for the endpoints.

Limits

Exceeding a cap returns a 4xx with a specific code (children_cap_exceeded, key_cap_exceeded, rate_limited with a Retry-After header). See each endpoint page for the full list.

Next steps

Create a child

Provision a new business account.

Mint an API key

Issue a scoped key for a child.