Firmas electrónicas

Envía cualquier documento a firmar electrónicamente: mandatos, contratos de compraventa, representaciones de entidad y declaraciones de extravío. El firmante recibe un email o SMS, firma desde el navegador y tú recibes el PDF firmado a través de un webhook.

Esta funcionalidad está en desarrollo. Los endpoints de firmas están publicados en la referencia API pero aún no están activos. Puedes planificar tu integración contra el contrato — el comportamiento descrito aquí es el definitivo.

Crea la solicitud de firma

Envía la solicitud en una llamada, el firmante recibe un email o SMS con el enlace para firmar y tú recibes eventos conforme avanza la firma.

1. Creas la firma
2. Recibes eventos
3. Obtienes el documento
Tu empresa
Punto
POST/v1/signatures/mandate-generic
→201
Enviamos la solicitud de firma al firmante↓
signature.status_changed←
webhook
El firmante completa la firma↓
signature.status_changed←
webhook
GET/v1/signatures/{id}
→200

Paso 1 — Creas la firma

Envía una llamada POST al endpoint del tipo de documento que necesitas firmar. Cada tipo tiene su propio conjunto de campos requeridos, pero todos comparten la misma estructura de firmante (signer, o seller/buyer en el contrato de compraventa). La solicitud queda con estado submitted y recibirás un identificador único.

▾
Autorización genérica para que nuestro gestor actúe en nombre del firmante ante la DGT u otros organismos, sin vincularse a un trámite ni vehículo concreto. Útil para clientes que harán muchos trámites.
CampoDescripción
signer.typeobligatorio"person" o "company".
signer.idNumberobligatorioDNI/NIE si type es "person", CIF si es "company".
signer.fullnameobligatorioNombre completo del firmante. Requerido cuando type es "person".
signer.companyNameobligatorioRazón social. Requerido cuando type es "company".
signer.representativeobligatorioRepresentante legal: { idNumber, fullname }. Requerido cuando type es "company".
signer.addressobligatorioDirección del firmante: { street, zipCode, provinceName, municipalityName }.
signer.phoneobligatorioMóvil del firmante, usado para el OTP por SMS. Ej: +34612345678
signer.emailobligatorioEmail del firmante, al que se enviará el enlace de firma si deliveryMethod es "email".
signer.deliveryMethodobligatorio"email" o "sms" — canal por el que se notifica al firmante.
companyTaxIdopcionalNIF/CIF de la empresa a la que se atribuye la solicitud. Necesario cuando la cuenta tiene acceso a varias empresas.
userEmailopcionalEmail del usuario de tu organización al que se atribuye la solicitud. Por defecto, el usuario del API token.
metadataopcionalMetadatos adicionales con información de vuestra empresa. Ej: { external_reference: "sig-001" }
POST /v1/signatures/mandate-generic — Request
{
  "signer": {
    "type": "person",
    "idNumber": "12345678Z",
    "fullname": "Juan Pérez",
    "address": {
      "street": "Calle Mayor 1",
      "zipCode": "28001",
      "provinceName": "Madrid",
      "municipalityName": "Madrid"
    },
    "phone": "+34612345678",
    "email": "firmante@ejemplo.com",
    "deliveryMethod": "email"
  }
}
201 Created — Response
{
  "id": "sig_3ab7kp",
  "companyTaxId": "B12345678",
  "status": "submitted",
  "documents": [
    {
      "type": "mandate",
      "name": "Mandato genérico"
    }
  ],
  "signers": [
    {
      "idNumber": "12345678Z",
      "fullname": "Juan Pérez"
    }
  ],
  "pendingSigners": [
    {
      "idNumber": "12345678Z",
      "fullname": "Juan Pérez"
    }
  ],
  "createdAt": "2026-05-26T10:30:00.000Z",
  "updatedAt": "2026-05-26T10:30:00.000Z"
}

Ver referencia completa de este endpoint →


Paso 2 — Recibes eventos

Punto envía un evento signature.status_changed a tu webhook cada vez que cambia el estado de la solicitud de firma. Cuando el estado es signed, el evento incluye el array documents con la URL de descarga del PDF firmado en signedDocumentUrl de cada documento.

signature.status_changed (firmado)
{
  "event": "signature.status_changed",
  "data": {
    "id": "sig_3ab7kp",
    "path": "/v1/signatures/sig_3ab7kp",
    "status": "signed",
    "documents": [
      {
        "type": "mandate",
        "name": "Mandato genérico",
        "signedDocumentUrl": "https://api.punto.ai/v1/signatures/sig_3ab7kp/signed-pdf/sigdoc_abc123"
      }
    ],
    "timestamp": "2025-08-12T10:31:00.000Z"
  }
}

Paso 3 — Obtienes el documento firmado

Consulta la firma con el identificador recibido. Cuando el estado es signed, cada elemento de documents incluye signedDocumentUrl: un endpoint de la API (requiere tu Bearer token) para descargar el PDF firmado.

GET /v1/signatures/{id} — 200 OK
{
  "id": "sig_3ab7kp",
  "companyTaxId": "B12345678",
  "status": "signed",
  "documents": [
    {
      "type": "mandate",
      "name": "Mandato genérico",
      "signedDocumentUrl": "https://api.punto.ai/v1/signatures/sig_3ab7kp/signed-pdf/sigdoc_abc123"
    }
  ],
  "signers": [
    {
      "idNumber": "12345678Z",
      "fullname": "Juan Pérez"
    }
  ],
  "pendingSigners": [],
  "createdAt": "2025-08-12T10:30:00.000Z",
  "updatedAt": "2025-08-12T10:31:00.000Z",
  "sentAt": "2025-08-12T10:30:05.000Z"
}

Anexo — Estados de una firma

EstadoDescripción
draftSolicitud en borrador, aún no enviada
submittedLa solicitud se ha aceptado y está en cola de envío
sentEl documento se ha enviado al firmante o firmantes
partially_signedHay más de un firmante y solo alguno ha firmado todavía
signedTodos los firmantes han completado la firma — el PDF está disponible
rejectedAlgún firmante ha rechazado la firma
expiredLa solicitud caducó sin ser firmada
cancelledLa solicitud fue cancelada
errorError al procesar la solicitud

En el flujo habitual con un único firmante, los estados se suceden en orden: submitted → sent → (signed, rejected o expired).


Anexo — Eventos

Todos los eventos que Punto emite bajo la familia signature.*.

signature.status_changed

Se emite cada vez que cambia el estado de la solicitud de firma. Cuando el estado es signed, el payload incluye el array documents, con signedDocumentUrl en cada documento firmado.

signature.status_changed — enviado
{
  "event": "signature.status_changed",
  "data": {
    "id": "sig_3ab7kp",
    "path": "/v1/signatures/sig_3ab7kp",
    "status": "sent",
    "timestamp": "2025-08-12T10:30:05.000Z"
  }
}
signature.status_changed — firmado
{
  "event": "signature.status_changed",
  "data": {
    "id": "sig_3ab7kp",
    "path": "/v1/signatures/sig_3ab7kp",
    "status": "signed",
    "documents": [
      {
        "type": "mandate",
        "name": "Mandato genérico",
        "signedDocumentUrl": "https://api.punto.ai/v1/signatures/sig_3ab7kp/signed-pdf/sigdoc_abc123"
      }
    ],
    "timestamp": "2025-08-12T10:31:00.000Z"
  }
}
signature.status_changed — expirado
{
  "event": "signature.status_changed",
  "data": {
    "id": "sig_3ab7kp",
    "path": "/v1/signatures/sig_3ab7kp",
    "status": "expired",
    "timestamp": "2025-08-19T10:30:00.000Z"
  }
}

Anexo — Otras acciones

Reenviar la solicitud de firma

Si el firmante no ha recibido el email o SMS, o necesita un nuevo enlace, puedes reenviar la notificación de la solicitud de firma:

POST /v1/signatures/{id}/resend — 200 OK
{
  "id": "sig_3ab7kp",
  "companyTaxId": "B12345678",
  "status": "sent",
  "documents": [
    {
      "type": "mandate",
      "name": "Mandato genérico"
    }
  ],
  "signers": [
    {
      "idNumber": "12345678Z",
      "fullname": "Juan Pérez"
    }
  ],
  "pendingSigners": [
    {
      "idNumber": "12345678Z",
      "fullname": "Juan Pérez"
    }
  ],
  "lastNotifiedAt": "2025-08-12T11:00:00.000Z"
}

Siguientes pasos

  • Trámites DGT — matriculaciones, transferencias y otros trámites
  • Informes DGT — solicita informes de vehículos sin crear un trámite
  • Referencia API — documentación completa de todos los endpoints