# Connect 23 Telecom to Iterable

> Send SMS from Iterable journeys with a Journey Webhook to 23 Telecom — a custom POST body, stable event idempotency, retry handling and carrier delivery tracking.
> Source: https://docs.23telecom.co.uk/integrations/iterable/
> Activation: Managed activation

Instructions for LLMs: This is one page of the 23 Telecom messaging API docs
(SMS today; more channels planned). Base URL: https://restlink23telecom.com/api/v1,
auth via the X-API-Key header. Match errors on the error_code field, never on
description text. Full docs: https://docs.23telecom.co.uk/llms-full.txt · Schemas: https://docs.23telecom.co.uk/openapi.yaml

| | |
| --- | --- |
| **Setup type** | Webhook · self-service |
| **Setup time** | About 15 minutes |
| **Sends SMS** | Yes |
| **Delivery status in Iterable** | No — check 23 Telecom |
| **Who can configure** | Iterable user with the **Manage Integrations** permission |

  23 Telecom supports Iterable through Journey Webhooks. Start with the sandbox
  recipe below; when you're ready to launch, your account manager enables live
  sending and completes a short configuration check for response handling,
  idempotency and retries. On the current batch endpoint, confirm
  `results[0].status` is `"accepted"` with a non-empty
  `results[0].message_id`.

## What this connection does

An Iterable **Journey Webhook** calls the 23 Telecom API to send an SMS from a
journey step. Iterable records whether it got an HTTP `200`; carrier delivery
reports stay in 23 Telecom.

## Before you start

- The **Manage Integrations** permission. Add `X-API-Key` as a **Secure** custom
  header so Iterable protects the saved value, and use a dedicated restricted key.
- An [active workspace](https://docs.23telecom.co.uk/account/workspaces), an
  [approved sender ID](https://docs.23telecom.co.uk/sms/sender-id) and an E.164 test number, e.g.
  `+447911123456`.
- A restricted 23 Telecom [API key](https://docs.23telecom.co.uk/api-keys) with only `sms.send` — start with
  a sandbox `sk_test_` key ([Sandbox & test mode](https://docs.23telecom.co.uk/sandbox)).

`POST /api/v1/sms/send-individual` (permission: `sms.send`)

## Connect 23 Telecom

1. Go to **Integrations → Journey Webhooks → New Webhook → Custom** and set the
   method to **POST**.

2. Set the URL to
   `https://restlink23telecom.com/api/v1/sms/send-individual` and add headers
   `Content-Type: application/json` and your secret `X-API-Key`. Mark
   `X-API-Key` as **Secure**.

3. Add the custom JSON body. For the one-off sandbox test, add
   `Idempotency-Key: iterable-sandbox-001`; do not reuse that value for another
   message. The production idempotency mapping is confirmed during activation.

4. In the journey, add a **Call Webhook** tile that points at this webhook.

5. Run a test journey against one test profile.

### Request body

```json title="Custom body"
{
  "messages": [
    { "to": "+447911123456", "message": "Your message", "sender_id": "YourBrand" }
  ]
}
```

Map `to` and `message` to your journey/profile fields.

### Field mapping

| Iterable field | Value |
| --- | --- |
| Method | `POST` |
| URL | `https://restlink23telecom.com/api/v1/sms/send-individual` |
| `Content-Type` | `application/json` |
| `X-API-Key` | your restricted 23 Telecom key (sandbox first); mark the header **Secure** |
| `Idempotency-Key` | one-off value for sandbox; production mapping supplied during managed activation |
| `messages[0].to` | recipient phone (E.164) |
| `messages[0].message` | your message content |
| `messages[0].sender_id` | your approved sender ID |

## Send a test

Run a **separate test journey** or test profile with your `sk_test_` key. For a
manual sandbox test set `Idempotency-Key` to the one-off value
`iterable-sandbox-001` and use it for that test only.

  The standard Iterable Call Webhook path evaluates the HTTP transport status
  rather than the 23 Telecom response fields, so it cannot tell whether the
  message was accepted or returned `blocked_country`.
  Missing local pricing is not a rejection: valid live API traffic is accepted
  fail-open and the delivery report supplies the final status and cost. For the
  sandbox test, confirm acceptance in the 23 Telecom [message log](https://docs.23telecom.co.uk/sms/messages),
  **not** inside Iterable, and never auto-retry from transport status alone. This
  is exactly why production needs the strict integration endpoint (see below).

  Iterable treats **HTTP `200` as success** and retries
  `429/502/503/504`/timeout after ~3 minutes, up to **3 attempts**. Journey
  Webhook custom headers may be static, while production retries need a value
  that is unique per event and stable across its attempts. The sandbox value
  above is deliberately one-off. During managed activation, 23 Telecom confirms
  the supported retry-safe path for your tenant; never reuse one static key
  across an audience.

## Production activation

Live traffic uses managed activation because Iterable routes on the HTTP status
and production retries require per-event idempotency. Your 23 Telecom team
confirms a supported retry-safe path: either the strict integration endpoint
with a stable header mechanism verified in your tenant, or an adapter that
validates the response body.

The activation package includes the approved production URL or adapter mapping,
the restricted key and a one-message launch check. Apply that configuration —
rather than changing only the API key on the sandbox batch template — and then
publish the journey.

## Verify the result

**Accepted** means queued. Read carrier delivery in [Message status](https://docs.23telecom.co.uk/sms/status)
or [Statistics](https://docs.23telecom.co.uk/sms/statistics), or add a live
[delivery webhook](https://docs.23telecom.co.uk/webhooks/delivery). Delivery back inside Iterable needs a
separate Iterable event/API update.

## Troubleshooting

| Response | Cause & fix |
| --- | --- |
| `400 IDEMPOTENCY_KEY_REQUIRED` | Add the `Idempotency-Key` header |
| `401 INVALID_API_KEY` | Wrong or disabled key in the secret header |
| `403 NO_SMS_ACCESS` | SMS not enabled — contact 23 Telecom |
| `409 IDEMPOTENCY_KEY_REUSED` | Same key with a different body — use the stable identifier for the new event |

## Need help?

- **Journey, webhook or permissions** — Iterable support.
- **API key, sender ID, accepted-but-not-delivered** — your 23 Telecom account
  manager, or the [contact form](https://23telecom.co.uk/contact).

## Official platform documentation

- [Iterable Journey Webhooks](https://support.iterable.com/hc/en-us/articles/205480275-Journey-Webhooks)

*Last verified: 16 July 2026.*