Get message status
Copy page
Check the delivery status of a sent message.
GET /api/v1/sms/status/:message_id · Permission: sms.read
Request
Section titled “Request”curl https://restlink23telecom.com/api/v1/sms/status/api_42_1743667200123456789_a3f8b2c1d9e45f67 \ -H "X-API-Key: $API_KEY"const res = await fetch('https://restlink23telecom.com/api/v1/sms/status/api_42_1743667200123456789_a3f8b2c1d9e45f67', { method: 'GET', headers: { 'X-API-Key': process.env.API_KEY },});
if (!res.ok) { const err = await res.json(); throw new Error(`${err.error_code}: ${err.description}`);}const data = await res.json();console.log(data);import osimport requests
res = requests.get( "https://restlink23telecom.com/api/v1/sms/status/api_42_1743667200123456789_a3f8b2c1d9e45f67", headers={"X-API-Key": os.environ["API_KEY"]},)res.raise_for_status()print(res.json())<?php$ch = curl_init('https://restlink23telecom.com/api/v1/sms/status/api_42_1743667200123456789_a3f8b2c1d9e45f67');curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['X-API-Key: ' . getenv('API_KEY')],]);
$response = curl_exec($ch);$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);curl_close($ch);
if ($status !== 200) { throw new Exception("HTTP $status: $response");}$data = json_decode($response, true);print_r($data);require "net/http"require "json"
uri = URI("https://restlink23telecom.com/api/v1/sms/status/api_42_1743667200123456789_a3f8b2c1d9e45f67")req = Net::HTTP::Get.new(uri)req["X-API-Key"] = ENV.fetch("API_KEY")
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }raise "HTTP #{res.code}: #{res.body}" unless res.is_a?(Net::HTTPSuccess)
puts JSON.parse(res.body)import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://restlink23telecom.com/api/v1/sms/status/api_42_1743667200123456789_a3f8b2c1d9e45f67")) .header("X-API-Key", System.getenv("API_KEY")) .GET() .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());System.out.println(response.body());package main
import ( "fmt" "io" "net/http" "os")
func main() { req, err := http.NewRequest("GET", "https://restlink23telecom.com/api/v1/sms/status/api_42_1743667200123456789_a3f8b2c1d9e45f67", nil) if err != nil { panic(err) } req.Header.Set("X-API-Key", os.Getenv("API_KEY"))
res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close()
data, _ := io.ReadAll(res.Body) fmt.Println(string(data))}using System.Text;
using var client = new HttpClient();client.DefaultRequestHeaders.Add("X-API-Key", Environment.GetEnvironmentVariable("API_KEY"));
var response = await client.GetAsync("https://restlink23telecom.com/api/v1/sms/status/api_42_1743667200123456789_a3f8b2c1d9e45f67");
response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());Response
Section titled “Response”{ "status": true, "message": { "message_id": "api_42_1743667200123456789_a3f8b2c1d9e45f67", "telecom_message_id": "6946d0f5-040b-106e-42c7-49026f2b5bc1", "recipient": "+14155551234", "segments": 1, "message": "Your verification code is 847291", "sender_id": "MyApp", "status": "DELIVRD", "status_code": "000", "cost": 0.0085, "created_at": "2026-02-13T10:30:00Z", "delivered_at": "2026-02-13T10:30:04Z", "clicked": true, "total_click_events": 2, "human_click_events": 1, "bot_click_events": 1, "first_click_at": "2026-02-13T10:31:00Z", "last_click_at": "2026-02-13T10:32:00Z", "first_human_click_at": "2026-02-13T10:31:00Z", "last_human_click_at": "2026-02-13T10:31:00Z" }}Live IDs start with api_; sandbox (sk_test_) IDs start with test_ and are
retained for 24 hours. 404 NOT_FOUND distinguishes an unknown/expired sandbox
ID, a test_ ID queried with a live key (use its sk_test_ key), and a live ID
not in this workspace. telecom_message_id, status_code, cost and delivered_at can be null. Sandbox responses add "sandbox": true and an empty telecom_message_id, with no click fields. A missing ID in a portal session returns 400 INVALID_ID; an unavailable sandbox returns 503 SANDBOX_UNAVAILABLE; a failed lookup returns 500 INTERNAL_ERROR.
Status values
Section titled “Status values”| Status | Description | Final? |
|---|---|---|
pending |
Queued, waiting to send | No |
sent |
Submitted to carrier network | No |
ENROUTE |
Accepted by carrier, in transit | No |
ACCEPTD |
Accepted by carrier for delivery | No |
DELIVRD |
Delivered to recipient’s handset | Yes |
UNDELIV |
Delivery failed (invalid number, phone off) | Yes |
REJECTD |
Rejected by carrier (filtered, blacklisted) | Yes |
EXPIRED |
Delivery timed out | Yes |
DELETED |
Message deleted on the carrier network | Yes |
UNKNOWN |
Outcome unknown, including a send whose result was unclear (for example a timeout); a later delivery report can still replace it | No |
failed |
Rejected by the gateway before routing (usually no route available), or an internal queue failure. Never charged — the portal reports these as Not Billed. | Yes |
Raw carrier statuses (ENROUTE, ACCEPTD, DELETED) can appear verbatim —
treat any status not in your known set as non-final and keep polling, except
the clearly terminal ones above. See delivery statuses
for typical status flows.
When filtering the message list by status, the accepted
filter values are delivered, undelivered, expired, pending,
not_billed, sent, clicked and converted (legacy aliases failed and unknown represent
undelivered plus gateway-rejected failed). clicked selects messages with a human click;
converted returns no direct-API messages. The other values map to groups of the raw statuses above.
Polling guidance
Section titled “Polling guidance”If you poll instead of using webhooks:
- Poll every 3–5 seconds, stop on any final status.
- Give up after a few minutes and treat it as in flight — nothing finalizes an API message automatically; rely on webhooks.
- Prefer webhooks for anything beyond low-volume testing: they remove polling load and deliver statuses the moment carriers report them.
