# Connect 23 Telecom to WebEngage

> Send SMS from WebEngage journeys with a Call API block to 23 Telecom — a raw JSON body, idempotency from a stable event ID, the throttling limits, and where carrier delivery is tracked.
> Source: https://docs.23telecom.co.uk/integrations/webengage/
> 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** | Call API · self-service |
| **Setup time** | About 15 minutes |
| **Sends SMS** | Yes |
| **Delivery status in WebEngage** | No — check 23 Telecom |
| **Who can configure** | WebEngage journey editor |

  23 Telecom supports WebEngage through its Call API journey step. 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 throughput. On the current batch endpoint, confirm
  `results[0].status` is `"accepted"` with a non-empty
  `results[0].message_id`.

## What this connection does

A WebEngage **Call API** block calls the 23 Telecom API to send an SMS from a
journey, with separate **On Success** and **On Failure** paths. WebEngage records
the response; carrier delivery reports stay in 23 Telecom.

## Before you start

- 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)).
- A **stable source event ID** to use for idempotency.

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

## Connect 23 Telecom

1. In the **Journey Designer**, add a **Call API** block.

2. Under **Build API Request**, set method `POST` and URL
   `https://restlink23telecom.com/api/v1/sms/send-individual`.

3. Add headers `Content-Type: application/json`, your secret `X-API-Key`, and an
   `Idempotency-Key` set to a stable source event ID.

4. Add the JSON body, then use placeholder values and **Call API Now** to review
   the **Response Status**.

### Request body

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

Map `to` and `message` to user/event personalization.

### Field mapping

| WebEngage 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) |
| `Idempotency-Key` | a stable source event ID |
| `messages[0].to` | recipient phone (E.164) |
| `messages[0].message` | your message content |
| `messages[0].sender_id` | your approved sender ID |

## Send a test

Use placeholder values and **Call API Now** with your `sk_test_` key, and read the
**Response Status** on the **On Success** path. For the test, set `Idempotency-Key`
to a fixed value such as `webengage-sandbox-001`.

  A `200` only means the request was received. Treat the message as queued **only**
  when `results[0].status` is `"accepted"` **and** `results[0].message_id` is
  present. `blocked_country` is not queued. Missing local pricing is different:
  valid live API traffic is accepted fail-open, and the delivery report supplies
  the final status and cost. Do not route on the **On Success** path alone or
  auto-retry a non-accepted body without checking the 23 Telecom message log.

  WebEngage retries with exponential backoff (the exact matrix is not published),
  so use a **stable source event ID** as `Idempotency-Key`. Default throttling is
  **100 calls/min** (configurable **1–10,000**); agree throughput with 23 Telecom
  before enabling a large audience. A Call API success does **not** trigger native
  SMS `On Delivery`/`On Failure` semantics — carrier delivery back inside
  WebEngage needs a 23 Telecom → WebEngage event bridge.

## Production activation

Live traffic uses managed activation because WebEngage routes the **On Success**
path from the HTTP status. Your 23 Telecom team confirms a retry-safe path using
the strict integration endpoint, where a `2xx` guarantees acceptance, or an
adapter that validates the response body, and aligns throughput and idempotency.

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

## 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 |
| `429 RATE_LIMIT_EXCEEDED` | Above your budget — lower the Call API throttle |

## Need help?

- **Journey, Call API block or throttling** — WebEngage 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

- [Journey creation & the Call API block](https://knowledgebase.webengage.com/docs/journey-creation-concepts)

*Last verified: 16 July 2026.*