Contactivity
Compatibility.md

Migrating from Twilio or Telnyx

Contactivity has its own native API (/v1/projects/{project_id}/..., documented in api/README.md) and, kept apart from it, competitor-compatible URL layouts under /compat/{vendor}. The compatible layouts exist so that code written for Twilio or Telnyx keeps working after one change: the SDK base URL. New code should use the native API.

Migrating from Set the SDK base URL to Auth
Twilio REST (api.twilio.com/2010-04-01/...) https://api.contactivity.io/compat/twilio Basic: AccountSid + AuthToken (or API key SID + secret) from the portal
Telnyx Call Control v2 (api.telnyx.com/v2/...) https://api.contactivity.io/compat/telnyx/v2 Authorization: Bearer <API key>
Telnyx TeXML REST (api.telnyx.com/v2/texml/Accounts/...) https://api.contactivity.io/compat/telnyx/v2 Basic: AccountSid + AuthToken

Regional hosts work the same way: https://api[.<edge>].<region>.contactivity.io/compat/twilio. Credentials only work in their own region.

The SDK appends its usual paths to that base, so requests look like:

POST https://api.contactivity.io/compat/twilio/2010-04-01/Accounts/{AccountSid}/Calls.json
POST https://api.contactivity.io/compat/telnyx/v2/calls/{call_control_id}/actions/answer
GET  https://api.contactivity.io/compat/telnyx/v2/texml/Accounts/{AccountSid}/Calls

The unprefixed layouts (/2010-04-01/..., /v2/...) are not served.

SDKs

  • Twilio SDKs. Our SDK contactivity (Node and Python) defaults to https://api.contactivity.io/compat/twilio. With the upstream twilio package, send its requests to that base (for example with a custom HTTP client that swaps https://api.twilio.com for it).
  • Telnyx SDKs. Our SDK contactivity-callcontrol defaults to https://api.contactivity.io/compat/telnyx/v2. With the upstream telnyx package set baseURL (Node) or base_url (Python) to that URL.

Twilio-shaped responses carry uri, subresource_uris, first_page_uri and next_page_uri relative to the SDK base URL, exactly as Twilio's are relative to https://api.twilio.com: for example "uri": "/2010-04-01/Accounts/AC.../Calls/CA....json". Twilio SDKs follow them by appending them to the base, so paging works unchanged. A plain HTTP client should do the same: https://api.contactivity.io/compat/twilio + uri.

Absolute URLs are given in full, under /compat/twilio:

Field Example
Recording media_url https://api.contactivity.io/compat/twilio/2010-04-01/Accounts/{AccountSid}/Recordings/{RecordingSid}
RecordingUrl (recording status callback, <Record> action) same as media_url
TranscriptionUrl (transcribe callback) https://api.contactivity.io/compat/twilio/2010-04-01/Accounts/{AccountSid}/Recordings/{RecordingSid}/Transcriptions/{TranscriptionSid}

Append .wav or .mp3 to a recording URL to download the audio. Telnyx-shaped events carry native recording URLs (https://api.contactivity.io/v1/voice/Recordings/{id}.wav).

What is supported

Twilio (/compat/twilio/2010-04-01/Accounts/{AccountSid}/...)

The AccountSid in the URL must be the authenticated account (the AC... SID, or the project id); another account's SID is refused with 401, as Twilio does. Voice resources only:

Resource Methods
{AccountSid}.json (account) GET
Calls, Calls/{CallSid} GET, POST (create, modify), DELETE
Calls/{CallSid}/Recordings[/{RecordingSid}] GET, POST, DELETE
Calls/{CallSid}/Streams[/{StreamSid}] POST
Conferences[/{ConferenceSid}], .../Participants[/{CallSid}], .../Recordings[/{RecordingSid}] GET, POST, DELETE
Recordings[/{RecordingSid}], .../Transcriptions[/{TranscriptionSid}], Transcriptions[/{Sid}] GET, DELETE
Queues[/{QueueSid}], .../Members[/{CallSid}] GET, POST, DELETE
Applications[/{ApplicationSid}] GET, POST, DELETE
OutgoingCallerIds[/{Sid}] GET, POST, DELETE
IncomingPhoneNumbers[/{Sid}] GET, POST, DELETE (see below)
AvailablePhoneNumbers[/{Country}/{Type}] GET (see below)

Parameters, response fields and error codes per resource: api/compatibility.md and the Compatibility reference (its /v1/voice/... paths are what these URLs reach).

Phone numbers

GET AvailablePhoneNumbers.json lists the countries numbers are sold in (US only during beta), each with subresource_uris for local, toll_free and mobile.

GET AvailablePhoneNumbers/{Country}/{Local|TollFree|Mobile}.json searches numbers to buy:

Parameter Meaning
AreaCode Area code (for TollFree, the toll-free prefix, e.g. 833)
Contains Digits the number contains; * only at the start or end
InRegion State, e.g. CA
PageSize 1-1000, default 50 (at most 200 numbers are returned)

Other Twilio filters (InPostalCode, InLocality, InRateCenter, InLata, NearNumber, NearLatLong, Distance) and SmsEnabled/MmsEnabled/FaxEnabled=true are refused with 400 / 20001 rather than ignored. Numbers are voice-only during beta (capabilities.SMS and MMS are false).

POST IncomingPhoneNumbers.json buys PhoneNumber, or the first number found in AreaCode, and routes it with the usual fields (VoiceUrl, VoiceMethod, VoiceApplicationSid, StatusCallback, ...). It charges the account like an order in the portal and honours Idempotency-Key. POST IncomingPhoneNumbers/{Sid}.json updates the routing; DELETE IncomingPhoneNumbers/{Sid}.json releases the number. Every other DELETE (Calls, Recordings, Transcriptions, Queues, Applications, OutgoingCallerIds) archives: the record is kept but answers 404 and leaves lists, and it stops working at once. Nothing is erased.

Code HTTP When
21421 400 PhoneNumber and AreaCode both missing, or PhoneNumber is not E.164
21422 409 / 400 The number is not available to buy
21452 400 No number found in AreaCode
20402 402 Balance too low (the message gives the amount required and the balance)
21220 409 Release refused: the number is still being provisioned by the carrier
20001 400 AreaCode is not 3 digits, or an unsupported search filter
20503 503 Number search is temporarily unavailable

Telnyx (/compat/telnyx/v2/...)

Path Methods
calls, calls/{call_control_id} POST (dial), GET
calls/{call_control_id}/actions/{command} POST (client_state_update also PUT)
conferences, conferences/{id}, conferences/{id}/participants GET, POST
conferences/{id}/actions/{command} POST
recordings, recordings/{id} GET, DELETE
call_control_applications[/{id}], texml_applications[/{id}] GET, POST, PATCH, DELETE
texml/Accounts/{AccountSid}/... The Twilio resources above, with Telnyx TeXML's JSON request bodies accepted

DELETE on recordings and applications archives them: they answer 404 and leave lists afterwards; nothing is erased.

Unchanged: markup and callbacks

TwiML (CoXML) and Plivo XML documents, Twilio-style webhook parameters (AccountSid, CallSid, ApiVersion, ...) and X-Twilio-Signature, and Telnyx-style webhook events and telnyx-signature-ed25519 are markup and callback formats, not routes. They work the same whichever API created the call.

Known differences

  • Only voice is served. Other Twilio product namespaces (Messaging, Verify, ...) and other Telnyx resources return 404.
  • TeXML responses use Twilio's response shape and uri values (relative to /compat/twilio), not Telnyx's /v2/texml URIs.
  • Phone numbers: US only and voice-only during beta; the search filters listed above only.
  • Error bodies follow each vendor's shape; more_info links point to the vendor's error pages.