Create Campaign
Create a new SMS 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 /sms/campaigns/:id/send when you are ready to send or schedule.
Common use cases:
- A retail brand announcing a weekend sale to their KSA subscriber list.
- An e-commerce store sending a limited-time discount to tagged VIP contacts.
Endpoint
POST /sms/campaigns
Returns: 201 Created
Prerequisites
The from must be registered and approved for the destination country. Sender names are provisioned by Arsel on your behalf — contact support@arsel.sa to register one. Approval timelines vary by country (KSA, Egypt). Campaigns with unregistered sender names 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 /sms/campaigns/:id.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No | Internal name for the campaign. Max 100 characters. |
description | string | No | Optional description for internal reference. Max 500 characters. |
content | string | No | SMS message body. Max 3,200 characters. Supports {{variables}} from contact properties. |
from | string | No | Registered SMS sender name, registered for marketing. Country-specific approval required; see List Senders. |
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; see List Segments. |
Response
{
"id": "0192a1b2-c3d4-7e5f-9000-abcdef123456"
}
Response Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique campaign ID. Use this with GET /sms/campaigns/:id to fetch the full record, or with POST /sms/campaigns/:id/send to send or schedule. |
Examples
- cURL
- JavaScript
- Python
- C#
- PHP
curl -X POST "https://api.arsel.sa/v1/sms/campaigns" \
-H "Authorization: Bearer $ARSEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Summer Sale 2026",
"description": "Sale announcement to KSA list",
"content": "Acme Store: 50% off everything this weekend! Shop now: {{link}}",
"from": "ACME",
"list_ids": ["list-uuid-1"]
}'
const response = await fetch("https://api.arsel.sa/v1/sms/campaigns", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ARSEL_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Summer Sale 2026",
description: "Sale announcement to KSA list",
content: "Acme Store: 50% off everything this weekend! Shop now: {{link}}",
from: "ACME",
list_ids: ["list-uuid-1"],
}),
});
const data = await response.json();
if (!response.ok) {
throw new Error(`${data.name}: ${data.message}`);
}
console.log(data);
import os
import requests
response = requests.post(
"https://api.arsel.sa/v1/sms/campaigns",
headers={"Authorization": f"Bearer {os.environ['ARSEL_API_KEY']}"},
json={
"name": "Summer Sale 2026",
"description": "Sale announcement to KSA list",
"content": "Acme Store: 50% off everything this weekend! Shop now: {{link}}",
"from": "ACME",
"list_ids": ["list-uuid-1"],
},
)
response.raise_for_status()
print(response.json())
using System.Net.Http.Headers;
using System.Text;
var client = new HttpClient(); // share one instance across requests
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Bearer", Environment.GetEnvironmentVariable("ARSEL_API_KEY"));
var request = new HttpRequestMessage(HttpMethod.Post, "https://api.arsel.sa/v1/sms/campaigns")
{
Content = new StringContent(
"""
{
"name": "Summer Sale 2026",
"description": "Sale announcement to KSA list",
"content": "Acme Store: 50% off everything this weekend! Shop now: {{link}}",
"from": "ACME",
"list_ids": ["list-uuid-1"]
}
""",
Encoding.UTF8,
"application/json"),
};
var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
throw new HttpRequestException($"{(int)response.StatusCode}: {body}");
Console.WriteLine(body);
<?php
$ch = curl_init("https://api.arsel.sa/v1/sms/campaigns");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("ARSEL_API_KEY"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"name" => "Summer Sale 2026",
"description" => "Sale announcement to KSA list",
"content" => "Acme Store: 50% off everything this weekend! Shop now: {{link}}",
"from" => "ACME",
"list_ids" => ["list-uuid-1"],
]),
]);
$data = json_decode(curl_exec($ch), true);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) >= 400) {
throw new Exception("{$data['name']}: {$data['message']}");
}
print_r($data);
Error Responses
- 422 Validation Error
- 401 Unauthorized
{
"status_code": 422,
"name": "validation_error",
"message": "name must not exceed 100 characters"
}
{
"status_code": 401,
"name": "unauthorized",
"message": "Invalid API Key"
}
After creating a campaign, you can:
- Update its content with
PATCH /sms/campaigns/:id. - Browse all campaigns with
GET /sms/campaigns. - Send or schedule it with
POST /sms/campaigns/:id/send.