Desarrolladores
API de DocuFirma
Integra la firma electrónica avanzada con sello de tiempo cualificado en tu software: crea envíos, sigue su estado, descarga los documentos firmados y recibe avisos por webhook.
Introducción
La API es REST, usa JSON en peticiones y respuestas, y está disponible para cuentas con el Plan Pro activo. Las firmas y los SMS que consume son los de tu cuenta, igual que desde la web.
URL base: https://docufirma.es/api/v1
Autenticación
Crea una clave en Ajustes → API y webhooks. Se muestra una sola vez: guárdala en tu gestor de secretos. Envíala en la cabecera Authorization en cada petición. Puedes tener hasta 5 claves activas y revocarlas en cualquier momento.
curl https://docufirma.es/api/v1/account \
-H "Authorization: Bearer df_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"Primer envío en una llamada
Crea el envío con sus firmantes y un documento en base64 (hasta 3 MB) y envíalo a la vez con send: true. La respuesta incluye el estado de cada firmante y el código de verificación.
curl https://docufirma.es/api/v1/envelopes \
-H "Authorization: Bearer $DOCUFIRMA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Contrato de servicios",
"message": "Hola Lucía, aquí tienes el contrato.",
"locale": "es",
"signers": [
{ "first_name": "Lucía", "last_name": "Gómez", "email": "lucia@example.com" }
],
"documents": [
{ "name": "contrato.pdf", "content_base64": "'"$(base64 -w0 contrato.pdf)"'" }
],
"send": true
}'{
"id": "6c36f47e-86d5-4693-b4f5-c5da17f37621",
"object": "envelope",
"status": "sent",
"title": "Contrato de servicios",
"verification_code": "DF-7K2M-9QXA",
"sent_at": "2026-11-03T10:15:02Z",
"expires_at": "2026-12-03T10:15:02Z",
"signers": [
{ "id": "…", "object": "signer", "email": "lucia@example.com", "status": "sent", … }
],
"documents": [
{ "id": "…", "object": "document", "name": "contrato.pdf", "page_count": 3, "sha256": "…" }
]
}Documentos grandes
Para archivos de hasta 25 MB, pide una URL de subida, envía el archivo con PUT y confirma la subida. DocuFirma valida el PDF (o convierte la imagen) y calcula su huella SHA-256.
# 1. Upload slot (valid for 2 hours)
curl -X POST https://docufirma.es/api/v1/envelopes/$ENVELOPE_ID/uploads \
-H "Authorization: Bearer $DOCUFIRMA_API_KEY" -H "Content-Type: application/json" \
-d '{ "name": "anexo.pdf", "size_bytes": 8421337 }'
# → { "id": "<upload_id>", "upload_url": "https://…", "method": "PUT", … }
# 2. Send the file
curl -X PUT "$UPLOAD_URL" -H "Content-Type: application/pdf" --data-binary @anexo.pdf
# 3. Complete
curl -X POST https://docufirma.es/api/v1/envelopes/$ENVELOPE_ID/uploads/$UPLOAD_ID/complete \
-H "Authorization: Bearer $DOCUFIRMA_API_KEY" -H "Content-Type: application/json" \
-d '{ "name": "anexo.pdf" }'
# 4. Send the envelope
curl -X POST https://docufirma.es/api/v1/envelopes/$ENVELOPE_ID/send -H "Authorization: Bearer $DOCUFIRMA_API_KEY"Endpoints
| Método | Ruta | Descripción |
|---|---|---|
| GET | /account | Tu cuenta: plan, firmas y SMS disponibles. |
| GET | /envelopes | Lista de envíos, del más reciente al más antiguo. Filtra por status y pagina con limit y starting_after. |
| POST | /envelopes | Crea un envío en borrador, con firmantes y documentos opcionales; con send: true lo envía. |
| GET | /envelopes/{id} | Detalle de un envío con firmantes y documentos. |
| PATCH | /envelopes/{id} | Modifica un borrador. signers sustituye la lista completa. |
| DELETE | /envelopes/{id} | Elimina un borrador y sus documentos. |
| POST | /envelopes/{id}/documents | Añade un documento en base64 (hasta 3 MB) a un borrador. |
| POST | /envelopes/{id}/uploads | Devuelve una URL firmada para subir un archivo grande con PUT. |
| POST | /envelopes/{id}/uploads/{upload_id}/complete | Valida el archivo subido y lo añade al borrador. |
| POST | /envelopes/{id}/send | Envía el borrador: reserva las firmas y avisa a los firmantes. |
| POST | /envelopes/{id}/cancel | Cancela un envío pendiente y devuelve las firmas reservadas. |
| POST | /envelopes/{id}/remind | Vuelve a avisar a los firmantes pendientes (máximo una vez por hora). |
| GET | /envelopes/{id}/files | URLs de descarga temporales (5 min): originales y, al completarse, PDF firmados, certificado de evidencias y sellos de tiempo. |
| GET | /envelopes/{id}/events | Cronología completa del envío. |
| POST | /envelopes/{id}/signers/{signer_id}/signing-url | Enlace de firma para un firmante presencial. |
Estados
Un envío pasa por draft → sent → viewed → completed, o termina en declined, expired o canceled. Cada firmante pasa por pending → sent → viewed → signed, o declined. Tras la última firma, el estado completed llega en unos segundos, cuando los PDF están firmados y sellados.
Errores
Los errores devuelven un código HTTP y un objeto error con un code estable y un mensaje legible. Los de validación incluyen details con el campo afectado.
HTTP/1.1 402 Payment Required
{
"error": {
"code": "insufficient_credits",
"message": "Not enough signatures to send this envelope.",
"details": { "needed": 3, "available": 1 }
}
}- 400
- JSON mal formado.
- 401
- Clave ausente, no válida o revocada.
- 402
- No tienes firmas o SMS suficientes (insufficient_credits, sms_no_credits).
- 403
- Sin Plan Pro activo (subscription_required) o email sin confirmar.
- 404
- El recurso no existe o no es tuyo.
- 409
- El estado no permite la operación (envelope_not_draft, not_cancelable).
- 413
- Documento demasiado grande para subirlo en línea.
- 422
- Datos no válidos o documento no admitido.
- 429
- Límite de peticiones superado.
Límites y paginación
Cada clave admite 120 peticiones por minuto; las cabeceras X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset indican tu consumo y, si lo superas, Retry-After indica cuándo reintentar. Por envío: hasta 10 documentos (25 MB cada uno) y 10 firmantes. Las listas devuelven has_more; pide la siguiente página con starting_after igual al id del último elemento.
Webhooks
Configura una URL HTTPS en Ajustes → API y webhooks para recibir un POST en cada cambio de estado. Responde con cualquier 2xx; si falla, reintentamos dos veces. Cada petición lleva la cabecera DocuFirma-Signature para que compruebes que viene de nosotros.
- envelope.sent
- El envío se ha enviado a los firmantes.
- envelope.signed
- Un firmante ha firmado (data.signer_id).
- envelope.completed
- Todos han firmado y los PDF están sellados y listos.
- envelope.declined
- Un firmante ha rechazado firmar.
- envelope.expired
- El envío ha caducado sin completarse.
- envelope.canceled
- Has cancelado el envío.
POST /webhooks/docufirma HTTP/1.1
Content-Type: application/json
DocuFirma-Signature: t=1793790902,v1=5f0c4e…
{
"id": "evt_9b1d…",
"object": "event",
"type": "envelope.completed",
"created_at": "2026-11-03T10:42:11Z",
"data": { "envelope": { "id": "6c36f47e-…", "status": "completed", … } }
}Verifica la firma: calcula el HMAC-SHA256 de «t.cuerpo» con tu secreto y compáralo con v1. Rechaza mensajes con t de hace más de 5 minutos.
import crypto from "node:crypto";
export function verifyDocuFirma(rawBody, header, secret) {
const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}