Endpoints de la API. Especificación exacta de cada operación de la API v1 (parámetros, cuerpo, respuestas y ejemplos), generada del documento OpenAPI con el que se valida cada respuesta real. Los procedimientos completos están en Guías.
/webhooks
Crear una suscripción
Registra una URL para recibir los eventos indicados. La respuesta trae el secreto de firma (secret)
una sola vez: debe guardarse para verificar X-Chainlink-Signature. Si no se envía secret, Chainlink genera uno.
La URL debe usar https:// y apuntar a una dirección pública de internet: se rechazan con 422 las
direcciones privadas, locales, de enlace local, CGNAT, multicast, reservadas y de metadatos de la nube, en IPv4
e IPv6, también cuando el dominio resuelve a una de ellas. La comprobación se repite en cada entrega.
- Alcance (cliente de integración)
webhooks:manage- Permiso (token de usuario)
users.manage- Idempotency-Key
- Opcional
- Requisitos
- Plan Professional o Enterprise
Cabeceras
-
Idempotency-KeystringLlave única por operación (se recomienda un UUID v4). Reenviar la misma solicitud con la misma llave en las siguientes 24 horas devuelve la respuesta original sin repetir la operación.
Cuerpo de la solicitud application/json
-
urlstring (uri) obligatorioURL pública con https:// que recibirá los eventos. Se rechazan direcciones privadas, locales, de enlace local, CGNAT, multicast y de metadatos de la nube (IPv4 e IPv6), también si el dominio resuelve a ellas.
-
eventsarray de textos obligatorioValores:receipt.created,receipt.completed,picking.created,picking.completed,transfer.created,transfer.completed,transfer.dispatched,transfer.received,shipment.dispatched,return.received,return.dispositioned,packing_order.transitioned,rfid_validation.completed,product.created,product.updated,stock.updated,layout.published,wave.planned,wave.released,wave.completed,wave.cancelled -
secretstring | nullSecreto de firma propio; si no se envía, se genera uno.
Respuestas
201
Suscripción creada, con su secreto. Location apunta al nuevo recurso.
-
dataobjeto obligatorio9 campos de
data-
idinteger obligatorio -
urlstring (uri) obligatorio -
eventsarray de textos obligatorioValores:receipt.created,receipt.completed,picking.created,picking.completed,transfer.created,transfer.completed,transfer.dispatched,transfer.received,shipment.dispatched,return.received,return.dispositioned,packing_order.transitioned,rfid_validation.completed,product.created,product.updated,stock.updated,layout.published,wave.planned,wave.released,wave.completed,wave.cancelled -
is_activeboolean obligatorioSe desactiva sola tras 10 entregas fallidas seguidas.
-
failure_countinteger obligatorio -
last_triggered_atstring (date-time) | null -
created_atstring (date-time) | null -
updated_atstring (date-time) | null -
secretstring obligatorioSecreto de firma. Solo aparece en esta respuesta.
-
401 Falta el token o no es válido.
Cuerpo: el sobre de error.
402 La función no está en el plan de la empresa, o la cuenta está suspendida o cancelada.
Cuerpo: el sobre de error.
403
Al cliente le falta el alcance (missing_scope), al usuario el permiso (forbidden), o el token de usuario no
tiene acceso a la ruta (client_not_allowed: aplicación móvil o usuario con verificación en dos pasos).
Cuerpo: el sobre de error.
409
Otra solicitud con la misma Idempotency-Key sigue en proceso.
Cuerpo: el sobre de error.
422
Datos no válidos (validation_failed), una llave de idempotencia reutilizada con otra solicitud
(idempotency_key_reused) o una regla de negocio que bloquea la operación (rule_blocked).
Cuerpo: el sobre de error.
429
Se superó el límite por minuto. Reintente después de los segundos de Retry-After.
Cuerpo: el sobre de error.
Probar
Probar con una instancia
curl -X POST "https://empresa.chainlink.mx/api/v1/webhooks" \
-H "Authorization: Bearer $CHAINLINK_TOKEN" \
-H "Accept: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"url": "https://erp.example.com/chainlink/webhooks",
"events": [
"receipt.completed",
"picking.completed",
"stock.updated"
]
}'
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://empresa.chainlink.mx/api/v1/webhooks', [
'headers' => [
'Authorization' => 'Bearer ' . getenv('CHAINLINK_TOKEN'),
'Accept' => 'application/json',
'Idempotency-Key' => (string) \Ramsey\Uuid\Uuid::uuid4(),
],
'json' => [
'url' => 'https://erp.example.com/chainlink/webhooks',
'events' => [
'receipt.completed',
'picking.completed',
'stock.updated',
],
],
]);
$data = json_decode((string) $response->getBody(), true);
const response = await fetch('https://empresa.chainlink.mx/api/v1/webhooks', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.CHAINLINK_TOKEN}`,
Accept: 'application/json',
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"url": "https://erp.example.com/chainlink/webhooks",
"events": [
"receipt.completed",
"picking.completed",
"stock.updated"
]
}),
});
const data = await response.json();
import os
import uuid
import requests
response = requests.post(
"https://empresa.chainlink.mx/api/v1/webhooks",
headers={
"Authorization": f"Bearer {os.environ['CHAINLINK_TOKEN']}",
"Accept": "application/json",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"url": "https://erp.example.com/chainlink/webhooks",
"events": [
"receipt.completed",
"picking.completed",
"stock.updated"
]
},
)
data = response.json()
{
"data": {
"id": 3,
"url": "https://erp.example.com/chainlink/webhooks",
"events": [
"receipt.completed",
"picking.completed",
"stock.updated"
],
"is_active": true,
"failure_count": 0,
"last_triggered_at": null,
"created_at": "2026-10-06T16:40:00.000000Z",
"updated_at": "2026-10-06T16:40:00.000000Z",
"secret": "9f2c1d7e0a5b4c3d8e6f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d"
}
}
{
"error": {
"code": "unauthenticated",
"message": "Falta el token de acceso o ya no es válido.",
"doc_url": "https://chainlink.mx/developers/errores#unauthenticated",
"request_id": "req_01j9x2m4k7q8r5t6v3w0y1z2a3"
},
"errors": [],
"message": "Falta el token de acceso o ya no es válido."
}
{
"error": {
"code": "feature_not_in_plan",
"message": "Función no disponible en tu plan actual.",
"feature": "webhooks.enabled",
"upgrade_url": "/billing/plans",
"doc_url": "https://chainlink.mx/developers/errores#feature_not_in_plan",
"request_id": "req_01j9x2m4k7q8r5t6v3w0y1z2a3"
},
"errors": [],
"message": "Función no disponible en tu plan actual."
}
{
"error": {
"code": "missing_scope",
"message": "El cliente no tiene el alcance products:write.",
"scope": "products:write",
"doc_url": "https://chainlink.mx/developers/errores#missing_scope",
"request_id": "req_01j9x2m4k7q8r5t6v3w0y1z2a3"
},
"errors": [],
"message": "El cliente no tiene el alcance products:write."
}
{
"error": {
"code": "duplicate_in_flight",
"message": "Esta solicitud ya se está procesando.",
"doc_url": "https://chainlink.mx/developers/errores#duplicate_in_flight",
"request_id": "req_01j9x2m4k7q8r5t6v3w0y1z2a3"
},
"errors": [],
"message": "Esta solicitud ya se está procesando."
}
{
"error": {
"code": "validation_failed",
"message": "El campo name es obligatorio.",
"field": "name",
"doc_url": "https://chainlink.mx/developers/errores#validation_failed",
"request_id": "req_01j9x2m4k7q8r5t6v3w0y1z2a3"
},
"errors": [
{
"field": "name",
"message": "El campo name es obligatorio."
}
],
"message": "El campo name es obligatorio."
}
{
"error": {
"code": "rate_limited",
"message": "Superaste el límite de solicitudes por minuto. Espera los segundos que indica Retry-After.",
"doc_url": "https://chainlink.mx/developers/errores#rate_limited",
"request_id": "req_01j9x2m4k7q8r5t6v3w0y1z2a3"
},
"errors": [],
"message": "Superaste el límite de solicitudes por minuto. Espera los segundos que indica Retry-After."
}