What actually changes
Everything else is identical: the same endpoints, the same object shapes, the
same errors, the same events, the same signature scheme.
Before you switch
- Read the Terms for Partners. They add to Listo’s general terms and cover the API, your keys, test and live mode, the access level of each store, who pays for each delivery, and how you report an incident on one. One person on your team accepts them in the dashboard for the whole team. Until someone has, the API and the dashboard keep working, but you cannot file incident reports. The document is in Spanish only.
- Issue a live key and store it like a password. Keys are shown once and can do everything their mode allows, unless you issue them as read-only (they can read and nothing else, so they are the ones to hand to an AI agent or a monitoring tool). Keep them server side and out of your repository. If one leaks, revoke it in the dashboard; revocation takes effect immediately.
- Point a live webhook endpoint at production, with its own secret. The two modes have separate endpoint URLs and separate secrets. A live endpoint left unset means events are simply not sent, and nothing will complain.
- Fund the plan before you create a store. Every live store carries one Plan
Listo, charged to you, and its first month is charged in the same
POST /v1/storesrequest that creates it. Fund the live balance or save a card on the dashboard first, and send anIdempotency-Keyon every live create so a retry cannot start a second plan. A store whose charge fails is still created, but its deliveries are refused with402 plan_requireduntil the month is paid. See plan and billing. - Create your live stores. A store belongs to the world it was created in, so your test stores do not exist for a live key. Give each one the phone a courier can actually call and its real pickup instructions. A restaurant that already runs on Listo with an account of its own is connected rather than created: see connect a restaurant that already uses Listo.
- Fund the live balance, and give yourself a floor to alert on. See balance and withdrawals.
- Register the bank account withdrawals go to.
- Finish card onboarding if you take card. Read
GET /v1/stores/{id}/stripe_statusfor each live store and confirm it saysconnected. Until it does, a card create is refused withcard_not_ready. Cash and prepaid orders need none of this. - Check your
external_ids and idempotency keys are unique in production. Both are unique per mode, so a value you reused freely across test runs has to be genuinely unique among your live orders.
Handle the failures you skipped
Test mode rarely produces the interesting ones. Before you carry real orders, make sure each of these does something sensible in your code:402 insufficient_balance: the order was not dispatched. Surface it to somebody who can top up.503 provider_unavailableand409 cancel_failed: both carry"retryable": true, and both mean nothing changed. Retry them; do not treat them as a failed order.409 no_couriers_available: every courier near the trip is busy. It is"retryable": trueand nothing was created, but it is not an outage: retry after a few minutes, a bounded number of times, and then tell a person.429 rate_limited: back off for the number of seconds inRetry-After.no_courier: a real outcome, not an error. Decide whether you retry it automatically or ask a human, and readfailure_reasonto choose.- A create that times out: repeat it with the same
Idempotency-Key. A new key sends a second courier.
error.code only. error.message is prose meant for whoever reads
your logs and its wording is not part of the contract. Send
Accept-Language: es-MX and those messages arrive in Spanish, which is worth
doing if they end up in front of Spanish-speaking staff.
Rate limits
600 requests per minute per key, and 300 per minute of those onPOST /v1/quotes, which is the one call that costs Listo an upstream request.
Over either limit you get 429 rate_limited with a Retry-After header.
The limits are per key, not per IP, so several servers sharing one key share one
budget.
Once you are live
- Keep the
idor yourexternal_idfor every delivery. Between them, everything about an order can be read back. support_referenceis on every delivery. Quote it when you contact Listo about a specific order; it is the fastest way to the right trip.- Watch for
store.updatedevents. A store’s readiness to take card can change without you calling anything. - Reconcile from
GET /v1/ledgerrather than from the events you stored. It is the record of every movement on your balance, and it is where a cost that landed after an order finished will be waiting. See balance and withdrawals.