> ## 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.

# Messaging API

> Send and manage messages across SMS, WhatsApp, RCS, Viber, and Email channels

# Messaging API

Send messages on any supported channel, retrieve delivery status, retry failed sends, and manage reusable templates.

**Base path:** `/v1/messages`

***

## Send SMS

`POST /v1/messages/sms`

Send an SMS message to a single recipient.

<ParamField body="to" type="string" required>
  Recipient phone number in E.164 format (e.g., `+14155552671`)
</ParamField>

<ParamField body="body" type="string" required>
  The text content of the SMS (max 1600 characters; automatically segmented)
</ParamField>

<ParamField body="webhook_url" type="string">
  URL to receive delivery status callbacks for this message
</ParamField>

<ParamField body="metadata" type="object">
  Arbitrary key-value pairs attached to the message for your reference
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X POST "https://orbit-api.devotel.io/api/v1/messages/sms" \
      -H "X-API-Key: dv_live_sk_your_key_here" \
      -H "Content-Type: application/json" \
      -d '{
      "to": "+14155552671",
      "body": "Your verification code is 123456",
      "webhook_url": "https://example.com/webhooks/sms",
      "metadata": {
        "campaign": "onboarding"
      }
    }'
    ```

    ```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://orbit-api.devotel.io/api/v1/messages/sms', {
      method: 'POST',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
      "to": "+14155552671",
      "body": "Your verification code is 123456",
      "webhook_url": "https://example.com/webhooks/sms",
      "metadata": {
        "campaign": "onboarding"
      }
    }),
    })
    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://orbit-api.devotel.io/api/v1/messages/sms", headers=headers, json={
      "to": "+14155552671",
      "body": "Your verification code is 123456",
      "webhook_url": "https://example.com/webhooks/sms",
      "metadata": {
        "campaign": "onboarding"
      }
    })
    print(r.json())
    ```

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

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

    func main() {
    	req, _ := http.NewRequest("POST", "https://orbit-api.devotel.io/api/v1/messages/sms", bytes.NewBuffer([]byte(`{
      "to": "+14155552671",
      "body": "Your verification code is 123456",
      "webhook_url": "https://example.com/webhooks/sms",
      "metadata": {
        "campaign": "onboarding"
      }
    }`)))
    	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://orbit-api.devotel.io/api/v1/messages/sms')
    req = Net::HTTP::Post.new(uri)
    req['X-API-Key'] = ENV['ORBIT_API_KEY']
    req['Content-Type'] = 'application/json'
    req.body = {
      "to": "+14155552671",
      "body": "Your verification code is 123456",
      "webhook_url": "https://example.com/webhooks/sms",
      "metadata": {
        "campaign": "onboarding"
      }
    }.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://orbit-api.devotel.io/api/v1/messages/sms');
    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
    {
      "to": "+14155552671",
      "body": "Your verification code is 123456",
      "webhook_url": "https://example.com/webhooks/sms",
      "metadata": {
        "campaign": "onboarding"
      }
    }
    JSON);
    echo curl_exec($ch);
    ```
  </CodeGroup>
</RequestExample>

<ResponseExample>
  ```json 202 theme={null}
  {
    "data": {
      "message_id": "msg_abc123",
      "channel": "sms",
      "to": "+14155552671",
      "status": "queued",
      "created_at": "2026-03-08T12:00:00Z"
    },
    "meta": {
      "request_id": "req_xyz789",
      "timestamp": "2026-03-08T12:00:00Z"
    }
  }
  ```
</ResponseExample>

***

## Send WhatsApp Message

`POST /v1/messages/whatsapp`

Send a WhatsApp message — free-form text, a pre-approved template, or media.

<ParamField body="to" type="string" required>
  Recipient phone number in E.164 format
</ParamField>

<ParamField body="text" type="object">
  Free-form text message object

  <Expandable>
    <ParamField body="text.body" type="string" required>
      Message text content
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="template" type="object">
  Pre-approved WhatsApp template (use instead of `text` for business-initiated conversations)

  <Expandable>
    <ParamField body="template.name" type="string" required>
      Registered template name
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="media" type="object">
  Media attachment

  <Expandable>
    <ParamField body="media.url" type="string" required>
      Publicly accessible URL to the media file
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="metadata" type="object">
  Arbitrary key-value pairs attached to the message
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X POST "https://orbit-api.devotel.io/api/v1/messages/whatsapp" \
      -H "X-API-Key: dv_live_sk_your_key_here" \
      -H "Content-Type: application/json" \
      -d '{
      "to": "+905551234567",
      "text": {
        "body": "Hello from Orbit!"
      }
    }'
    ```

    ```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://orbit-api.devotel.io/api/v1/messages/whatsapp', {
      method: 'POST',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
      "to": "+905551234567",
      "text": {
        "body": "Hello from Orbit!"
      }
    }),
    })
    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://orbit-api.devotel.io/api/v1/messages/whatsapp", headers=headers, json={
      "to": "+905551234567",
      "text": {
        "body": "Hello from Orbit!"
      }
    })
    print(r.json())
    ```

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

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

    func main() {
    	req, _ := http.NewRequest("POST", "https://orbit-api.devotel.io/api/v1/messages/whatsapp", bytes.NewBuffer([]byte(`{
      "to": "+905551234567",
      "text": {
        "body": "Hello from Orbit!"
      }
    }`)))
    	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://orbit-api.devotel.io/api/v1/messages/whatsapp')
    req = Net::HTTP::Post.new(uri)
    req['X-API-Key'] = ENV['ORBIT_API_KEY']
    req['Content-Type'] = 'application/json'
    req.body = {
      "to": "+905551234567",
      "text": {
        "body": "Hello from Orbit!"
      }
    }.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://orbit-api.devotel.io/api/v1/messages/whatsapp');
    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
    {
      "to": "+905551234567",
      "text": {
        "body": "Hello from Orbit!"
      }
    }
    JSON);
    echo curl_exec($ch);
    ```
  </CodeGroup>
</RequestExample>

<ResponseExample>
  ```json 202 theme={null}
  {
    "data": {
      "message_id": "msg_wa_456",
      "channel": "whatsapp",
      "to": "+905551234567",
      "status": "queued",
      "created_at": "2026-03-08T12:00:00Z"
    },
    "meta": {
      "request_id": "req_abc456",
      "timestamp": "2026-03-08T12:00:00Z"
    }
  }
  ```
</ResponseExample>

***

## Send Email

`POST /v1/messages/email`

Send a transactional email.

<ParamField body="to" type="string | string[]" required>
  Recipient email address or array of addresses
</ParamField>

<ParamField body="subject" type="string" required>
  Email subject line
</ParamField>

<ParamField body="html" type="string">
  HTML body of the email (provide `html` or `text`, or both)
</ParamField>

<ParamField body="text" type="string">
  Plain-text body of the email
</ParamField>

<ParamField body="metadata" type="object">
  Arbitrary key-value pairs attached to the message
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X POST "https://orbit-api.devotel.io/api/v1/messages/email" \
      -H "X-API-Key: dv_live_sk_your_key_here" \
      -H "Content-Type: application/json" \
      -d '{
      "to": "user@example.com",
      "subject": "Welcome to Orbit",
      "html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>"
    }'
    ```

    ```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://orbit-api.devotel.io/api/v1/messages/email', {
      method: 'POST',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
      "to": "user@example.com",
      "subject": "Welcome to Orbit",
      "html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>"
    }),
    })
    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://orbit-api.devotel.io/api/v1/messages/email", headers=headers, json={
      "to": "user@example.com",
      "subject": "Welcome to Orbit",
      "html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>"
    })
    print(r.json())
    ```

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

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

    func main() {
    	req, _ := http.NewRequest("POST", "https://orbit-api.devotel.io/api/v1/messages/email", bytes.NewBuffer([]byte(`{
      "to": "user@example.com",
      "subject": "Welcome to Orbit",
      "html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>"
    }`)))
    	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://orbit-api.devotel.io/api/v1/messages/email')
    req = Net::HTTP::Post.new(uri)
    req['X-API-Key'] = ENV['ORBIT_API_KEY']
    req['Content-Type'] = 'application/json'
    req.body = {
      "to": "user@example.com",
      "subject": "Welcome to Orbit",
      "html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>"
    }.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://orbit-api.devotel.io/api/v1/messages/email');
    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
    {
      "to": "user@example.com",
      "subject": "Welcome to Orbit",
      "html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>"
    }
    JSON);
    echo curl_exec($ch);
    ```
  </CodeGroup>
</RequestExample>

<ResponseExample>
  ```json 202 theme={null}
  {
    "data": {
      "message_id": "msg_em_789",
      "channel": "email",
      "to": "user@example.com",
      "status": "queued",
      "created_at": "2026-03-08T12:00:00Z"
    },
    "meta": {
      "request_id": "req_em_101",
      "timestamp": "2026-03-08T12:00:00Z"
    }
  }
  ```
</ResponseExample>

***

## Send RCS / Viber Message

`POST /v1/messages/rcs` | `POST /v1/messages/viber`

Send a message on the RCS or Viber channel. Both use the same generic payload.

<ParamField body="to" type="string" required>
  Recipient phone number in E.164 format
</ParamField>

<ParamField body="body" type="string" required>
  Message text content
</ParamField>

<ParamField body="metadata" type="object">
  Arbitrary key-value pairs attached to the message
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X POST "https://orbit-api.devotel.io/api/v1/messages/rcs" \
      -H "X-API-Key: dv_live_sk_your_key_here" \
      -H "Content-Type: application/json" \
      -d '{
      "to": "+14155552671",
      "body": "Your order has shipped!"
    }'
    ```

    ```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://orbit-api.devotel.io/api/v1/messages/rcs', {
      method: 'POST',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
      "to": "+14155552671",
      "body": "Your order has shipped!"
    }),
    })
    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://orbit-api.devotel.io/api/v1/messages/rcs", headers=headers, json={
      "to": "+14155552671",
      "body": "Your order has shipped!"
    })
    print(r.json())
    ```

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

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

    func main() {
    	req, _ := http.NewRequest("POST", "https://orbit-api.devotel.io/api/v1/messages/rcs", bytes.NewBuffer([]byte(`{
      "to": "+14155552671",
      "body": "Your order has shipped!"
    }`)))
    	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://orbit-api.devotel.io/api/v1/messages/rcs')
    req = Net::HTTP::Post.new(uri)
    req['X-API-Key'] = ENV['ORBIT_API_KEY']
    req['Content-Type'] = 'application/json'
    req.body = {
      "to": "+14155552671",
      "body": "Your order has shipped!"
    }.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://orbit-api.devotel.io/api/v1/messages/rcs');
    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
    {
      "to": "+14155552671",
      "body": "Your order has shipped!"
    }
    JSON);
    echo curl_exec($ch);
    ```
  </CodeGroup>
</RequestExample>

<ResponseExample>
  ```json 202 theme={null}
  {
    "data": {
      "message_id": "msg_rcs_321",
      "channel": "rcs",
      "to": "+14155552671",
      "status": "queued",
      "created_at": "2026-03-08T12:00:00Z"
    },
    "meta": {
      "request_id": "req_rcs_555",
      "timestamp": "2026-03-08T12:00:00Z"
    }
  }
  ```
</ResponseExample>

***

## List Messages

`GET /v1/messages`

Retrieve a paginated list of sent messages with optional filters.

<ParamField query="cursor" type="string">
  Cursor for pagination (returned in previous response)
</ParamField>

<ParamField query="limit" type="integer" default="20">
  Number of results per page (max 100)
</ParamField>

<ParamField query="channel" type="string">
  Filter by channel: `sms`, `whatsapp`, `rcs`, `viber`, `email`
</ParamField>

<ParamField query="status" type="string">
  Filter by status: `queued`, `sent`, `delivered`, `failed`, `read`
</ParamField>

<ParamField query="to" type="string">
  Filter by recipient (exact match)
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X GET "https://orbit-api.devotel.io/api/v1/messages?channel=sms&status=delivered&limit=10" \
      -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://orbit-api.devotel.io/api/v1/messages?channel=sms&status=delivered&limit=10', {
      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://orbit-api.devotel.io/api/v1/messages?channel=sms&status=delivered&limit=10", headers=headers)
    print(r.json())
    ```

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

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

    func main() {
    	req, _ := http.NewRequest("GET", "https://orbit-api.devotel.io/api/v1/messages?channel=sms&status=delivered&limit=10", 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://orbit-api.devotel.io/api/v1/messages?channel=sms&status=delivered&limit=10')
    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://orbit-api.devotel.io/api/v1/messages?channel=sms&status=delivered&limit=10');
    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>

<ResponseExample>
  ```json 200 theme={null}
  {
    "data": [
      {
        "message_id": "msg_001",
        "channel": "sms",
        "to": "+14155552671",
        "status": "delivered",
        "created_at": "2026-03-08T11:00:00Z"
      }
    ],
    "meta": {
      "request_id": "req_list_001",
      "timestamp": "2026-03-08T12:00:00Z",
      "pagination": {
        "cursor": "cur_msg_abc",
        "has_more": true,
        "total": 1542
      }
    }
  }
  ```
</ResponseExample>

***

## Get Message

`GET /v1/messages/{id}`

Retrieve details of a single message, including delivery status and timestamps.

<ParamField path="id" type="string" required>
  Message ID (e.g., `msg_abc123`)
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X GET "https://orbit-api.devotel.io/api/v1/messages/msg_abc123" \
      -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://orbit-api.devotel.io/api/v1/messages/msg_abc123', {
      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://orbit-api.devotel.io/api/v1/messages/msg_abc123", headers=headers)
    print(r.json())
    ```

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

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

    func main() {
    	req, _ := http.NewRequest("GET", "https://orbit-api.devotel.io/api/v1/messages/msg_abc123", 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://orbit-api.devotel.io/api/v1/messages/msg_abc123')
    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://orbit-api.devotel.io/api/v1/messages/msg_abc123');
    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>

<ResponseExample>
  ```json 200 theme={null}
  {
    "data": {
      "message_id": "msg_abc123",
      "channel": "sms",
      "to": "+14155552671",
      "body": "Your verification code is 123456",
      "status": "delivered",
      "created_at": "2026-03-08T12:00:00Z",
      "delivered_at": "2026-03-08T12:00:03Z"
    },
    "meta": {
      "request_id": "req_get_001",
      "timestamp": "2026-03-08T12:01:00Z"
    }
  }
  ```
</ResponseExample>

***

## Retry Message

`POST /v1/messages/{id}/retry`

Re-send a message that previously failed. The original message parameters are reused.

<ParamField path="id" type="string" required>
  ID of the failed message to retry
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X POST "https://orbit-api.devotel.io/api/v1/messages/msg_fail_001/retry" \
      -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://orbit-api.devotel.io/api/v1/messages/msg_fail_001/retry', {
      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://orbit-api.devotel.io/api/v1/messages/msg_fail_001/retry", headers=headers, json={})
    print(r.json())
    ```

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

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

    func main() {
    	req, _ := http.NewRequest("POST", "https://orbit-api.devotel.io/api/v1/messages/msg_fail_001/retry", 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://orbit-api.devotel.io/api/v1/messages/msg_fail_001/retry')
    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://orbit-api.devotel.io/api/v1/messages/msg_fail_001/retry');
    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>

<ResponseExample>
  ```json 202 theme={null}
  {
    "data": {
      "message_id": "msg_retry_002",
      "original_message_id": "msg_fail_001",
      "status": "queued",
      "created_at": "2026-03-08T12:05:00Z"
    },
    "meta": {
      "request_id": "req_retry_001",
      "timestamp": "2026-03-08T12:05:00Z"
    }
  }
  ```
</ResponseExample>

***

## Templates

### List Templates

`GET /v1/messages/templates`

Retrieve all message templates with cursor-based pagination.

<ParamField query="cursor" type="string">
  Cursor for pagination
</ParamField>

<ParamField query="limit" type="integer" default="20">
  Number of results per page (max 100)
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X GET "https://orbit-api.devotel.io/api/v1/messages/templates?limit=10" \
      -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://orbit-api.devotel.io/api/v1/messages/templates?limit=10', {
      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://orbit-api.devotel.io/api/v1/messages/templates?limit=10", headers=headers)
    print(r.json())
    ```

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

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

    func main() {
    	req, _ := http.NewRequest("GET", "https://orbit-api.devotel.io/api/v1/messages/templates?limit=10", 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://orbit-api.devotel.io/api/v1/messages/templates?limit=10')
    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://orbit-api.devotel.io/api/v1/messages/templates?limit=10');
    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 Template

`POST /v1/messages/templates`

Create a new message template for a given channel.

<ParamField body="channel" type="string" required>
  Channel the template is for: `sms`, `whatsapp`, `rcs`, `viber`, `email`
</ParamField>

<ParamField body="name" type="string" required>
  Template name (unique per channel)
</ParamField>

<ParamField body="content" type="string" required>
  Template body content — use `{{variable_name}}` for dynamic placeholders
</ParamField>

<ParamField body="category" type="string">
  Template category (e.g., `marketing`, `transactional`, `otp`)
</ParamField>

<ParamField body="language" type="string">
  Language code (e.g., `en`, `tr`, `ar`)
</ParamField>

<ParamField body="variables" type="array">
  List of variable definitions used in the template content
</ParamField>

<ParamField body="status" type="string">
  Initial status: `draft` or `pending_approval`
</ParamField>

<RequestExample>
  <CodeGroup>
    ```bash cURL theme={null}
    curl -X POST "https://orbit-api.devotel.io/api/v1/messages/templates" \
      -H "X-API-Key: dv_live_sk_your_key_here" \
      -H "Content-Type: application/json" \
      -d '{
      "channel": "whatsapp",
      "name": "order_confirmation",
      "content": "Hi {{customer_name}}, your order #{{order_id}} has been confirmed.",
      "category": "transactional",
      "language": "en"
    }'
    ```

    ```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://orbit-api.devotel.io/api/v1/messages/templates', {
      method: 'POST',
      headers: {
        'X-API-Key': process.env.ORBIT_API_KEY!,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
      "channel": "whatsapp",
      "name": "order_confirmation",
      "content": "Hi {{customer_name}}, your order #{{order_id}} has been confirmed.",
      "category": "transactional",
      "language": "en"
    }),
    })
    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://orbit-api.devotel.io/api/v1/messages/templates", headers=headers, json={
      "channel": "whatsapp",
      "name": "order_confirmation",
      "content": "Hi {{customer_name}}, your order #{{order_id}} has been confirmed.",
      "category": "transactional",
      "language": "en"
    })
    print(r.json())
    ```

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

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

    func main() {
    	req, _ := http.NewRequest("POST", "https://orbit-api.devotel.io/api/v1/messages/templates", bytes.NewBuffer([]byte(`{
      "channel": "whatsapp",
      "name": "order_confirmation",
      "content": "Hi {{customer_name}}, your order #{{order_id}} has been confirmed.",
      "category": "transactional",
      "language": "en"
    }`)))
    	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://orbit-api.devotel.io/api/v1/messages/templates')
    req = Net::HTTP::Post.new(uri)
    req['X-API-Key'] = ENV['ORBIT_API_KEY']
    req['Content-Type'] = 'application/json'
    req.body = {
      "channel": "whatsapp",
      "name": "order_confirmation",
      "content": "Hi {{customer_name}}, your order #{{order_id}} has been confirmed.",
      "category": "transactional",
      "language": "en"
    }.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://orbit-api.devotel.io/api/v1/messages/templates');
    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": "whatsapp",
      "name": "order_confirmation",
      "content": "Hi {{customer_name}}, your order #{{order_id}} has been confirmed.",
      "category": "transactional",
      "language": "en"
    }
    JSON);
    echo curl_exec($ch);
    ```
  </CodeGroup>
</RequestExample>

<ResponseExample>
  ```json 201 theme={null}
  {
    "data": {
      "id": "tpl_abc123",
      "channel": "whatsapp",
      "name": "order_confirmation",
      "content": "Hi {{customer_name}}, your order #{{order_id}} has been confirmed.",
      "category": "transactional",
      "language": "en",
      "status": "pending_approval",
      "created_at": "2026-03-08T12:00:00Z"
    },
    "meta": {
      "request_id": "req_tpl_001",
      "timestamp": "2026-03-08T12:00:00Z"
    }
  }
  ```
</ResponseExample>

### Delete Template

`DELETE /v1/messages/templates/{id}`

Permanently delete a message template.

<ParamField path="id" type="string" required>
  Template ID
</ParamField>

**Response:** `204 No Content`
