POST
/send-bulk
Send the same SMS message to multiple recipients in a single API call. Up to 100 recipients per request. Requires a paid plan and the simcoal:bulk scope.
Endpoint
POST https://coals.ai/api/v1/simcoal/send-bulk
Request Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| recipients | array | required | Array of recipient objects. Maximum 100 entries per request. Each object must include to and optionally carrier. |
| recipients[].to | string | required | Recipient phone number, 10–11 digits, no dashes or spaces. |
| recipients[].carrier | string | optional | Carrier code for this recipient. Required on free tier; optional on paid plans. |
| message | string | required | The SMS body text sent to all recipients. Maximum 1600 characters. |
Request Body
{ "recipients": [ { "to": "5551234567", "carrier": "verizon" }, { "to": "5559876543", "carrier": "tmobile" }, { "to": "5554567890", "carrier": "cricket" } ], "message": "Your appointment is tomorrow at 10am. Reply STOP to opt out." }
Response — 200 OK
{ "success": true, "total": 3, "successful": 3, "failed": 0, "results": [ { "to": "5551234567", "id": "msg_001", "status": "sent", "cost": 0.0075 }, { "to": "5559876543", "id": "msg_002", "status": "sent", "cost": 0.0075 }, { "to": "5554567890", "id": "msg_003", "status": "sent", "cost": 0.0075 } ] }
| Field | Description |
|---|---|
| total | Total number of recipients in the request. |
| successful | Number of messages successfully dispatched. |
| failed | Number of messages that could not be sent. Check individual results entries for error details. |
| results | Array of per-recipient outcomes. Each entry includes to, id, status, and cost. |
curl Example
curl -X POST https://coals.ai/api/v1/simcoal/send-bulk \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "recipients": [ { "to": "5551234567", "carrier": "verizon" }, { "to": "5559876543", "carrier": "tmobile" }, { "to": "5554567890", "carrier": "cricket" } ], "message": "Your appointment is tomorrow at 10am." }'
// Using Guzzle $response = $client->post('https://coals.ai/api/v1/simcoal/send-bulk', [ 'headers' => ['Authorization' => 'Bearer YOUR_API_KEY'], 'json' => [ "recipients" => [ [ "to" => "5551234567", "carrier" => "verizon" ], [ "to" => "5559876543", "carrier" => "tmobile" ], [ "to" => "5554567890", "carrier" => "cricket" ] ], "message" => "Your appointment is tomorrow at 10am." ] ]); $data = json_decode($response->getBody(), true);
# Using requests import requests response = requests.post( "https://coals.ai/api/v1/simcoal/send-bulk", headers={"Authorization": "Bearer YOUR_API_KEY"}, json={ "recipients": [ { "to": "5551234567", "carrier": "verizon" }, { "to": "5559876543", "carrier": "tmobile" }, { "to": "5554567890", "carrier": "cricket" } ], "message": "Your appointment is tomorrow at 10am." } ) data = response.json()
# Using net/http require "net/http" require "json" uri = URI("https://coals.ai/api/v1/simcoal/send-bulk") req = Net::HTTP::Post.new(uri) req["Authorization"] = "Bearer YOUR_API_KEY" req["Content-Type"] = "application/json" req.body = '{ "recipients": [ { "to": "5551234567", "carrier": "verizon" }, { "to": "5559876543", "carrier": "tmobile" }, { "to": "5554567890", "carrier": "cricket" } ], "message": "Your appointment is tomorrow at 10am." }' res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) } data = JSON.parse(res.body)
// Using fetch (Node 18+) const response = await fetch("https://coals.ai/api/v1/simcoal/send-bulk", { method: "POST", headers: { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" }, body: JSON.stringify({ "recipients": [ { "to": "5551234567", "carrier": "verizon" }, { "to": "5559876543", "carrier": "tmobile" }, { "to": "5554567890", "carrier": "cricket" } ], "message": "Your appointment is tomorrow at 10am." }) }); const data = await response.json();
Bulk sends are processed asynchronously. A status: "sent" in the result means the message was dispatched to the carrier gateway, not that the end device has received it. Use /logs/{id} to check final delivery status.
Partial success is possible — the request returns 200 even if some recipients fail. Always check the failed count and individual results entries.