Libraries & SDKs
Copy page
The API is a clean REST + JSON interface, so it works from any language with an HTTP client — no SDK required. Every endpoint page in these docs includes ready-to-paste examples in eight languages:
| Language | HTTP client used in examples |
|---|---|
| cURL | — |
| Node.js | Built-in fetch (Node 18+) |
| Python | requests |
| PHP | curl extension |
| Ruby | net/http (stdlib) |
| Java | java.net.http.HttpClient (Java 11+) |
| Go | net/http (stdlib) |
| .NET | HttpClient (C#) |
Pick your language once in any code block — the choice follows you across the entire site.
The full loop in your language
Section titled “The full loop in your language”Send a message:
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": "Your verification code is 847291", "sender_id": "MyApp"}'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": "Your verification code is 847291", "sender_id": "MyApp" }),});
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.post( "https://restlink23telecom.com/api/v1/sms/send", headers={"X-API-Key": os.environ["API_KEY"]}, json={ "to": ["+14155551234"], "message": "Your verification code is 847291", "sender_id": "MyApp" },)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' => 'Your verification code is 847291', 'sender_id' => 'MyApp' ]),]);
$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: "Your verification code is 847291", sender_id: "MyApp"}.to_json
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/send")) .header("X-API-Key", System.getenv("API_KEY")) .header("Content-Type", "application/json") .POST(HttpRequest.BodyPublishers.ofString(""" { "to": [ "+14155551234" ], "message": "Your verification code is 847291", "sender_id": "MyApp" }""")) .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());System.out.println(response.body());package main
import ( "fmt" "io" "net/http" "os" "strings")
func main() { payload := strings.NewReader(`{ "to": [ "+14155551234" ], "message": "Your verification code is 847291", "sender_id": "MyApp"}`)
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": "Your verification code is 847291", "sender_id": "MyApp"}""";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());Check its status:
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());For webhook receivers in Python, Node.js and PHP, see the delivery webhook examples.
Package availability
Section titled “Package availability”Official TypeScript, Python and PHP SDK packages are not publicly distributed yet. Do not install similarly named third-party packages and assume they are maintained by 23 Telecom.
Today, use the eight-language examples above or generate a typed client from the OpenAPI 3.1 specification. Both routes call the same documented REST contract and work with free sandbox keys.
Integration tips that save support tickets
Section titled “Integration tips that save support tickets”- Store the key in an environment variable like the examples do — rotating keys then never touches code.
- Treat
messages[].message_idas your join key between send responses, status polls and webhook events. - Handle
429with backoff (rate limits) and monitorcredit_blockedbefore large sends (balance). - Make webhook handlers idempotent — retries deliver duplicates by design.