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

# Generar un acceso temporal de firma para un firmante

> Llamar desde el backend del tercero, nunca desde el navegador. Devuelve una URL `/sign/launch/:token` de un solo uso que vence en 5 minutos. El correo sólo localiza al firmante: al abrir la URL, la plataforma le envía un código a ese correo y no muestra el documento ni permite firmar sin validarlo. Diez accesos cada 10 minutos por firmante.



## OpenAPI

````yaml https://signature.api.staging.data-lo.online/api/v1/integration/docs-json post /api/v1/integration/documents/{documentId}/signing-access
openapi: 3.0.0
info:
  title: Firmalo Integration API
  description: >-
    API para que tu sistema cree documentos PDF con su flujo de firmas, consulte
    su estado y gestione el acceso de los firmantes en Firmalo.


    **Autenticación.** Todas las rutas usan la API key de tu organización en el
    header `X-API-Key`, con formato `fma_live_<publicId>_<secret>`. Pégala en
    «Authorize» para probar desde esta página. Ejemplo (no es una llave real):


    `X-API-Key:
    fma_live_0123456789abcdef_EjemploNoRealEjemploNoRealEjemploNoReal1234`


    **Idempotencia.** `POST /integration/documents` exige `Idempotency-Key`:
    repetir la petición con la misma clave y el mismo contenido devuelve el
    documento original, sin crear ni cobrar otro. Ejemplo:


    `Idempotency-Key: erp-contrato-2026-000184`


    **Errores.** Todos tienen la forma `{ "success": false, "error": { "code",
    "message", "details" } }`, con un `code` estable para decidir qué hacer sin
    depender del texto.
  version: '1.0'
servers: []
security:
  - integration-api-key: []
tags:
  - name: Integration Documents
    description: Documentos, firmantes y accesos de firma de tu organización
paths:
  /api/v1/integration/documents/{documentId}/signing-access:
    post:
      tags:
        - Integration Documents
      summary: Generar un acceso temporal de firma para un firmante
      description: >-
        Llamar desde el backend del tercero, nunca desde el navegador. Devuelve
        una URL `/sign/launch/:token` de un solo uso que vence en 5 minutos. El
        correo sólo localiza al firmante: al abrir la URL, la plataforma le
        envía un código a ese correo y no muestra el documento ni permite firmar
        sin validarlo. Diez accesos cada 10 minutos por firmante.
      operationId: IntegrationDocumentsController_createSigningAccess
      parameters:
        - name: documentId
          required: true
          in: path
          schema:
            type: string
            format: uuid
            example: 2be3b9d7-4c5d-4e6f-8a9b-0c1d2e3f4a5b
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateIntegrationSigningAccessDto'
      responses:
        '200':
          description: Acceso temporal emitido
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntegrationSigningAccessResponse'
        '400':
          description: >-
            `INTEGRATION_TENANT_OVERRIDE_NOT_ALLOWED`: la petición trae
            `organizationId`, `taxId`, `userId`, `accountId`, `createdBy`,
            `createdByUserId`, `permissionIds`, `X-Account-Id` o
            `X-Organization-Id` (la organización y el autor salen de la llave).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntegrationErrorResponseDto'
              examples:
                tenantOverride:
                  summary: Campo de organización o autor no permitido
                  value:
                    success: false
                    error:
                      code: INTEGRATION_TENANT_OVERRIDE_NOT_ALLOWED
                      message: >-
                        La organización, la cuenta y el autor salen de la API
                        key; no se aceptan: organizationId
        '401':
          description: >-
            `API_KEY_INVALID` (falta, formato incorrecto, secreto que no
            coincide o llave revocada) o `API_KEY_EXPIRED`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntegrationErrorResponseDto'
              examples:
                invalid:
                  summary: Llave ausente, inválida o revocada
                  value:
                    success: false
                    error:
                      code: API_KEY_INVALID
                      message: API key inválida o revocada
                expired:
                  summary: Llave vencida
                  value:
                    success: false
                    error:
                      code: API_KEY_EXPIRED
                      message: La API key venció. Genera una nueva desde Integraciones.
        '403':
          description: >-
            `API_KEY_PERMISSION_DENIED` (la llave no está autorizada para la
            operación), `API_KEY_ORGANIZATION_INACTIVE` o
            `API_KEY_ACTOR_INACTIVE` (quien emitió la llave ya no es miembro
            activo).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntegrationErrorResponseDto'
              examples:
                permissionDenied:
                  summary: Operación no autorizada
                  value:
                    success: false
                    error:
                      code: API_KEY_PERMISSION_DENIED
                      message: La API key no está autorizada para esta operación
                organizationInactive:
                  summary: Organización desactivada
                  value:
                    success: false
                    error:
                      code: API_KEY_ORGANIZATION_INACTIVE
                      message: La organización de esta API key está desactivada
        '404':
          description: >-
            `INTEGRATION_SIGNER_NOT_FOUND`: el documento no es de la
            organización o ningún firmante tiene ese correo
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntegrationErrorResponseDto'
              examples:
                signerNotFound:
                  summary: Firmante no encontrado
                  value:
                    success: false
                    error:
                      code: INTEGRATION_SIGNER_NOT_FOUND
                      message: >-
                        No existe ese firmante en un documento de la
                        organización
        '409':
          description: >-
            `WAITING_FOR_PREVIOUS_SIGNER` (no es su turno),
            `INTEGRATION_AMBIGUOUS_SIGNER` (más de un firmante con ese correo) o
            `INTEGRATION_INVITATION_NOT_RESENDABLE` (ya no espera esa firma o
            firma desde su cuenta)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntegrationErrorResponseDto'
              examples:
                notInTurn:
                  summary: No es su turno
                  value:
                    success: false
                    error:
                      code: WAITING_FOR_PREVIOUS_SIGNER
                      message: >-
                        Todavía no es el turno de este firmante: falta la firma
                        de un firmante anterior
                ambiguous:
                  summary: Correo de más de un firmante
                  value:
                    success: false
                    error:
                      code: INTEGRATION_AMBIGUOUS_SIGNER
                      message: El correo corresponde a más de un firmante del documento
                notResendable:
                  summary: El firmante ya no espera firma
                  value:
                    success: false
                    error:
                      code: INTEGRATION_INVITATION_NOT_RESENDABLE
                      message: El documento ya no espera la firma de este firmante
        '422':
          description: '`INVALID_REQUEST`: `email` no es un correo válido.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntegrationErrorResponseDto'
              examples:
                invalidRequest:
                  summary: Campos inválidos
                  value:
                    success: false
                    error:
                      code: INVALID_REQUEST
                      message: La petición tiene campos inválidos.
                      details:
                        errors:
                          - email debe ser un correo válido
        '429':
          description: >-
            `TOO_MANY_REQUESTS`: se superaron los diez accesos en 10 minutos
            para ese firmante.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntegrationErrorResponseDto'
              examples:
                tooManyRequests:
                  summary: Demasiadas solicitudes para el firmante
                  value:
                    success: false
                    error:
                      code: TOO_MANY_REQUESTS
                      message: >-
                        Demasiados intentos. Espera unos minutos antes de volver
                        a intentarlo.
      security:
        - integration-api-key: []
components:
  schemas:
    CreateIntegrationSigningAccessDto:
      type: object
      properties:
        email:
          type: string
          example: ana@correo.com
          description: Correo del firmante
      required:
        - email
    IntegrationSigningAccessResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
          description: Indica si la operación fue exitosa
        message:
          type: string
          example: Acceso temporal de firma generado
          description: Mensaje descriptivo del resultado de la operación
          enum:
            - Operación realizada con éxito
            - Recurso creado correctamente
            - Recurso no encontrado
            - Datos de entrada inválidos
            - No autorizado para realizar esta acción
            - El firmante no está asociado al recurso
            - El recurso ya existe
            - Error interno del servidor
        data:
          description: Datos de la respuesta
          allOf:
            - $ref: '#/components/schemas/IntegrationSigningAccessData'
      required:
        - success
        - message
        - data
    IntegrationErrorResponseDto:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          $ref: '#/components/schemas/IntegrationErrorData'
      required:
        - success
        - error
    IntegrationSigningAccessData:
      type: object
      properties:
        url:
          type: string
          example: https://app.firmalo.com/sign/launch/EjemploDeTokenNoReal
          description: >-
            URL `/sign/launch/:token` de un solo uso para abrir desde tu portal.
            Al abrirla, la plataforma envía un código al correo del firmante.
        expiresAt:
          format: date-time
          type: string
          example: '2026-10-26T12:05:00.000Z'
          description: 'Vencimiento de la URL: cinco minutos después de emitirla'
      required:
        - url
        - expiresAt
    IntegrationErrorData:
      type: object
      properties:
        code:
          type: string
          example: DUPLICATE_PARTICIPANT_EMAIL
          description: >-
            Código estable del error (p. ej. `PARTICIPANTS_REQUIRED`,
            `SIGNER_REQUIRED`, `MAX_PARTICIPANTS_EXCEEDED`,
            `INVALID_PARTICIPANT_ROLE`, `INVALID_PARTICIPANT_EMAIL`,
            `DUPLICATE_PARTICIPANT_EMAIL`, `SIGNER_SIGNATURE_POSITION_REQUIRED`,
            `WITNESS_SIGNATURE_POSITION_NOT_ALLOWED`, `INVALID_SIGNING_ORDER`,
            `DUPLICATE_SIGNING_ORDER`, `INVALID_SIGNATURE_POSITION`,
            `SIGNATURE_POSITION_PAGE_OUT_OF_RANGE`,
            `SIGNATURE_POSITION_OVERLAP`, `API_KEY_INVALID`, `INTERNAL_ERROR`)
        message:
          type: string
          example: Un colaborador sólo puede participar una vez en el documento.
        details:
          type: object
          example:
            field: participants[2].email
            email: ana@correo.com
          description: >-
            Datos del error: `field` con la ruta del campo afectado cuando
            aplica, y los valores que lo explican (`limit`, `received`, `page`,
            `totalPages`…).
      required:
        - code
        - message
  securitySchemes:
    integration-api-key:
      type: apiKey
      in: header
      name: X-API-Key
      description: >-
        API key de tu organización, con formato `fma_live_<publicId>_<secret>`.
        Se emite (y se rota o revoca) desde **Integraciones** en Firmalo; el
        secreto completo sólo se muestra al emitirla.


        Ejemplo (no es una llave real):
        `fma_live_0123456789abcdef_EjemploNoRealEjemploNoRealEjemploNoReal1234`


        La organización y el contexto de acceso salen de la llave: no se usan
        JWT, `X-Account-Id` ni `X-Organization-Id`. Llama a la API sólo desde tu
        backend; nunca expongas la llave en un navegador o una app móvil.

````

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