> ## 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.

# Create an invoice

> Build and stamp a CFDI 4.0 from friendly JSON. The issuer comes from `fiscal_profile_id` (the only body field the schema hard-requires); every other field is validated in the service, which returns a precise error with remediation if something is missing or wrong. Required for type I (ingreso) and E (egreso): `customer` and at least one `items` line, each with `product_key`, `unit_key`, `quantity`, and `unit_price`, plus `payment_form` and `payment_method` (PUE|PPD; PPD forces payment_form "99"), and a `use` (invoice-level or `customer.use`). Type E (nota de crédito) also requires `relation` ({ type "01" or "03", uuids }). Type P (pago): omit `items`/`payment_form`/`payment_method` and supply `payments` (complemento de pagos 2.0). Set `draft: true` to hold a signed draft and stamp it later. Send an Idempotency-Key to make retries safe.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/invoices
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/invoices:
    post:
      tags:
        - invoices
      summary: Create an invoice
      description: >-
        Build and stamp a CFDI 4.0 from friendly JSON. The issuer comes from
        `fiscal_profile_id` (the only body field the schema hard-requires);
        every other field is validated in the service, which returns a precise
        error with remediation if something is missing or wrong. Required for
        type I (ingreso) and E (egreso): `customer` and at least one `items`
        line, each with `product_key`, `unit_key`, `quantity`, and `unit_price`,
        plus `payment_form` and `payment_method` (PUE|PPD; PPD forces
        payment_form "99"), and a `use` (invoice-level or `customer.use`). Type
        E (nota de crédito) also requires `relation` ({ type "01" or "03", uuids
        }). Type P (pago): omit `items`/`payment_form`/`payment_method` and
        supply `payments` (complemento de pagos 2.0). Set `draft: true` to hold
        a signed draft and stamp it later. Send an Idempotency-Key to make
        retries safe.
      parameters:
        - schema:
            anyOf:
              - type: string
              - type: array
                items:
                  type: string
          in: query
          name: expand
          required: false
          description: Comma-separated related objects to inline, e.g. "fiscal_profile".
        - schema:
            anyOf:
              - type: string
              - type: array
                items:
                  type: string
          in: query
          name: expand[]
          required: false
          description: Bracket-array form of `expand`, e.g. ?expand[]=fiscal_profile.
        - $ref: '#/components/parameters/InvoiceVersion'
        - $ref: '#/components/parameters/InvoiceAccount'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                type:
                  default: I
                  description: >-
                    CFDI TipoDeComprobante: "I" ingreso (default), "E" egreso
                    (nota de crédito), "P" pago.
                  type: string
                  enum:
                    - I
                    - E
                    - P
                serie:
                  description: CFDI Serie (optional invoice series prefix).
                  type: string
                  minLength: 1
                  maxLength: 25
                folio:
                  description: CFDI Folio; auto-assigned when omitted.
                  type: string
                  minLength: 1
                  maxLength: 40
                date:
                  description: >-
                    CFDI Fecha, ISO-8601; defaults to now at build time. Must be
                    within the past 72 hours.
                  type: string
                payment_form:
                  description: >-
                    c_FormaPago code (FormaPago), e.g. "01" efectivo, "03"
                    transferencia, "99" por definir. Required for type I/E;
                    forced to "99" when payment_method is PPD. See GET
                    /v1/catalogs/payment_forms (or the SAT catalogs guide) for
                    each code's meaning.
                  type: string
                  enum:
                    - '01'
                    - '02'
                    - '03'
                    - '04'
                    - '05'
                    - '06'
                    - '08'
                    - '12'
                    - '13'
                    - '14'
                    - '15'
                    - '17'
                    - '23'
                    - '24'
                    - '25'
                    - '26'
                    - '27'
                    - '28'
                    - '29'
                    - '30'
                    - '31'
                    - '99'
                payment_method:
                  description: >-
                    c_MetodoPago: "PUE" pago en una sola exhibición or "PPD"
                    pago en parcialidades o diferido. Required for type I/E.
                  type: string
                  enum:
                    - PUE
                    - PPD
                currency:
                  default: MXN
                  description: >-
                    c_Moneda currency code (Moneda), e.g. "MXN" (default) or
                    "USD". See GET /v1/catalogs/currencies (or the SAT catalogs
                    guide) for each code's meaning.
                  type: string
                  enum:
                    - MXN
                    - USD
                    - EUR
                    - CAD
                    - GBP
                    - JPY
                    - CHF
                    - CNY
                    - AUD
                    - BRL
                    - ARS
                    - COP
                    - CLP
                    - PEN
                    - DKK
                    - SEK
                    - NOK
                    - HKD
                    - SGD
                    - NZD
                    - KRW
                    - XXX
                exchange_rate:
                  description: >-
                    TipoCambio: MXN per 1 unit of currency; required when
                    currency is neither MXN nor XXX.
                  anyOf:
                    - type: string
                      pattern: ^-?\d+(\.\d+)?$
                    - type: number
                use:
                  description: >-
                    c_UsoCFDI code (UsoCFDI), e.g. "G03"; falls back to
                    customer.use. Required for type I/E. See GET
                    /v1/catalogs/uso_cfdi (or the SAT catalogs guide) for each
                    code's meaning.
                  type: string
                  enum:
                    - G01
                    - G02
                    - G03
                    - I01
                    - I02
                    - I03
                    - I04
                    - I05
                    - I06
                    - I07
                    - I08
                    - D01
                    - D02
                    - D03
                    - D04
                    - D05
                    - D06
                    - D07
                    - D08
                    - D09
                    - D10
                    - S01
                    - CP01
                    - CN01
                export:
                  default: '01'
                  description: >-
                    c_Exportacion code (Exportacion). Default "01" (no aplica);
                    other codes need the Comercio Exterior complement (not
                    supported in v1). See GET /v1/catalogs/export_types (or the
                    SAT catalogs guide) for each code's meaning.
                  type: string
                  enum:
                    - '01'
                    - '02'
                    - '03'
                    - '04'
                relation:
                  description: >-
                    CFDI relation (CfdiRelacionados). Required for type E (nota
                    de crédito).
                  type: object
                  properties:
                    type:
                      type: string
                      description: >-
                        c_TipoRelacion code, e.g. "01" nota de crédito, "03"
                        devolución, "04" sustitución. See GET
                        /v1/catalogs/relation_types (or the SAT catalogs guide)
                        for each code's meaning.
                      enum:
                        - '01'
                        - '02'
                        - '03'
                        - '04'
                        - '05'
                        - '06'
                        - '07'
                    uuids:
                      minItems: 1
                      type: array
                      items:
                        type: string
                        pattern: >-
                          ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$
                      description: The related CFDI UUIDs (RFC-4122 folios fiscales).
                  required:
                    - type
                    - uuids
                customer:
                  type: object
                  properties:
                    rfc:
                      description: >-
                        Customer RFC (12/13 chars, or generic XAXX010101000
                        público en general / XEXX010101000 foreign).
                      type: string
                    name:
                      type: string
                      minLength: 1
                      maxLength: 254
                      description: >-
                        Customer legal name (razón social) exactly as on their
                        Constancia de Situación Fiscal.
                    zip:
                      type: string
                      pattern: ^\d{5}$
                      description: >-
                        Customer fiscal-domicile ZIP (DomicilioFiscalReceptor),
                        exactly 5 digits.
                    tax_regime:
                      type: string
                      description: >-
                        Customer c_RegimenFiscal code, e.g. "616" (sin
                        obligaciones fiscales). See GET /v1/catalogs/tax_regimes
                        (or the SAT catalogs guide) for each code's meaning.
                      enum:
                        - '601'
                        - '603'
                        - '605'
                        - '606'
                        - '607'
                        - '608'
                        - '610'
                        - '611'
                        - '612'
                        - '614'
                        - '615'
                        - '616'
                        - '620'
                        - '621'
                        - '622'
                        - '623'
                        - '624'
                        - '625'
                        - '626'
                    use:
                      description: >-
                        Customer c_UsoCFDI code, e.g. "G03" (gastos en general);
                        the invoice-level `use` is the fallback. See GET
                        /v1/catalogs/uso_cfdi (or the SAT catalogs guide) for
                        each code's meaning.
                      type: string
                      enum:
                        - G01
                        - G02
                        - G03
                        - I01
                        - I02
                        - I03
                        - I04
                        - I05
                        - I06
                        - I07
                        - I08
                        - D01
                        - D02
                        - D03
                        - D04
                        - D05
                        - D06
                        - D07
                        - D08
                        - D09
                        - D10
                        - S01
                        - CP01
                        - CN01
                    residence_country:
                      description: >-
                        c_Pais code for foreign receptors (ResidenciaFiscal),
                        e.g. "USA"; required with num_reg_id_trib.
                      type: string
                      minLength: 3
                      maxLength: 3
                    num_reg_id_trib:
                      description: >-
                        Foreign tax registration id (NumRegIdTrib) for
                        non-Mexican receptors.
                      type: string
                      minLength: 1
                      maxLength: 40
                  required:
                    - rfc
                    - name
                    - zip
                    - tax_regime
                  description: Customer (Receptor) — who the invoice is for.
                items:
                  default: []
                  description: >-
                    Line items (Conceptos). Required for type I/E; must be empty
                    for type P.
                  type: array
                  items:
                    type: object
                    properties:
                      product_key:
                        type: string
                        pattern: ^\d{8}$
                        description: >-
                          8-digit SAT c_ClaveProdServ, e.g. "80141600".
                          Validated against the catalog.
                      unit_key:
                        type: string
                        pattern: ^[A-Z0-9]{1,3}$
                        description: >-
                          1-3 char uppercase SAT c_ClaveUnidad, e.g. "H87"
                          (pieza) or "E48" (unidad de servicio).
                      unit_name:
                        description: >-
                          Human-readable unit label (Unidad), e.g. "Pieza";
                          derived from unit_key when omitted.
                        type: string
                        minLength: 1
                        maxLength: 20
                      description:
                        type: string
                        minLength: 1
                        maxLength: 1000
                        description: >-
                          Free-text line description (Descripción), e.g.
                          "Consultoría".
                      quantity:
                        anyOf:
                          - type: string
                            pattern: ^-?\d+(\.\d+)?$
                          - type: number
                        description: >-
                          Quantity (Cantidad), a positive decimal, e.g. "1" or
                          "2.5".
                      unit_price:
                        anyOf:
                          - type: string
                            pattern: ^-?\d+(\.\d+)?$
                          - type: number
                        description: >-
                          Unit price before taxes (ValorUnitario), decimal
                          string, e.g. "100.00".
                      discount:
                        description: >-
                          Per-line discount amount (Descuento), decimal string,
                          e.g. "10.00".
                        anyOf:
                          - type: string
                            pattern: ^-?\d+(\.\d+)?$
                          - type: number
                      sku:
                        description: Internal SKU / product code (NoIdentificacion).
                        type: string
                        minLength: 1
                        maxLength: 100
                      tax_object:
                        description: >-
                          c_ObjetoImp: "01" no objeto de impuesto, "02" sí
                          objeto, "03" sí objeto y no obligado al desglose, "04"
                          sí objeto y no causa impuesto. Defaults to "02" when
                          taxes present, "01" when none. See GET
                          /v1/catalogs/tax_objects (or the SAT catalogs guide)
                          for each code's meaning.
                        type: string
                        enum:
                          - '01'
                          - '02'
                          - '03'
                          - '04'
                      taxes:
                        description: >-
                          Per-line taxes. Defaults to 16% IVA traslado when
                          omitted.
                        type: array
                        items:
                          type: object
                          properties:
                            type:
                              type: string
                              enum:
                                - IVA
                                - ISR
                                - IEPS
                              description: >-
                                Tax type: "IVA", "ISR", or "IEPS" (maps to the
                                SAT c_Impuesto code).
                            rate:
                              description: >-
                                Tasa/Cuota rate as a decimal, e.g. "0.160000"
                                for 16% IVA. Omitted/ignored for factor
                                "Exento".
                              anyOf:
                                - type: string
                                  pattern: ^-?\d+(\.\d+)?$
                                - type: number
                            factor:
                              default: Tasa
                              description: >-
                                c_TipoFactor: "Tasa" (percentage), "Cuota"
                                (fixed per unit), or "Exento" (exempt). Default
                                "Tasa".
                              type: string
                              enum:
                                - Tasa
                                - Cuota
                                - Exento
                            withholding:
                              default: false
                              description: >-
                                true = retención (withholding); false/absent =
                                traslado (default).
                              type: boolean
                          required:
                            - type
                      tax_included:
                        default: false
                        description: >-
                          When true, unit_price already includes taxes and the
                          taxable base is back-computed. Default false.
                        type: boolean
                    required:
                      - product_key
                      - unit_key
                      - description
                      - quantity
                      - unit_price
                payments:
                  description: >-
                    Complemento de pagos 2.0 entries. Required for and only
                    valid on type P.
                  type: array
                  items:
                    type: object
                    properties:
                      date:
                        type: string
                        description: >-
                          Payment date/time (FechaPago), ISO-8601, e.g.
                          "2026-07-01T12:00:00".
                      form:
                        type: string
                        description: >-
                          c_FormaPago of the actual payment (FormaDePagoP), e.g.
                          "03" transferencia; cannot be "99".
                      currency:
                        default: MXN
                        description: >-
                          c_Moneda of the payment (MonedaP), a real currency
                          (not XXX). Default "MXN".
                        type: string
                      exchange_rate:
                        description: >-
                          TipoCambioP: MXN per 1 unit of MonedaP; required when
                          MonedaP ≠ MXN.
                        anyOf:
                          - type: string
                            pattern: ^-?\d+(\.\d+)?$
                          - type: number
                      amount:
                        anyOf:
                          - type: string
                            pattern: ^-?\d+(\.\d+)?$
                          - type: number
                        description: Total amount of this payment (Monto), decimal string.
                      num_operation:
                        description: >-
                          Payment reference number (NumOperacion), e.g. a
                          transfer id.
                        type: string
                        minLength: 1
                        maxLength: 100
                      related_documents:
                        minItems: 1
                        type: array
                        items:
                          type: object
                          properties:
                            uuid:
                              type: string
                              pattern: >-
                                ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$
                              description: >-
                                UUID of the invoice being paid (IdDocumento /
                                folio fiscal).
                            serie:
                              description: Serie of the related document (SerieDR).
                              type: string
                              minLength: 1
                              maxLength: 25
                            folio:
                              description: Folio of the related document (FolioDR).
                              type: string
                              minLength: 1
                              maxLength: 40
                            currency:
                              type: string
                              description: >-
                                c_Moneda of the related document (MonedaDR),
                                e.g. "MXN".
                            equivalence:
                              description: >-
                                EquivalenciaDR: units of MonedaDR per 1 MonedaP;
                                "1" when they are equal. Required when MonedaDR
                                ≠ MonedaP.
                              anyOf:
                                - type: string
                                  pattern: ^-?\d+(\.\d+)?$
                                - type: number
                            installment:
                              type: integer
                              exclusiveMinimum: 0
                              maximum: 9007199254740991
                              description: >-
                                Payment installment number (NumParcialidad),
                                1-based.
                            previous_balance:
                              anyOf:
                                - type: string
                                  pattern: ^-?\d+(\.\d+)?$
                                - type: number
                              description: >-
                                Balance before this payment (ImpSaldoAnt),
                                decimal string.
                            amount_paid:
                              anyOf:
                                - type: string
                                  pattern: ^-?\d+(\.\d+)?$
                                - type: number
                              description: >-
                                Amount applied to this document (ImpPagado),
                                decimal string.
                            outstanding_balance:
                              anyOf:
                                - type: string
                                  pattern: ^-?\d+(\.\d+)?$
                                - type: number
                              description: >-
                                Balance after this payment (ImpSaldoInsoluto),
                                decimal string.
                            tax_object:
                              type: string
                              enum:
                                - '01'
                                - '02'
                                - '03'
                                - '04'
                              description: >-
                                c_ObjetoImp of the related document
                                (ObjetoImpDR), e.g. "02" sí objeto de impuesto.
                            taxes:
                              description: >-
                                Taxes carried by the related document
                                (ImpuestosDR).
                              type: array
                              items:
                                type: object
                                properties:
                                  type:
                                    type: string
                                    enum:
                                      - IVA
                                      - ISR
                                      - IEPS
                                    description: 'Tax type: "IVA", "ISR", or "IEPS".'
                                  base:
                                    anyOf:
                                      - type: string
                                        pattern: ^-?\d+(\.\d+)?$
                                      - type: number
                                    description: >-
                                      Taxable base for this tax (BaseDR),
                                      decimal string.
                                  rate:
                                    description: >-
                                      Tasa/Cuota rate as a decimal, e.g.
                                      "0.160000". Omitted for "Exento".
                                    anyOf:
                                      - type: string
                                        pattern: ^-?\d+(\.\d+)?$
                                      - type: number
                                  factor:
                                    default: Tasa
                                    description: >-
                                      c_TipoFactor: "Tasa", "Cuota", or
                                      "Exento". Default "Tasa".
                                    type: string
                                    enum:
                                      - Tasa
                                      - Cuota
                                      - Exento
                                  amount:
                                    description: >-
                                      Tax amount (ImporteDR), decimal string;
                                      computed from base × rate when omitted.
                                    anyOf:
                                      - type: string
                                        pattern: ^-?\d+(\.\d+)?$
                                      - type: number
                                  withholding:
                                    default: false
                                    description: >-
                                      true = retención; false = traslado
                                      (default).
                                    type: boolean
                                required:
                                  - type
                                  - base
                          required:
                            - uuid
                            - currency
                            - installment
                            - previous_balance
                            - amount_paid
                            - outstanding_balance
                            - tax_object
                        description: >-
                          The invoices this payment settles (at least one
                          DoctoRelacionado).
                    required:
                      - date
                      - form
                      - amount
                      - related_documents
                global_information:
                  description: >-
                    InformacionGlobal for a factura global (público en general
                    XAXX010101000).
                  type: object
                  properties:
                    periodicity:
                      type: string
                      description: >-
                        c_Periodicidad code, e.g. "01" diario, "04" mensual
                        (factura global público en general).
                    months:
                      type: string
                      pattern: ^(0[1-9]|1[0-8])$
                      description: >-
                        c_Meses code: "01"-"12" for a month, "13"-"18" for a
                        bimester.
                    year:
                      type: integer
                      minimum: 2021
                      maximum: 2099
                      description: Four-digit fiscal year of the global invoice, e.g. 2026.
                  required:
                    - periodicity
                    - months
                    - year
                fiscal_profile_id:
                  type: string
                  minLength: 1
                  description: >-
                    Id of the fiscal profile (issuer) to stamp with, e.g.
                    "fp_2P9K3sample".
                draft:
                  description: >-
                    Hold the invoice as a signed draft instead of stamping it
                    immediately (default false).
                  type: boolean
                metadata:
                  description: >-
                    Integrator-owned key-value map (≤50 keys), stored and echoed
                    back verbatim.
                  type: object
                  propertyNames:
                    type: string
                    minLength: 1
                    maxLength: 40
                  additionalProperties:
                    type: string
                    maxLength: 500
              required:
                - fiscal_profile_id
              additionalProperties: {}
            example:
              fiscal_profile_id: fp_2P9K3sample
              type: I
              customer:
                rfc: XAXX010101000
                name: PUBLICO EN GENERAL
                tax_regime: '616'
                postal_code: '06000'
                cfdi_use: S01
              items:
                - product_key: '01010101'
                  unit_key: H87
                  description: Consultoria
                  quantity: '1'
                  unit_price: '100.00'
                  taxes:
                    - type: IVA
                      rate: '0.160000'
                      factor: Tasa
              payment_form: '03'
              payment_method: PUE
              metadata:
                order_id: ord_1789
      responses:
        '201':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                properties:
                  object:
                    type: string
                    description: Always "invoice".
                    enum:
                      - invoice
                  id:
                    type: string
                    description: Invoice id, e.g. "inv_2P9K3sample".
                  livemode:
                    type: boolean
                    description: True if stamped with a live-mode key against the real SAT.
                  status:
                    type: string
                    enum:
                      - draft
                      - stamping
                      - stamped
                      - stamp_failed
                    description: >-
                      Lifecycle status: draft, stamping (in flight), stamped, or
                      stamp_failed.
                  type:
                    type: string
                    enum:
                      - I
                      - E
                      - P
                    description: >-
                      CFDI TipoDeComprobante: "I" ingreso, "E" egreso (nota de
                      crédito), "P" pago.
                  fiscal_profile_id:
                    type: string
                    description: >-
                      Id of the fiscal profile (issuer) that stamped this
                      invoice.
                  serie:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: CFDI Serie, or null if unset.
                  folio:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: CFDI Folio, or null if unset.
                  customer:
                    type: object
                    properties:
                      rfc:
                        type: string
                        description: Customer (receptor) RFC.
                      name:
                        type: string
                        description: Customer legal name (razón social).
                      zip:
                        anyOf:
                          - type: string
                          - type: 'null'
                        description: >-
                          Customer fiscal-domicile ZIP
                          (DomicilioFiscalReceptor).
                      tax_regime:
                        anyOf:
                          - type: string
                          - type: 'null'
                        description: Customer c_RegimenFiscal code.
                      use:
                        anyOf:
                          - type: string
                          - type: 'null'
                        description: Customer c_UsoCFDI code, e.g. "G03".
                    required:
                      - rfc
                      - name
                      - zip
                      - tax_regime
                      - use
                    additionalProperties: false
                    description: The receptor (customer) as stamped onto the CFDI.
                  currency:
                    type: string
                    description: c_Moneda currency code, e.g. "MXN".
                  subtotal:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: >-
                      Sum of line amounts before taxes, decimal string, e.g.
                      "100.00".
                  total:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: >-
                      Grand total including taxes, decimal string, e.g.
                      "116.00".
                  uuid:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: SAT folio fiscal (UUID) once stamped, else null.
                  stamped_at:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: When the CFDI was stamped (ISO-8601 UTC), or null.
                  sello_cfd:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: Issuer digital seal (Sello del CFDI), or null.
                  sello_sat:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: SAT digital seal from the TimbreFiscalDigital, or null.
                  no_certificado_sat:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: SAT certificate serial that timbró the CFDI, or null.
                  cancellation:
                    type: object
                    properties:
                      status:
                        type: string
                        enum:
                          - none
                          - cancel_pending
                          - cancelled
                          - cancel_rejected
                        description: >-
                          Cancellation state: "none" not requested,
                          "cancel_pending" awaiting receptor/SAT, "cancelled"
                          done, "cancel_rejected" receptor rejected.
                      reason:
                        anyOf:
                          - type: string
                          - type: 'null'
                        description: >-
                          SAT motivo de cancelación (01-04) if requested, else
                          null.
                      substitute_invoice_id:
                        anyOf:
                          - type: string
                          - type: 'null'
                        description: >-
                          Replacement CFDI id when cancelled with reason "01",
                          else null.
                      acuse_available:
                        type: boolean
                        description: True when the SAT acuse de cancelación is retrievable.
                    required:
                      - status
                      - reason
                      - substitute_invoice_id
                      - acuse_available
                    additionalProperties: false
                    description: Cancellation status for this CFDI.
                  error:
                    anyOf:
                      - {}
                      - type: 'null'
                    description: >-
                      The last stamping error (problem+json shape) when status
                      is stamp_failed, else null.
                  xml_url:
                    type: string
                    description: >-
                      Path to download the CFDI XML, e.g.
                      "/v1/invoices/:id/xml".
                  pdf_url:
                    type: string
                    description: >-
                      Path to download the CFDI PDF, e.g.
                      "/v1/invoices/:id/pdf".
                  metadata:
                    type: object
                    propertyNames:
                      type: string
                    additionalProperties:
                      type: string
                    description: Integrator-owned key-value map echoed back.
                  fiscal_profile:
                    description: >-
                      The full issuer profile — present only when
                      `?expand=fiscal_profile` is requested.
                    type: object
                    properties:
                      object:
                        type: string
                        description: Always "fiscal_profile".
                        enum:
                          - fiscal_profile
                      id:
                        type: string
                        description: Fiscal-profile id, e.g. "fp_2P9K3sample".
                      rfc:
                        type: string
                        description: Issuer RFC, derived from the CSD certificate.
                      legal_name:
                        type: string
                        description: Issuer legal name (razón social).
                      tax_regime:
                        type: string
                        description: c_RegimenFiscal code of the issuer, e.g. "601".
                      zip:
                        type: string
                        description: Issuer fiscal-domicile ZIP (LugarExpedicion).
                      csd:
                        type: object
                        properties:
                          serial:
                            type: string
                            description: >-
                              CSD certificate serial number (número de
                              certificado).
                          valid_from:
                            type: string
                            description: CSD validity start, ISO-8601 UTC.
                          valid_to:
                            type: string
                            description: CSD validity end (expiry), ISO-8601 UTC.
                          rfc:
                            type: string
                            description: RFC embedded in the CSD certificate.
                        required:
                          - serial
                          - valid_from
                          - valid_to
                          - rfc
                        additionalProperties: false
                        description: >-
                          Public metadata of the stored CSD (never the private
                          key).
                      status:
                        type: string
                        enum:
                          - requires_action
                          - active
                        description: >-
                          Derived readiness state. "requires_action": the carta
                          manifiesto is not yet signed, so this profile CANNOT
                          stamp CFDIs. "active": the manifiesto is signed and
                          the profile is authorized to stamp for its RFC.
                          Derived from manifest_status at serialization time.
                      has_fiel:
                        type: boolean
                        description: >-
                          True when a FIEL (e.firma) is stored (used to sign the
                          carta manifiesto and for descarga masiva).
                      manifest_status:
                        type: string
                        enum:
                          - pending_signature
                          - signed
                        description: Carta-manifiesto signing state.
                      manifest_signed_at:
                        anyOf:
                          - type: string
                          - type: 'null'
                        description: >-
                          When the carta manifiesto was signed (ISO-8601 UTC),
                          or null if unsigned.
                      next_actions:
                        type: array
                        items:
                          type: object
                          properties:
                            type:
                              type: string
                              description: >-
                                Stable, machine-readable action identifier, e.g.
                                "sign_manifest".
                            message:
                              type: string
                              description: >-
                                Human- and agent-readable explanation of what to
                                do and why.
                            endpoint:
                              type: string
                              description: >-
                                The exact API call that performs the action,
                                e.g. "POST /v1/fiscal_profiles/fp_123/manifest".
                            requires:
                              type: array
                              items:
                                type: string
                              description: >-
                                Inputs the action needs, e.g. ["fiel"] — the
                                taxpayer's FIEL (e.firma).
                          required:
                            - type
                            - message
                            - endpoint
                            - requires
                          additionalProperties: false
                        description: >-
                          Actions to make this profile active (identical content
                          to pending_actions). Empty when active.
                      pending_actions:
                        type: array
                        items:
                          type: object
                          properties:
                            type:
                              type: string
                              description: >-
                                Stable, machine-readable action identifier, e.g.
                                "sign_manifest".
                            message:
                              type: string
                              description: >-
                                Human- and agent-readable explanation of what to
                                do and why.
                            endpoint:
                              type: string
                              description: >-
                                The exact API call that performs the action,
                                e.g. "POST /v1/fiscal_profiles/fp_123/manifest".
                            requires:
                              type: array
                              items:
                                type: string
                              description: >-
                                Inputs the action needs, e.g. ["fiel"] — the
                                taxpayer's FIEL (e.firma).
                          required:
                            - type
                            - message
                            - endpoint
                            - requires
                          additionalProperties: false
                        description: >-
                          Outstanding actions before this profile can stamp
                          CFDIs (identical content to next_actions). Empty when
                          active.
                      metadata:
                        type: object
                        propertyNames:
                          type: string
                        additionalProperties:
                          type: string
                        description: Integrator-owned key-value map echoed back.
                      brand_color:
                        anyOf:
                          - type: string
                          - type: 'null'
                        description: PDF accent color (#RRGGBB), or null if unset.
                      has_logo:
                        type: boolean
                        description: >-
                          Whether a PDF logo is stored (the raw data URL is not
                          echoed to keep responses small).
                      livemode:
                        type: boolean
                        description: True if this profile was created with a live-mode key.
                      created_at:
                        type: string
                        description: Creation timestamp, ISO-8601 UTC.
                      updated_at:
                        type: string
                        description: Last-update timestamp, ISO-8601 UTC.
                    required:
                      - object
                      - id
                      - rfc
                      - legal_name
                      - tax_regime
                      - zip
                      - csd
                      - status
                      - has_fiel
                      - manifest_status
                      - manifest_signed_at
                      - next_actions
                      - pending_actions
                      - metadata
                      - brand_color
                      - has_logo
                      - livemode
                      - created_at
                      - updated_at
                    additionalProperties: false
                  created_at:
                    type: string
                    description: Creation timestamp, ISO-8601 UTC.
                  updated_at:
                    type: string
                    description: Last-update timestamp, ISO-8601 UTC.
                required:
                  - object
                  - id
                  - livemode
                  - status
                  - type
                  - fiscal_profile_id
                  - serie
                  - folio
                  - customer
                  - currency
                  - subtotal
                  - total
                  - uuid
                  - stamped_at
                  - sello_cfd
                  - sello_sat
                  - no_certificado_sat
                  - cancellation
                  - error
                  - xml_url
                  - pdf_url
                  - metadata
                  - created_at
                  - updated_at
                additionalProperties: false
              example:
                object: invoice
                id: obj_2P9K3sample
                livemode: false
                status: draft
                type: I
                fiscal_profile_id: fp_2P9K3sample
                serie: string
                folio: string
                customer:
                  rfc: XAXX010101000
                  name: string
                  zip: string
                  tax_regime: string
                  use: string
                currency: MXN
                subtotal: '116.00'
                total: '116.00'
                uuid: 5FB2822E-396D-4725-8521-CDC4BDD20CCF
                stamped_at: '2026-07-10T18:25:43Z'
                sello_cfd: string
                sello_sat: string
                no_certificado_sat: string
                cancellation:
                  status: none
                  reason: string
                  substitute_invoice_id: inv_2P9K3sample
                  acuse_available: true
                error: string
                xml_url: https://example.com/webhooks/invoice
                pdf_url: https://example.com/webhooks/invoice
                metadata: {}
                fiscal_profile:
                  object: fiscal_profile
                  id: obj_2P9K3sample
                  rfc: XAXX010101000
                  legal_name: string
                  tax_regime: string
                  zip: string
                  csd:
                    serial: string
                    valid_from: string
                    valid_to: string
                    rfc: XAXX010101000
                  status: requires_action
                  has_fiel: true
                  manifest_status: pending_signature
                  manifest_signed_at: '2026-07-10T18:25:43Z'
                  next_actions:
                    - type: string
                      message: string
                      endpoint: string
                      requires:
                        - string
                  pending_actions:
                    - type: string
                      message: string
                      endpoint: string
                      requires:
                        - string
                  metadata: {}
                  brand_color: string
                  has_logo: true
                  livemode: false
                  created_at: '2026-07-10T18:25:43Z'
                  updated_at: '2026-07-10T18:25:43Z'
                created_at: '2026-07-10T18:25:43Z'
                updated_at: '2026-07-10T18:25:43Z'
          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/invoice_already_stamped
                title: Invoice already stamped
                status: 409
                code: invoice.already_stamped
                detail: This invoice is already stamped.
                remediation: Fetch the stamped invoice; do not re-stamp.
                doc_url: /docs/errors#invoice-already_stamped
                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/cfdi_invalid_input
                title: Invalid invoice
                status: 422
                code: cfdi.invalid_input
                detail: 'items.0.unit_price: expected a decimal string.'
                remediation: >-
                  Fix every field listed in `errors` and resubmit. See
                  /openapi.json for the schema.
                doc_url: /docs/errors#cfdi-invalid_input
                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'
        '502':
          description: PAC/SAT transient failure.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
              example:
                type: https://errors.invoiceapi.mx/pac_internal_error
                title: PAC internal error
                status: 502
                code: pac.internal_error
                detail: The stamping service reported a transient internal error.
                remediation: >-
                  Retry with backoff; idempotency guards against duplicate
                  stamps.
                doc_url: /docs/errors#pac-internal_error
                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_...`.'

````