> ## 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 a fiscal profile

> Register an issuer RFC with its CSD (and optionally FIEL). The simplest way is to upload the raw files via multipart/form-data — `curl -F csd_cer=@csd.cer -F csd_key=@csd.key -F csd_password=... -F legal_name=... -F tax_regime=601 -F zip=06000`. Sending base64 in a JSON body is the alternative. Private keys are AES-256-GCM encrypted at rest and never returned; the RFC is derived from the certificate.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/fiscal_profiles
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/fiscal_profiles:
    post:
      tags:
        - fiscal_profiles
      summary: Create a fiscal profile
      description: >-
        Register an issuer RFC with its CSD (and optionally FIEL). The simplest
        way is to upload the raw files via multipart/form-data — `curl -F
        csd_cer=@csd.cer -F csd_key=@csd.key -F csd_password=... -F
        legal_name=... -F tax_regime=601 -F zip=06000`. Sending base64 in a JSON
        body is the alternative. Private keys are AES-256-GCM encrypted at rest
        and never returned; the RFC is derived from the certificate.
      parameters:
        - $ref: '#/components/parameters/InvoiceVersion'
        - $ref: '#/components/parameters/InvoiceAccount'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                legal_name:
                  type: string
                  description: Issuer legal name (razón social).
                tax_regime:
                  type: string
                  description: c_RegimenFiscal code, e.g. "601".
                zip:
                  type: string
                  description: Issuer place-of-issue ZIP (LugarExpedicion), 5 digits.
                csd_cer:
                  type: string
                  format: binary
                  description: The raw CSD certificate (.cer) file — no base64 needed.
                csd_key:
                  type: string
                  format: binary
                  description: The raw CSD private-key (.key) file — no base64 needed.
                csd_password:
                  type: string
                  description: CSD private-key password ("contraseña de la clave privada").
                fiel_cer:
                  type: string
                  format: binary
                  description: The raw FIEL certificate (.cer) file — no base64 needed.
                fiel_key:
                  type: string
                  format: binary
                  description: The raw FIEL private-key (.key) file — no base64 needed.
                fiel_password:
                  type: string
                  description: FIEL private-key password (only if uploading a FIEL).
                brand_color:
                  type: string
                  description: 'PDF accent color as #RRGGBB, e.g. "#0B5FFF".'
                logo:
                  type: string
                  format: binary
                  description: >-
                    The raw issuer logo image (PNG or JPEG) — embedded in the
                    PDF; no data URL needed.
                metadata:
                  type: string
                  description: >-
                    Integrator-owned metadata as a JSON string, e.g.
                    {"order_id":"123"}.
              required:
                - legal_name
                - tax_regime
                - zip
                - csd_cer
                - csd_key
                - csd_password
            example:
              legal_name: Acme Cafe SA de CV
              tax_regime: '601'
              zip: '06000'
              csd_cer: '@csd_cer.cer'
              csd_key: '@csd_key.key'
              csd_password: 12345678a
          application/json:
            schema:
              type: object
              properties:
                legal_name:
                  type: string
                  minLength: 1
                  maxLength: 300
                  description: >-
                    Issuer legal name (razón social) exactly as registered at
                    the SAT.
                tax_regime:
                  type: string
                  minLength: 1
                  maxLength: 4
                  description: >-
                    c_RegimenFiscal code of the issuer, e.g. "601" (General de
                    Ley Personas Morales).
                zip:
                  type: string
                  pattern: ^\d{5}$
                  description: >-
                    Issuer fiscal-domicile ZIP (LugarExpedicion), exactly 5
                    digits, e.g. "06000".
                csd:
                  type: object
                  properties:
                    cer_base64:
                      type: string
                      minLength: 1
                      description: >-
                        Base64 of the certificate (.cer) exactly as issued by
                        the SAT (DER). Tip: skip base64 entirely — upload the
                        raw file via multipart/form-data (e.g. `csd_cer`)
                        instead.
                    key_base64:
                      type: string
                      minLength: 1
                      description: >-
                        Base64 of the private key (.key, DER-encoded encrypted
                        PKCS#8) as issued by the SAT. Tip: upload the raw file
                        via multipart/form-data (e.g. `csd_key`) to skip base64.
                    password:
                      type: string
                      minLength: 1
                      description: >-
                        The private-key password ("contraseña de la clave
                        privada").
                  required:
                    - cer_base64
                    - key_base64
                    - password
                  description: >-
                    The CSD (Certificado de Sello Digital) used to sign invoices
                    — its .cer, .key, and password.
                fiel:
                  description: >-
                    Optional FIEL (e.firma) — its .cer, .key, and password. Used
                    to sign the carta manifiesto that authorizes CFDI stamping
                    for this RFC (and reused for descarga masiva); can also be
                    supplied later at POST /v1/fiscal_profiles/:id/manifest.
                  type: object
                  properties:
                    cer_base64:
                      type: string
                      minLength: 1
                      description: >-
                        Base64 of the certificate (.cer) exactly as issued by
                        the SAT (DER). Tip: skip base64 entirely — upload the
                        raw file via multipart/form-data (e.g. `csd_cer`)
                        instead.
                    key_base64:
                      type: string
                      minLength: 1
                      description: >-
                        Base64 of the private key (.key, DER-encoded encrypted
                        PKCS#8) as issued by the SAT. Tip: upload the raw file
                        via multipart/form-data (e.g. `csd_key`) to skip base64.
                    password:
                      type: string
                      minLength: 1
                      description: >-
                        The private-key password ("contraseña de la clave
                        privada").
                  required:
                    - cer_base64
                    - key_base64
                    - password
                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
                brand_color:
                  description: 'PDF accent color as a #RRGGBB hex string, e.g. "#0B5FFF".'
                  type: string
                  pattern: ^#[0-9a-fA-F]{6}$
                logo:
                  description: >-
                    Issuer logo (PNG/JPEG data URL) embedded in the PDF
                    representación impresa.
                  type: string
                  maxLength: 1000000
                  pattern: ^data:image\/(png|jpe?g);base64,[A-Za-z0-9+/]+=*$
              required:
                - legal_name
                - tax_regime
                - zip
                - csd
            example:
              legal_name: string
              tax_regime: string
              zip: string
              csd:
                cer_base64: string
                key_base64: string
                password: string
              fiel:
                cer_base64: string
                key_base64: string
                password: string
              metadata: {}
              brand_color: string
              logo: string
      responses:
        '201':
          description: Default Response
          content:
            application/json:
              schema:
                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
              example:
                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'
          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/fiscal_profile_in_use
                title: Fiscal profile is in use
                status: 409
                code: fiscal_profile.in_use
                detail: The profile is referenced by issued invoices.
                remediation: >-
                  Profiles with invoices are retained; rotate the CSD instead of
                  deleting.
                doc_url: /docs/errors#fiscal_profile-in_use
                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/fiscal_profile_invalid_csd
                title: Invalid CSD certificate or password
                status: 422
                code: fiscal_profile.invalid_csd
                detail: The CSD .cer/.key pair could not be opened.
                remediation: >-
                  Verify cer_base64 is the .cer, key_base64 is the .key, and the
                  password.
                doc_url: /docs/errors#fiscal_profile-invalid_csd
                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. 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_...`.'

````