Skip to main content
Going live is swapping one credential for another. There is no separate host, no version change and no different request shape: the same code that dispatched a simulated courier dispatches a real one the moment it sends a live key. That is the reason to read the rest of this page. Nothing will tell you that you forgot something; the first sign will be a real courier at a real address.

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/stores request that creates it. Fund the live balance or save a card on the dashboard first, and send an Idempotency-Key on every live create so a retry cannot start a second plan. A store whose charge fails is still created, but its deliveries are refused with 402 plan_required until 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_status for each live store and confirm it says connected. Until it does, a card create is refused with card_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_unavailable and 409 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": true and 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 in Retry-After.
  • no_courier: a real outcome, not an error. Decide whether you retry it automatically or ask a human, and read failure_reason to choose.
  • A create that times out: repeat it with the same Idempotency-Key. A new key sends a second courier.
Branch on 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 on POST /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 id or your external_id for every delivery. Between them, everything about an order can be read back.
  • support_reference is 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.updated events. A store’s readiness to take card can change without you calling anything.
  • Reconcile from GET /v1/ledger rather 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.
Keep the test key workingTest mode does not expire and costs nothing. Point your staging environment at it permanently rather than testing against production, and you get a real lifecycle, real events and real signatures to develop against for as long as the integration lives.