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

# Consultar export masivo

> Devuelve el estado del export y, cuando está `listo`, una URL firmada para descargar el ZIP. La URL es de solo lectura y **vive 15 minutos** desde que se genera: no la almacenes, guarda el `id` y vuelve a llamar a este endpoint.

`estatus` es `pendiente`, `en_proceso`, `listo` o `fallido`. Un export `listo` con `expirado: true` y sin `url` se generó bien pero su archivo ya se borró por la política de retención (7 días): hay que volver a pedirlo, no es un error.



## OpenAPI

````yaml /openapi.json get /cfdi/exports/{id}
openapi: 3.1.0
info:
  description: API de timbrado CFDI 4.0 de Palenca.
  title: Ipsofactura API
  version: v1
servers:
  - description: Producción
    url: https://api.ipsofactura.com
  - description: Sandbox (pruebas, sin validez fiscal)
    url: https://sandbox.api.ipsofactura.com
security:
  - apiKeyAuth: []
tags:
  - description: Timbrado, nómina, complemento de pago, cancelación y descarga de CFDIs.
    name: CFDI
  - description: Alta y consulta de empresas emisoras.
    name: Empresas
  - description: Administración del Certificado de Sello Digital (CSD).
    name: Certificados
  - description: >-
      Suscripciones de webhooks: notificaciones de timbrado, cancelación y
      pagos.
    name: Webhooks
paths:
  /cfdi/exports/{id}:
    get:
      tags:
        - CFDI
      summary: Consultar export masivo
      description: >-
        Devuelve el estado del export y, cuando está `listo`, una URL firmada
        para descargar el ZIP. La URL es de solo lectura y **vive 15 minutos**
        desde que se genera: no la almacenes, guarda el `id` y vuelve a llamar a
        este endpoint.


        `estatus` es `pendiente`, `en_proceso`, `listo` o `fallido`. Un export
        `listo` con `expirado: true` y sin `url` se generó bien pero su archivo
        ya se borró por la política de retención (7 días): hay que volver a
        pedirlo, no es un error.
      operationId: getExport
      parameters:
        - in: path
          name: id
          required: true
          schema:
            format: uuid
            type: string
      responses:
        '200':
          content:
            application/json:
              example:
                desde: '2026-08-01'
                estatus: listo
                hasta: '2026-08-31'
                id: 9a4f07ff-3abc-435f-b7a6-88c2bc65b4c1
                tamano_bytes: 5242880
                total_cfdis: 1043
                url: https://storage.ipsofactura.com/exports/9a4f07ff.zip?sig=...
              schema:
                $ref: '#/components/schemas/ExportResponse'
          description: Estado del export
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: id mal formado (INVALID_UUID_FORMAT)
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: >-
            API key faltante o inválida (AUTHENTICATION_REQUIRED /
            INVALID_API_KEY)
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: >-
            La cuenta está suspendida (ACCOUNT_SUSPENDED). Un recurso de otra
            cuenta NO responde 403: responde 404, igual que uno que no existe.
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: No existe un export de esta cuenta con ese id (EXPORT_NOT_FOUND)
        '429':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: >-
            Límite de requests por minuto excedido (RATE_LIMIT_EXCEEDED). Ver
            headers X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
            y Retry-After.
        '503':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: >-
            El almacenamiento de documentos no está disponible; reintenta en
            unos momentos
components:
  schemas:
    ExportResponse:
      description: Estado de un export masivo de XML
      properties:
        completedAt:
          description: Cuándo terminó de generarse o de fallar.
          format: date-time
          type: string
        createdAt:
          description: Cuándo se pidió el export.
          format: date-time
          type: string
        desde:
          description: Primer día del rango, inclusive.
          example: '2026-08-01'
          format: date
          type: string
        errorCode:
          description: >-
            Por qué falló, cuando el estatus es `fallido`. Código estable; el
            texto de `error_message` es informativo y no debe parsearse.
          example: EXPORT_TOO_LARGE
          type: string
        errorMessage:
          description: Descripción del fallo, para quien lo lea.
          type: string
        estatus:
          description: >-
            `pendiente` (en cola), `en_proceso` (armando el archivo), `listo`
            (descargable) o `fallido`.
          example: pendiente
          type: string
        expirado:
          description: >-
            `true` cuando el export se generó correctamente pero su archivo ya
            se borró por la política de retención. No es un error: hay que
            volver a pedir el export.
          example: false
          type: boolean
        hasta:
          description: Último día del rango, inclusive.
          example: '2026-08-31'
          format: date
          type: string
        id:
          description: >-
            Id del export. Es lo que se debe almacenar: la URL de descarga se
            vuelve a pedir con él.
          example: 9a4f07ff-3abc-435f-b7a6-88c2bc65b4c1
          format: uuid
          type: string
        rfcEmisor:
          description: Emisor al que se limitó el export, si se pidió así.
          example: EKU9003173C9
          type: string
        tamanoBytes:
          description: Tamaño del ZIP en bytes. Sólo cuando el export está `listo`.
          example: 5242880
          format: int64
          type: integer
        totalCfdis:
          description: >-
            CFDIs incluidos en el archivo. Sólo cuando el export está `listo`.
            Puede ser 0: un rango sin CFDIs produce un ZIP válido y vacío.
          example: 1043
          format: int32
          type: integer
        url:
          description: >-
            URL firmada, de solo lectura, con vigencia de 15 minutos desde que
            se genera. No la almacenes: guarda el `id` y vuelve a llamar a `GET
            /cfdi/exports/{id}`. El ZIP contiene un XML por CFDI, nombrado por
            folio fiscal, más un `manifiesto.csv` que los relaciona con serie,
            folio, receptor, total y estatus.
          example: https://storage.ipsofactura.com/exports/9a4f07ff.zip?sig=...
          type: string
      type: object
    ErrorResponse:
      properties:
        code:
          description: >-
            Código de error de ipsofactura. Estable y cerrado (catálogo
            ErrorCode), pero deliberadamente grueso: TODO rechazo de validación
            del SAT llega como VALIDATION_ERROR. Úsalo para decidir el flujo
            general (reintentar, autenticar de nuevo, corregir el comprobante).
          example: VALIDATION_ERROR
          type: string
        id:
          type: string
        idempotencyKey:
          type: string
        message:
          description: >-
            Descripción legible del error, en texto libre. NO la parsees: cuando
            el rechazo viene del SAT, este texto lo redacta el PAC, cambia entre
            proveedores y puede cambiar sin previo aviso. Para ramificar por
            regla del SAT usa sat_code; para ramificar por tipo de error usa
            code. El mensaje es para mostrarlo o registrarlo.
          example: >-
            CFDI40147: El RFC del receptor no se encuentra en la lista de
            contribuyentes inscritos no cancelados del SAT
          type: string
        retryAfter:
          format: int32
          type: integer
        sat_code:
          description: >-
            Código del SAT del rechazo. Presente SÓLO cuando el rechazo viene
            del SAT a través de un PAC; null en errores propios de ipsofactura
            (validación local, autenticación, rate limit, servicio no
            disponible). Es específico donde `code` es genérico: `code` te dice
            que hubo un rechazo de validación, `sat_code` te dice exactamente
            qué rechazó el SAT. Dos formas según la operación: `CFDIxxxxx`
            cuando el SAT rechaza un timbrado, y el código de tres dígitos de
            cancelación (203 a 212) cuando rechaza una cancelación. También es
            null si el PAC no devolvió ningún código: nunca se inventa uno.
          example: CFDI40147
          type: string
  securitySchemes:
    apiKeyAuth:
      description: API key emitida por Ipsofactura, enviada en el header x-api.
      in: header
      name: x-api
      type: apiKey

````