Search

Search guides and the API reference

Get started

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 emailOr this numberWhat the sandbox does
delivered@sandbox.onme.com+12125550100Gift delivers successfully (the default).
delivery-failed@sandbox.onme.com+12125550101Delivery fails. The gift becomes eligible for PUT /gifts/:id/delivery.
opened@sandbox.onme.com+12125550102Gift is created already opened by the recipient.
claimed@sandbox.onme.com+12125550103Gift is created already claimed onto a card.
spent@sandbox.onme.com+12125550104Gift is created claimed, with a first spend recorded.
processing@sandbox.onme.com+12125550107Order is accepted but reports `processing` with no gifts for about 20 seconds, then completes. Use it to exercise polling.
insufficient-funds@sandbox.onme.com+12125550105Whole order is rejected with 402 insufficient_balance, whatever your balance is.
order-error@sandbox.onme.com+12125550106Whole 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.

EndpointWhat it does
POST /v1/sandbox/gifts/:id/deliverMarks delivery delivered or failed
POST /v1/sandbox/gifts/:id/openMarks the gift opened
POST /v1/sandbox/gifts/:id/claimClaims it onto a card
POST /v1/sandbox/gifts/:id/spendRecords 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.com returns 402 insufficient_balance whatever your balance is
  • order-error@sandbox.onme.com returns 500 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.