API Reference
REST API de DocLayer. Base: https://api.doclayer.mx
dl_live_YOUR_API_KEY_HERE.Introducción
La API REST de DocLayer te permite generar PDFs desde tus plantillas HTML, programáticamente, sin pasar por el portal web. Mismo motor (Chromium headless), mismo cache, mismo rate limit que el portal.
- Base URL:
https://api.doclayer.mx - Versión: v1 (implícita en path /api)
- Formato request: JSON o XML según endpoint
- Formato response: JSON, excepto POST /api/documentos que devuelve binario application/pdf
- Disponibilidad: planes Starter, Pro, Enterprise (Free no tiene acceso al API)
Autenticación
Todas las llamadas requieren tu API key. Hay dos formas válidas de mandarla:
# Recomendado: header X-API-Key
curl https://api.doclayer.mx/api/ping \
-H "X-API-Key: dl_live_YOUR_API_KEY_HERE"
# Alternativo: Authorization Bearer
curl https://api.doclayer.mx/api/ping \
-H "Authorization: Bearer dl_live_YOUR_API_KEY_HERE"Genera tu API key en la sección API Keys. La key solo se muestra completa una vez al crearla — guárdala segura, no se puede recuperar después.
Rate limits
Hay dos límites independientes. Si pegás cualquiera, el endpoint devuelve 429 Too Many Requests con header Retry-After.
1. Requests por minuto
Política FixedWindow particionada por API key. Se reinicia cada 60s.
| Plan | Requests/min | Acceso API |
|---|---|---|
| Free | 10 | ✗ |
| Starter | 60 | ✓ |
| Pro | 300 | ✓ |
| Enterprise | 1,000 | ✓ |
2. PDFs generados por mes (cupo)
Solo cuenta para POST /api/documentos exitosos. Lecturas y plantillas no consumen cupo. El ciclo se reinicia cada 30 días desde tu fecha de alta.
| Plan | PDFs/mes | Plantillas activas |
|---|---|---|
| Free | 100 | 1 |
| Starter | 500 | Ilimitadas |
| Pro | 3,000 | Ilimitadas |
| Enterprise | 25,000 | Ilimitadas |
La respuesta de POST /api/documentos incluye headers X-Usage-Count y X-Usage-Limit para monitorear consumo.
Códigos de error
Toda respuesta de error trae body JSON con campo error (string). Algunos endpoints añaden campos extra (ver cada endpoint).
| Código | Nombre | Significado | Cuándo pasa |
|---|---|---|---|
200 | OK | Éxito | La operación se completó. |
201 | Created | Recurso creado | POST /api/plantillas exitoso. |
204 | No Content | Éxito sin body | DELETE /api/plantillas/{id} exitoso. |
400 | Bad Request | Payload inválido | Falta nombre, falta html, XML/JSON malformado, payload supera 512 KB. |
401 | Unauthorized | Sin autenticación | No mandaste header X-API-Key (o Authorization: Bearer), o la key no existe. |
402 | Payment Required | Cupo o feature no disponible | Free intentando crear 2 plantillas, o feature exclusiva de plan superior. |
403 | Forbidden | Acceso denegado | Empresa inactiva, o plan Free intentando usar el API. |
404 | Not Found | Recurso no existe | Plantilla no encontrada, o no pertenece a tu empresa. |
409 | Conflict | Conflicto con estado actual | Nombre de plantilla duplicado, o request_hash ya procesado. |
422 | Unprocessable Entity | Datos no procesables | Plantilla existe pero su HTML está vacío. |
429 | Too Many Requests | Rate limit o cupo agotado | Pegaste el límite de requests/min de tu plan, o agotaste el cupo mensual de PDFs. |
503 | Service Unavailable | Renderer saturado | Cola de Playwright llena (más de 3 PDFs simultáneos). Reintenta en 30s. |
504 | Gateway Timeout | Render demasiado lento | Tu HTML tardó más del timeout en renderizar (probablemente CSS pesado o recursos remotos). |
Idempotencia
POST /api/documentos acepta el campo opcional request_hash en el body. Si mandás dos veces el mismo hash con la misma API key, la segunda llamada devuelve 409 Conflict con el documento_id del primer doc generado, en lugar de duplicar.
Útil cuando tu backend tiene retries automáticos y querés evitar generar el mismo PDF dos veces (y consumir el cupo dos veces).
{
"plantilla_id": 12,
"json": { ... },
"request_hash": "uuid-de-tu-orden-interna"
}Webhooks (Pro y Enterprise)
DocLayer envía un POST a la URL que configures cuando un documento se completa o falla. Útil para integrar con tu CRM, ERP, pipelines de nómina, o cualquier sistema que necesite reaccionar a un PDF generado sin polear la API.
Configura tus webhooks en app.doclayer.mx/portal/webhooks. Al crear uno se genera un secret que se muestra una sola vez — guárdalo en una variable de entorno; lo necesitas para verificar la firma de cada request.
Eventos
| Evento | Cuándo |
|---|---|
documento.completado | Se dispara cuando un PDF termina de renderizar correctamente (HTTP 200 del POST /api/documentos). |
documento.fallido | Se dispara cuando el render falla (timeout, error de plantilla, error de Chromium). El PDF no se entrega. |
Payload (JSON)
Body del request. Content-Type: application/json.
{
"evento": "documento.completado",
"documento_id": 1234,
"empresa_id": 4,
"plantilla_id": 8,
"plantilla_nombre": "Factura CFDI",
"status": "ok",
"generado_at": "2026-05-11T08:32:13.6450018Z",
"tamano_bytes": 45098
}Headers
| Header | Ejemplo | Descripción |
|---|---|---|
X-DocLayer-Event | documento.completado | El tipo de evento. Usa este header para enrutar la lógica en tu handler. |
X-DocLayer-Signature | sha256=a3f5b8c9d2e1... | HMAC-SHA256 del body raw, firmado con el secret del webhook. Verifícalo en cada request para garantizar que viene de DocLayer. |
X-DocLayer-Delivery-Id | 1234 | ID único de esta entrega. Si recibes el mismo delivery_id dos veces, es un reintento — procesa idempotente. |
User-Agent | DocLayer-Webhook/1.0 | Identifica al cliente HTTP de DocLayer. Útil para filtrar logs. |
Verificación de firma
Cada request incluye X-DocLayer-Signature: sha256=<hmac>, donde el HMAC es HMAC-SHA256(secret, body_raw) en hex. Siempre verifica la firma con el body RAW antes de procesar el evento — un cliente HTTP que parseé el body como JSON y lo re-serialice puede romper la firma por diferencias de espacios.
Node.js (Express)
import crypto from "node:crypto";
import express from "express";
const app = express();
const SECRET = process.env.DOCLAYER_WEBHOOK_SECRET; // "whsec_..."
// IMPORTANTE: usa el body RAW (Buffer), no JSON parseado.
app.post("/webhook/doclayer", express.raw({ type: "application/json" }), (req, res) => {
const signature = req.header("X-DocLayer-Signature") || "";
const expected = "sha256=" + crypto.createHmac("sha256", SECRET)
.update(req.body)
.digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
return res.status(401).end();
}
const event = JSON.parse(req.body.toString("utf8"));
// event.evento === "documento.completado" | "documento.fallido"
// event.documento_id, event.plantilla_nombre, etc.
res.status(200).end();
});Python (Flask)
import hmac, hashlib, os
from flask import Flask, request, abort
app = Flask(__name__)
SECRET = os.environ["DOCLAYER_WEBHOOK_SECRET"].encode() # "whsec_..."
@app.post("/webhook/doclayer")
def doclayer_webhook():
signature = request.headers.get("X-DocLayer-Signature", "")
expected = "sha256=" + hmac.new(SECRET, request.data, hashlib.sha256).hexdigest()
if not hmac.compare_digest(signature, expected):
abort(401)
event = request.get_json()
# event["evento"], event["documento_id"], etc.
return ("", 200)C# (ASP.NET Core minimal API)
using System.Security.Cryptography;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
var secret = Environment.GetEnvironmentVariable("DOCLAYER_WEBHOOK_SECRET")!; // "whsec_..."
app.MapPost("/webhook/doclayer", async (HttpRequest request) =>
{
// IMPORTANTE: lee el body RAW antes de cualquier deserialización.
using var reader = new StreamReader(request.Body);
var body = await reader.ReadToEndAsync();
var signature = request.Headers["X-DocLayer-Signature"].ToString();
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(body));
var expected = "sha256=" + Convert.ToHexString(hash).ToLowerInvariant();
if (!CryptographicOperations.FixedTimeEquals(
Encoding.UTF8.GetBytes(signature),
Encoding.UTF8.GetBytes(expected)))
{
return Results.Unauthorized();
}
var evt = System.Text.Json.JsonDocument.Parse(body).RootElement;
// evt.GetProperty("evento").GetString()
// evt.GetProperty("documento_id").GetInt32()
return Results.Ok();
});
app.Run();Go (net/http)
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"io"
"net/http"
"os"
)
func main() {
secret := []byte(os.Getenv("DOCLAYER_WEBHOOK_SECRET")) // "whsec_..."
http.HandleFunc("/webhook/doclayer", func(w http.ResponseWriter, r *http.Request) {
// IMPORTANTE: lee el body RAW antes de cualquier decode JSON.
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "", http.StatusBadRequest)
return
}
received := r.Header.Get("X-DocLayer-Signature")
mac := hmac.New(sha256.New, secret)
mac.Write(body)
expected := "sha256=" + hex.EncodeToString(mac.Sum(nil))
if !hmac.Equal([]byte(received), []byte(expected)) {
http.Error(w, "", http.StatusUnauthorized)
return
}
var event map[string]any
_ = json.Unmarshal(body, &event)
// event["evento"], event["documento_id"], etc.
w.WriteHeader(http.StatusOK)
})
http.ListenAndServe(":8080", nil)
}Reintentos
Si tu endpoint no responde con 2xx dentro de 10 segundos, DocLayer reintenta con backoff exponencial: 10s, 1min, 5min, 30min, 2h. Después de 5 intentos fallidos, la entrega queda marcada como failed y no se reintenta más. Puedes ver el historial de cada webhook en el portal.
Como los reintentos pueden llegar a tu sistema, procesa idempotente: usa X-DocLayer-Delivery-Id como clave de idempotencia. El mismo delivery_id nunca representa eventos distintos.
Disponibilidad
Webhooks están disponibles en los planes Pro y Enterprise. En planes Free y Starter, la creación devuelve 402 Payment Required.
Endpoints
/api/pingVerificar autenticación
Devuelve los datos básicos de tu empresa. Útil para validar que tu API key funciona.
Parámetros
| Nombre | En | Tipo | Requerido | Descripción |
|---|---|---|---|---|
X-API-Key | header | string | Sí | Tu API key generada en /portal/api-keys. |
Ejemplo
curl -X GET https://api.doclayer.mx/api/ping \
-H "X-API-Key: dl_live_YOUR_API_KEY_HERE"Respuesta
{
"empresa_id": 1,
"empresa": "ACME S.A. de C.V.",
"plan": "starter"
}Errores posibles
| Código | Razón |
|---|---|
401 | API key faltante o inválida |
403 | Empresa inactiva o plan free |
/api/plantillasListar plantillas
Devuelve todas las plantillas activas de tu empresa, ordenadas por última actualización.
Parámetros
| Nombre | En | Tipo | Requerido | Descripción |
|---|---|---|---|---|
X-API-Key | header | string | Sí | Tu API key generada en /portal/api-keys. |
include_inactive | query | boolean | No | Si es true, incluye plantillas dadas de baja. |
created_from | query | ISO 8601 datetime | No | Filtra plantillas creadas desde esta fecha. |
created_to | query | ISO 8601 datetime | No | Filtra plantillas creadas hasta esta fecha. |
updated_from | query | ISO 8601 datetime | No | Filtra plantillas actualizadas desde esta fecha. |
updated_to | query | ISO 8601 datetime | No | Filtra plantillas actualizadas hasta esta fecha. |
Ejemplo
curl -X GET https://api.doclayer.mx/api/plantillas \
-H "X-API-Key: dl_live_YOUR_API_KEY_HERE"Respuesta
[
{
"id": 12,
"empresa_id": 1,
"nombre": "Cotización 2026",
"descripcion": "Cotización con datos de empresa y cliente",
"activa": true,
"created_at": "2026-04-23T16:05:20.123Z",
"updated_at": "2026-05-09T12:30:45.789Z"
}
]Errores posibles
| Código | Razón |
|---|---|
401 | API key faltante o inválida |
403 | Empresa inactiva o plan Free (sin acceso API) |
/api/plantillas/{id}Obtener una plantilla
Devuelve una plantilla activa específica, incluyendo su HTML completo.
Parámetros
| Nombre | En | Tipo | Requerido | Descripción |
|---|---|---|---|---|
X-API-Key | header | string | Sí | Tu API key generada en /portal/api-keys. |
id | path | integer | Sí | ID numérico de la plantilla. |
Ejemplo
curl -X GET https://api.doclayer.mx/api/plantillas/12 \
-H "X-API-Key: dl_live_YOUR_API_KEY_HERE"Respuesta
{
"id": 12,
"empresa_id": 1,
"nombre": "Cotización 2026",
"descripcion": "Cotización con datos de empresa y cliente",
"html": "<!doctype html>...",
"activa": true,
"created_at": "2026-04-23T16:05:20.123Z",
"updated_at": "2026-05-09T12:30:45.789Z"
}Errores posibles
| Código | Razón |
|---|---|
401 | API key faltante o inválida |
403 | Empresa inactiva o plan Free (sin acceso API) |
404 | Plantilla no encontrada o no pertenece a tu empresa |
/api/plantillasCrear plantilla
Crea una plantilla nueva. Si tu plan es Free, máximo 1 plantilla activa.
Parámetros
| Nombre | En | Tipo | Requerido | Descripción |
|---|---|---|---|---|
X-API-Key | header | string | Sí | Tu API key generada en /portal/api-keys. |
Content-Type | header | string | Sí | Debe ser application/json. |
nombre | body | string (max 150) | Sí | Nombre legible de la plantilla. Único por empresa. |
html | body | string | Sí | HTML completo con variables {{variable}} (notación con / para anidados). |
descripcion | body | string (max 500) | No | Descripción opcional de para qué sirve la plantilla. |
Ejemplo
curl -X POST https://api.doclayer.mx/api/plantillas \
-H "X-API-Key: dl_live_YOUR_API_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{"nombre": "Cotización 2026","html": "<!doctype html><html><body><h1>{{empresa/nombre}}</h1></body></html>","descripcion": "Cotización con datos de empresa y cliente"}'Respuesta
{
"id": 12,
"empresa_id": 1,
"nombre": "Cotización 2026",
"descripcion": "Cotización con datos de empresa y cliente",
"activa": true,
"created_at": "2026-05-09T12:30:45.789Z",
"updated_at": "2026-05-09T12:30:45.789Z"
}Errores posibles
| Código | Razón |
|---|---|
400 | nombre o html faltantes, nombre supera 150 caracteres, o descripcion supera 500 caracteres |
401 | API key faltante o inválida |
402 | Plan Free ya tiene 1 plantilla activa |
403 | Empresa inactiva o plan Free (sin acceso API) |
409 | Ya existe una plantilla con ese nombre en tu empresa |
/api/plantillas/{id}Actualizar plantilla
Sobrescribe nombre, HTML y opcionalmente descripción de una plantilla. Reactiva la plantilla si estaba inactiva.
Parámetros
| Nombre | En | Tipo | Requerido | Descripción |
|---|---|---|---|---|
X-API-Key | header | string | Sí | Tu API key generada en /portal/api-keys. |
Content-Type | header | string | Sí | Debe ser application/json. |
id | path | integer | Sí | ID de la plantilla a actualizar. |
nombre | body | string (max 150) | Sí | Nuevo nombre. |
html | body | string | Sí | Nuevo HTML. |
descripcion | body | string (max 500) | No | Nueva descripción. Si se omite, se mantiene la actual. Si se manda string vacío o solo espacios, se borra (null). |
Ejemplo
curl -X PUT https://api.doclayer.mx/api/plantillas/12 \
-H "X-API-Key: dl_live_YOUR_API_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{"nombre": "Cotización 2026 v2","html": "<!doctype html>...","descripcion": "Cotización actualizada con nuevo IVA"}'Respuesta
{
"id": 12,
"empresa_id": 1,
"nombre": "Cotización 2026 v2",
"descripcion": "Cotización actualizada con nuevo IVA",
"activa": true,
"created_at": "2026-04-23T16:05:20.123Z",
"updated_at": "2026-05-09T13:15:00.000Z"
}Errores posibles
| Código | Razón |
|---|---|
400 | nombre o html faltantes, nombre supera 150 caracteres, o descripcion supera 500 caracteres |
401 | API key faltante o inválida |
403 | Empresa inactiva o plan Free (sin acceso API) |
404 | Plantilla no encontrada |
409 | Ya existe otra plantilla con ese nombre |
/api/plantillas/{id}Dar de baja plantilla
Marca la plantilla como inactiva (soft delete). No se elimina físicamente; podés reactivarla con PUT.
Parámetros
| Nombre | En | Tipo | Requerido | Descripción |
|---|---|---|---|---|
X-API-Key | header | string | Sí | Tu API key generada en /portal/api-keys. |
id | path | integer | Sí | ID de la plantilla. |
Ejemplo
curl -X DELETE https://api.doclayer.mx/api/plantillas/12 \
-H "X-API-Key: dl_live_YOUR_API_KEY_HERE"Respuesta
(204 No Content — sin body)Errores posibles
| Código | Razón |
|---|---|
401 | API key faltante o inválida |
403 | Empresa inactiva o plan Free (sin acceso API) |
404 | Plantilla no encontrada |
/api/documentosGenerar PDF
Renderiza una plantilla con tus datos y devuelve el PDF binario. Cuenta para tu cupo mensual.
Parámetros
| Nombre | En | Tipo | Requerido | Descripción |
|---|---|---|---|---|
X-API-Key | header | string | Sí | Tu API key generada en /portal/api-keys. |
Content-Type | header | string | Sí | Debe ser application/json. |
plantilla_id | body | integer | Sí | ID de la plantilla a usar. |
json | body | object | No | Datos en JSON. Las claves se mapean a variables {{var}} de la plantilla. Acepta anidación con /. Mutuamente excluyente con xml. Máximo 512 KB. |
xml | body | string | No | Datos en XML como string. Mutuamente excluyente con json. Máximo 512 KB. |
request_hash | body | string | No | Idempotency key. Si ya procesaste el mismo hash, devuelve 409 con el documento_id existente en lugar de duplicar. |
Ejemplo
curl -X POST https://api.doclayer.mx/api/documentos \
-H "X-API-Key: dl_live_YOUR_API_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{"plantilla_id": 12,"json": {"empresa": { "nombre": "ACME" },"cliente": { "nombre": "Juan Pérez" },"cotizacion": {"folio": "2026-001","total": "$149,000 MXN"}},"request_hash": "abc-def-123"}' \
--output documento.pdfRespuesta
(binary application/pdf)Headers de respuesta
| Header | Descripción |
|---|---|
X-Document-Id | ID del documento generado en tu histórico. |
X-Usage-Count | Cuántos PDFs llevas generados en el ciclo actual. |
X-Usage-Limit | Tu cupo total del ciclo. |
Retry-After | Segundos a esperar antes de reintentar. Solo aparece en respuestas 429 (rate limit) y 503 (cola saturada). |
Errores posibles
| Código | Razón |
|---|---|
400 | Falta plantilla_id; no se envió json ni xml; se enviaron json Y xml al mismo tiempo (son mutuamente excluyentes); payload supera 512 KB; o JSON/XML malformado |
401 | API key faltante o inválida |
403 | Empresa inactiva o plan Free (sin acceso API) |
404 | Plantilla no encontrada o inactiva |
409 | request_hash ya procesado. Body: { "error": "...", "documento_id": 1234 } |
422 | La plantilla existe pero tiene HTML vacío |
429 | Rate limit por minuto pegado — body: { error, plan, requests_per_minute, retry_after_seconds }. O cupo mensual agotado — body: { error, documentos_generados, documentos_max }. Ambos incluyen header Retry-After. |
503 | Cola de renderizado saturada (>3 simultáneos). Reintenta en 30s (header Retry-After) |
504 | El render tardó demasiado (timeout) |
/api/webhooksListar endpoints de webhook
Devuelve todos los endpoints de webhook configurados para tu empresa, ordenados por fecha de creación descendente. Disponible en planes Pro y Enterprise.
Parámetros
| Nombre | En | Tipo | Requerido | Descripción |
|---|---|---|---|---|
X-API-Key | header | string | Sí | Tu API key generada en /portal/api-keys. |
Ejemplo
curl -X GET https://api.doclayer.mx/api/webhooks \
-H "X-API-Key: dl_live_YOUR_API_KEY_HERE"Respuesta
[
{
"id": 7,
"url": "https://miempresa.com/webhooks/doclayer",
"eventos": ["documento.completado", "documento.fallido"],
"descripcion": "Producción",
"activo": true,
"created_at": "2026-05-09T12:30:45.789Z",
"last_delivery_at": "2026-05-11T08:32:13.645Z"
}
]Errores posibles
| Código | Razón |
|---|---|
401 | API key faltante o inválida |
403 | Empresa inactiva o plan Free (sin acceso API) |
/api/webhooksCrear endpoint de webhook
Registra una URL donde DocLayer enviará eventos. Devuelve el secret (whsec_*) en texto plano una sola vez — guárdalo, no se puede consultar después. Requiere plan Pro o Enterprise.
Parámetros
| Nombre | En | Tipo | Requerido | Descripción |
|---|---|---|---|---|
X-API-Key | header | string | Sí | Tu API key generada en /portal/api-keys. |
Content-Type | header | string | Sí | Debe ser application/json. |
url | body | string (https) | Sí | URL absoluta https donde recibirás los POSTs. Solo http permitido si es localhost. |
eventos | body | string[] | Sí | Array de eventos a suscribir. Valores permitidos: documento.completado, documento.fallido. |
descripcion | body | string | No | Etiqueta opcional para distinguir endpoints (ej: "producción", "staging"). |
Ejemplo
curl -X POST https://api.doclayer.mx/api/webhooks \
-H "X-API-Key: dl_live_YOUR_API_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{"url": "https://miempresa.com/webhooks/doclayer","eventos": ["documento.completado", "documento.fallido"],"descripcion": "Producción"}'Respuesta
{
"id": 7,
"url": "https://miempresa.com/webhooks/doclayer",
"eventos": ["documento.completado", "documento.fallido"],
"descripcion": "Producción",
"activo": true,
"secret": "whsec_a3f5b8c9d2e1...",
"created_at": "2026-05-11T08:32:13.645Z"
}Errores posibles
| Código | Razón |
|---|---|
400 | url requerida, url no es absoluta o no es https, o eventos inválidos |
401 | API key faltante o inválida |
402 | Crear webhook requiere plan Pro o Enterprise. Nota: si haces downgrade a Starter, los webhooks existentes siguen disparándose; para detenerlos usa PATCH activo=false o DELETE. |
403 | Empresa inactiva o plan Free (sin acceso API) |
/api/webhooks/{id}Actualizar endpoint de webhook
Modifica activo, eventos o descripcion. Solo los campos enviados se actualizan. La URL y el secret son inmutables — para cambiarlos crea un endpoint nuevo.
Parámetros
| Nombre | En | Tipo | Requerido | Descripción |
|---|---|---|---|---|
X-API-Key | header | string | Sí | Tu API key generada en /portal/api-keys. |
Content-Type | header | string | Sí | Debe ser application/json. |
id | path | integer | Sí | ID del webhook. |
activo | body | boolean | No | true para activar, false para pausar entregas. |
eventos | body | string[] | No | Nuevo set de eventos. Reemplaza el actual (no es merge). |
descripcion | body | string | No | Nueva descripción. String vacío para borrarla. |
Ejemplo
curl -X PATCH https://api.doclayer.mx/api/webhooks/12 \
-H "X-API-Key: dl_live_YOUR_API_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{"activo": false,"descripcion": "Pausado mientras migramos a nueva infra"}'Respuesta
{
"id": 7,
"url": "https://miempresa.com/webhooks/doclayer",
"eventos": ["documento.completado", "documento.fallido"],
"descripcion": "Pausado mientras migramos a nueva infra",
"activo": false
}Errores posibles
| Código | Razón |
|---|---|
400 | eventos inválidos (valores no permitidos) |
401 | API key faltante o inválida |
403 | Empresa inactiva o plan Free (sin acceso API) |
404 | Webhook no encontrado o no pertenece a tu empresa |
/api/webhooks/{id}Eliminar endpoint de webhook
Elimina permanentemente un endpoint y todas sus entregas históricas. No es soft delete — no hay manera de recuperarlo.
Parámetros
| Nombre | En | Tipo | Requerido | Descripción |
|---|---|---|---|---|
X-API-Key | header | string | Sí | Tu API key generada en /portal/api-keys. |
id | path | integer | Sí | ID del webhook. |
Ejemplo
curl -X DELETE https://api.doclayer.mx/api/webhooks/12 \
-H "X-API-Key: dl_live_YOUR_API_KEY_HERE"Respuesta
(204 No Content — sin body)Errores posibles
| Código | Razón |
|---|---|
401 | API key faltante o inválida |
403 | Empresa inactiva o plan Free (sin acceso API) |
404 | Webhook no encontrado |
/api/webhooks/{id}/deliveriesListar entregas de un webhook
Devuelve las últimas 50 entregas (deliveries) de un endpoint, ordenadas por fecha descendente. Útil para depurar fallas — incluye intentos, último status code, último error y próximo reintento.
Parámetros
| Nombre | En | Tipo | Requerido | Descripción |
|---|---|---|---|---|
X-API-Key | header | string | Sí | Tu API key generada en /portal/api-keys. |
id | path | integer | Sí | ID del webhook. |
Ejemplo
curl -X GET https://api.doclayer.mx/api/webhooks/12/deliveries \
-H "X-API-Key: dl_live_YOUR_API_KEY_HERE"Respuesta
[
{
"id": 4521,
"documento_id": 1234,
"evento": "documento.completado",
"status": "delivered",
"intentos": 1,
"last_status_code": 200,
"last_error": null,
"created_at": "2026-05-11T08:32:13.645Z",
"last_attempt_at": "2026-05-11T08:32:14.012Z",
"next_attempt_at": null
},
{
"id": 4520,
"documento_id": 1233,
"evento": "documento.completado",
"status": "failing",
"intentos": 3,
"last_status_code": 502,
"last_error": "Bad Gateway",
"created_at": "2026-05-11T08:30:00.000Z",
"last_attempt_at": "2026-05-11T08:35:00.000Z",
"next_attempt_at": "2026-05-11T09:05:00.000Z"
}
]Errores posibles
| Código | Razón |
|---|---|
401 | API key faltante o inválida |
403 | Empresa inactiva o plan Free (sin acceso API) |
404 | Webhook no encontrado |