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

# Request a constancia

> Request the taxpayer's constancia de situación fiscal as a PDF, using the SAT credential saved on the fiscal profile. Requires a `verified`, unexpired credential. Answers immediately with a `pending` resource; wait for the `fiscal_document.ready` webhook or poll GET. If a request for this profile is already in flight it is returned with 200 and no new SAT job starts. In live mode one constancia per RFC is free each calendar quarter (Mexico City time), and only a delivered PDF uses it; a further request gets 402 `fiscal_document.free_quota_exceeded` before anything is sent to SAT. Test-mode and sandbox profiles get a simulated PDF that is not a SAT document, and nothing leaves this API.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/fiscal_documents
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: ticket_invoices
    description: Self-invoice merchant tickets from a photo (autofacturación)
  - name: downloads
    description: SAT descarga masiva jobs
  - name: fiscal_documents
    description: SAT documents such as the constancia
  - 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/fiscal_documents:
    post:
      tags:
        - fiscal_documents
      summary: Request a constancia
      description: >-
        Request the taxpayer's constancia de situación fiscal as a PDF, using
        the SAT credential saved on the fiscal profile. Requires a `verified`,
        unexpired credential. Answers immediately with a `pending` resource;
        wait for the `fiscal_document.ready` webhook or poll GET. If a request
        for this profile is already in flight it is returned with 200 and no new
        SAT job starts. In live mode one constancia per RFC is free each
        calendar quarter (Mexico City time), and only a delivered PDF uses it; a
        further request gets 402 `fiscal_document.free_quota_exceeded` before
        anything is sent to SAT. Test-mode and sandbox profiles get a simulated
        PDF that is not a SAT document, and nothing leaves this API.
      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: >-
                    Fiscal profile whose saved SAT credential is used, e.g.
                    "fp_2P9K3sample".
                type:
                  type: string
                  description: Always "constancia" for now.
                  enum:
                    - constancia
                simulate:
                  description: >-
                    Test mode only: force this outcome. A live key that sends it
                    gets 422 `fiscal_document.simulate_test_only`. See the
                    Testing guide.
                  type: string
                  enum:
                    - failed
                    - needs_action
                    - cancelled
                    - credential_rejected
                    - capacity_reached
              required:
                - fiscal_profile_id
                - type
            example:
              fiscal_profile_id: fp_2P9K3sample
              type: constancia
              simulate: failed
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                properties:
                  object:
                    type: string
                    description: Always "fiscal_document".
                    enum:
                      - fiscal_document
                  id:
                    type: string
                    description: Fiscal document id, e.g. "fdoc_2P9K3sample".
                  fiscal_profile_id:
                    type: string
                    description: The fiscal profile this document belongs to.
                  type:
                    type: string
                    description: Always "constancia" for now.
                    enum:
                      - constancia
                  status:
                    type: string
                    enum:
                      - pending
                      - processing
                      - ready
                      - needs_action
                      - failed
                      - cancelled
                      - expired
                    description: >-
                      pending: accepted, not started yet (also the state while
                      our SAT document service is at capacity). processing: the
                      document is being fetched. ready: the PDF can be
                      downloaded. needs_action: stopped until someone acts, see
                      `error`. failed: did not complete. cancelled: the request
                      was cancelled. expired: the PDF was removed after the
                      retention period.
                  livemode:
                    type: boolean
                    description: >-
                      False for test mode: the PDF is simulated and is not a SAT
                      document.
                  deadline:
                    type: string
                    description: When we stop working on this request, ISO-8601 UTC.
                  sha256:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: SHA-256 (hex) of the PDF once it is ready.
                  size_bytes:
                    anyOf:
                      - type: integer
                        minimum: -9007199254740991
                        maximum: 9007199254740991
                      - type: 'null'
                    description: PDF size in bytes once it is ready.
                  pdf_url:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: Path to download the PDF; null unless status is ready.
                  pdf_expires_at:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: When the PDF is deleted from our storage, ISO-8601 UTC.
                  error:
                    anyOf:
                      - type: object
                        properties:
                          code:
                            type: string
                            description: >-
                              Stable machine code, e.g.
                              "sat_service.credential_rejected".
                          title:
                            type: string
                            description: Short human-readable title.
                          remediation:
                            type: string
                            description: What to do next. Written for humans and agents.
                          retryable:
                            type: boolean
                            description: >-
                              Whether creating a new request (after any
                              remediation) is reasonable.
                        required:
                          - code
                          - title
                          - remediation
                          - retryable
                        additionalProperties: false
                      - type: 'null'
                    description: >-
                      Why it stopped, set on needs_action, failed and cancelled;
                      null otherwise.
                  created_at:
                    type: string
                    description: Creation timestamp, ISO-8601 UTC.
                  updated_at:
                    type: string
                    description: Last-update timestamp, ISO-8601 UTC.
                  ready_at:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: When the PDF was stored, ISO-8601 UTC.
                required:
                  - object
                  - id
                  - fiscal_profile_id
                  - type
                  - status
                  - livemode
                  - deadline
                  - sha256
                  - size_bytes
                  - pdf_url
                  - pdf_expires_at
                  - error
                  - created_at
                  - updated_at
                  - ready_at
                additionalProperties: false
              example:
                object: fiscal_document
                id: obj_2P9K3sample
                fiscal_profile_id: fp_2P9K3sample
                type: constancia
                status: pending
                livemode: false
                deadline: string
                sha256: string
                size_bytes: -9007199254740991
                pdf_url: https://example.com/webhooks/invoice
                pdf_expires_at: '2026-07-10T18:25:43Z'
                error:
                  code: string
                  title: string
                  remediation: string
                  retryable: true
                created_at: '2026-07-10T18:25:43Z'
                updated_at: '2026-07-10T18:25:43Z'
                ready_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'
        '201':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                properties:
                  object:
                    type: string
                    description: Always "fiscal_document".
                    enum:
                      - fiscal_document
                  id:
                    type: string
                    description: Fiscal document id, e.g. "fdoc_2P9K3sample".
                  fiscal_profile_id:
                    type: string
                    description: The fiscal profile this document belongs to.
                  type:
                    type: string
                    description: Always "constancia" for now.
                    enum:
                      - constancia
                  status:
                    type: string
                    enum:
                      - pending
                      - processing
                      - ready
                      - needs_action
                      - failed
                      - cancelled
                      - expired
                    description: >-
                      pending: accepted, not started yet (also the state while
                      our SAT document service is at capacity). processing: the
                      document is being fetched. ready: the PDF can be
                      downloaded. needs_action: stopped until someone acts, see
                      `error`. failed: did not complete. cancelled: the request
                      was cancelled. expired: the PDF was removed after the
                      retention period.
                  livemode:
                    type: boolean
                    description: >-
                      False for test mode: the PDF is simulated and is not a SAT
                      document.
                  deadline:
                    type: string
                    description: When we stop working on this request, ISO-8601 UTC.
                  sha256:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: SHA-256 (hex) of the PDF once it is ready.
                  size_bytes:
                    anyOf:
                      - type: integer
                        minimum: -9007199254740991
                        maximum: 9007199254740991
                      - type: 'null'
                    description: PDF size in bytes once it is ready.
                  pdf_url:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: Path to download the PDF; null unless status is ready.
                  pdf_expires_at:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: When the PDF is deleted from our storage, ISO-8601 UTC.
                  error:
                    anyOf:
                      - type: object
                        properties:
                          code:
                            type: string
                            description: >-
                              Stable machine code, e.g.
                              "sat_service.credential_rejected".
                          title:
                            type: string
                            description: Short human-readable title.
                          remediation:
                            type: string
                            description: What to do next. Written for humans and agents.
                          retryable:
                            type: boolean
                            description: >-
                              Whether creating a new request (after any
                              remediation) is reasonable.
                        required:
                          - code
                          - title
                          - remediation
                          - retryable
                        additionalProperties: false
                      - type: 'null'
                    description: >-
                      Why it stopped, set on needs_action, failed and cancelled;
                      null otherwise.
                  created_at:
                    type: string
                    description: Creation timestamp, ISO-8601 UTC.
                  updated_at:
                    type: string
                    description: Last-update timestamp, ISO-8601 UTC.
                  ready_at:
                    anyOf:
                      - type: string
                      - type: 'null'
                    description: When the PDF was stored, ISO-8601 UTC.
                required:
                  - object
                  - id
                  - fiscal_profile_id
                  - type
                  - status
                  - livemode
                  - deadline
                  - sha256
                  - size_bytes
                  - pdf_url
                  - pdf_expires_at
                  - error
                  - created_at
                  - updated_at
                  - ready_at
                additionalProperties: false
              example:
                object: fiscal_document
                id: obj_2P9K3sample
                fiscal_profile_id: fp_2P9K3sample
                type: constancia
                status: pending
                livemode: false
                deadline: string
                sha256: string
                size_bytes: -9007199254740991
                pdf_url: https://example.com/webhooks/invoice
                pdf_expires_at: '2026-07-10T18:25:43Z'
                error:
                  code: string
                  title: string
                  remediation: string
                  retryable: true
                created_at: '2026-07-10T18:25:43Z'
                updated_at: '2026-07-10T18:25:43Z'
                ready_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/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/request_validation_failed
                title: Request validation failed
                status: 422
                code: request.validation_failed
                detail: One or more fields did not satisfy the schema.
                remediation: Fix the fields listed in `errors` and resubmit.
                doc_url: /docs/errors#request-validation_failed
                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'
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. A successful (2xx) response is stored for 24h and
        replayed byte-for-byte for identical retries (the replay adds an
        `idempotent-replayed: true` header). A non-2xx releases the key, so you
        can fix the cause and retry with the same key;
        `pac.stamp_outcome_unknown`, `pac.auth_failed` and
        `download.request_failed` are the exceptions and replay like a success.
        Reusing the key of a stored response with a different body is 409
        `idempotency.key_reuse`; an in-flight duplicate is 409
        `idempotency.key_processing`.
      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_...`.'

````

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