# Sandbox & test mode

> Test the 23 Telecom SMS API for free with sk_test_ sandbox keys — simulated sends, synthesized delivery webhooks and full response parity. Build your whole integration before spending a cent.
> Source: https://docs.23telecom.co.uk/sandbox/

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

Sandbox keys (`sk_test_…`) let you build and test your entire integration —
sending, status polling, **and webhook handling** — without sending real SMS
or spending money. Switching to production is swapping one environment
variable.

## How it works

| | Live key (`sk_prod_…`) | Sandbox key (`sk_test_…`) |
| --- | --- | --- |
| Validation & errors | Real | **Identical** — same codes, same order |
| Segments & encoding | Real | **Identical** (GSM-7/UCS-2 detection) |
| Cost preview | Real rates | Real rates when cached, else 0 |
| SMS delivery | Real carrier | **Simulated** — nothing is sent |
| Balance | Deducted | **Never touched** |
| Delivery webhook | Real DLR | **Synthesized `DELIVRD` ~5s after send**, same HMAC signing |
| Message storage | Permanent history | 24 hours, last 500 messages |
| Response | — | Carries `"sandbox": true` |

1. **Create a sandbox key.** In the [portal](https://restlink23telecom.com)
   under **Settings → API Keys**, enable **Test mode** when creating the key.
   You get an `sk_test_…` key.

2. **Send a simulated SMS** — same request as production:

   ```
POST https://restlink23telecom.com/api/v1/sms/send
Header: X-API-Key: <your key>
```
*(The web page shows this example in cURL, Node.js, Python, PHP, Ruby, Java, Go and .NET.)*

   The response has the exact production shape plus `"sandbox": true`.

3. **Watch the delivery report arrive.** About 5 seconds later your
   configured `delivery_url` receives a synthesized `DELIVRD` webhook with
   a valid HMAC signature — verify it exactly like a real one
   ([securing webhooks](/webhooks/security)).

4. **Poll status if you prefer:** `GET /sms/status/{message_id}` returns
   `sent`, then `DELIVRD` after the simulated carrier latency.

## What is intentionally different

- Sandbox message history is kept for **24 hours** (last 500 per workspace) —
  it never appears in production statistics or exports.
- URL auto-shortening and blocked-country filtering are skipped.
- `GET /sms/messages` supports pagination but not SQL-grade filters.
- If the simulator is unavailable you get `503 SANDBOX_UNAVAILABLE` — a test
  key never falls through to the live pipeline.

## Going live

Replace the key. That's the whole migration:

```bash
# before
export API_KEY=sk_test_abc...
# after
export API_KEY=sk_prod_xyz...
```

  Sandbox keys are perfect for AI agents ([MCP server](/tools/install-tools))
  and CI pipelines — deterministic, free, and clearly marked in every
  response.