API - SMS, Text Message Sending and Receiving

You can take advantage of IO Phone programmatically through our API. This article covers sending a text message with POST /text and receiving delivery receipts and inbound messages on your own server through a callback URL (webhook).

MethodURLPackage
POSThttps://rental.software/api6/textWP/API and IO Phone (at least one IO Phone number on your account)

Base URL: https://rental.software/api6. Every request needs your apiKey.


Limits

While texting plans are unlimited, we do throttle and have limits in place on an account level (regardless of location or phone number) for billable outbound messages to prevent abuse, whether intentional or accidental.

LimitValue
Text messages per hour200
Text messages per day300
Text messages per week1,500
API requestsThe normal API rate limits apply. See API - Errors and Rate Limits

If a texting limit is hit, you may still send manual text messages, including through the API but not via an automation, at the rate of 1 message every 5 minutes. Certain system text messages sent on your behalf, such as wind alerts, are unbillable and are not counted in these limits.

Permissions

The only permission required is that you either do not set restrictions by worker on the number you want to use, or, if you are setting these restrictions, you also enable the API worker profile you are using to have access. On multi-location accounts the API key also needs access to a location the number belongs to.


POST /text

Request Body Parameters

ParameterTypeRequiredDescription
toNumberstringYesThe phone number the message should be sent to. E.164 format (for example +15554447777) is recommended but not required
textstringYesThe contents of the text message. Must be 2048 characters or less
fromNumberstringNoOne of your IO Phone numbers that the message should be sent from. E.164 format is recommended but not required. If omitted, an IO Phone number of yours will be chosen automatically
callbackUrlstringNoThe URL where webhook requests will be sent. See the callback notes below
countrystringNoDefault "US". Optional country code with which to force toNumber to be parsed, in ISO 3166-1 alpha-2 format. It's recommended to only specify this parameter if the country of origin of toNumber is known and its format is nonstandard or unknown
customKeystringNoAn optional custom string value that, when specified, will be returned in the subsequent outbound message webhook. This can be useful for tracking purposes. Must be 32 characters or less
mediaarray of stringsNoAn optional array of URLs that, when specified, will be included as media attachments as part of the message (MMS). Each URL must not exceed 4096 characters

How the Callback URL Works

  • http or https is required. https (TLS) is highly recommended.
  • The most recent callback URL that you've sent is stored on our server (one per fromNumber).
  • If omitted, the most recent callback URL associated with fromNumber will be used.
  • The callback URL can be cleared from our server by sending it to us as an empty string ("").
  • If a callback URL has never been specified or was cleared for a given fromNumber, webhooks will not be sent.
  • Once a callback URL is stored for a number, you receive a webhook for every message on that number, inbound and outbound.

Response Schema

FieldTypeSent whenDescription
idintegerAcceptedThe unique ID associated with the message
timestringAcceptedThe UTC timestamp of the message, in ISO 8601 format
segmentCountintegerAcceptedThe number of segments that the message was broken into before sending over to carrier networks
directionstringAcceptedThe direction of the message, either in or out
tostringAcceptedThe phone number the message was sent to, in E.164 format
fromstringAcceptedThe phone number the message was sent from, in E.164 format
textstringAcceptedThe text message content that was sent to the recipient
mediaarrayAcceptedThe list of URLs that were sent along to the recipient as media attachments (if specified in the request)
statusintegerAlwaysThe status code associated with the request. If the message was accepted, 202 should be expected. Errors will return a status code from 400 to 599
messagestringFailedA message describing the error
request_timeintegerAcceptedThe current request time as a Unix timestamp in seconds

Example Request

POST https://rental.software/api6/text?apiKey=YOUR_API_KEY
Content-Type: application/json

{
  "toNumber": "+15554447777",
  "fromNumber": "+15551112222",
  "text": "Hello world",
  "callbackUrl": "https://my-callback-url/path",
  "media": ["https://my-server/image.jpg"]
}

Example Responses

Successful response:

200 OK
Content-Type: application/json

{
  "id": 1753065,
  "time": "2023-09-14T17:28:18.709287Z",
  "segmentCount": 1,
  "direction": "out",
  "to": "+15554447777",
  "from": "+15551112222",
  "text": "Hello world",
  "status": 202,
  "media": ["https://my-server/image.jpg"],
  "request_time": 1694712498
}

Error responses:

400 Bad Request
Content-Type: application/json

{
  "status": 400,
  "message": "Required parameter 'text' cannot be empty"
}
403 Forbidden
Content-Type: application/json

{
  "status": 403,
  "message": "This account is not authorized to send text messages from this number ('fromNumber')"
}

Common Errors

StatusMessageWhat to do
400Missing required parameter 'toNumber' (or 'text')Send both required parameters
400Could not parse 'toNumber'. Must be sent in a valid formatSend the number in E.164 format, or add country
400Length of 'text' parameter cannot exceed 2048 charactersShorten the message
400This text contains N segments but must not exceed 15Shorten the message. Long messages are split into segments, and a message can be at most 15 segments
400The recipient has not opted-in to receiving text messagesThe recipient has opted out of texts, so the message cannot be sent
400Unable to find a number to send this text message fromSend a fromNumber that the API key is allowed to use
403This account is not authorized to send text messages from this number ('fromNumber')Check the worker restrictions on the number
429You are sending messages too quickly. Please wait and try again later.A texting limit was hit. Wait before sending again

Webhook Examples

Webhooks are sent to your callback URL as a POST request with a JSON body:

POST {YOUR_CALLBACK_URL}
Content-Type: application/json

Your server should answer quickly. A webhook that fails is not sent again.

Outbound Message Delivery Receipt

{
  "id": 1753064,
  "time": "2023-09-14T15:59:38.406172698Z",
  "type": "message-delivered",
  "description": "Message delivered to carrier.",
  "segmentCount": 1,
  "direction": "out",
  "to": "+15554447777",
  "from": "+15551112222",
  "text": "Hello world",
  "customKey": "custom string",
  "media": ["https://rental.software/your-outbound-hosted-image.jpg"]
}

Inbound Message Received

{
  "id": 1753060,
  "time": "2023-09-14T13:52:27.881412Z",
  "type": "message-received",
  "description": "Incoming message received",
  "segmentCount": 1,
  "direction": "in",
  "to": "+15551112222",
  "from": "+15554447777",
  "text": "Hello world",
  "media": ["https://rental.software/inbound-hosted-image.jpg"]
}

Outbound Message Failure

{
  "id": 1753063,
  "time": "2023-09-14T17:56:57.406573455Z",
  "type": "message-failed",
  "description": "invalid-destination-address",
  "segmentCount": 0,
  "direction": "out",
  "to": "+15554447777",
  "from": "+15551112222",
  "errorCode": 4720,
  "text": "Hello world",
  "customKey": "custom string"
}

Testing

You can test sending through the API by using a fromNumber of (999) 999-9999. Test SMS messages are not sent, but we simulate as if they are, and will also initiate a send to your callback URL if you have specified one in the same request. Test messages are not counted as API transactions. See the example send and callback below.

Send:

{
  "id": 5553,
  "time": "2023-09-18T15:49:43.052Z",
  "segmentCount": 1,
  "direction": "out",
  "to": "+15554447777",
  "from": "+19999999999",
  "text": "API Test Request",
  "status": 202,
  "request_time": 1695066583
}

Callback:

{
  "id": 5553,
  "time": "2023-09-18T15:49:43.052Z",
  "type": "message-delivered",
  "description": "Message delivered to carrier.",
  "segmentCount": 1,
  "direction": "out",
  "to": "+15554447777",
  "from": "+19999999999",
  "text": "API Test Request"
}

Related Links

Is this article helpful?
2 0 2