Quickstart — send your first SMS
Copy page
This guide takes you from zero to a delivered SMS in about five minutes.
Prerequisites: an active 23 Telecom account with SMS sending enabled. Your account manager provides your login credentials.
-
Get your API key.
Log in to the customer portal, go to Settings → API Keys, and create a key with the
sms.sendandsms.readpermissions. -
Send your first SMS.
Replace the recipient with your own phone number in E.164 format (for example
+447911123456):Terminal window curl -X POST https://restlink23telecom.com/api/v1/sms/send \-H "X-API-Key: $API_KEY" \-H "Content-Type: application/json" \-d '{"to": ["+14155551234"],"message": "Hello from 23 Telecom!","sender_id": "MyCompany"}'const res = await fetch('https://restlink23telecom.com/api/v1/sms/send', {method: 'POST',headers: { 'X-API-Key': process.env.API_KEY, 'Content-Type': 'application/json' },body: JSON.stringify({"to": ["+14155551234"],"message": "Hello from 23 Telecom!","sender_id": "MyCompany"}),});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 requestsres = requests.post("https://restlink23telecom.com/api/v1/sms/send",headers={"X-API-Key": os.environ["API_KEY"]},json={"to": ["+14155551234"],"message": "Hello from 23 Telecom!","sender_id": "MyCompany"},)res.raise_for_status()print(res.json())<?php$ch = curl_init('https://restlink23telecom.com/api/v1/sms/send');curl_setopt_array($ch, [CURLOPT_CUSTOMREQUEST => 'POST',CURLOPT_RETURNTRANSFER => true,CURLOPT_HTTPHEADER => ['X-API-Key: ' . getenv('API_KEY'), 'Content-Type: application/json'],CURLOPT_POSTFIELDS => json_encode(['to' => ['+14155551234'],'message' => 'Hello from 23 Telecom!','sender_id' => 'MyCompany']),]);$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/send")req = Net::HTTP::Post.new(uri)req["X-API-Key"] = ENV.fetch("API_KEY")req["Content-Type"] = "application/json"req.body = {to: ["+14155551234"],message: "Hello from 23 Telecom!",sender_id: "MyCompany"}.to_jsonres = 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/send")).header("X-API-Key", System.getenv("API_KEY")).header("Content-Type", "application/json").POST(HttpRequest.BodyPublishers.ofString("""{"to": ["+14155551234"],"message": "Hello from 23 Telecom!","sender_id": "MyCompany"}""")).build();HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());System.out.println(response.body());package mainimport ("fmt""io""net/http""os""strings")func main() {payload := strings.NewReader(`{"to": ["+14155551234"],"message": "Hello from 23 Telecom!","sender_id": "MyCompany"}`)req, err := http.NewRequest("POST", "https://restlink23telecom.com/api/v1/sms/send", payload)if err != nil {panic(err)}req.Header.Set("X-API-Key", os.Getenv("API_KEY"))req.Header.Set("Content-Type", "application/json")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 json = """{"to": ["+14155551234"],"message": "Hello from 23 Telecom!","sender_id": "MyCompany"}""";var content = new StringContent(json, Encoding.UTF8, "application/json");var response = await client.PostAsync("https://restlink23telecom.com/api/v1/sms/send", content);response.EnsureSuccessStatusCode();Console.WriteLine(await response.Content.ReadAsStringAsync());A successful response confirms acceptance and tells you the cost, encoding and a
message_idfor each recipient:200 OK {"status": true,"messages": [{"dnis": "+14155551234","message_id": "api_42_1743667200123456789_a3f8b2c1d9e45f67","segment_num": 1}],"results": [{"dnis": "+14155551234","message_id": "api_42_1743667200123456789_a3f8b2c1d9e45f67","segments": 1,"status": "accepted"}],"summary": {"total_recipients": 1,"total_segments": 1,"total_cost": 0.01,"encoding": "GSM-7","accepted_count": 1,"blocked_count": 0}} -
Check the delivery status.
Use the
message_idfrom the send response:Terminal window 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 requestsres = 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 mainimport ("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());200 OK {"status": true,"message": {"message_id": "api_42_1743667200123456789_a3f8b2c1d9e45f67","recipient": "+14155551234","sender_id": "MyCompany","message": "Hello from 23 Telecom!","segments": 1,"status": "DELIVRD","cost": 0.0085,"created_at": "2026-02-13T10:30:00Z","delivered_at": "2026-02-13T10:30:04Z"}}DELIVRDmeans the message reached the recipient’s handset. See all possible values in delivery statuses.
Next steps
Section titled “Next steps”- Stop polling, start listening — set up a delivery webhook to receive real-time delivery reports on your server.
- Going to production? Read authentication for HMAC request signing and rate limits.
- Sending campaigns? Check encoding & segments so long or Unicode messages don’t surprise you on cost.
- Prefer clicking to coding? Import the Postman collection or open the API playground.