Skip to main content

Formats

Timestamps

Always RFC 3339, always UTC, on the way out:

"startTime": "2026-08-11T13:20:01Z"

There is no local-time variant and no epoch variant. If you need to show a user their own wall-clock time, GET /users returns each user's IANA timeZone (America/New_York) — convert client-side.

Phone numbers

On inputFormatting is stripped. "(212) 555-0188", "212-555-0188" and "12125550188" are the same number.
On outputDigits, 11-digit form for US numbers: "12125550188". No +, no punctuation.

Two consequences worth knowing:

Copy output straight into input. number from GET /sms/lines is exactly what POST /sms/messages wants as from. No reformatting step.

Normalized values come back in the response. A send to "(347) 555-0123" returns "13475550123" in messages[].to — what was actually dialled and what the charge is against. The one exception is skipped[].to, which echoes your input, because a skipped recipient may not have normalized at all and you need to match it back to what you sent.

Extensions vs numbers

Both appear as strings and they are not interchangeable:

  • "204" — an internal extension.
  • "12125550188" — an external number.

On a recording's from/to, an internal leg carries extensions, not phone numbers. Do not assume every value is dialable from outside.

Ids

IdTypeExample
User idinteger481920
Webhook idinteger2074
SMS message idinteger88214417
Call idstring"1754489201.884213"
Recording leg id (uniqueId)string"1754489201.884213"

A call id is a unix timestamp, a dot, and a sequence number. Keep it a string — parsing it as a float loses precision and silently corrupts the id. Malformed call ids get a 400 naming the expected shape, not a 404.

Money

{"currency": "USD", "unitPrice": 0.0025, "price": 0.0025, "totalPrice": 0.0025}

Prices are JSON numbers in whole dollars0.0025 is a quarter of a cent, not 25 of anything. currency is always USD today and is stated on every response so you never have to assume.

:::caution Do not sum these as floats A per-segment SMS price has four decimal places, and accumulating thousands of them in a float drifts. Convert to a decimal type on arrival, or work in ten-thousandths of a dollar as integers. :::

price = unitPrice × units, always. See SMS billing for what a unit is.

Booleans mean what they say

No 0/1, no "true" strings. true and false.

The one to watch is billing.billed, which is always true — it describes the endpoint (this costs money), not the individual call. It stays true even when a particular request cost nothing because everything was skipped.