---
title: "Send Bulk SMS"
description: "Send SMS messages to multiple recipients simultaneously using your approved sender name."
---

# Send Bulk SMS

Use the bulk SMS endpoint to deliver messages to multiple recipients in a single API call.

It is suitable for:

- batch notifications
- marketing campaigns and broadcasts
- operational announcements
- multiple recipient alerts

## Endpoint

```http
POST /api/v2/messages/sms/bulk
```

## Authorization

Authenticate using your API token in the `Authorization` HTTP header:

```http
Authorization: Bearer <your_api_token>
Content-Type: application/json
```

<Note>
**Backward Compatibility**: Legacy `X-API-Key` and `X-API-Secret` headers, as well as credentials passed in the JSON body or query parameters, continue to be supported.
</Note>

## Request Format

Instead of remembering a long UUID `sender_id`, you can simply supply your sender ID name directly via `"sender"`:

```json
{
  "sender": "BULK_IT",
  "mobiles": [
    "254700000001",
    "254733000002"
  ],
  "message": "Hello, thank you for being a valued customer!"
}
```

<Info>
**Sender Flexibility**: You can pass your alphanumeric sender name in `"sender"` (e.g. `"BULK_IT"` or `"YOUR_BRAND"`). If you have existing integrations using `"sender_id"` with a UUID or numeric ID, those will continue to work without modification.
</Info>

## Scheduled Bulk SMS

To schedule a broadcast for future delivery, pass an ISO 8601 timestamp in `scheduled_at`:

```json
{
  "sender": "BULK_IT",
  "mobiles": [
    "254700000001",
    "254733000002"
  ],
  "message": "Flash sale starts at 10:00 AM!",
  "scheduled_at": "2026-03-10T10:00:00+03:00"
}
```

## Code Examples

<CodeGroup>

```bash curl
curl -X POST "https://api.bulkitsms.com/api/v2/messages/sms/bulk" \
  -H "Authorization: Bearer bk_live_8n6JQv3K1h9Lp0Md" \
  -H "Content-Type: application/json" \
  -d '{
    "sender": "BULK_IT",
    "mobiles": [
      "254700000001",
      "254733000002"
    ],
    "message": "Hello! Your monthly statement is ready for viewing."
  }'
```

```python python.py
import requests

headers = {
    "Authorization": "Bearer bk_live_8n6JQv3K1h9Lp0Md",
    "Content-Type": "application/json",
}

payload = {
    "sender": "BULK_IT",
    "mobiles": [
        "254700000001",
        "254733000002"
    ],
    "message": "Hello! Your monthly statement is ready for viewing."
}

response = requests.post(
    "https://api.bulkitsms.com/api/v2/messages/sms/bulk",
    headers=headers,
    json=payload,
    timeout=30,
)
response.raise_for_status()

print(response.json())
```

```go main.go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
)

type BulkSMSRequest struct {
	Sender      string   `json:"sender"`
	Mobiles     []string `json:"mobiles"`
	Message     string   `json:"message"`
	ScheduledAt string   `json:"scheduled_at,omitempty"`
}

func main() {
	payload := BulkSMSRequest{
		Sender:  "BULK_IT",
		Mobiles: []string{"254700000001", "254733000002"},
		Message: "Hello! Your monthly statement is ready for viewing.",
	}

	body, err := json.Marshal(payload)
	if err != nil {
		panic(err)
	}

	req, err := http.NewRequest(
		http.MethodPost,
		"https://api.bulkitsms.com/api/v2/messages/sms/bulk",
		bytes.NewReader(body),
	)
	if err != nil {
		panic(err)
	}

	req.Header.Set("Authorization", "Bearer bk_live_8n6JQv3K1h9Lp0Md")
	req.Header.Set("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	var result map[string]interface{}
	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		panic(err)
	}

	fmt.Printf("%+v\n", result)
}
```

```php php
<?php

$payload = [
    "sender" => "BULK_IT",
    "mobiles" => [
        "254700000001",
        "254733000002"
    ],
    "message" => "Hello! Your monthly statement is ready for viewing."
];

$ch = curl_init("https://api.bulkitsms.com/api/v2/messages/sms/bulk");

curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer bk_live_8n6JQv3K1h9Lp0Md",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode($payload, JSON_THROW_ON_ERROR),
]);

$response = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if ($response === false) {
    throw new Exception(curl_error($ch));
}

curl_close($ch);

echo $statusCode . PHP_EOL;
echo $response . PHP_EOL;
```

</CodeGroup>

## Parameters

| Parameter | Required | Type | Description |
| --- | --- | --- | --- |
| `sender` | Yes | string | Your sender ID name (e.g. `BULK_IT` or `YOUR_BRAND`). |
| `mobiles` | Yes | array of strings | List of recipient phone numbers in international or local format (e.g. `["254700000001", "0733000002"]`). |
| `message` | Yes | string | SMS text to send. Long messages will automatically be divided into multiple units. |
| `scheduled_at` | No | string | Optional ISO 8601 timestamp for scheduled delivery (e.g. `2026-03-10T10:00:00+03:00`). |
| `sender_id` | Legacy | string / number | Legacy UUID or numeric ID for backward compatibility with older integrations. |

## Responses

### Success Response

```json
{
  "status": "success",
  "message": "Bulk SMS processed",
  "data": {
    "requested": 2,
    "queued": 2,
    "failed": []
  }
}
```

### Partial Bulk Failure

If one of the numbers is invalid, valid recipients are still queued and invalid ones are reported in `failed`:

```json
{
  "status": "success",
  "message": "Bulk SMS processed",
  "data": {
    "requested": 2,
    "queued": 1,
    "failed": [
      {
        "mobile": "12345",
        "message": "Invalid number"
      }
    ]
  }
}
```

### Error Response

```json
{
  "status": "error",
  "message": "Invalid sender ID"
}
```

## Common Error Codes

- `Invalid credentials`: Missing or invalid Bearer token / API key.
- `Insufficient balance`: Account balance is insufficient for the requested message units.
- `Invalid number`: None of the supplied numbers are valid phone numbers.
- `Invalid sender ID`: Specified sender name or ID does not exist or is not approved for your account.
- `Restricted send time`: Safaricom promotional window restriction (promotional messages are permitted between 8:00 AM and 6:00 PM Africa/Nairobi time).
