> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Campaigns API

> Bulk campaign creation, scheduling, and analytics

# Campaigns API

Bulk campaign creation, scheduling, and analytics

**Base path:** `/api/v1/campaigns`

**Endpoint count:** 4

***

### List campaigns

<Note>
  `GET /api/v1/campaigns/`
</Note>

Retrieve campaigns with cursor-based pagination. Filter by status; supported values are draft, pending\_approval, scheduled, running, sending, aborting, completed, partially\_failed, paused, cancelled, and failed.

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X GET "https://api.orbit.devotel.io/api/v1/campaigns/" \
      -H "X-API-Key: dv_live_sk_your_key_here" 
    ```

    ```typescript Node.js theme={null}
    import { Orbit } from '@devotel/orbit-sdk'

    const orbit = new Orbit({
      apiKey: process.env.ORBIT_API_KEY!,
    })

    const res = await fetch('https://api.orbit.devotel.io/api/v1/campaigns/', {
      method: 'GET',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!,
      },
    })
    console.log(await res.json())


    ```

    ```python Python theme={null}
    import os, requests

    headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
    r = requests.get("https://api.orbit.devotel.io/api/v1/campaigns/", headers=headers)
    print(r.json())
    ```

    ```go Go theme={null}
    package main

    import (
    	"bytes"
    	"net/http"
    	"os"
    )

    func main() {
    	req, _ := http.NewRequest("GET", "https://api.orbit.devotel.io/api/v1/campaigns/", nil)
    	req.Header.Set("X-API-Key", os.Getenv("ORBIT_API_KEY"))

    	http.DefaultClient.Do(req)
    }
    ```

    ```ruby Ruby theme={null}
    require 'net/http'
    require 'json'

    uri = URI('https://api.orbit.devotel.io/api/v1/campaigns/')
    req = Net::HTTP::Get.new(uri)
    req['X-API-Key'] = ENV['ORBIT_API_KEY']


    res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
    puts res.body
    ```

    ```php PHP theme={null}
    <?php
    $ch = curl_init('https://api.orbit.devotel.io/api/v1/campaigns/');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'X-API-Key: ' . getenv('ORBIT_API_KEY'),

    ]);

    echo curl_exec($ch);
    ```
  </CodeGroup>
</RequestExample>

***

### Create a campaign

<Note>
  `POST /api/v1/campaigns/`
</Note>

Create a marketing campaign (blast, drip, or journey) targeting a list/segment/CSV/all-contacts audience. The campaign is created as a draft until POST /campaigns/{id}/send. message\_template is optional at creation but mandatory at send-time. For drip campaigns, the `steps` array defines the sequence; smart\_send spreads delivery across 24h using best-time-to-send predictions.

<ParamField body="name" type="string" required>
  —
</ParamField>

<ParamField body="description" type="string">
  —
</ParamField>

<ParamField body="type" type="string (enum: blast|drip|journey)">
  —
</ParamField>

<ParamField body="channel" type="string (enum: sms|mms|whatsapp|email|rcs|viber|…)" required>
  —
</ParamField>

<ParamField body="audience_type" type="string (enum: all|list|segment|csv)">
  —
</ParamField>

<ParamField body="audience_id" type="string">
  —
</ParamField>

<ParamField body="message_template" type="string">
  —
</ParamField>

<ParamField body="variables" type="object">
  —
</ParamField>

<ParamField body="scheduled_at" type="string">
  —
</ParamField>

<ParamField body="throttle_rate" type="integer">
  —
</ParamField>

<ParamField body="recurrence" type="object">
  Recurrence config. Accepts either canonical keys (type, end\_type, end\_date, end\_count, days, date, cron) or UI-prefixed keys (recurrence\_type, recurrence\_end\_type, recurrence\_end\_date, etc.). When end\_type === 'on\_date' the end\_date MUST be in the future; past dates are rejected with HTTP 400.
</ParamField>

<ParamField body="business_hours_only" type="boolean">
  —
</ParamField>

<ParamField body="steps" type="object[]">
  —
</ParamField>

<ParamField body="smart_send" type="boolean">
  —
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X POST "https://api.orbit.devotel.io/api/v1/campaigns/" \
      -H "X-API-Key: dv_live_sk_your_key_here" \
      -H "Content-Type: application/json" \
      -d '{
      "name": "string",
      "channel": "sms"
    }'
    ```

    ```typescript Node.js theme={null}
    import { Orbit } from '@devotel/orbit-sdk'

    const orbit = new Orbit({
      apiKey: process.env.ORBIT_API_KEY!,
    })

    const res = await fetch('https://api.orbit.devotel.io/api/v1/campaigns/', {
      method: 'POST',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
      "name": "string",
      "channel": "sms"
    }),
    })
    console.log(await res.json())
    ```

    ```python Python theme={null}
    import os, requests

    headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
    headers["Content-Type"] = "application/json"
    r = requests.post("https://api.orbit.devotel.io/api/v1/campaigns/", headers=headers, json={
      "name": "string",
      "channel": "sms"
    })
    print(r.json())
    ```

    ```go Go theme={null}
    package main

    import (
    	"bytes"
    	"net/http"
    	"os"
    )

    func main() {
    	req, _ := http.NewRequest("POST", "https://api.orbit.devotel.io/api/v1/campaigns/", bytes.NewBuffer([]byte(`{
      "name": "string",
      "channel": "sms"
    }`)))
    	req.Header.Set("X-API-Key", os.Getenv("ORBIT_API_KEY"))
    	req.Header.Set("Content-Type", "application/json")
    	http.DefaultClient.Do(req)
    }
    ```

    ```ruby Ruby theme={null}
    require 'net/http'
    require 'json'

    uri = URI('https://api.orbit.devotel.io/api/v1/campaigns/')
    req = Net::HTTP::Post.new(uri)
    req['X-API-Key'] = ENV['ORBIT_API_KEY']
    req['Content-Type'] = 'application/json'
    req.body = {
      "name": "string",
      "channel": "sms"
    }.to_json
    res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
    puts res.body
    ```

    ```php PHP theme={null}
    <?php
    $ch = curl_init('https://api.orbit.devotel.io/api/v1/campaigns/');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'X-API-Key: ' . getenv('ORBIT_API_KEY'),
      'Content-Type: application/json',
    ]);
    curl_setopt($ch, CURLOPT_POSTFIELDS, <<<JSON
    {
      "name": "string",
      "channel": "sms"
    }
    JSON);
    echo curl_exec($ch);
    ```
  </CodeGroup>
</RequestExample>

***

### Preview send-time experiment cohort plan

<Note>
  `POST /api/v1/campaigns/{id}/send-time-experiment/preview`
</Note>

Returns the deterministic cohort assignment for each send window in a send-time A/B test, including control arm size, recipient distribution, and next fire times. Reads the opt-in `variables.send_time_experiment` config already persisted on the campaign and resolves the declared audience. Read-only — it never enqueues a job, touches the wallet, or calls a provider. Returns 400 when no send-time experiment (at least two windows) is configured on the campaign.

<ParamField path="id" type="string" required>
  —
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X POST "https://api.orbit.devotel.io/api/v1/campaigns/{id}/send-time-experiment/preview" \
      -H "X-API-Key: dv_live_sk_your_key_here" \
      -H "Content-Type: application/json" \
      -d '{}'
    ```

    ```typescript Node.js theme={null}
    import { Orbit } from '@devotel/orbit-sdk'

    const orbit = new Orbit({
      apiKey: process.env.ORBIT_API_KEY!,
    })

    const res = await fetch('https://api.orbit.devotel.io/api/v1/campaigns/{id}/send-time-experiment/preview', {
      method: 'POST',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({}),
    })
    console.log(await res.json())
    ```

    ```python Python theme={null}
    import os, requests

    headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
    headers["Content-Type"] = "application/json"
    r = requests.post("https://api.orbit.devotel.io/api/v1/campaigns/{id}/send-time-experiment/preview", headers=headers, json={})
    print(r.json())
    ```

    ```go Go theme={null}
    package main

    import (
    	"bytes"
    	"net/http"
    	"os"
    )

    func main() {
    	req, _ := http.NewRequest("POST", "https://api.orbit.devotel.io/api/v1/campaigns/{id}/send-time-experiment/preview", bytes.NewBuffer([]byte(`{}`)))
    	req.Header.Set("X-API-Key", os.Getenv("ORBIT_API_KEY"))
    	req.Header.Set("Content-Type", "application/json")
    	http.DefaultClient.Do(req)
    }
    ```

    ```ruby Ruby theme={null}
    require 'net/http'
    require 'json'

    uri = URI('https://api.orbit.devotel.io/api/v1/campaigns/{id}/send-time-experiment/preview')
    req = Net::HTTP::Post.new(uri)
    req['X-API-Key'] = ENV['ORBIT_API_KEY']
    req['Content-Type'] = 'application/json'
    req.body = {}.to_json
    res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
    puts res.body
    ```

    ```php PHP theme={null}
    <?php
    $ch = curl_init('https://api.orbit.devotel.io/api/v1/campaigns/{id}/send-time-experiment/preview');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'X-API-Key: ' . getenv('ORBIT_API_KEY'),
      'Content-Type: application/json',
    ]);
    curl_setopt($ch, CURLOPT_POSTFIELDS, <<<JSON
    {}
    JSON);
    echo curl_exec($ch);
    ```
  </CodeGroup>
</RequestExample>

***

### Score draft campaign content for deliverability (pre-flight)

<Note>
  `POST /api/v1/campaigns/deliverability-lab`
</Note>

Score a draft campaign before you send it. Pass the draft message content and channel in the request body (no saved campaign needed) and get back the content issues that could hurt deliverability — spam-trigger words and risky links — plus a predicted delivery rate for each destination carrier, based on your own historical delivery results. This check is read-only: it never sends your campaign, charges your wallet, or changes anything in your account.

<ParamField body="channel" type="string (enum: sms|mms|whatsapp|email|rcs|viber|…)" required>
  Campaign channel the draft content targets.
</ParamField>

<ParamField body="body" type="string">
  Draft message body to score. Defaults to empty string.
</ParamField>

<ParamField body="subject" type="string">
  Email-only subject line.
</ParamField>

<ParamField body="window" type="string (enum: 7d|30d|90d)">
  Historical lookback window for the carrier delivery baseline. Defaults to 30d.
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X POST "https://api.orbit.devotel.io/api/v1/campaigns/deliverability-lab" \
      -H "X-API-Key: dv_live_sk_your_key_here" \
      -H "Content-Type: application/json" \
      -d '{
      "channel": "sms"
    }'
    ```

    ```typescript Node.js theme={null}
    import { Orbit } from '@devotel/orbit-sdk'

    const orbit = new Orbit({
      apiKey: process.env.ORBIT_API_KEY!,
    })

    const res = await fetch('https://api.orbit.devotel.io/api/v1/campaigns/deliverability-lab', {
      method: 'POST',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
      "channel": "sms"
    }),
    })
    console.log(await res.json())
    ```

    ```python Python theme={null}
    import os, requests

    headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
    headers["Content-Type"] = "application/json"
    r = requests.post("https://api.orbit.devotel.io/api/v1/campaigns/deliverability-lab", headers=headers, json={
      "channel": "sms"
    })
    print(r.json())
    ```

    ```go Go theme={null}
    package main

    import (
    	"bytes"
    	"net/http"
    	"os"
    )

    func main() {
    	req, _ := http.NewRequest("POST", "https://api.orbit.devotel.io/api/v1/campaigns/deliverability-lab", bytes.NewBuffer([]byte(`{
      "channel": "sms"
    }`)))
    	req.Header.Set("X-API-Key", os.Getenv("ORBIT_API_KEY"))
    	req.Header.Set("Content-Type", "application/json")
    	http.DefaultClient.Do(req)
    }
    ```

    ```ruby Ruby theme={null}
    require 'net/http'
    require 'json'

    uri = URI('https://api.orbit.devotel.io/api/v1/campaigns/deliverability-lab')
    req = Net::HTTP::Post.new(uri)
    req['X-API-Key'] = ENV['ORBIT_API_KEY']
    req['Content-Type'] = 'application/json'
    req.body = {
      "channel": "sms"
    }.to_json
    res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
    puts res.body
    ```

    ```php PHP theme={null}
    <?php
    $ch = curl_init('https://api.orbit.devotel.io/api/v1/campaigns/deliverability-lab');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'X-API-Key: ' . getenv('ORBIT_API_KEY'),
      'Content-Type: application/json',
    ]);
    curl_setopt($ch, CURLOPT_POSTFIELDS, <<<JSON
    {
      "channel": "sms"
    }
    JSON);
    echo curl_exec($ch);
    ```
  </CodeGroup>
</RequestExample>

***
