> ## Documentation Index
> Fetch the complete documentation index at: https://docs.listo.delivery/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Notes on the Listo Partner Delivery API:
> - Every endpoint is under `https://api.listo.delivery/v1/` and authenticates with a bearer API key.
> - This documentation site is at https://docs.listo.delivery. The full machine-readable reference is the OpenAPI document at https://api.listo.delivery/docs/openapi.yaml (served by the API host, not by this site).
> - Any page of this site is also available as raw markdown by appending `.md` to its URL, for example https://docs.listo.delivery/en/guides/webhooks.md. The index of every page is https://docs.listo.delivery/llms.txt and all of them in one file is https://docs.listo.delivery/llms-full.txt.
> - Every page is published in English under https://docs.listo.delivery/en/ and in Spanish under https://docs.listo.delivery/es/, with the same path after the language. The API reference is under https://docs.listo.delivery/api-reference/ in English and https://docs.listo.delivery/es/api-reference/ in Spanish.
> - To debug an integration yourself: `GET /v1/request_logs` lists the calls your keys made with what you sent and what was answered, `GET /v1/events` lists the events Listo emitted, `GET /v1/webhook_deliveries` lists every attempt to deliver them, `POST /v1/events/{id}/resend` sends one event again and `POST /v1/test_webhooks` sends a sample event (`"test": true`). The page https://docs.listo.delivery/en/guides/debugging describes them. A resent event is a snapshot from when it happened; `GET /v1/deliveries` is still how you recover current state.
> - Every error response has `error.doc_url`, a page that explains that error code and what to do, and `error.request_id`, the same value as the `X-Request-Id` response header. All the pages are listed at https://docs.listo.delivery/en/errors. Filter `GET /v1/request_logs` with `request_id` to read the logged call.
> - A `409 account_exists` from `POST /v1/stores` means the restaurant already has its own Listo account: connect it instead of creating it, as the page https://docs.listo.delivery/en/guides/connect-existing-account describes.
> - Every live store carries one Plan Listo, charged to the partner. The exception is a connected restaurant that had already paid its current month: it keeps paying its own plan until its next renewal, shown as `paid_by: "store"` with the handover date in `pending_paid_by_on`. A `402 plan_required` from a quote, a delivery create or a retry means the store's plan is not paid or has ended; the page https://docs.listo.delivery/en/guides/plan-and-billing describes the plan, the `plan` block on a store and how to end or restart it.
> - An AI assistant (Claude Code, Cursor, Codex) can act through the same API key at `https://api.listo.delivery/mcp`, an MCP server over Streamable HTTP authenticated with `Authorization: Bearer <API key>`. Every tool runs the matching `/v1/` endpoint, and each one that moves money first previews and then needs a confirmation token; the page https://docs.listo.delivery/en/guides/connect-ai-client lists the tools and describes the two steps.

# Lista tus tiendas

> Tus tiendas, las más nuevas primero, paginadas por keyset. Pasa el `cursor` de la página anterior para seguir; `has_more` te dice cuándo parar. No hay conteo total, por diseño.

Una llave solo ve las tiendas de su propio modo: una llave de prueba no puede ver ni dirigirse a tiendas reales, y al revés.




## OpenAPI

````yaml /openapi/es.yaml get /v1/stores
openapi: 3.1.0
info:
  title: Listo Delivery API
  version: 1.34.0
  description: >
    Cotiza un envío, despáchalo y sigue el recorrido hasta la puerta.


    Cada solicitud se autentica con una llave de API bearer. La llave misma
    decide el modo en el que actúa: una llave de prueba despacha repartidores
    simulados y no mueve dinero, y una llave real despacha repartidores reales.
    Una llave también puede ser de solo lectura: solo puede llamar a GET y HEAD,
    y cualquier otra llamada responde `403 read_only_key`. El dinero siempre va
    en pesos mexicanos y siempre en centavos enteros, y cada marca de tiempo es
    ISO-8601 en UTC.


    Los ids son cadenas opacas con prefijo (`st_` una tienda, `qt_` una
    cotización, `dlv_` un

    envío, `wd_` un retiro, `evt_` un evento, `le_` un movimiento del historial,

    `whd_` un intento de entrega de webhook, `req_` una llamada registrada).
    Trátalos

    como cadenas de longitud ilimitada y nunca los analices.


    Los cambios a v1 son aditivos: pueden aparecer campos nuevos y valores
    nuevos de enumeración, así que ignora lo que no reconozcas en lugar de
    fallar.
servers:
  - url: https://api.listo.delivery
security: []
tags:
  - name: Authentication
    description: Verifica que una llave funciona antes de empezar a construir con ella.
    x-group: Autenticación
  - name: Stores
    description: Las ubicaciones de recolección desde las que despachas.
    x-group: Tiendas
  - name: Account connection
    description: Conectar la cuenta de Listo que ya tiene un restaurante contigo.
    x-group: Conexión de cuenta
  - name: Quotes
    description: Lo que cuesta un envío, cotizado y retenido.
    x-group: Cotizaciones
  - name: Deliveries
    description: Despachar un pedido y seguirlo hasta la puerta.
    x-group: Envíos
  - name: Balance
    description: El saldo prepagado del que salen tus envíos.
    x-group: Saldo
  - name: Withdrawals
    description: Sacar dinero de ese saldo hacia tu banco.
    x-group: Retiros
  - name: Card onboarding
    description: Conectar la cuenta que recibe los pagos con tarjeta.
    x-group: Alta de cobros con tarjeta
  - name: Events
    description: >-
      Los eventos que Listo te envió, al reenviar uno y al enviar un evento de
      prueba a tu endpoint.
    x-group: Eventos
  - name: Webhook deliveries
    description: >-
      Cada intento que hizo Listo de enviar un evento a tu endpoint, y lo que
      respondió tu endpoint.
    x-group: Entregas de webhook
  - name: Request logs
    description: >-
      Cada llamada que hicieron tus llaves a esta API, con lo que enviaste y con
      lo que respondimos.
    x-group: Registro de solicitudes
  - name: Ledger
    x-group: Historial
  - name: Webhooks
    x-group: Webhooks
paths:
  /v1/stores:
    get:
      tags:
        - Stores
      summary: Lista tus tiendas
      description: >
        Tus tiendas, las más nuevas primero, paginadas por keyset. Pasa el
        `cursor` de la página anterior para seguir; `has_more` te dice cuándo
        parar. No hay conteo total, por diseño.


        Una llave solo ve las tiendas de su propio modo: una llave de prueba no
        puede ver ni dirigirse a tiendas reales, y al revés.
      operationId: listStores
      parameters:
        - name: cursor
          in: query
          required: false
          schema:
            type: string
          example: 1785628920000000-1024
        - name: external_id
          in: query
          required: false
          schema:
            type: string
          example: pos-store-41
      responses:
        '200':
          description: La solicitud fue exitosa.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StoreList'
              example:
                data:
                  - id: st_4bR8kM2wQ7xT1nV5cZ9pLdYe
                    external_id: null
                    name: Tortería La Mera Mera
                    phone: '+528112345678'
                    street: Av. Juan Palomar y Arias 765
                    apt_unit: null
                    lat: 20.691145
                    lng: -103.426885
                    pickup_notes: null
                    timezone: America/Mexico_City
                    default_business_fee_share: 0
                    default_fee_split_mode: percent
                    default_fee_split_amount_cents: null
                    access_tier: api_only
                    markup_cents: 0
                    billing: partner
                    plan: null
                    test: true
                    created_at: '2026-07-29T12:00:00Z'
                has_more: false
                cursor: null
        '401':
          description: >-
            La llave de API no existe, fue revocada o no es válida para este
            modo (`invalid_api_key`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: invalid_api_key
                  message: The API key is missing, revoked, or not valid for this mode.
                  param: null
                  retryable: false
                  doc_url: https://docs.listo.delivery/en/errors/invalid_api_key
                  request_id: 0b1f6c9a-7e2d-4c53-9a41-5d8e3f2a6b10
      security:
        - BearerAuth: []
components:
  schemas:
    StoreList:
      type: object
      description: Una página de tiendas, de la más reciente a la más antigua.
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Store'
        has_more:
          type: boolean
          description: Verdadero cuando existe una página siguiente.
        cursor:
          type:
            - string
            - 'null'
          description: >-
            Pásalo como `cursor` para leer la siguiente página. Null en la
            última página.
      required:
        - data
        - has_more
        - cursor
    ErrorResponse:
      type: object
      description: El cuerpo de toda respuesta 4xx y 5xx de esta API.
      properties:
        error:
          $ref: '#/components/schemas/Error'
      required:
        - error
    Store:
      type: object
      description: >
        Un punto de recolección. La disponibilidad para cobrar con tarjeta NO es
        un

        campo aquí a propósito: tiene endpoint propio, con detalle propio de
        requisitos pendientes.
      properties:
        id:
          type: string
          description: El id de la tienda, con prefijo `st_`.
          example: st_4bR8kM2wQ7xT1nV5cZ9pLdYe
        external_id:
          type:
            - string
            - 'null'
          description: >
            Tu propia referencia de esta ubicación, si enviaste una. Es única
            por modo de llave, y se puede filtrar en la lista, para que puedas
            conciliar contra tu propio libro de tiendas sin guardar nuestros
            ids.
          example: pos-store-41
        name:
          type: string
          description: >
            El nombre que le diste a la tienda; para un restaurante que conectó
            una cuenta con varias sucursales, el negocio y la sucursal, como lo
            leen sus propios clientes (`Tortería La Mera Mera, Zapopan`). Una
            sucursal cuyo nombre ya empieza con el nombre del negocio, como
            `Tortería La Mera Mera Centro`, se publica tal cual. Cuando envías
            un nombre, un valor que empieza con el nombre de negocio de la
            tienda y una coma se lee como ese negocio más la sucursal, así que
            devolver el nombre que leíste no cambia nada.
        phone:
          type: string
          description: E.164, normalizado al recibirlo.
        street:
          type: string
        apt_unit:
          type:
            - string
            - 'null'
        lat:
          type:
            - number
            - 'null'
          format: double
        lng:
          type:
            - number
            - 'null'
          format: double
        pickup_notes:
          type:
            - string
            - 'null'
          description: Instrucciones permanentes para el repartidor que recoge aquí.
        timezone:
          type: string
          description: >
            La zona IANA en la que la tienda guarda sus horarios, normalizada a
            una

            sola escritura por zona. Se deriva de las coordenadas de la tienda,
            y

            se vuelve a derivar cada vez que la posición de la tienda se mueve.
            Una zona que tú envías

            se usa solo cuando la posición no puede responder (una tienda sin

            coordenadas, o una posición que ninguna zona reclama), y una que no
            coincide con la posición ni se guarda ni se trata

            como error.
          example: America/Mexico_City
        default_business_fee_share:
          type: integer
          minimum: 0
          maximum: 100
          description: >
            La parte de la tarifa de envío que esta tienda cubre por defecto,
            como porcentaje. El resto se cobra al cliente. Solo está vigente
            cuando `default_fee_split_mode` es `percent`; en cualquiera de los
            dos modos de monto, este es el porcentaje que la tienda conserva
            para cuando vuelva a ser uno.
        default_fee_split_mode:
          type: string
          enum:
            - percent
            - business_amount
            - customer_amount
          description: >
            Qué forma tiene el reparto predeterminado de esta tienda, y por eso
            cuál de los dos campos de arriba y de abajo está vigente. `percent`
            reparte la tarifa según `default_business_fee_share`;
            `business_amount` significa que la tienda cubre hasta
            `default_fee_split_amount_cents` de ella y el cliente paga el resto;
            `customer_amount` es el espejo, el cliente paga hasta ese monto y la
            tienda cubre el resto.


            Solo lectura. Lo fija el restaurante en su propia consola de Listo,
            y enviar `default_business_fee_share` al crear o actualizar devuelve
            la tienda a `percent`.
        default_fee_split_amount_cents:
          type:
            - integer
            - 'null'
          minimum: 0
          description: >
            El monto entre el que dividen la tarifa los dos modos de monto, en
            centavos. Es null en

            modo `percent`, y nunca es null en ninguno de los dos modos de
            monto. Solo lectura.
        access_tier:
          type: string
          enum:
            - api_only
            - wallet
            - full
          description: >
            Cuánto de Listo usa la propia tienda. Los envíos de una tienda
            `api_only` gastan tu saldo, y los de una tienda `wallet` o `full`
            gastan el suyo; `billing` dice cuál. Se puede escribir al crear y al
            actualizar, y siempre es `api_only` en una tienda de prueba. Una
            tienda real de una cuenta cuyos restaurantes pagan su propio Plan
            Listo no puede ser `api_only`: no tiene consola desde la cual
            comprar un plan, así que una creación o una actualización que lo
            pida se rechaza con `422 validation_failed` y `param:
            "access_tier"`.
        markup_cents:
          type: integer
          minimum: 0
          description: >
            Tu propio margen sobre cada envío de esta tienda, en centavos. Se
            suma a la tarifa de envío, se reparte con el cliente como el resto
            de la tarifa, y se abona a tu saldo cuando el envío se entrega. Se
            puede escribir al crear y al actualizar.
        billing:
          type: string
          enum:
            - partner
            - store
          description: >
            De quién es el saldo que paga los envíos de esta tienda, leído de
            `access_tier` para que nunca tengas que derivarlo: `partner` es
            tuyo, `store` es el propio de la tienda. Solo lectura. No es quién
            paga el plan de la tienda, que es `plan.paid_by`.
        test:
          type: boolean
        created_at:
          type: string
          format: date-time
        plan:
          description: >
            El Plan Listo de la tienda, o `null` cuando la tienda no necesita
            plan: una tienda de prueba, o una tienda real creada antes de que
            existiera Plan Listo, que sigue pidiendo repartidores sin uno.
            También es `null` cuando la tienda paga su propio plan (cada tienda
            de una cuenta cuyas tiendas pagan su propio Plan Listo) y el
            restaurante todavía no ha comprado uno: el restaurante lo compra en
            su propia consola, y no tienes nada que pagar ni reactivar. También
            es `null` para una tienda de un socio con el esquema de precios sin
            Plan Listo, que no necesita plan. Cuando es un objeto, todas las
            llaves están presentes, y las que no aplican son `null`. Consulta
            [Plan y
            facturación](https://docs.listo.delivery/es/guides/plan-and-billing).
          type:
            - object
            - 'null'
          properties:
            status:
              type: string
              enum:
                - active
                - past_due
                - canceling
                - canceled
                - awaiting_payment
              description: >
                `active` está al corriente y se renueva en `next_charge_on`
                (null en un plan que está pasando al restaurante, ver
                `pending_paid_by`). `past_due` tiene un mes sin pagar, y sus
                envíos se rechazan con `402

                plan_required` hasta que el cobro pase. `awaiting_payment` es
                una tienda cuyo primer mes no pudieron cubrir ni tu saldo ni tu
                tarjeta: todavía no tiene plan, `price_cents` es el precio que
                se le cobrará antes de IVA (el monto necesario para pagar es ese
                más IVA), todas las fechas son null, sus envíos se rechazan con
                `402 plan_required`, y Listo le cobra por sí mismo en cuanto tu
                saldo o tu tarjeta lo cubran. `canceling` se canceló y se sirve
                hasta el día anterior a `ends_on`. `canceled` ya terminó, y se
                puede reiniciar.
            price_cents:
              type: integer
              description: >
                Lo que te cuesta un mes del plan de esta tienda, antes de IVA:
                tu precio, incluso mientras un restaurante que se conectó
                contigo sigue pagando su propio plan. Cuando `paid_by` es
                `store` porque la tienda paga su propio plan, es el precio de un
                `interval` del plan propio del restaurante, que no te
                corresponde pagar.
              example: 199000
            currency:
              type: string
              example: MXN
            interval:
              type: string
              description: >
                Cuánto dura un periodo de este plan, y el ciclo del que
                `price_cents` es el precio. `month` para todo plan que pagas.
                Una tienda que paga su propio plan reporta el intervalo que
                compró su restaurante, así que `year` es un restaurante que pagó
                doce meses de una vez.
              example: month
            current_period_ends_on:
              type:
                - string
                - 'null'
              format: date
              description: >
                El último día del periodo actual, ya pagado salvo que `status`
                sea `past_due`.
            next_charge_on:
              type:
                - string
                - 'null'
              format: date
              description: >
                El día en que se te cobra lo siguiente: la siguiente renovación
                o, mientras un restaurante que se conectó contigo siga pagando
                su propio plan, tu primer cobro. Es null una vez que el plan
                está terminando o ya terminó, y es null mientras está
                `past_due`: el mes adeudado se cobra en el momento en que tu
                saldo o tu tarjeta guardada lo permitan, y se reintenta cada día
                hasta que se paga. También es null mientras `courtesy` sea true.
                Igualmente es null en un plan que tú pagas y que está pasando al
                restaurante (`pending_paid_by` es `store`): pagas el periodo en
                el que estás y nada después. Cuando `paid_by` es `store` porque
                la tienda paga su propio plan, es el día en que se renueva el
                plan propio del restaurante, no un cobro a ti.
            canceled_at:
              type:
                - string
                - 'null'
              format: date-time
              description: Cuándo cancelaste el plan.
            ends_on:
              type:
                - string
                - 'null'
              format: date
              description: >
                El día en que el plan deja de dar servicio a la tienda, que es
                el día después del último día pagado, o el día en que se canceló
                un plan cuyo cobro estaba pendiente. Es null salvo que el plan
                esté terminando o ya haya terminado.
            paid_by:
              type: string
              enum:
                - partner
                - store
              description: >
                Quién paga este plan: `partner`, que eres tú, o `store`, el
                propio restaurante. `store` es un restaurante que se conectó
                contigo y aún paga su propio plan, y cada tienda que paga su
                propio Plan Listo porque tu cuenta está configurada así; ninguna
                de ellas te toca pagar.
            pending_paid_by:
              type:
                - string
                - 'null'
              description: >
                Quién lo pagará a partir de `pending_paid_by_on`, cuando eso
                está por cambiar, o null. `partner` eres tú: un restaurante que
                se conectó contigo y aún paga su propio plan, hasta la
                renovación que pagas tú. `store` es el restaurante: un plan que
                pagas tú y que pasa al restaurante en su próxima renovación
                porque tu cuenta está configurada para que cada restaurante
                pague su propio plan. Pagas el periodo en el que estás y nada
                después de él, por eso `next_charge_on` es null.
            pending_paid_by_on:
              type:
                - string
                - 'null'
              format: date
              description: >
                La fecha en que entra el cambio (el día en que empieza el primer
                periodo del nuevo pagador), o null.
            courtesy:
              type: boolean
              description: >
                `courtesy` es true mientras Listo le perdona el plan a esta
                tienda: no se cobra nada y `next_charge_on` es null.
          required:
            - status
            - price_cents
            - currency
            - interval
            - current_period_ends_on
            - next_charge_on
            - canceled_at
            - ends_on
            - paid_by
            - pending_paid_by
            - pending_paid_by_on
            - courtesy
      required:
        - id
        - external_id
        - name
        - phone
        - street
        - apt_unit
        - lat
        - lng
        - pickup_notes
        - timezone
        - default_business_fee_share
        - default_fee_split_mode
        - default_fee_split_amount_cents
        - access_tier
        - markup_cents
        - billing
        - test
        - created_at
        - plan
    Error:
      type: object
      description: >
        Cómo se ve todo rechazo y toda falla. `code` es el único

        campo en el que decidir; `message` es para una persona que lee un
        registro y puede

        cambiar de redacción o de idioma sin aviso.
      properties:
        code:
          type: string
          description: >
            Un nombre estable y legible por máquina de lo que salió mal, como

            `validation_failed`, `not_found` o `insufficient_balance`. Decide

            con base en esto y nunca en `message`. La lista crece sin romper
            nada: trata

            un código que no conozcas como el fallo genérico que indica su
            código de estado.

            Cada código tiene una página en `doc_url`.
          example: validation_failed
        message:
          type: string
          description: |
            Una oración para quien depura. Puede cambiar de redacción o de
            idioma en cualquier momento, así que nunca la uses para comparar.
          example: order_value_cents is required.
        param:
          type:
            - string
            - 'null'
          description: >
            El campo de la solicitud al que se refiere el rechazo, cuando
            aplica, escrito

            como lo enviaste (`dropoff.street`, `manifest.items`). Null cuando
            la

            falla no se refiere a un solo campo.
          example: order_value_cents
        retryable:
          type: boolean
          description: >
            Si volver a enviar la misma solicitud podría tener éxito. `false`

            significa que nunca lo tendrá sin un cambio de tu lado o en el
            mundo.
          example: false
        doc_url:
          type: string
          format: uri
          description: La página de documentación de este `code`.
          example: https://docs.listo.delivery/en/errors/validation_failed
        request_id:
          type: string
          description: >
            Nuestro id de esta solicitud, el mismo valor que el encabezado de
            respuesta

            `X-Request-Id`. Cítalo a soporte, y filtra

            `GET /v1/request_logs` por él.
          example: 0b1f6c9a-7e2d-4c53-9a41-5d8e3f2a6b10
      required:
        - code
        - message
        - param
        - retryable
        - doc_url
        - request_id
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        Tu llave de API, enviada como `Authorization: Bearer <key>`. Las llaves
        reales y de prueba son distintas; la llave que envías decide en qué modo
        actúa la llamada. Para probar llamadas, usa una llave de prueba (empieza
        con `lst_test_`): no se envía ningún repartidor real y no se mueve
        dinero real, pero los webhooks se disparan y el `dropoff.phone` que des
        puede recibir mensajes de WhatsApp, así que usa tu propio número. Una
        llave real (empieza con `lst_live_`) reserva y cobra envíos reales.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.