SMS
Get SMS status
Returns the latest delivery status for one message.
/api/v1/sms/messages/statusBefore you start
Use the message ID returned when your SMS was accepted.
Result
Read the current delivery state and any failure, refund or text-conversion information.
Charges and safe retries
A validation-rejected recipient has no queued message ID or delivery webhook.
Authentication
Send your account API key in the X-Api-Key header. Keep it on your server; never embed it in browser code.
Request examples
Replace the example values with your own inputs. Examples do not run on this page. Production requests can change your account or incur charges.
cURL
curl -X GET "https://api.illyvoip.com/api/v1/sms/messages/status?message_id=YOUR_MESSAGE_ID" \
-H "X-Api-Key: ${ILLYVOIP_API_KEY:?Set ILLYVOIP_API_KEY}"Node.js
const response = await fetch("https://api.illyvoip.com/api/v1/sms/messages/status?message_id=YOUR_MESSAGE_ID", {
method: "GET",
headers: {
"X-Api-Key": process.env.ILLYVOIP_API_KEY
}
});
const data = await response.json();
console.log(response.status, data);PHP
<?php
$ch = curl_init('https://api.illyvoip.com/api/v1/sms/messages/status?message_id=YOUR_MESSAGE_ID');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-Api-Key: ' . getenv('ILLYVOIP_API_KEY')
],
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status . PHP_EOL;
echo $response;Python
import os
import json
import requests
response = requests.request(
"GET",
"https://api.illyvoip.com/api/v1/sms/messages/status?message_id=YOUR_MESSAGE_ID",
headers={
"X-Api-Key": os.environ["ILLYVOIP_API_KEY"]
},
)
print(response.status_code)
print(response.json())Node.js examples run on the server (Node.js 22.17+). Python examples require requests; PHP examples require cURL. Set the environment variables referenced in each example.
Request parameters
Query parameters
message_idstringrequiredMessage ID returned by the send endpoint.
Request behavior
Use this when you poll for message status instead of subscribing to webhooks. Public SMS statuses are queued, sent, delivered, failed, refund_pending, refunded, and unknown.
Conditions and examples
If you prefer push delivery over polling, subscribe a webhook endpoint to sms_sent, sms_delivered, and sms_failed in Account Settings → Integrations / CRM & webhooks. Sending charges may apply to accepted SMS even when delivery fails. New messages expose submission_status, delivery_status, charge_status, customer_charge_amount, refund_amount and financial_review_required. A pending or unknown result is not a refund and is not automatically submitted again. Older messages keep their original charging policy; these additive fields may be absent.
A confirmed character-encoding rejection includes error_code: unsupported_encoding and error_message in message status and sms_failed webhook message data. The explanation is: This message was rejected because it is not in GSM-7 (GSM 03.38) encoding. Edit unsupported characters and try again. A confirmed invalid-number rejection instead includes error_code: invalid_destination and the explanation: The destination phone number is invalid. Check the country code and full number, then try again. Confirmed rejections before acceptance release the reserved SMS charge automatically; the refund fields show whether that credit is pending or complete. These fields are optional and are absent for other outcomes. The send response confirms queuing; check the later status or webhook for the result. Charging and refund fields describe the recorded balance outcome separately.
Error responses
Expected failures return status: error and a message. Save any error_code when contacting support.
400 · Input or review required
The message ID is missing or is not owned by the authenticated account.
-
message_id not found.
-
message_idis required.
401 · Authentication
The API key is missing or invalid.
-
Invalid API key.
-
Missing API key.
403 · Account access
API or SMS access, account role, or KYC policy does not permit the request.
-
SMS is disabled for this account.
-
API access is disabled.
-
API access is disabled for this account.
-
Only portal administrators can query message status.
429 · Rate limit
The API request rate was exceeded.
- Too many API requests. Please retry in a minute.
500 · Unexpected error
An unexpected server error occurred. Quote error_code when contacting support.
- There is a problem with our backend services right now. Please try again later.
503 · Temporarily unavailable
The SMS status store is temporarily unavailable.
- Unable to load SMS status right now.
Response fields
status: Request outcome. Read the resource state separately; success does not always mean delivery or completion.message_id: Public message reference for status and webhook correlation.from: Sender identity or originating number for the resource.to: Destination number or recipients for the resource.sms_status: Current SMS delivery state.status_label: Human-readable label for the status.status_message: Explanation accompanying the current status.cost: Charge returned for this operation; see the endpoint for its currency and units.created_date: Resource creation date in the returned format.sent_at: Time the message was submitted, if available.delivered_at: Time delivery was confirmed, if available.updated_at: Time the resource was last updated.refunded: Whether the associated charge was refunded.refunded_amount: Amount credited back for this resource.refunded_at: Time the refund was recorded, if any.
HTTP responses
Expand a status to inspect its documented response format and examples. Example prices, IDs and timestamps are illustrative values, not quotes or account records.
200 Successful customer-facing response.
application/json
{
"status": "success",
"message_id": "sms_01HXYZ123",
"from": "IllyVoIP",
"to": "+12025550123",
"sms_status": "delivered",
"status_label": "Delivered",
"status_message": "",
"cost": 0.05,
"created_date": "2026-07-27 10:14:54",
"sent_at": "2026-07-27 10:14:55",
"delivered_at": "2026-07-27 10:15:00",
"updated_at": "2026-07-27 10:15:00",
"refunded": false,
"refunded_amount": 0,
"refunded_at": ""
}statusstringrequiredmessage_idstringrequiredfromstringrequiredtostringrequiredsms_statusstringrequiredstatus_labelstringrequiredstatus_messagestringrequiredcostnumberrequiredcreated_datestringrequiredsent_atstringrequireddelivered_atstringrequiredupdated_atstringrequiredrefundedbooleanrequiredrefunded_amountnumberrequiredrefunded_atstringrequiredtext_conversion_possiblebooleanoptionalWhether the retained sending plan contains a converted variant.
text_conversion_appliedbooleanoptionalTrue only when confirmed submission used converted text.
submitted_messagestringoptionalExact text of the confirmed submission; original message text remains unchanged.
submitted_encodingstringoptionalsubmitted_segmentsintegeroptionalsubmission_statusstringoptionaldelivery_statusstringoptionalcharge_statusstringoptionalcustomer_charge_amountstringoptionalRecorded sending charge in EUR as a decimal string; null means unresolved.
refund_amountstringoptionalCommitted refund in EUR as a decimal string; pending credits are not included.
financial_review_requiredbooleanoptionalerror_codestringoptionalOptional safe reason for a confirmed message rejection. This is a message outcome, not a failure of the status request.
error_messagestringoptionalOptional customer explanation: This message was rejected because it is not in GSM-7 (GSM 03.38) encoding. Edit unsupported characters and try again.
Additional properties: not allowed.
Full schema
{
"type": "object",
"additionalProperties": false,
"properties": {
"status": {
"type": "string",
"enum": [
"success"
]
},
"message_id": {
"type": "string"
},
"from": {
"type": "string"
},
"to": {
"type": "string"
},
"sms_status": {
"type": "string",
"enum": [
"queued",
"sent",
"delivered",
"failed",
"refund_pending",
"refunded",
"unknown"
]
},
"status_label": {
"type": "string"
},
"status_message": {
"type": "string"
},
"cost": {
"type": "number"
},
"created_date": {
"type": "string"
},
"sent_at": {
"type": "string"
},
"delivered_at": {
"type": "string"
},
"updated_at": {
"type": "string"
},
"refunded": {
"type": "boolean"
},
"refunded_amount": {
"type": "number"
},
"refunded_at": {
"type": "string"
},
"text_conversion_possible": {
"type": "boolean",
"description": "Whether the retained sending plan contains a converted variant."
},
"text_conversion_applied": {
"type": "boolean",
"description": "True only when confirmed submission used converted text."
},
"submitted_message": {
"type": "string",
"nullable": true,
"description": "Exact text of the confirmed submission; original message text remains unchanged."
},
"submitted_encoding": {
"type": "string",
"nullable": true,
"enum": [
"GSM-7",
"UCS-2",
null
]
},
"submitted_segments": {
"type": "integer",
"nullable": true,
"minimum": 1
},
"submission_status": {
"type": "string",
"enum": [
"queued",
"accepted",
"unknown",
"not_submitted"
]
},
"delivery_status": {
"type": "string",
"enum": [
"pending",
"delivered",
"partial",
"not_delivered",
"unknown"
]
},
"charge_status": {
"type": "string",
"enum": [
"reserved",
"under_review",
"refund_pending",
"free",
"charged",
"refunded",
"partially_refunded"
]
},
"customer_charge_amount": {
"type": "string",
"nullable": true,
"description": "Recorded sending charge in EUR as a decimal string; null means unresolved."
},
"refund_amount": {
"type": "string",
"description": "Committed refund in EUR as a decimal string; pending credits are not included."
},
"financial_review_required": {
"type": "boolean"
},
"error_code": {
"type": "string",
"enum": [
"unsupported_encoding",
"invalid_destination"
],
"description": "Optional safe reason for a confirmed message rejection. This is a message outcome, not a failure of the status request."
},
"error_message": {
"type": "string",
"description": "Optional customer explanation: This message was rejected because it is not in GSM-7 (GSM 03.38) encoding. Edit unsupported characters and try again."
}
},
"required": [
"status",
"message_id",
"from",
"to",
"sms_status",
"status_label",
"status_message",
"cost",
"created_date",
"sent_at",
"delivered_at",
"updated_at",
"refunded",
"refunded_amount",
"refunded_at"
],
"description": "Submission, delivery and charging are separate facts. Accepted-but-undelivered SMS may still be charged. New messages include the optional commercial fields; old messages retain their original policy. A Sent event describes the initial acceptance, not later delivery or refund facts."
}400 The message ID is missing or is not owned by the authenticated account.
application/json
{
"status": "error",
"message": "message_id not found."
}{
"status": "error",
"message": "`message_id` is required."
}statusstringrequiredmessagestringrequirederror_codestringoptionalPublic incident or validation code when the endpoint provides one.
fieldsobjectoptionalPublic validation details when supplied by the endpoint.
Additional properties: not allowed.
Full schema
{
"type": "object",
"additionalProperties": false,
"required": [
"status",
"message"
],
"properties": {
"status": {
"type": "string",
"enum": [
"error"
]
},
"message": {
"type": "string"
},
"error_code": {
"type": "string",
"nullable": true,
"description": "Public incident or validation code when the endpoint provides one."
},
"fields": {
"type": "object",
"additionalProperties": true,
"description": "Public validation details when supplied by the endpoint."
}
}
}401 The API key is missing or invalid.
application/json
{
"status": "error",
"message": "Invalid API key."
}{
"status": "error",
"message": "Missing API key."
}statusstringrequiredmessagestringrequirederror_codestringoptionalPublic incident or validation code when the endpoint provides one.
fieldsobjectoptionalPublic validation details when supplied by the endpoint.
Additional properties: not allowed.
Full schema
{
"type": "object",
"additionalProperties": false,
"required": [
"status",
"message"
],
"properties": {
"status": {
"type": "string",
"enum": [
"error"
]
},
"message": {
"type": "string"
},
"error_code": {
"type": "string",
"nullable": true,
"description": "Public incident or validation code when the endpoint provides one."
},
"fields": {
"type": "object",
"additionalProperties": true,
"description": "Public validation details when supplied by the endpoint."
}
}
}403 API or SMS access, account role, or KYC policy does not permit the request.
application/json
{
"status": "error",
"message": "SMS is disabled for this account."
}{
"status": "error",
"message": "API access is disabled."
}{
"status": "error",
"message": "API access is disabled for this account."
}{
"status": "error",
"message": "Only portal administrators can query message status."
}statusstringrequiredmessagestringrequirederror_codestringoptionalPublic incident or validation code when the endpoint provides one.
fieldsobjectoptionalPublic validation details when supplied by the endpoint.
Additional properties: not allowed.
Full schema
{
"type": "object",
"additionalProperties": false,
"required": [
"status",
"message"
],
"properties": {
"status": {
"type": "string",
"enum": [
"error"
]
},
"message": {
"type": "string"
},
"error_code": {
"type": "string",
"nullable": true,
"description": "Public incident or validation code when the endpoint provides one."
},
"fields": {
"type": "object",
"additionalProperties": true,
"description": "Public validation details when supplied by the endpoint."
}
}
}429 The API request rate was exceeded.
application/json
{
"status": "error",
"message": "Too many API requests. Please retry in a minute."
}statusstringrequiredmessagestringrequirederror_codestringoptionalPublic incident or validation code when the endpoint provides one.
fieldsobjectoptionalPublic validation details when supplied by the endpoint.
Additional properties: not allowed.
Full schema
{
"type": "object",
"additionalProperties": false,
"required": [
"status",
"message"
],
"properties": {
"status": {
"type": "string",
"enum": [
"error"
]
},
"message": {
"type": "string"
},
"error_code": {
"type": "string",
"nullable": true,
"description": "Public incident or validation code when the endpoint provides one."
},
"fields": {
"type": "object",
"additionalProperties": true,
"description": "Public validation details when supplied by the endpoint."
}
}
}500 An unexpected server error occurred. Quote error_code when contacting support.
application/json
{
"status": "error",
"message": "There is a problem with our backend services right now. Please try again later.",
"error_code": "IVERR-20260814101501-example"
}statusstringrequiredmessagestringrequirederror_codestringoptionalPublic incident or validation code when the endpoint provides one.
fieldsobjectoptionalPublic validation details when supplied by the endpoint.
Additional properties: not allowed.
Full schema
{
"type": "object",
"additionalProperties": false,
"required": [
"status",
"message"
],
"properties": {
"status": {
"type": "string",
"enum": [
"error"
]
},
"message": {
"type": "string"
},
"error_code": {
"type": "string",
"nullable": true,
"description": "Public incident or validation code when the endpoint provides one."
},
"fields": {
"type": "object",
"additionalProperties": true,
"description": "Public validation details when supplied by the endpoint."
}
}
}503 The SMS status store is temporarily unavailable.
application/json
{
"status": "error",
"message": "Unable to load SMS status right now."
}statusstringrequiredmessagestringrequirederror_codestringoptionalPublic incident or validation code when the endpoint provides one.
fieldsobjectoptionalPublic validation details when supplied by the endpoint.
Additional properties: not allowed.
Full schema
{
"type": "object",
"additionalProperties": false,
"required": [
"status",
"message"
],
"properties": {
"status": {
"type": "string",
"enum": [
"error"
]
},
"message": {
"type": "string"
},
"error_code": {
"type": "string",
"nullable": true,
"description": "Public incident or validation code when the endpoint provides one."
},
"fields": {
"type": "object",
"additionalProperties": true,
"description": "Public validation details when supplied by the endpoint."
}
}
}Sandbox scenarios
Use https://sandbox-api.illyvoip.com with Sandbox credentials and the X-Illyvoip-Sandbox-Scenario header. Omit the header for the documented success default. This header belongs to sandbox requests.
success, not-found, rate-limited, forbidden, service-unavailable, delivered, failed, queued
Try this operation in Sandbox · Environment setup and limitations