# Send a campaign to a list

```http
POST https://smsprovider-web.vercel.app/api/v1/campaigns
```

Send to a contact list with dynamic fields `{{df1}}`…`{{df6}}`. Unsubscribed and blacklisted contacts are filtered out automatically.

**Authentication:** `Authorization: Bearer bm_live_…` · **Required scope:** `sms:send`

> Send an `Idempotency-Key` header (a unique string, e.g. a UUID). Repeating the same key within 24 hours returns the same response without charging again.

## Request body

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `list_id` | string (uuid) | yes |  |
| `name` | string | no | len 1–100 |
| `from` | string | no | len 2–20 |
| `body` | string | yes | len 1–1005 |
| `schedule_at` | string (date-time) | no |  |
| `unsubscribe` | `none` \| `link` \| `reply` | no | default `"none"` |
| `skip_recent_days` | integer | no | 1–14 |
| `links` | map<string, string (uri)> | no |  |

## Response

`200` — `SendResult`

## Errors

| Status | Code |
| --- | --- |
| 400 | `validation_error` |
| 400 | `idempotency_key_required` |
| 409 | `idempotency_conflict` |
| 402 | `insufficient_credits` |
| 403 | `sender_not_verified` |
| 422 | `invalid_destination` |
| 429 | `daily_limit_exceeded` |
| 403 | `org_suspended` |
| 401 | `unauthorized` |
| 403 | `insufficient_scope` |
| 429 | `rate_limited` |
| 500 | `internal_error` |
| 404 | `not_found` |

## Examples

### curl
```bash
curl -X POST "https://smsprovider-web.vercel.app/api/v1/campaigns" \
  -H "Authorization: Bearer $BATLER_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"list_id":"5b0d2a8e-1d7c-4a35-9a7e-3c1a3b5e9f00","from":"MyBrand","body":"היי {{df1}}, מבצע סוף עונה: 20% הנחה! [shop]","links":{"shop":"https://example.com/sale"},"unsubscribe":"link","schedule_at":"2026-11-05T09:00:00+02:00"}'
```
### Node.js
```ts
import { BatlerSMS } from "@batler/sms";

const sms = new BatlerSMS({ apiKey: process.env.BATLER_API_KEY! });
const body = {
  "list_id": "5b0d2a8e-1d7c-4a35-9a7e-3c1a3b5e9f00",
  "from": "MyBrand",
  "body": "היי {{df1}}, מבצע סוף עונה: 20% הנחה! [shop]",
  "links": {
    "shop": "https://example.com/sale"
  },
  "unsubscribe": "link",
  "schedule_at": "2026-11-05T09:00:00+02:00"
};
const result = await sms.campaigns.create(body);
```
### PHP
```php
<?php
$ch = curl_init("https://smsprovider-web.vercel.app/api/v1/campaigns");
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer " . getenv("BATLER_API_KEY"),
    "Content-Type: application/json",
    "Idempotency-Key: " . bin2hex(random_bytes(16)),
  ],
  CURLOPT_POSTFIELDS => json_encode(["list_id" => "5b0d2a8e-1d7c-4a35-9a7e-3c1a3b5e9f00", "from" => "MyBrand", "body" => "היי {{df1}}, מבצע סוף עונה: 20% הנחה! [shop]", "links" => ["shop" => "https://example.com/sale"], "unsubscribe" => "link", "schedule_at" => "2026-11-05T09:00:00+02:00"], JSON_UNESCAPED_UNICODE),
]);
$result = json_decode(curl_exec($ch), true);
```
### Python
```python
import os, uuid, requests

resp = requests.request(
    "POST", "https://smsprovider-web.vercel.app/api/v1/campaigns",
    headers={"Authorization": f"Bearer {os.environ['BATLER_API_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={"list_id": "5b0d2a8e-1d7c-4a35-9a7e-3c1a3b5e9f00", "from": "MyBrand", "body": "היי {{df1}}, מבצע סוף עונה: 20% הנחה! [shop]", "links": {"shop": "https://example.com/sale"}, "unsubscribe": "link", "schedule_at": "2026-11-05T09:00:00+02:00"},
    timeout=30,
)
resp.raise_for_status()
result = resp.json()
```
### C#
```csharp
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new("Bearer", Environment.GetEnvironmentVariable("BATLER_API_KEY"));
var req = new HttpRequestMessage(HttpMethod.Post, "https://smsprovider-web.vercel.app/api/v1/campaigns");
req.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
req.Content = new StringContent("{\"list_id\":\"5b0d2a8e-1d7c-4a35-9a7e-3c1a3b5e9f00\",\"from\":\"MyBrand\",\"body\":\"היי {{df1}}, מבצע סוף עונה: 20% הנחה! [shop]\",\"links\":{\"shop\":\"https://example.com/sale\"},\"unsubscribe\":\"link\",\"schedule_at\":\"2026-11-05T09:00:00+02:00\"}", System.Text.Encoding.UTF8, "application/json");
var res = await http.SendAsync(req);
var result = await res.Content.ReadAsStringAsync();
```
