Quickstart
This guide takes you from a new account to a delivered SMS. You need one of these: a terminal with curl, Python 3 with requests (pip install requests), Node.js 18 or later (save the sample as a .mjs file, because it uses top-level await), or PHP with the curl extension.
1. Set up your account
- Create an account and open the verification link we e-mail you.
- In the dashboard, open Sender IDs and request the name your recipients will see, such as your brand. Wait until 500Calls approves it: it then shows Approved, and you can send from it straight away.
- Open Wallet and billing and top up. You pay the amount you add plus the Paystack fee.
2. Create an API key
Open Developers, then API keys, and create a key with the scopes messages:send, messages:read, balance:read and sender_ids:read. The key starts with 500c_live_… and is shown only once, so store it in your secret manager.
Keep the key on your server, in an environment variable named API_KEY_500CALLS, which every sample on this site reads. To try the samples in a terminal, run this command, paste the key and press Enter. The key is read without being shown, and it stays out of your shell history:
read -rs API_KEY_500CALLS && export API_KEY_500CALLS3. Check your balance
curl 'https://api.messaging.500calls.com/v1/balance' \ -H "Authorization: Bearer $API_KEY_500CALLS"import osimport requestsresponse = requests.get( "https://api.messaging.500calls.com/v1/balance", headers={ "Authorization": f"Bearer {os.environ['API_KEY_500CALLS']}", }, timeout=30,)print(response.status_code, response.json())const response = await fetch("https://api.messaging.500calls.com/v1/balance", { headers: { Authorization: `Bearer ${process.env.API_KEY_500CALLS}`, },});console.log(response.status, await response.json());<?php$curl = curl_init('https://api.messaging.500calls.com/v1/balance');curl_setopt_array($curl, [ CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . getenv('API_KEY_500CALLS'), ], CURLOPT_RETURNTRANSFER => true,]);$body = curl_exec($curl);$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);echo $status, PHP_EOL, $body, PHP_EOL;available is what new sends can use. Amounts are strings with four decimal places: "15215.0000" is ₦15,215.00.
4. Find your sender ID
curl 'https://api.messaging.500calls.com/v1/sender-ids?status=approved' \ -H "Authorization: Bearer $API_KEY_500CALLS"import osimport requestsresponse = requests.get( "https://api.messaging.500calls.com/v1/sender-ids?status=approved", headers={ "Authorization": f"Bearer {os.environ['API_KEY_500CALLS']}", }, timeout=30,)print(response.status_code, response.json())const response = await fetch("https://api.messaging.500calls.com/v1/sender-ids?status=approved", { headers: { Authorization: `Bearer ${process.env.API_KEY_500CALLS}`, },});console.log(response.status, await response.json());<?php$curl = curl_init('https://api.messaging.500calls.com/v1/sender-ids?status=approved');curl_setopt_array($curl, [ CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . getenv('API_KEY_500CALLS'), ], CURLOPT_RETURNTRANSFER => true,]);$body = curl_exec($curl);$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);echo $status, PHP_EOL, $body, PHP_EOL;Send from a sender ID whose usable is true.
5. Send an SMS
Replace to with your own number and from with your sender ID:
curl -X POST 'https://api.messaging.500calls.com/v1/sms/messages' \ -H "Authorization: Bearer $API_KEY_500CALLS" \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: order-78123-otp' \ -d '{ "to": "08031234567", "from": "ACME", "body": "Your ACME code is 482913. It expires in 5 minutes.", "client_reference": "order-78123"}'import osimport requestsresponse = requests.post( "https://api.messaging.500calls.com/v1/sms/messages", headers={ "Authorization": f"Bearer {os.environ['API_KEY_500CALLS']}", "Idempotency-Key": "order-78123-otp", }, json={ "to": "08031234567", "from": "ACME", "body": "Your ACME code is 482913. It expires in 5 minutes.", "client_reference": "order-78123", }, timeout=30,)print(response.status_code, response.json())const response = await fetch("https://api.messaging.500calls.com/v1/sms/messages", { method: "POST", headers: { Authorization: `Bearer ${process.env.API_KEY_500CALLS}`, "Content-Type": "application/json", "Idempotency-Key": "order-78123-otp", }, body: JSON.stringify({ "to": "08031234567", "from": "ACME", "body": "Your ACME code is 482913. It expires in 5 minutes.", "client_reference": "order-78123" }),});console.log(response.status, await response.json());<?php$curl = curl_init('https://api.messaging.500calls.com/v1/sms/messages');curl_setopt_array($curl, [ CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . getenv('API_KEY_500CALLS'), 'Content-Type: application/json', 'Idempotency-Key: order-78123-otp', ], CURLOPT_POSTFIELDS => json_encode([ 'to' => '08031234567', 'from' => 'ACME', 'body' => 'Your ACME code is 482913. It expires in 5 minutes.', 'client_reference' => 'order-78123', ]), CURLOPT_RETURNTRANSFER => true,]);$body = curl_exec($curl);$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);echo $status, PHP_EOL, $body, PHP_EOL;A 202 means the message was accepted, not that it was sent. The response holds the message's id and its first status, queued.
The Idempotency-Key header makes the request safe to retry: the same key with the same body gets the first response again, and nothing is sent twice. Give each new message a new key, such as the ID of the order it is about: the samples' key is only an example. Within 24 hours, the same key with a different body, such as a new to, gets 409 idempotency_key_reused. See idempotency and retries.
6. Follow its status
curl 'https://api.messaging.500calls.com/v1/messages/msg_01M3KR6CEGVQVV5PV6Q9J1G6SP' \ -H "Authorization: Bearer $API_KEY_500CALLS"import osimport requestsresponse = requests.get( "https://api.messaging.500calls.com/v1/messages/msg_01M3KR6CEGVQVV5PV6Q9J1G6SP", headers={ "Authorization": f"Bearer {os.environ['API_KEY_500CALLS']}", }, timeout=30,)print(response.status_code, response.json())const response = await fetch("https://api.messaging.500calls.com/v1/messages/msg_01M3KR6CEGVQVV5PV6Q9J1G6SP", { headers: { Authorization: `Bearer ${process.env.API_KEY_500CALLS}`, },});console.log(response.status, await response.json());<?php$curl = curl_init('https://api.messaging.500calls.com/v1/messages/msg_01M3KR6CEGVQVV5PV6Q9J1G6SP');curl_setopt_array($curl, [ CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . getenv('API_KEY_500CALLS'), ], CURLOPT_RETURNTRANSFER => true,]);$body = curl_exec($curl);$status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);echo $status, PHP_EOL, $body, PHP_EOL;Within seconds the status moves to sent, then to delivered when the network confirms delivery. Message statuses explains each one.
7. Get told instead of asking
Instead of polling, register a webhook in the dashboard under Developers, then Webhooks: we send a signed request to your server when a message's status changes. See webhooks.