---
title: "Start a sandbox activation"
method: POST
path: "/v1/whatsapp/sandbox/sessions"
tags: ["WhatsApp Sandbox"]
---

# Start a sandbox activation

`POST /v1/whatsapp/sandbox/sessions`

Creates (or refreshes) a pending sandbox session for the given phone and
immediately fires the verified sandbox template from the shared sandbox
number to that phone. The session activates when the phone owner replies
to that WhatsApp message — the reply itself is proof of ownership.

One phone per user: if the caller already has a non-expired session for
a DIFFERENT phone, the request is rejected with `invalid_field_value`
(the message names the existing phone so it can be revoked first).
Re-creating a session for the SAME phone is idempotent and refreshes
the verification template.

If Meta rejects the template send (not a WhatsApp number, paused WABA,
token issue), the pending row is rolled back and the Meta error message
is returned in `error` so the caller knows why.

## Request body

- object
  - `phone` string, required — Recipient phone in international format. Digits, spaces, dashes and a leading `+` are all accepted; the server normalizes to E.164 digits-only.

## Response `200`

Session created or refreshed; verification template sent

- object
  - `session` WhatsAppSandboxSession — A per-user activation session against the shared WhatsApp sandbox number. Transitions `pending → active` when the inbound webhook receives a reply from the matching phone (the reply itself proves ownership).
    - `id` string, required — Session id. Use this to revoke via DELETE.
    - `phoneE164` string, required — Digits-only E.164 form (no +, spaces, or dashes).
    - `status` 'pending' | 'active', required — `pending` until the phone replies to the activation template, then `active`. Expired sessions are pruned by TTL and never appear in list responses.
    - `expiresAt` string, date-time, required — UTC timestamp at which the session becomes invalid. Pending sessions get a 24h window; activated sessions get 7 days.
    - `activatedAt` string, date-time, nullable — When the session transitioned `pending → active`, or null.
    - `createdAt` string, date-time, nullable
  - `sandboxNumber` string

## Other responses

- `400` — Returned when (a) phone format is invalid, (b) phone equals the sandbox number itself, (c) the user already has a session for a different phone, or (d) Meta rejected the template send. The `error` field contains the specific reason; `param` is set when a field is at fault.
- `401` — Unauthorized
- `403` — Inbox addon required

---

[API](https://skmtc.net/zernio/apis/zernio-api.md) · [All operations](https://skmtc.net/zernio/apis/zernio-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/zernio/zernio-api/versions/f81ca70ea6b9/schema)
