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

# Request a massive download

> Start a SAT descarga masiva for issued or received CFDIs over a date range, as full XML or a metadata index. Requires a signed carta manifiesto on the fiscal profile. Note the SAT limits: only 2 identical lifetime requests, 200k XML cap, and package URLs expire in ~5 minutes — fragment wide ranges rather than retrying.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/downloads
openapi: 3.1.0
info:
  title: Invoice API
  description: >-
    Mexican CFDI 4.0 invoicing API. Versioned via the Invoice-Version header;
    current: 2026-07-15. See GET /v1/versions.
  version: 0.1.0
servers:
  - url: https://api.newinvoice.dev
    description: Production
  - url: http://localhost:3000
    description: Local development
security:
  - bearerAuth: []
tags:
  - name: api_keys
    description: Platform API-key lifecycle (create, list, revoke)
  - name: accounts
    description: 'Connect: platform-owned connected accounts (multi-tenant)'
  - name: fiscal_profiles
    description: Emitter RFC + CSD/FIEL registration
  - name: invoices
    description: Create, stamp, cancel CFDI 4.0 invoices
  - name: validations
    description: Validate arbitrary CFDI XML
  - name: downloads
    description: SAT descarga masiva jobs
  - name: webhook_endpoints
    description: HMAC-signed event delivery
  - name: events
    description: Event log
  - name: balance
    description: Remaining stamp credits
  - name: usage
    description: Metered usage records (stamps consumed)
  - name: catalogs
    description: SAT reference catalogs (uso CFDI, payment forms/methods, tax regimes, …)
  - name: docs
    description: Served documentation (error catalog + guides)
paths:
  /v1/downloads:
    post:
      tags:
        - downloads
      summary: Request a massive download
      description: >-
        Start a SAT descarga masiva for issued or received CFDIs over a date
        range, as full XML or a metadata index. Requires a signed carta
        manifiesto on the fiscal profile. Note the SAT limits: only 2 identical
        lifetime requests, 200k XML cap, and package URLs expire in ~5 minutes —
        fragment wide ranges rather than retrying.
      parameters:
        - $ref: '#/components/parameters/InvoiceVersion'
        - $ref: '#/components/parameters/InvoiceAccount'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                fiscal_profile_id:
                  type: string
                  minLength: 1
                  description: >-
                    Id of the fiscal profile whose FIEL authorizes the download,
                    e.g. "fp_2P9K3sample".
                side:
                  type: string
                  enum:
                    - issued
                    - received
                  description: >-
                    Which CFDIs to pull: "issued" (emitidos by this RFC) or
                    "received" (recibidos).
                type:
                  type: string
                  enum:
                    - cfdi
                    - metadata
                  description: >-
                    Package contents: "cfdi" (full XML files) or "metadata" (a
                    summary index only).
                date_from:
                  type: string
                  description: >-
                    Start of the range, ISO date (YYYY-MM-DD) or datetime; a
                    bare date covers from 00:00:00.
                date_to:
                  type: string
                  description: >-
                    End of the range, ISO date (YYYY-MM-DD) or datetime; a bare
                    date covers to 23:59:59.
                status_filter:
                  description: >-
                    Advisory SAT estatus filter: "active" (vigentes) or
                    "cancelled" (cancelados). Metadata-only per Prodigia.
                  type: string
                  enum:
                    - active
                    - cancelled
              required:
                - fiscal_profile_id
                - side
                - type
                - date_from
                - date_to
            example:
              fiscal_profile_id: fp_2P9K3sample
              side: received
              type: cfdi
              date_from: '2026-06-01'
              date_to: '2026-06-30'
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                properties:
                  object:
                    type: string
                    description: Always "download".
                    enum:
                      - download
                  id:
                    type: string
                    description: Download id, e.g. "dl_2P9K3sample".
                  fiscal_profile_id:
                    type: string
                    description: >-
                      Id of the fiscal profile whose FIEL authorized this
                      download.
                  livemode:
                    type: boolean
                    description: True if created with a live-mode key.
                  side:
                    type: string
                    enum:
                      - issued
                      - received
                    description: '"issued" (emitidos) or "received" (recibidos).'
                  type:
                    type: string
                    enum:
                      - cfdi
                      - metadata
                    description: '"cfdi" (full XML) or "metadata" (summary index).'
                  date_from:
                    type: string
                    description: >-
                      Start of the requested range (SAT format
                      yyyy-MM-ddTHH:mm:ss).
                  date_to:
                    type: string
                    description: >-
                      End of the requested range (SAT format
                      yyyy-MM-ddTHH:mm:ss).
                  status:
                    type: string
                    enum:
                      - requested
                      - processing
                      - ready
                      - no_data
                      - failed
                    description: >-
                      Lifecycle status: "requested", "processing", "ready"
                      (packages available), "no_data", or "failed".
                  sat_request_id:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: SAT solicitud id (IdSolicitud), or null until registered.
                  package_count:
                    type: integer
                    minimum: -9007199254740991
                    maximum: 9007199254740991
                    description: Number of downloadable packages once ready.
                  error:
                    anyOf:
                      - {}
                      - type: 'null'
                    description: >-
                      Failure detail (problem+json shape) when status is
                      "failed", else null.
                  created_at:
                    type: string
                    description: Creation timestamp, ISO-8601 UTC.
                  updated_at:
                    type: string
                    description: Last-update timestamp, ISO-8601 UTC.
                  metadata:
                    type: object
                    properties:
                      warnings:
                        type: array
                        items:
                          type: string
                        description: >-
                          Advisory warnings, e.g. about SAT lifetime/size limits
                          or a wide date range.
                    required:
                      - warnings
                    additionalProperties: false
                    description: Request-time advisory metadata.
                required:
                  - object
                  - id
                  - fiscal_profile_id
                  - livemode
                  - side
                  - type
                  - date_from
                  - date_to
                  - status
                  - sat_request_id
                  - package_count
                  - error
                  - created_at
                  - updated_at
                  - metadata
                additionalProperties: false
              example:
                object: download
                id: obj_2P9K3sample
                fiscal_profile_id: fp_2P9K3sample
                livemode: false
                side: issued
                type: cfdi
                date_from: string
                date_to: string
                status: requested
                sat_request_id: obj_2P9K3sample
                package_count: -9007199254740991
                error: string
                created_at: '2026-07-10T18:25:43Z'
                updated_at: '2026-07-10T18:25:43Z'
                metadata:
                  warnings:
                    - string
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestId'
            Invoice-Version:
              $ref: '#/components/headers/InvoiceVersionResponse'
            traceparent:
              $ref: '#/components/headers/Traceparent'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
        '201':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                properties:
                  object:
                    type: string
                    description: Always "download".
                    enum:
                      - download
                  id:
                    type: string
                    description: Download id, e.g. "dl_2P9K3sample".
                  fiscal_profile_id:
                    type: string
                    description: >-
                      Id of the fiscal profile whose FIEL authorized this
                      download.
                  livemode:
                    type: boolean
                    description: True if created with a live-mode key.
                  side:
                    type: string
                    enum:
                      - issued
                      - received
                    description: '"issued" (emitidos) or "received" (recibidos).'
                  type:
                    type: string
                    enum:
                      - cfdi
                      - metadata
                    description: '"cfdi" (full XML) or "metadata" (summary index).'
                  date_from:
                    type: string
                    description: >-
                      Start of the requested range (SAT format
                      yyyy-MM-ddTHH:mm:ss).
                  date_to:
                    type: string
                    description: >-
                      End of the requested range (SAT format
                      yyyy-MM-ddTHH:mm:ss).
                  status:
                    type: string
                    enum:
                      - requested
                      - processing
                      - ready
                      - no_data
                      - failed
                    description: >-
                      Lifecycle status: "requested", "processing", "ready"
                      (packages available), "no_data", or "failed".
                  sat_request_id:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: SAT solicitud id (IdSolicitud), or null until registered.
                  package_count:
                    type: integer
                    minimum: -9007199254740991
                    maximum: 9007199254740991
                    description: Number of downloadable packages once ready.
                  error:
                    anyOf:
                      - {}
                      - type: 'null'
                    description: >-
                      Failure detail (problem+json shape) when status is
                      "failed", else null.
                  created_at:
                    type: string
                    description: Creation timestamp, ISO-8601 UTC.
                  updated_at:
                    type: string
                    description: Last-update timestamp, ISO-8601 UTC.
                  metadata:
                    type: object
                    properties:
                      warnings:
                        type: array
                        items:
                          type: string
                        description: >-
                          Advisory warnings, e.g. about SAT lifetime/size limits
                          or a wide date range.
                    required:
                      - warnings
                    additionalProperties: false
                    description: Request-time advisory metadata.
                required:
                  - object
                  - id
                  - fiscal_profile_id
                  - livemode
                  - side
                  - type
                  - date_from
                  - date_to
                  - status
                  - sat_request_id
                  - package_count
                  - error
                  - created_at
                  - updated_at
                  - metadata
                additionalProperties: false
              example:
                object: download
                id: obj_2P9K3sample
                fiscal_profile_id: fp_2P9K3sample
                livemode: false
                side: issued
                type: cfdi
                date_from: string
                date_to: string
                status: requested
                sat_request_id: obj_2P9K3sample
                package_count: -9007199254740991
                error: string
                created_at: '2026-07-10T18:25:43Z'
                updated_at: '2026-07-10T18:25:43Z'
                metadata:
                  warnings:
                    - string
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestId'
            Invoice-Version:
              $ref: '#/components/headers/InvoiceVersionResponse'
            traceparent:
              $ref: '#/components/headers/Traceparent'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
        '401':
          description: Missing or invalid API key.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                type: https://errors.invoiceapi.mx/auth_unauthorized
                title: Authentication required
                status: 401
                code: auth.unauthorized
                detail: Missing or invalid API key.
                remediation: >-
                  Send `Authorization: Bearer sk_test_...` (or sk_live_...) with
                  a valid API key.
                doc_url: /docs/errors#auth-unauthorized
                request_id: req_2P9K3sample
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestId'
            Invoice-Version:
              $ref: '#/components/headers/InvoiceVersionResponse'
            traceparent:
              $ref: '#/components/headers/Traceparent'
        '409':
          description: Conflict (e.g. idempotency/state).
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                type: https://errors.invoiceapi.mx/idempotency_key_reuse
                title: Idempotency-Key reused with a different request body
                status: 409
                code: idempotency.key_reuse
                detail: This Idempotency-Key was already used for a different payload.
                remediation: >-
                  Reuse an Idempotency-Key only for byte-identical retries; use
                  a fresh key otherwise.
                doc_url: /docs/errors#idempotency-key_reuse
                request_id: req_2P9K3sample
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestId'
            Invoice-Version:
              $ref: '#/components/headers/InvoiceVersionResponse'
            traceparent:
              $ref: '#/components/headers/Traceparent'
        '422':
          description: Request validation failed.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                type: https://errors.invoiceapi.mx/download_invalid_range
                title: Invalid date range
                status: 422
                code: download.invalid_range
                detail: date_from must be on or before date_to.
                remediation: Provide date_from <= date_to.
                doc_url: /docs/errors#download-invalid_range
                request_id: req_2P9K3sample
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestId'
            Invoice-Version:
              $ref: '#/components/headers/InvoiceVersionResponse'
            traceparent:
              $ref: '#/components/headers/Traceparent'
        '429':
          description: Rate limit exceeded — back off per the Retry-After header.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                type: https://errors.invoiceapi.mx/rate_limit_exceeded
                title: Rate limit exceeded
                status: 429
                code: rate_limit.exceeded
                detail: >-
                  Too many requests for this key + request class (reads and
                  writes are limited separately).
                remediation: >-
                  Back off and retry after the number of seconds in the
                  Retry-After header; batch work or lower your request rate.
                doc_url: /docs/errors#rate_limit-exceeded
                request_id: req_2P9K3sample
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestId'
            Invoice-Version:
              $ref: '#/components/headers/InvoiceVersionResponse'
            traceparent:
              $ref: '#/components/headers/Traceparent'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
            Retry-After:
              $ref: '#/components/headers/RetryAfter'
        '500':
          description: Internal server error.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                type: https://errors.invoiceapi.mx/internal_error
                title: Internal server error
                status: 500
                code: internal.error
                detail: An unexpected error occurred.
                remediation: >-
                  Retry later; contact support with the request_id if it
                  persists.
                doc_url: /docs/errors#internal-error
                request_id: req_2P9K3sample
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestId'
            Invoice-Version:
              $ref: '#/components/headers/InvoiceVersionResponse'
            traceparent:
              $ref: '#/components/headers/Traceparent'
        '503':
          description: PAC/SAT temporarily down.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                type: https://errors.invoiceapi.mx/sat_download_rejected
                title: SAT rejected the solicitud
                status: 503
                code: sat.download_rejected
                detail: The descarga masiva request was rejected upstream.
                remediation: Verify the FIEL matches the requesting RFC and role.
                doc_url: /docs/errors#sat-download_rejected
                request_id: req_2P9K3sample
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestId'
            Invoice-Version:
              $ref: '#/components/headers/InvoiceVersionResponse'
            traceparent:
              $ref: '#/components/headers/Traceparent'
components:
  parameters:
    InvoiceVersion:
      name: Invoice-Version
      in: header
      required: false
      description: >-
        Pin a dated API release (Stripe-style). Omit to use the current version.
        An unknown value returns 400 `request.invalid_version`. Echoed back on
        every response.
      schema:
        type: string
        example: '2026-07-10'
    InvoiceAccount:
      name: Invoice-Account
      in: header
      required: false
      description: >-
        Connect: act on behalf of one of your connected accounts (its
        `acct_…`/`org_…` id). Omit to act as your own organization. Not honored
        on /v1/api_keys.
      schema:
        type: string
        example: org_2P9connectedacct
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      description: >-
        Safely retry any POST. The first response is stored for 24h and replayed
        byte-for-byte for identical retries (the replay adds an
        `idempotent-replayed: true` header). Reusing the key with a different
        body is 409 `idempotency.key_reuse`; an in-flight duplicate is 409
        `idempotency.key_processing`. This makes retrying a 502/429 safe — no
        duplicate stamp.
      schema:
        type: string
        example: a1b2c3d4-e5f6-4789-8abc-1234567890ab
  headers:
    RequestId:
      description: >-
        Unique id for this request. Also the `request_id` in every error body —
        log it and quote it to support; idempotency keys off it too.
      schema:
        type: string
        example: req_2P9K3sample
    InvoiceVersionResponse:
      description: >-
        The dated API version resolved for this request (request header → key
        pin → current). Echoed on every response.
      schema:
        type: string
        example: '2026-07-15'
    Traceparent:
      description: >-
        W3C Trace Context. When you send a valid `traceparent`, the response
        continues the trace (same trace-id, a fresh span-id, sampled flag).
      schema:
        type: string
        example: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
    RateLimitLimit:
      description: >-
        IETF draft rate-limit: the ceiling of the token bucket consulted for
        this request class (reads and writes have independent buckets).
      schema:
        type: integer
        example: 100
    RateLimitRemaining:
      description: 'IETF draft rate-limit: tokens left in the bucket after this request.'
      schema:
        type: integer
        example: 99
    RateLimitReset:
      description: 'IETF draft rate-limit: seconds until the bucket refills to its ceiling.'
      schema:
        type: integer
        example: 1
    RetryAfter:
      description: >-
        Seconds to wait before retrying (RFC 9110). Present on 429 and on
        retryable upstream failures.
      schema:
        type: integer
        example: 1
  schemas:
    Problem:
      type: object
      description: RFC 9457 problem+json error with agent-first extensions.
      properties:
        type:
          type: string
          format: uri
        title:
          type: string
        status:
          type: integer
        code:
          type: string
          description: Stable dotted machine code to switch on.
        detail:
          type: string
        remediation:
          type: string
          description: Actionable next step for a human or agent.
        request_id:
          type: string
        pac:
          type: object
          properties:
            provider:
              type: string
            codigo:
              type: string
            mensaje:
              type: string
        errors:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
              message:
                type: string
      required:
        - type
        - title
        - status
        - code
        - request_id
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'API key: `Authorization: Bearer sk_test_...` or `sk_live_...`.'

````