Getting started
Sandbox mode
Sandbox isn't a separate environment — it's a data dimension that rides alongside your live data in the same tenant. The same flows run and the same messages render, but nothing reaches a real customer and nothing counts against your quota.
How you enter sandbox
There are two ways in, depending on which surface you're calling:
- Authenticated endpoints — use a
fh_test_key. The key mode decides the dimension: test keys read and write sandbox data, live keys read and write live data. You never pass a flag. - Ingest endpoints — an endpoint carries live data by default. Opt a
single request into sandbox with a
?sandbox=1query parameter on the ingest URL. The signature and everything else are unchanged.
curl -X POST "https://api.flyhalf.run/v1/ingest/YOUR_ENDPOINT_KEY?sandbox=1" \ -H "X-Signature: $SIG" \ -d "$BODY"
What sandbox changes
An is_sandbox flag rides on participants, events, flow runs, ledger
entries, messages, redemptions and webhook deliveries. The two dimensions never mix:
- Comms render but never send. A sandbox message is fully rendered
and logged as
simulated— you can inspect the exact email or WhatsApp body, but it goes nowhere. - List reads are scoped.
GET /v1/events,/v1/participantsand friends return only rows matching the calling key's dimension. A test key never sees live rows and vice versa. - Sandbox events aren't metered. Only live events increment your monthly quota, so you can load-test flows freely.
- Widgets are live-only. Minting a widget token for a sandbox participant fails — embeddable widgets only ever surface live data.
Simulated is not success
In the dashboard, a simulated message is rendered in cobalt, never the jade of a real send. If you see cobalt, the message was built correctly but deliberately not delivered — that's the sandbox working, not a failure.
A typical onboarding loop
- Build and publish a flow.
- Fire test events with a
fh_test_key (or?sandbox=1). - Read the flow run trace and the rendered simulated message to confirm the logic.
- Switch to a
fh_live_key. Same flow, same code — now it reaches customers.
Because sandbox and live share one flow definition, there's nothing to promote or re-deploy between them. Ready to send real events? Head to Events.