curl -X POST https://api.tracklysms.com/api/v1/voice/calls \
-H "X-Api-Key: trk_your_api_key_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 8f2c1a9e-4b7d-4c3a-9e21-3f0a1b2c3d4e" \
-d '{
"to": "+14155551234",
"from": "+18005551234",
"connectTo": "+14155559876",
"record": true,
"customData": { "caseId": "abc-123" }
}'
{
"call": {
"id": "665f1e2a9c4b1a0012ab34cd",
"direction": "outbound",
"state": "calling",
"legKind": "primary",
"from": "+18005551234",
"to": "+14155551234",
"connectTo": "+14155559876",
"queueId": null,
"conferenceId": null,
"parentCallId": null,
"bridgedCallId": null,
"monitorRole": null,
"record": true,
"recordingState": "requested",
"recordingFileIds": [],
"customData": { "caseId": "abc-123" },
"recipientProvenance": {},
"error": null,
"startedAt": "2026-08-21T18:00:00.000000Z",
"answeredAt": null,
"endedAt": null,
"createdAt": "2026-08-21T18:00:00.000000Z"
}
}
Voice Calls (v1)
Place a Call
Place an outbound programmable voice call, optionally bridging to an agent on answer.
POST
/
v1
/
voice
/
calls
curl -X POST https://api.tracklysms.com/api/v1/voice/calls \
-H "X-Api-Key: trk_your_api_key_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 8f2c1a9e-4b7d-4c3a-9e21-3f0a1b2c3d4e" \
-d '{
"to": "+14155551234",
"from": "+18005551234",
"connectTo": "+14155559876",
"record": true,
"customData": { "caseId": "abc-123" }
}'
{
"call": {
"id": "665f1e2a9c4b1a0012ab34cd",
"direction": "outbound",
"state": "calling",
"legKind": "primary",
"from": "+18005551234",
"to": "+14155551234",
"connectTo": "+14155559876",
"queueId": null,
"conferenceId": null,
"parentCallId": null,
"bridgedCallId": null,
"monitorRole": null,
"record": true,
"recordingState": "requested",
"recordingFileIds": [],
"customData": { "caseId": "abc-123" },
"recipientProvenance": {},
"error": null,
"startedAt": "2026-08-21T18:00:00.000000Z",
"answeredAt": null,
"endedAt": null,
"createdAt": "2026-08-21T18:00:00.000000Z"
}
}
Places an outbound telephone call from one of your assigned numbers. When
Authorized businesses can screen a US recipient as an optional, separate request before calling. Normal Voice accounts do not need that request or
connectTo is supplied, Trackly dials that telephone target after the destination answers and bridges the conversation when the target answers. Hosted calling returns 201; Trackly-managed calling returns 202. Neither response proves an answered or bridged conversation.
A managed 202 includes a Location header such as /api/v1/voice/calls/{call.id}. Request that path with the same API key to read the accepted call.
For a salesperson using a browser headset, use Salesforce and browser calling. This endpoint does not attach a browser agent through connectTo.
If your business is approved for agent-first outbound calling, use the browser calling flow; direct phone-first calls through this endpoint return 403 agent_first_required.
When calling-review enforcement is enabled for your account, an unverified approval blocks new calls.
Requires the voice_calls.write scope and the Voice Calls product entitlement.
Body Parameters
string
Omit this field or use
hosted for hosted calling. Use managed for enabled Trackly-managed calling. Managed calls require an Idempotency-Key and retain the issuing API key’s ownership for later access and controls.string
required
Destination phone number in E.164 format (e.g.
+14155551234).string
required
The calling number in E.164 format. Must be a number that has been assigned to your account.
string
A telephone destination to bridge the call to once it is answered. Accepts either an E.164 number or the
id of a phone agent, not a browser agent. The resolved destination is screened against your account’s compliance suppression (DNC, opt-out, quiet hours) before dialing.boolean
default:false
Request recording of this call leg from answer. On the hosted backend, joining a conference ends its individual recording; this does not enable hosted conference recording. For Trackly-managed calls, capture starts on the selected call leg when it answers. See call recording.
object
Key/value metadata retained on the call object. The hosted backend also forwards it to the provider. Values must be JSON-serializable.
object
An optional caller attestation to this recipient’s existing consent or confirmed contact:
{ "kind": "consent", "date": "YYYY-MM-DD" }. Normal Voice accounts can omit it. If supplied, kind and date are required; null and {} are invalid. The response contains {} when the request omitted this field. kind may be consent or confirmed_contact. Use the actual date, not an import, list-creation, or dial date, today’s date as a default, or an answer by an unidentified person. You may also provide an opaque evidenceReference from your records; if supplied, it must be stable, printable, at most 200 characters, and have no leading or trailing whitespace, phone number, email address, or message content. Trackly binds supplied provenance to this account and destination. Supplying it does not itself verify consent or run reassigned-number screening.recipientProvenance to place a call; account-specific automatic screening admission is off by default. A business explicitly enrolled in automatic admission needs a qualifying date and a current screening result for US outbound recipients; it does not need to send a source-record reference to Trackly. If optional screening confirms reassignment, a seller-scoped restriction can block a new call to that recipient even when the call omits provenance. A no_data result does not establish a reassigned-number safe harbor.
Headers
string
Required for Trackly-managed calling: a nonblank key of at most 128 characters. Reuse the same key, API key and request body; changed input returns
409 idempotency_conflict. For hosted calling, this header is optional and an existing key returns its call without comparing the body; validation and compliance checks still apply, and a definitive rejection can release the key. An uncertain response can leave the original call pending, so reuse its key instead of starting another attempt.Response Fields
object
The created call.
Hide Call properties
Hide Call properties
string
The call’s unique identifier.
string
hosted or managed. Later controls use this saved mode.string
outbound for calls placed through this endpoint.string
Lifecycle state. A freshly placed call starts as
calling. See Call states.string
primary, bridge, or monitor. Calls placed here are primary.string
The calling number.
string
The destination number.
string | null
The resolved bridge target, if any.
string | null
The queue this call is parked in, if any.
string | null
The hosted provider conference ID when present. Trackly-managed bridges do not require a conference ID.
string | null
For a bridge/monitor leg, the primary call it belongs to.
string | null
For a primary call, the currently bridged agent leg.
string | null
MONITOR or ADVISOR for a monitor leg.boolean
Whether recording was requested.
string | null
requested, started, stopped, ready, failed, or deleted.array
Provider file ids for completed recordings.
object
The metadata you supplied.
object
The retained recipient date and any supplied reference, or
{} when omitted.string | null
A machine-readable reason when the call failed.
string | null
ISO 8601 timestamp when the call was placed.
string | null
ISO 8601 timestamp when the call was answered.
string | null
ISO 8601 timestamp when the call ended.
string | null
ISO 8601 timestamp when the record was created.
Examples
curl -X POST https://api.tracklysms.com/api/v1/voice/calls \
-H "X-Api-Key: trk_your_api_key_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 8f2c1a9e-4b7d-4c3a-9e21-3f0a1b2c3d4e" \
-d '{
"to": "+14155551234",
"from": "+18005551234",
"connectTo": "+14155559876",
"record": true,
"customData": { "caseId": "abc-123" }
}'
{
"call": {
"id": "665f1e2a9c4b1a0012ab34cd",
"direction": "outbound",
"state": "calling",
"legKind": "primary",
"from": "+18005551234",
"to": "+14155551234",
"connectTo": "+14155559876",
"queueId": null,
"conferenceId": null,
"parentCallId": null,
"bridgedCallId": null,
"monitorRole": null,
"record": true,
"recordingState": "requested",
"recordingFileIds": [],
"customData": { "caseId": "abc-123" },
"recipientProvenance": {},
"error": null,
"startedAt": "2026-08-21T18:00:00.000000Z",
"answeredAt": null,
"endedAt": null,
"createdAt": "2026-08-21T18:00:00.000000Z"
}
}
Error Codes
| Status | Code | Meaning |
|---|---|---|
| 403 | voice_not_entitled | Voice calling is not enabled for your account. |
| 403 | agent_first_required | This business must connect its browser agent before dialing the recipient. Use browser calling. |
| 403 | outbound_not_approved | This business is approved for inbound calling only. Contact Trackly before starting outbound calls. |
| 403 | kyc_approval_unverified | Trackly could not verify the saved calling approval. Contact Trackly before placing another call. |
| 409 | idempotency_conflict | The Trackly-managed key belongs to a different input or issuing key. |
| 422 | idempotency_key_required | Trackly-managed creation requires a nonblank key of at most 128 characters. |
| 503 | call_media_unavailable | The selected calling service is unavailable. |
| 503 | kyc_approval_unavailable | Calling approval could not be checked temporarily. Retry later. |
| 403 | compliance_dnc / compliance_opted_out / compliance_suppressed / compliance_quiet_hours | The destination is blocked by a compliance rule. |
| 422 | from_not_owned | from is not a number assigned to your account. |
| 422 | missing_fields | A required field (to or from) is missing. |
| 422 | invalid_number | to or connectTo is not a valid E.164 number. |
| 404 | agent_not_found | connectTo is an agent id that does not exist. |
| 429 | concurrency_limit | Your account has too many concurrent calls in progress. |
| 502 | provider_error | The upstream telephony provider rejected the request. |