Create Campaign
Create a new email campaign. The campaign is created in Draft status and is fully editable until it is sent or scheduled for delivery. Recipients are configured by attaching contact lists, tags and/or segments to the campaign. Use this endpoint to prepare the campaign, then call POST /email/campaigns/:id/send when you are ready to send or schedule.
Common use cases:
- A marketing team preparing a weekly newsletter before scheduling it for Monday morning.
- A SaaS company drafting a product-launch announcement to review before sending.
Endpoint
POST /email/campaigns
Returns: 201 Created
Prerequisites
The from must belong to a verified domain. You can verify your domain in the Arsel Dashboard under Settings > Domains. Domain verification requires adding DNS records (SPF, DKIM, DMARC) to prove ownership. Campaigns from unverified domains will be rejected at send time.
Headers
| Header | Value | Required |
|---|---|---|
Authorization | Bearer <your-api-key> | Yes |
Content-Type | application/json | Yes |
Body Parameters
All parameters are optional. You can create an empty campaign and fill in the details later via PATCH /email/campaigns/:id.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No | Internal name for the campaign. Max 100 characters. |
subject | string | No | Email subject line. Supports {{variables}} from contact properties. |
preheader | string | No | Preview text shown alongside the subject line in email inboxes. |
from_name | string | No | Display name shown alongside the sender address. |
from | string | No | Sender email address. Must belong to a verified domain. |
reply_to | string | No | Reply-to email address. |
template_id | string | No | ID of the email template to use. Create one via POST /templates, copy from the gallery, or use the dashboard. |
list_ids | string[] | No | IDs of contact lists whose contacts should receive the campaign. |
tag_ids | string[] | No | IDs of tags whose tagged contacts should receive the campaign. |
segment_ids | string[] | No | IDs of segments whose matching contacts should receive the campaign. |
Don't have a template_id yet? Copy any starter design from the gallery in one call: see POST /templates/gallery/:id/copy.
Use {{unsubscribe_link}} anywhere in your template HTML to place a per-recipient tracked unsubscribe link. If your template has no unsubscribe element, a footer is appended automatically at send time. Custom external unsubscribe URLs are not supported. See Send Campaign → Unsubscribe Compliance for full details.
Response
{
"id": "0192a1b2-c3d4-7e5f-9000-abcdef123456"
}
Response Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique campaign ID. Use this with GET /email/campaigns/:id to fetch the full record, or with POST /email/campaigns/:id/send to send or schedule. |
Examples
- cURL
- JavaScript
- Python
- C#
- PHP
curl -X POST "https://api.arsel.sa/v1/email/campaigns" \
-H "Authorization: Bearer be_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Summer Sale 2026",
"subject": "50% Off Everything!",
"preheader": "Limited time offer",
"from_name": "Acme Store",
"from": "marketing@acme.com",
"reply_to": "support@acme.com",
"template_id": "0192a1b2-aaaa-7bbb-8ccc-dddddddddddd",
"list_ids": ["list-uuid-1"]
}'
const response = await fetch("https://api.arsel.sa/v1/email/campaigns", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer be_your_api_key",
},
body: JSON.stringify({
name: "Summer Sale 2026",
subject: "50% Off Everything!",
preheader: "Limited time offer",
from_name: "Acme Store",
from: "marketing@acme.com",
reply_to: "support@acme.com",
template_id: "0192a1b2-aaaa-7bbb-8ccc-dddddddddddd",
list_ids: ["list-uuid-1"],
}),
});
const { id } = await response.json();
console.log(id); // Use this ID for subsequent operations
import requests
response = requests.post(
"https://api.arsel.sa/v1/email/campaigns",
headers={
"Content-Type": "application/json",
"Authorization": "Bearer be_your_api_key",
},
json={
"name": "Summer Sale 2026",
"subject": "50% Off Everything!",
"preheader": "Limited time offer",
"from_name": "Acme Store",
"from": "marketing@acme.com",
"reply_to": "support@acme.com",
"template_id": "0192a1b2-aaaa-7bbb-8ccc-dddddddddddd",
"list_ids": ["list-uuid-1"],
},
)
data = response.json()
print(data["id"])
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer be_your_api_key");
var payload = new
{
name = "Summer Sale 2026",
subject = "50% Off Everything!",
preheader = "Limited time offer",
from_name = "Acme Store",
from = "marketing@acme.com",
reply_to = "support@acme.com",
template_id = "0192a1b2-aaaa-7bbb-8ccc-dddddddddddd",
list_ids = new[] { "list-uuid-1" }
};
var json = System.Text.Json.JsonSerializer.Serialize(payload);
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
var response = await client.PostAsync("https://api.arsel.sa/v1/email/campaigns", content);
var result = await response.Content.ReadAsStringAsync();
// result: {"id":"..."}
Console.WriteLine(result);
<?php
$ch = curl_init("https://api.arsel.sa/v1/email/campaigns");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
"Authorization: Bearer be_your_api_key"
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
"name" => "Summer Sale 2026",
"subject" => "50% Off Everything!",
"preheader" => "Limited time offer",
"from_name" => "Acme Store",
"from" => "marketing@acme.com",
"reply_to" => "support@acme.com",
"template_id" => "0192a1b2-aaaa-7bbb-8ccc-dddddddddddd",
"list_ids" => ["list-uuid-1"]
]));
$response = curl_exec($ch);
$data = json_decode($response, true);
echo $data["id"];
curl_close($ch);
Error Responses
- 401 Unauthorized
- 422 Validation Error
{
"status_code": 401,
"name": "unauthorized",
"message": "Invalid or missing API key"
}
{
"status_code": 422,
"name": "validation_error",
"message": "from must be an email"
}
After creating a campaign, you can:
- Update its content with
PATCH /email/campaigns/:id. - Browse all campaigns with
GET /email/campaigns. - Send or schedule it with
POST /email/campaigns/:id/send.