Schedules a draft or sends it immediately. No date sends immediately. Maps to `schedule_campaign`. Permission: `send`.

The campaign must be `DRAFT` and must contain an unsubscribe link.

## Path Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `campaignId` | string | **Required.** Campaign id. |

## Body Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `scheduledAt` | string | Optional ISO 8601 send time. Omit to send immediately. |
| `timezone` | string | IANA timezone for the schedule. Default `Europe/Paris`. |

## Response Fields

| Field | Type | Description |
| ----- | ---- | ----------- |
| `id` | string | Campaign id. |
| `campaignId` | string | Same campaign id when the worker echoes it. |
| `subject` | string | Subject line. |
| `status` | string | `SCHEDULED` after accept. Immediate sends stay `SCHEDULED` until the worker starts. |
| `scheduledAt` | string | ISO 8601 scheduled time. |
| `timezone` | string | Schedule timezone when provided. |
| `recipientCount` | integer | Recipients at schedule time. |

## Errors

| Status | `name` | When |
| ------ | ------ | ---- |
| 401 | `missing_api_key` | Missing or invalid bearer token |
| 403 | `missing_permission` | Token lacks the `send` permission |
| 404 | `not_found` | Unknown campaign id |
| 400 | `validation_error` | Missing unsubscribe link, not a draft, or past `scheduledAt` |

## Related

- [Get Campaign](/docs/api-reference/v2/campaigns-get)
- [SDK: lumail.campaigns.send](/docs/sdk/v2/campaigns-send)


## API Reference
**Method:** POST
**Endpoint:** /api/v2/campaigns/:campaignId/send

### SDK
```ts
import { Lumail } from "lumail";

const lumail = new Lumail({ apiKey: process.env.LUMAIL_API_KEY });
const { data, error } = await lumail.campaigns.send("cmp_abc123", {
  scheduledAt: "2026-09-10T09:00:00.000Z",
  timezone: "Europe/Paris",
});
if (error) {
  throw error;
}
console.log(data.status, data.scheduledAt);
```

### cURL
```bash
curl -X POST https://lumail.io/api/v2/campaigns/cmp_abc123/send \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"scheduledAt":"2026-09-10T09:00:00.000Z","timezone":"Europe/Paris"}'
```

### JavaScript
```javascript
const response = await fetch(
  "https://lumail.io/api/v2/campaigns/cmp_abc123/send",
  {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_API_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      scheduledAt: "2026-09-10T09:00:00.000Z",
      timezone: "Europe/Paris",
    }),
  },
);
const data = await response.json();
```

### Success Response
```json
{
  "id": "cmp_abc123",
  "subject": "Hello",
  "status": "SCHEDULED",
  "scheduledAt": "2026-09-10T09:00:00.000Z",
  "recipientCount": 120
}
```

### Error Response
```json
{
  "name": "validation_error",
  "message": "Campaign must have an unsubscribe link before scheduling. Add an unsubscribe link to the email content.",
  "statusCode": 400
}
```
