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

# Solicitar timbraje de folios

> Pide folios al SII para tu empresa y te devuelve el **CAF** en XML para que emitas con tu propio facturador.

Es un **recurso asíncrono**: el trámite ante el SII son cuatro pasos y puede tardar minutos, así que la API registra el pedido, responde **201** con `status: "pending"` y el timbraje corre en segundo plano. Consulta el pedido con `GET /folio-requests/{id}` o suscríbete al webhook `folio_request.completed`.

**La cabecera `Idempotency-Key` es obligatoria.** Un folio timbrado no se puede devolver: si repites la llamada con la misma clave te devolvemos el pedido original (200) en vez de timbrar de nuevo. Usa una clave distinta por cada pedido real.

Requisitos: tu empresa debe tener cargado en Tupana un certificado digital vigente, y la persona del certificado debe estar autorizada ante el SII para timbrar por la empresa.



## OpenAPI

````yaml api-reference/openapi-v2.json POST /folio-requests/
openapi: 3.0.0
info:
  title: Tupana API — v2
  description: >-
    API v2 de Tupana: facturación electrónica, cesiones, recaudación, consultas,
    boleta de honorarios y nómina. Los identificadores de recursos son public
    IDs opacos con prefijo (docu_, ment_, cred_, doce_, empl_…).
  version: 2.0.0
servers:
  - url: https://api.tupana.ai/v2
    description: Producción (v2)
security:
  - apiKeyAuth: []
paths:
  /folio-requests/:
    post:
      tags:
        - Folios
      summary: Solicitar timbraje de folios
      description: >-
        Pide folios al SII para tu empresa y te devuelve el **CAF** en XML para
        que emitas con tu propio facturador.


        Es un **recurso asíncrono**: el trámite ante el SII son cuatro pasos y
        puede tardar minutos, así que la API registra el pedido, responde
        **201** con `status: "pending"` y el timbraje corre en segundo plano.
        Consulta el pedido con `GET /folio-requests/{id}` o suscríbete al
        webhook `folio_request.completed`.


        **La cabecera `Idempotency-Key` es obligatoria.** Un folio timbrado no
        se puede devolver: si repites la llamada con la misma clave te
        devolvemos el pedido original (200) en vez de timbrar de nuevo. Usa una
        clave distinta por cada pedido real.


        Requisitos: tu empresa debe tener cargado en Tupana un certificado
        digital vigente, y la persona del certificado debe estar autorizada ante
        el SII para timbrar por la empresa.
      operationId: createFolioRequest_v2
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            maxLength: 100
          description: >-
            Clave única del pedido. Repetirla devuelve el pedido original sin
            timbrar de nuevo.
          example: pedido-facturas-2026-08-27-01
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - master_entity_id
                - dte_type
                - quantity
              properties:
                master_entity_id:
                  type: string
                  description: >-
                    ID de la entidad maestra. El public ID de la entidad
                    (`ment_...`).
                  example: ment_4829301923847
                dte_type:
                  type: integer
                  description: Código del tipo de documento a timbrar.
                  enum:
                    - 33
                    - 34
                    - 39
                    - 41
                    - 43
                    - 46
                    - 52
                    - 56
                    - 61
                    - 110
                    - 111
                    - 112
                  example: 33
                quantity:
                  type: integer
                  minimum: 1
                  maximum: 1000
                  description: >-
                    Folios a pedir. El SII acota cada solicitud con su propio
                    máximo autorizado, que sube con el uso: es normal recibir
                    menos de los pedidos. Consulta el tope vigente en `GET
                    /folios`.
                  example: 50
                sii_environment:
                  type: string
                  enum:
                    - production
                    - certification
                  default: production
                  description: >-
                    Ambiente del SII contra el que se hace la operación.
                    `production` (palena) entrega folios REALES, que no se
                    devuelven; `certification` (maullin) entrega folios de
                    prueba, que NO sirven para emitir. Si se omite, producción.
                    Un valor distinto de los dos se rechaza con 422 en vez de
                    asumir un default.
                  example: certification
      responses:
        '200':
          description: >-
            Ya existía un pedido con esa `Idempotency-Key`: se devuelve el
            original, sin timbrar de nuevo
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FolioRequest'
        '201':
          description: Pedido registrado; el timbraje corre en segundo plano
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FolioRequest'
              example:
                id: fir_8d4a2f7c1e9b5
                dte_type: 33
                status: pending
                requested_quantity: 50
                granted_quantity: null
                folio_start: null
                folio_end: null
                caf_xml: null
                idempotency_key: pedido-facturas-2026-08-27-01
                error: ''
                created_at: '2026-08-27T14:30:00Z'
                completed_at: null
                sii_environment: production
                error_code: ''
        '400':
          description: >-
            Falta la cabecera `Idempotency-Key`, el tipo de DTE no es timbrable
            o la cantidad está fuera de rango
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: >-
                      La cabecera Idempotency-Key es obligatoria: sin ella un
                      reintento timbraría folios de nuevo.
        '403':
          description: Sin acceso a la entidad indicada
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                    example: No tienes acceso a esta entidad.
        '409':
          description: >-
            Ya hay un timbraje de ese tipo de documento en curso para la
            empresa. Espera a que termine: dos trámites simultáneos sobre el
            mismo tipo pueden consumir rangos de más.. También cuando la
            `Idempotency-Key` ya se usó en el otro ambiente
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  error_code:
                    type: string
                    enum:
                      - idempotency_environment_conflict
              example:
                error: >-
                  La clave de idempotencia 'pedido-01' ya se usó en production y
                  ahora se pide en certification. Usa una clave distinta por
                  ambiente.
                error_code: idempotency_environment_conflict
        '422':
          description: >-
            El ambiente pedido no existe, no está habilitado, o la empresa no
            está postulada en certificación
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  error_code:
                    type: string
                    enum:
                      - invalid_environment
                      - environment_not_allowed
                      - certification_not_enabled
              example:
                error: >-
                  Ambiente 'staging' desconocido. Valores válidos:
                  certification, production.
                error_code: invalid_environment
        '429':
          description: >-
            Cuota de timbrajes agotada (3 por hora o 20 por mes, por empresa).
            El cuerpo dice cuál se agotó y cuándo se libera.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FolioQuotaExceeded'
      security:
        - apiKeyAuth: []
components:
  schemas:
    FolioRequest:
      type: object
      description: Pedido de timbraje de folios ante el SII.
      properties:
        id:
          type: string
          example: fir_8d4a2f7c1e9b5
        dte_type:
          type: integer
          description: Tipo de documento timbrado.
          example: 33
        status:
          type: string
          enum:
            - pending
            - processing
            - completed
            - failed
            - authorized_without_caf
          description: >-
            `authorized_without_caf` significa que el SII autorizó el rango y no
            entregó el archivo: esos folios ya salieron de tu stock.
          example: completed
        requested_quantity:
          type: integer
          description: Folios que pediste.
          example: 50
        granted_quantity:
          type: integer
          nullable: true
          description: >-
            Folios que el SII autorizó. Puede ser menor al pedido: el tope por
            solicitud lo pone el SII y sube con el uso.
          example: 50
        partially_granted:
          type: boolean
          description: >-
            `true` cuando el SII entregó menos folios de los que pediste. Es un
            desenlace normal: el tope por solicitud lo fija el SII y sube con el
            uso de la empresa.
          example: true
        sii_max_per_request:
          type: integer
          nullable: true
          description: >-
            Tope por solicitud que el SII publicó al hacer este trámite: el
            motivo por el que se entregó menos de lo pedido.
          example: 9
        folio_start:
          type: integer
          nullable: true
          example: 539
        folio_end:
          type: integer
          nullable: true
          example: 588
        caf_xml:
          type: string
          nullable: true
          description: >-
            CAF entregado por el SII. Contiene la llave privada con la que se
            firman tus DTE: trátalo como secreto. Es `null` hasta que el pedido
            queda `completed`.
          example: <AUTORIZACION><CAF version="1.0">…</CAF></AUTORIZACION>
        idempotency_key:
          type: string
          description: La clave que enviaste al crear el pedido.
          example: pedido-facturas-2026-08-27-01
        error:
          type: string
          description: Motivo del SII cuando el pedido no terminó bien.
          example: ''
        created_at:
          type: string
          format: date-time
          example: '2026-08-27T14:30:00Z'
        completed_at:
          type: string
          format: date-time
          nullable: true
          example: '2026-08-27T14:32:11Z'
        sii_environment:
          type: string
          enum:
            - production
            - certification
          description: >-
            Ambiente del SII en el que se hizo la operación. Un CAF de
            `certification` NO sirve para emitir.
        error_code:
          type: string
          description: >-
            Vocabulario cerrado del desenlace fallido; vacío si no hubo error.
            Ver la página de códigos de error.
          enum:
            - ''
            - certification_not_enabled
            - missing_certificate
            - no_folios_authorized
            - sii_unavailable
            - sii_unrecognized_page
    FolioQuotaExceeded:
      type: object
      description: >-
        Cuota agotada para la empresa. Timbraje y consulta tienen cuotas
        separadas; las dos se cuentan por empresa, no por API key.
      properties:
        error:
          type: string
          example: 'Cuota de timbrajes agotada: 3 de 3 por hora.'
        limit:
          type: integer
          description: Tope de la ventana que se agotó.
          example: 3
        window:
          type: string
          enum:
            - hora
            - mes
          example: hora
        used:
          type: integer
          description: Timbrajes ya consumidos en esa ventana.
          example: 3
        resets_at:
          type: string
          format: date-time
          description: Cuándo vuelve a haber cupo.
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        API Key para autenticación. Debe proporcionarse en el header
        Authorization con el formato: 'Api-Key YOUR-API-KEY' (incluye el prefijo
        'Api-Key ' seguido de tu API key)

````

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