Sandbox and testing
The sandbox is a separate Delivr environment to build and test against. It behaves like production, with three differences:
- No real SMS. Recipient messages are recorded, not sent. Use any valid phone number of the market.
- Robo drivers. Test drivers deliver your on-demand orders in about two minutes.
- Test data only. Never send real customers’ names, phones or addresses.
| Base URL | https://driver-staging-api.delivr.no |
| Tracking pages | https://tracking-stage.delivr.no |
| Keys | Sandbox keys (dmk_…) from your Delivr contact. They never work in production. |
Getting set up
Section titled “Getting set up”- Ask your Delivr contact for a sandbox merchant and API key. Give them your webhook URL if you want webhooks; it must be public HTTPS. For local development, use a tunnel such as
cloudflaredorngrok. - Add your stores with
POST /v1/merchant/locations. Robo drivers park at a new store within a minute. - Check your webhook endpoint with
POST /v1/merchant/webhooks/test, thenGET /v1/merchant/webhooks/deliveriesto see what your server answered.
Robo drivers
Section titled “Robo drivers”Every store in the sandbox has robo drivers parked outside, online. Because they are nearby, quotes for your store offer on_demand, and when an order’s goods are released one of them accepts it.
A robo driver behaves like a real driver using the Delivr driver app:
| Step | Takes | Status and webhook |
|---|---|---|
| Accepts the offer | A few seconds after the search starts | driver_assigned, order.driver_assigned |
| Drives to the store | About 45 seconds | |
| Arrives and loads, with a pickup photo | 5 to 20 seconds | picked_up, order.picked_up |
| Drives to the recipient | About 45 seconds | |
| Delivers, with a drop-off photo | delivered, order.delivered with proofOfDelivery |
The recipient’s tracking page shows the robo driver moving on the map, just as a shopper would see a real one.
Testing failure paths with directives
Section titled “Testing failure paths with directives”Real drivers read pickup.note. Robo drivers do too, and they follow directives written there. Put one anywhere in the note of the order you place:
{ "quoteId": "…", "option": "on_demand", "externalRef": "test-no-driver-1", "pickup": { "note": "sandbox:no_driver" }, "delivery": { "…": "…" }}| Directive | What the robo driver does | What you can test |
|---|---|---|
| (none) | Accepts and delivers. | The happy path and every status webhook. |
sandbox:no_driver |
Every robo driver declines, and the search ends at once instead of after 15 minutes. | failed with reason no_driver, and your fallback policy. |
sandbox:hand_back |
The first driver accepts, sets off and gives the job back. Another driver then delivers it. | A driver handing a job back. For assisted checkout, sale.driver shows reassigning. |
sandbox:stop_en_route |
Accepts and stays on the way to the store. | Cancelling at the driver_en_route fee. |
sandbox:stop_at_pickup |
Accepts, arrives at the store and waits there. | Cancelling at the driver_arrived fee, and goods that are not ready when the driver arrives. |
Directives are not case-sensitive and can sit next to normal text, like "Ask for Kari. sandbox:stop_at_pickup". A store’s pickupInstructions work too, which is handy for a store you only use to test one path. In production, directives are ordinary text that drivers ignore.
A held driver (stop_*) gives the job back after an hour if you do nothing, and the order then searches again.
More things to test
Section titled “More things to test”| Scenario | How |
|---|---|
| Goods not ready | Set your store’s readySignal to required and send no ready or processing. You get order.ready_overdue at readyBy, then the order fails with goods_not_ready after the grace period. Send a readyBy a few minutes ahead to make it quick. |
| Packing time | Send POST /orders/{id}/processing {readyAt} a few minutes ahead. The driver search starts so that the driver arrives at about readyAt. |
| Price changes | Place an order on a quote older than five minutes. You get either the order at no more than the quoted price, or 409 price_changed. |
| Free cancellation | Cancel before a driver accepts, with maxFeeMinor: 0. |
| Webhook retries | Answer 500 from your endpoint, then look at GET /v1/merchant/webhooks/deliveries for the retry schedule. Replay an event with POST /v1/merchant/webhooks/events/{id}/replay. |
| Assisted checkout | Place with sale: "pending", poll until sale.driver is assigned, then complete with POST /orders/{id}/sale. |
Window orders
Section titled “Window orders”Window orders can be quoted, placed, rescheduled and cancelled in the sandbox. Robo drivers do not run window routes, so a window order usually stays scheduled. If you need to see picked_up and delivered on a window order, ask your Delivr contact to run one for you.
Limits and data
Section titled “Limits and data”- The same rate limits apply as in production.
- The sandbox is shared by every integrator, and Delivr may reset its data. Do not depend on old orders being there.
- Prices come from a sandbox agreement and are not your production prices.