Get started

Sandbox

A deterministic, free environment that exposes the full product surface — so your integration works end-to-end before a single BRL is billed.

Every project has a sandbox environment alongside its production environment. The two share the same HTTP API, the same request and response shapes, the same webhook envelope. The only differences are:

Because the contracts are identical, you build once against sandbox and promote to production by swapping the key.

Check sandbox readiness

GET/v1/sandbox/quickstart

Use this endpoint before the first send. It reports the current sandbox environment, whether a default sender exists, which scopes are missing, and the exact local listen event type: message.received.

curl https://api.tyxter.com/v1/sandbox/quickstart \
  -H "authorization: Bearer $TYXTER_API_KEY"

Simulate an inbound message

POST/v1/sandbox/inbound-messages

This is the canonical sandbox inbound endpoint and the sandbox's equivalent of a Meta webhook callback. It returns 202 Accepted, writes an inbound Message row, and fires message.received to your registered webhook endpoints with text normalized at data.content.text.body.

To open the WhatsApp 24-hour service window for a later free-form outbound send, set from to the customer phone you will send to next, and set to to the sandbox sender id used by that outbound request.

curl https://api.tyxter.com/v1/sandbox/inbound-messages \
  -H "authorization: Bearer $TYXTER_API_KEY" \
  -H "content-type: application/json" \
  -H "tyxter-trace-id: diag_open_window" \
  -d '{
    "channel": "whatsapp",
    "from": "+5511999999999",
    "to": "sandbox_sender",
    "type": "text",
    "text": { "body": "Oi, qual o status do meu pedido?" }
  }'

Opt-out keyword detection

The inbound worker scans the text body against the Brazilian opt-out keyword list (parar, sair, cancelar, stop). When a match fires:

You can exercise this path in sandbox by sending an inbound with body: "parar", then attempting an outbound send to the same number.

Simulate a paid payment

POST/v1/sandbox/payments/{payment_id}/status

Sandbox payment requests can be forced to paid, failed, expired, or cancelled. Use this fixture to test payment completion branches and payment.paid webhooks without relying on a real provider checkout. The connectionless sandbox default is a deterministic hosted-link fixture; Abacate Pay options require a selected Abacate Pay sandbox connection.

curl https://api.tyxter.com/v1/sandbox/payments/pay_123/status \
  -H "authorization: Bearer $TYXTER_API_KEY" \
  -H "content-type: application/json" \
  -H "idempotency-key: fixture-pay-123-paid" \
  -d '{ "status": "paid" }'

Going to production

  1. Top up credits from the dashboard.
  2. Register a Meta connection from the dashboard.
  3. Submit your templates for approval. Production sends a real template rejection when Meta rejects.
  4. Swap your key. Same code, tx_live_... instead of tx_sandbox_....
A production key whose org has a balance_brl <= -5 receives a 402 credit_balance_exhausted. Sandbox does not enforce this.