Testing in the sandbox
Rehearse every gift outcome without sending a real gift.
For AI agents: this page is available as Markdown, and every guide plus the API reference is in llms-full.txt.
The sandbox is a full copy of the API running against its own database. Orders you place there create real orders and real gifts, debit a real balance and return the same responses production does — but no card is charged, no message is sent, and no recipient is reached.
You reach it with a sandbox key. There is one base URL for both environments and your key decides which one serves the request, so moving an integration to production means swapping the key and changing nothing else.
Choosing what happens to a gift
In production, what becomes of a gift is up to its recipient: they open it, or they don't; the delivery lands, or it bounces. You cannot rehearse any of that against a real person.
So in the sandbox the recipient address chooses the outcome. Send a gift to one of these and you get that result immediately.
| Send to this email | Or this number | What the sandbox does |
|---|---|---|
delivered@sandbox.onme.com | +12125550100 | Gift delivers successfully (the default). |
delivery-failed@sandbox.onme.com | +12125550101 | Delivery fails. The gift becomes eligible for PUT /gifts/:id/delivery. |
opened@sandbox.onme.com | +12125550102 | Gift is created already opened by the recipient. |
claimed@sandbox.onme.com | +12125550103 | Gift is created already claimed onto a card. |
spent@sandbox.onme.com | +12125550104 | Gift is created claimed, with a first spend recorded. |
processing@sandbox.onme.com | +12125550107 | Order is accepted but reports `processing` with no gifts for about 20 seconds, then completes. Use it to exercise polling. |
insufficient-funds@sandbox.onme.com | +12125550105 | Whole order is rejected with 402 insufficient_balance, whatever your balance is. |
order-error@sandbox.onme.com | +12125550106 | Whole order fails with 500 api_error, for testing retry handling. |
The rest of your request is unchanged — same body, same headers, same code path. Only the recipient differs, which means the integration you test is the integration you ship.
curl https://api.onme.com/v1/orders \
-H "Authorization: Bearer omk-sandbox-..." \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"gifts": [{
"category": "coffee",
"amount": 2500,
"delivery": { "method": "email", "email": "delivery-failed@sandbox.onme.com" }
}]
}'That order comes back processed with one gift whose delivery.status is failed — the state you would otherwise have to wait for a real bounce to see, and the one that unlocks PUT /v1/gifts/:id/delivery.
Driving a gift that is already created
Triggers fire at order time. To move a gift that already exists — or one delivered by link, which has no recipient address to carry a trigger — use the sandbox endpoints. Open, claim and spend work on any gift in your sandbox. Deliver works only on gifts On Me sends by email or phone; a link gift returns gift_delivery_not_simulatable.
| Endpoint | What it does |
|---|---|
POST /v1/sandbox/gifts/:id/deliver | Marks delivery delivered or failed |
POST /v1/sandbox/gifts/:id/open | Marks the gift opened |
POST /v1/sandbox/gifts/:id/claim | Claims it onto a card |
POST /v1/sandbox/gifts/:id/spend | Records a first spend |
Order is enforced the way it is in production: a spend before a claim returns gift_not_claimed, and claiming twice returns gift_already_redeemed. Claiming also back-fills the opened timestamp, because a gift that was claimed without being opened is a state production never produces.
They are in the API reference alongside everything else, tagged Sandbox and badged Sandbox only.
Testing an order that takes a while
Most orders finish before the response returns. Occasionally one does not: the order is paid for, some gifts are still being created, and the response says processing. Your integration has to poll until it settles.
Send to processing@sandbox.onme.com and the sandbox reproduces that: the order reports processing with no gifts for about twenty seconds, then completes on its own. It finishes by itself rather than waiting for you to nudge it, so the loop you write here is the loop that runs in production.
Testing failures
Two triggers fail the whole order rather than the gift:
insufficient-funds@sandbox.onme.comreturns402 insufficient_balancewhatever your balance isorder-error@sandbox.onme.comreturns500 api_error, for exercising retry handling
Both are rejected before anything is created, so there is no order and no debit to clean up.
Starting over
Account → Developers has a reset control in sandbox mode. It deletes every sandbox order, gift and balance for your organization, including the balance ledger. Your API keys survive, and you will need to add funds again before you can order.
Reach for it when your sandbox has drifted into a state you can no longer account for. Everything in it is reproducible — a few calls recreate your fixtures — so starting clean is usually quicker than working out how it got there.