Zernio
APIFor you
Zernio
APIFor you
Platforms

WhatsApp

Overview

Set up

Connection & setupPhone NumbersSandbox

Messaging

InboxTemplatesBroadcastsFlowsGroup chatsContactsMeta Business Agent

Calls

Calling

Ad types

Click-to-WhatsApp ads

Reference

Pricing & costsMedia & limits
Dashboard
OverviewPlatformsAPI ReferenceResources
WhatsApp

Sandbox

Test WhatsApp sending, replies and webhooks against Zernio's shared sandbox number before buying a number of your own.


By the end of this page, you have sent a WhatsApp template to your own phone from Zernio's shared sandbox number and received the reply. You can then exchange free-form messages with it for 7 days.

Sandbox limits

PropertyValue
Shared numberOne Zernio-owned WhatsApp number, returned by GET /v1/phone-numbers under sandbox
VerificationReply-based: Zernio sends a template to your test phone, you reply, the session activates
Templates allowedOne, locked: sandbox_start (no variables)
Free-form text and interactive messagesYes, inside the 24-hour customer service window the reply opens
Test phones per user1 (one active session at a time)
Daily caps per user50 messages, 5 distinct recipients (in practice 1)
Pending session TTL24 hours
Activated session TTL7 days
BillingFree: no number charge, no message charge

The sandbox is for testing. Get a number of your own to send to more than one recipient, sync templates from WhatsApp Manager or run production traffic.

The number is shared, so a phone can only be targeted once its owner has proved control of it with a WhatsApp reply.

Before you start

You need an API key and a phone with WhatsApp.

No number purchase, no WABA and no Meta review is involved, and nothing is billed.

Step 1: Discover the sandbox

Call GET /v1/phone-numbers. The sandbox number, the accountId you send from and the locked template come back under sandbox.

import Zernio from '@zernio/node';

const zernio = new Zernio();

const { data: numbers } = await zernio.phonenumbers.listPhoneNumbers();

if (!numbers.sandbox) throw new Error('Sandbox not configured on this environment');
const sandbox = numbers.sandbox;

Response (200), trimmed to the sandbox:

{
  "numbers": [],
  "connected": [],
  "sandbox": {
    "phoneNumber": "+12029087457",
    "accountId": "66b2e19d8c3f5a7e9d0b1c2d",
    "template": { "name": "sandbox_start", "language": "en" },
    "isSandbox": true
  }
}

sandbox.accountId is the accountId for every send below.

Step 2: Start activation for your phone

Call POST /v1/whatsapp/sandbox/sessions with phone.

This creates a pending session and at once sends the sandbox_start template from the sandbox number to that phone.

The phone's owner opens WhatsApp and replies. Any text reply, including a tap on the "Reply and verify" button, flips the session to active.

const { data: started } = await zernio.whatsappsandbox.createWhatsAppSandboxSession({
  body: { phone: '+13105551234' }
});

console.log(started.session.id, started.session.status);

Response (200):

{
  "session": {
    "id": "66f7d4e5f6a7b8c9d0e1f2a4",
    "phoneE164": "13105551234",
    "status": "pending",
    "expiresAt": "2027-01-02T09:00:00Z",
    "activatedAt": null,
    "createdAt": "2027-01-01T09:00:00Z"
  },
  "sandboxNumber": "+12029087457"
}

Tell the user to check WhatsApp on that phone and reply. Posting the same phone again is idempotent and resends the template.

Step 3: Wait for the reply

Activation is automatic. Poll GET /v1/whatsapp/sandbox/sessions, or listen for message.received on your webhook endpoint, which fires for the reply itself.

const { data: sessions } = await zernio.whatsappsandbox.listWhatsAppSandboxSessions();

const session = sessions.sessions[0];
if (session?.status === 'active') {
  console.log('Verified at', session.activatedAt);
}

Response (200), once the phone has replied:

{
  "sessions": [
    {
      "id": "66f7d4e5f6a7b8c9d0e1f2a4",
      "phoneE164": "13105551234",
      "status": "active",
      "expiresAt": "2027-01-08T09:02:30Z",
      "activatedAt": "2027-01-01T09:02:30Z",
      "createdAt": "2027-01-01T09:00:00Z"
    }
  ],
  "sandboxNumber": "+12029087457"
}

Step 4: Send to the activated phone

The phone is now a normal WhatsApp conversation in your inbox.

Call POST /v1/inbox/conversations with the sandbox accountId, the phone as participantId (digits only, matching phoneE164) and the locked template.

A phone with no active session is rejected.

const { data: opened } = await zernio.messages.createInboxConversation({
  body: {
    accountId: sandbox.accountId,
    participantId: '13105551234',
    templateName: sandbox.template.name,
    templateLanguage: sandbox.template.language,
    templateParams: []
  }
});

const conversationId = opened.data.conversationId;

Response (201):

{
  "success": true,
  "data": {
    "messageId": "wamid.HBgLMTMxMDU1NTEyMzQVAgARGBI5QTNEMEY3RjQ4RjE2QjA3QzYA",
    "conversationId": "66c3d2ae7b4f6c8d0e1f2a3b",
    "participantId": "13105551234"
  }
}

Each reply from the phone opens a 24-hour customer service window.

Inside it, POST /v1/inbox/conversations/{conversationId}/messages with accountId and message sends free-form text, attachments and interactive messages, exactly as in any other conversation (WhatsApp inbox).

Replace the activated phone

Revoke the current session with DELETE /v1/whatsapp/sandbox/sessions/{sessionId}, then start activation for the new phone:

curl -X DELETE "https://zernio.com/api/v1/whatsapp/sandbox/sessions/66f7d4e5f6a7b8c9d0e1f2a4" \
  -H "Authorization: Bearer $ZERNIO_API_KEY"

curl -X POST "https://zernio.com/api/v1/whatsapp/sandbox/sessions" \
  -H "Authorization: Bearer $ZERNIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phone": "+442071234567"}'

Response (200), the revoke:

{
  "success": true
}

Response (200), the new activation, which sends the template to the new phone at once:

{
  "session": {
    "id": "66f7d4e5f6a7b8c9d0e1f2a5",
    "phoneE164": "442071234567",
    "status": "pending",
    "expiresAt": "2027-01-02T09:10:00Z",
    "activatedAt": null,
    "createdAt": "2027-01-01T09:10:00Z"
  },
  "sandboxNumber": "+12029087457"
}

Messages already exchanged with the old phone stay in the inbox; revocation only blocks future sends.

If it fails

A 400 from Step 2 while another phone still has a session names that phone so you can revoke it first:

{
  "error": "You can only test one phone at a time. Revoke +13105551234 first",
  "code": "invalid_field_value"
}

The other 400s on the sandbox endpoints:

ErrorCauseFix
invalid_field_value "This phone is not activated for sandbox sends"The recipient has no active session for the calling userRun Steps 2 and 3 for that phone first
invalid_field_value "Cannot activate the sandbox number itself"phone is the sandbox numberUse a real, different WhatsApp number
invalid_field_value "Could not send the activation message..."Meta rejected the template send (the number is not on WhatsApp, the WABA is paused); Meta's message is includedCheck the phone is a WhatsApp account on a registered number
rate_limitedThe 50 messages or 5 recipients per 24 hours capWait for the rolling window, or use a number of your own
403 from any /sandbox/* endpoint, code: "INBOX_REQUIRED"The team is on legacy billing without inbox accessMove to usage-based billing, which includes the inbox on every account, or start the free 7-day trial the error offers while trialAvailable is true (inbox access)

Related

  • WhatsApp phone numbers: get a number of your own when the sandbox is not enough.
  • WhatsApp inbox: what you can send inside the 24-hour window.
  • Inbox webhooks: message.received for the activation reply and every message after it.
  • Webhook account scope: set accountIds to the sandbox account id for a sandbox-only endpoint. A scoped webhook no longer receives events with no account, such as whatsapp.number.* and verification.*.
  • Sandbox API: the 3 session endpoints.
Was this page helpful?

Phone Numbers

Read a WhatsApp number's live status from Meta, tell a dead channel from a live one, and register a number whose two-step PIN blocked it.

Inbox

Receive and reply to WhatsApp conversations through the inbox API, send templates, interactive and commerce messages, and track delivery with webhooks.

On this page

Sandbox limitsBefore you startStep 1: Discover the sandboxStep 2: Start activation for your phoneStep 3: Wait for the replyStep 4: Send to the activated phoneReplace the activated phoneIf it failsRelated