Connect 23 Telecom to Customer.io
Copy page
| Setup type | Webhook · self-service |
| Setup time | About 10 minutes |
| Sends SMS | Yes |
| Delivery status in Customer.io | No — check 23 Telecom |
| Who can configure | Customer.io Workspace Manager |
What this connection does
Section titled “What this connection does”You add 23 Telecom as a reusable webhook in Customer.io, then call it from a
workflow’s Send and receive data step to send an SMS. Customer.io shows you
the flat API response. An HTTP 202 means 23 Telecom accepted the message;
carrier delivery reports stay in 23 Telecom.
Before you start
Section titled “Before you start”- A Customer.io Workspace Manager seat (creating webhooks is a workspace setting).
- An active workspace, an
approved sender ID and a test number in E.164 format, e.g.
+447911123456. - A restricted 23 Telecom API key with only the
sms.sendpermission — start with a sandboxsk_test_key (Sandbox & test mode).
POST
/api/v1/integrations/sms/send
· Permission: sms.send
Connect 23 Telecom
Section titled “Connect 23 Telecom”-
In Customer.io open Settings → Workspace Settings → Webhook configuration and select Create webhook.
-
Set Name to
23 Telecom SMS, Method toPOST, and the endpoint URL tohttps://restlink23telecom.com/api/v1/integrations/sms/send. -
Add only two headers —
Content-Type: application/jsonand your secretX-API-Key. Do not addIdempotency-KeyorX-CIO-Idempotency-Key: Customer.io adds its retry key automatically. Saving this as a reusable webhook lets campaign authors select it later without seeing the API key. -
In your workflow, add a Send and receive data action and pick the saved
23 Telecom SMSwebhook. -
Paste the request body below. There are only three fields to map.
-
Set the action to Draft, then run a test with a sandbox key.
Request body
Section titled “Request body”Use Customer.io’s official to_json filter so quotes and line breaks never
break the JSON:
{% capture sms_text -%}Hi {{ customer.first_name | default: "there" }}, your message goes here.{%- endcapture %}{ "to": {{ customer.phone | to_json }}, "message": {{ sms_text | strip | to_json }}, "sender_id": "YourBrand"}Field mapping
Section titled “Field mapping”| Customer.io field | Value |
|---|---|
| Method | POST |
| Endpoint URL | https://restlink23telecom.com/api/v1/integrations/sms/send |
Content-Type | application/json |
X-API-Key | your restricted 23 Telecom key (sandbox first) |
| Idempotency | automatic X-CIO-Idempotency-Key; do not add a header yourself |
to | recipient phone in E.164 (see to_json in the body above) |
message | your Liquid message text |
sender_id | your approved sender ID |
Send a test
Section titled “Send a test”-
Keep the action in Draft and use your
sk_test_key. Leave idempotency headers out of the webhook configuration; Customer.io supplies its automatic key on the request. -
Run the workflow against one test profile whose
phoneis your E.164 test number. -
Expect HTTP
202with a flat response containingstatus: "accepted", a non-emptymessage_id, andmode: "sandbox". Sandbox simulates the send — no live SMS or carrier delivery is created. -
Save
response.message_idas a journey attribute so you can correlate the message later.
Production activation
Section titled “Production activation”Ready to go live? Your 23 Telecom account manager enables the exact workspace
and confirms a dedicated workspace-bound key with only sms.send. The endpoint,
request body, existing API keys and HMAC settings remain unchanged.
We then complete a short launch check covering automatic retries, lost-response
replay and delivery tracking. Keep the action in Draft with your sandbox
sk_test_ key while activation is completed; then replace the key and publish
the workflow.
Verify the result
Section titled “Verify the result”- Accepted — HTTP
202withstatus: "accepted"andmessage_id— means 23 Telecom durably queued the message, not that it was delivered. - Delivered is a later carrier report. Check it in
Message status with the
message_id, or in Statistics. For a live DLR feed, add a delivery webhook in 23 Telecom.
Troubleshooting
Section titled “Troubleshooting”| Response | Cause & fix |
|---|---|
400 IDEMPOTENCY_KEY_REQUIRED | Customer.io did not supply its automatic retry key — keep the manual idempotency fields empty and contact support |
400 MULTIPLE_IDEMPOTENCY_KEYS | Remove the manually configured Idempotency-Key or X-CIO-Idempotency-Key |
400 INVALID_IDEMPOTENCY_KEY | The automatic key is outside the supported visible-ASCII contract — contact support |
401 INVALID_API_KEY | Wrong or disabled key in the secret header |
403 INTEGRATION_NOT_ENABLED | Live access is not enabled for this workspace — contact your account manager |
409 IDEMPOTENCY_KEY_REUSED | Same key sent with a different body — use a fresh unique key |
429 RATE_LIMIT_EXCEEDED | Honor Retry-After; Customer.io should retry the exact request automatically |
Need help?
Section titled “Need help?”- Webhook, workflow or Liquid questions — Customer.io support.
- API key, sender ID,
acceptedbut notdelivered— your 23 Telecom account manager.
Official platform documentation
Section titled “Official platform documentation”Last verified: 16 July 2026.