/v1/account/monitors
account/monitors
Monitoring: haz vigilar empresas; crear, pausar, eliminar.
Un monitor vigila una empresa por ti. Con un intervalo fijo comprobamos si hay nuevas señales y enviamos cada señal nueva por webhook a tus endpoints de webhook.
Costes y límites
| Qué | Créditos |
|---|---|
| Monitor comprobado cada día, durante 30 días | 50 |
| Monitor comprobado cada 3 días, durante 30 días | 40 |
| Monitor comprobado cada 7 días, durante 30 días | 20 |
| Monitor comprobado cada 30 días, durante 30 días | 10 |
| Cada comprobación correcta adicional en el periodo | +2 |
Límite: 30 solicitudes por minuto. Crear, modificar y eliminar: 10 por minuto.
Crear un monitor y la primera línea base son gratis. Un ciclo de 30 días se cobra en cuanto el monitor se activa. El precio depende del intervalo de comprobación y cubre todas las comprobaciones que el intervalo programa dentro de un ciclo.
Un intervalo entre dos escalones cuesta lo mismo que el siguiente escalón más frecuente: cada cuatro días cuesta lo mismo que cada tres días.
Las comprobaciones adicionales se producen sobre todo cuando acortas el intervalo a mitad de un ciclo. Cada comprobación adicional correcta cuesta el importe de la tabla.
Pasados 30 días, el ciclo se renueva automáticamente al precio vigente entonces. Las comprobaciones fallidas no cuestan nada. Si pausas, archivas o cambias el intervalo, no reembolsamos nada.
Cada cuenta puede tener hasta 50 monitores a la vez, uno por empresa. En 24 horas puedes crear hasta 50 monitores; los archivados también cuentan.
El precio de un intervalo lo obtienes gratis con GET /v1/account/monitoring/pricing, aquí para una comprobación cada siete días:
curl -G "https://handelsregister.ai/api/v1/account/monitoring/pricing" \ -H "x-api-key: TU_CLAVE_API" \ --data-urlencode 'poll_interval_days=7'
import requests response = requests.get( "https://handelsregister.ai/api/v1/account/monitoring/pricing", headers={"x-api-key": "TU_CLAVE_API"}, params={ "poll_interval_days": "7", }, ) data = response.json()
const url = new URL("https://handelsregister.ai/api/v1/account/monitoring/pricing"); url.searchParams.append("poll_interval_days", "7"); const response = await fetch(url, { headers: { "x-api-key": "TU_CLAVE_API" }, }); const data = await response.json();
1{2 "pricing": {3 "policy_version": "2026-08.v2",4 "credits_per_run": 2,5 "cycle_minimum_credits": 20,6 "included_runs": 5,7 "cycle_days": 30,8 "estimated_runs": 5,9 "estimated_credits": 2010 },11 "entitled": true,12 "meta": {13 "request_credit_cost": 0,14 "credits_remaining": 14515 }16}
Cómo funciona un monitor
- Crear. Indicas la empresa, el intervalo de comprobación y al menos un endpoint de webhook verificado. El monitor empieza con el estado
initializing. - Línea base. Registramos como conocidas las señales de los últimos días. No se entregan, así que solo recibes lo nuevo a partir de ahí.
- Activar. Cobramos el ciclo, el monitor pasa a
activey comprueba por primera vez al momento. - Comprobar. Después comprueba con el intervalo elegido. Cada señal nueva genera un mensaje por monitor a tus endpoints de webhook.
- Renovar. Tras cada ciclo se cobra automáticamente el siguiente, mientras tu saldo lo cubra.
El intervalo de comprobación está entre 1 y 30 días. El momento exacto de una comprobación puede variar dentro de una hora. Cada comprobación mira unos días hacia atrás, para que también lleguen las inscripciones publicadas tarde.
Un monitor entrega los temas de Signals de tu plan: cinco en cualquier cuenta, Insolvencias con Pro, Transformaciones y M&A con Max. Un webhook lleva en el campo data.signal la misma señal que signals.
| Estado | Significado |
|---|---|
| initializing | Creado; la línea base y la activación están en curso. |
| active | Comprueba con el intervalo elegido. |
| paused_user | Pausado por ti. |
| paused_configuration | Ya no hay conectado ningún endpoint de webhook activo y verificado. |
| paused_billing | Tu saldo no cubre el ciclo o una comprobación adicional. O el precio ha cambiado y espera tu conformidad. |
| error | Varias comprobaciones seguidas han fallado. |
| archived | Terminado definitivamente. Aún puedes leer el monitor por su ID, pero ya no aparece en la lista. |
En monitores pausados y con errores, status_reason explica por qué, por ejemplo no_verified_endpoint o insufficient_cycle_floor.
Endpoints
Todas las rutas están bajo /v1/account. Lees y escribes con tu clave API en el header x-api-key.
| Método | Ruta | Para qué |
|---|---|---|
| GET |
/v1/account/monitors |
Todos los monitores, los más recientes primero, sin los archivados. |
| POST |
/v1/account/monitors |
Crear un monitor. |
| GET |
/v1/account/monitors/{id} |
Un monitor con su ciclo y sus últimas comprobaciones. |
| PATCH |
/v1/account/monitors/{id} |
Cambiar el intervalo de comprobación. |
| POST |
/v1/account/monitors/{id}/pause |
Pausar. |
| POST |
/v1/account/monitors/{id}/resume |
Reanudar. |
| DELETE |
/v1/account/monitors/{id} |
Archivar. |
| GET |
/v1/account/monitoring/pricing |
Precio de un intervalo. |
Idempotency-Key
Cada solicitud de escritura necesita el header Idempotency-Key, un valor único por operación, idealmente un UUID. Sin él, la API responde con 428.
Si repites una solicitud con la misma clave y los mismos datos en 24 horas, recibes de vuelta la respuesta guardada. Lleva el header Idempotency-Status: replayed. Así un error de red no crea un segundo monitor.
Esto aplica también a las respuestas de error. Así que, para un nuevo intento tras una corrección, usa una clave nueva. La misma clave con datos distintos devuelve 409.
Se permiten hasta 128 caracteres: letras, dígitos y . _ : -. El primer carácter es una letra o un dígito. Una clave con cualquier otro formato devuelve 400.
Crear un monitor
Necesitas la entity_id de la empresa y al menos un endpoint de webhook verificado, consulta account/webhook-endpoints.
curl -X POST "https://handelsregister.ai/api/v1/account/monitors" \ -H "x-api-key: TU_CLAVE_API" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "entity_id": "94eb910fef13f94585c48c263fa446d4", "label": "Hetzner Online GmbH", "poll_interval_days": 7, "endpoint_ids": [ "wep_01m6b3j1g0cdz98hw8zdefbf52" ] }'
import uuid import requests response = requests.post( "https://handelsregister.ai/api/v1/account/monitors", headers={ "x-api-key": "TU_CLAVE_API", "Idempotency-Key": str(uuid.uuid4()), }, json={ "entity_id": "94eb910fef13f94585c48c263fa446d4", "label": "Hetzner Online GmbH", "poll_interval_days": 7, "endpoint_ids": [ "wep_01m6b3j1g0cdz98hw8zdefbf52" ] }, ) data = response.json()
const response = await fetch("https://handelsregister.ai/api/v1/account/monitors", { method: "POST", headers: { "x-api-key": "TU_CLAVE_API", "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json", }, body: JSON.stringify({ "entity_id": "94eb910fef13f94585c48c263fa446d4", "label": "Hetzner Online GmbH", "poll_interval_days": 7, "endpoint_ids": [ "wep_01m6b3j1g0cdz98hw8zdefbf52" ] }), }); const data = await response.json();
| Nombre | Tipo | Descripción | Ejemplo |
|---|---|---|---|
| Idempotency-KeyHeader | stringobligatorio | Un valor único por operación, idealmente un UUID. Consulta Idempotency-Key.Límites: 1 a 128 caracteres |
req-20260802-01 |
| entity_idBody | stringobligatorio |
La entity_id de la empresa de fetch-organization o search-organizations.Límites: 1 a 128 caracteres |
94eb910fef13f94585c48c263fa446d4 |
| labelBody | stringopcional | Un nombre para el monitor.Límites: como máximo 200 caracteres |
Hetzner Online GmbH |
| poll_interval_daysBody | integerobligatorio | Intervalo de comprobación en días.Límites: 1 a 30 |
7 |
| endpoint_idsBody | lista de stringobligatorio |
Los IDs de tus endpoints de webhook (wep_…). Cada uno debe estar activo y verificado.Límites: 1 a 10 entradas |
["wep_01m6b3j1g0cdz98hw8zdefbf52"] |
La API responde con 202: el monitor está creado, y la línea base y la activación se ejecutan en segundo plano. meta.billing.charged_credits muestra que no se cobró nada por ello.
1{2 "monitor": {3 "id": "mon_01m6b3m7945dn7cyvexzv41kjz",4 "type": "organization.signals",5 "entity_id": "94eb910fef13f94585c48c263fa446d4",6 "label": "Hetzner Online GmbH",7 "poll_interval_days": 7,8 "status": "initializing",9 "status_reason": null,10 "pricing_policy_version": "2026-08.v2",11 "baseline_completed_at": null,12 "activated_at": null,13 "last_succeeded_at": null,14 "next_poll_at": null,15 "created_at": "2026-11-01T08:29:13+00:00"16 },17 "meta": {18 "message": "Monitor created; the free baseline is queued and this request charged 0 credits. The cycle price is charged only when activation succeeds.",19 "baseline_queued": true,20 "billing": {21 "charged_credits": 0,22 "new_cycle": false,23 "floor_transaction_id": null24 },25 "request_credit_cost": 0,26 "credits_remaining": 14527 }28}
Listar y modificar monitores
GET /v1/account/monitors devuelve hasta 100 monitores en monitors, con total. Los archivados no están en la lista.
GET /v1/account/monitors/{id} muestra además el ciclo actual en billing_cycle y las últimas comprobaciones en recent_runs.
curl -G "https://handelsregister.ai/api/v1/account/monitors/mon_01m65pn3vm11sjjp1j076cbvec" \ -H "x-api-key: TU_CLAVE_API"
import requests response = requests.get( "https://handelsregister.ai/api/v1/account/monitors/mon_01m65pn3vm11sjjp1j076cbvec", headers={"x-api-key": "TU_CLAVE_API"}, ) data = response.json()
const url = new URL("https://handelsregister.ai/api/v1/account/monitors/mon_01m65pn3vm11sjjp1j076cbvec"); const response = await fetch(url, { headers: { "x-api-key": "TU_CLAVE_API" }, }); const data = await response.json();
1{2 "monitor": {3 "id": "mon_01m65pn3vm11sjjp1j076cbvec",4 "type": "organization.signals",5 "entity_id": "94eb910fef13f94585c48c263fa446d4",6 "label": "Hetzner Online GmbH",7 "poll_interval_days": 1,8 "status": "active",9 "status_reason": null,10 "pricing_policy_version": "2026-08.v2",11 "baseline_completed_at": "2026-10-30T06:06:28+00:00",12 "activated_at": "2026-10-30T06:06:28+00:00",13 "last_succeeded_at": "2026-10-30T06:06:53+00:00",14 "next_poll_at": "2026-10-31T06:19:12+00:00",15 "created_at": "2026-10-30T06:06:18+00:00"16 },17 "billing_cycle": {18 "starts_at": "2026-10-30T06:06:28+00:00",19 "ends_at": "2026-11-29T06:06:28+00:00",20 "floor_credits": 50,21 "credits_per_run": 2,22 "included_runs": 30,23 "successful_runs": 1,24 "extra_credits_settled": 0,25 "pricing_policy_version": "2026-08.v2"26 },27 "recent_runs": [28 {29 "due_slot_at": "2026-10-30T06:06:28+00:00",30 "kind": "activation_catchup",31 "status": "succeeded",32 "charge_state": "covered",33 "charge_credits": 0,34 "events_new": 0,35 "finished_at": "2026-10-30T06:06:55+00:00"36 }37 ],38 "meta": {39 "request_credit_cost": 0,40 "credits_remaining": 14541 }42}
| Campo | Significado |
|---|---|
| id |
ID del monitor, empieza por mon_.
|
| entity_id | La empresa vigilada. |
| poll_interval_days | Intervalo de comprobación en días. |
| status, status_reason |
Estado, consulta arriba. status_reason indica el motivo.
|
| baseline_completed_at, activated_at, last_succeeded_at | Momentos de la línea base, la activación y la última comprobación correcta. |
| next_poll_at | La próxima comprobación programada, solo en monitores activos. |
| billing_cycle | El ciclo actual: inicio, fin, precio, comprobaciones incluidas y comprobaciones hechas hasta ahora. |
| recent_runs |
Las últimas comprobaciones con resultado, cobro y el número de señales nuevas en events_new.
|
PATCH /v1/account/monitors/{id} cambia el intervalo de comprobación. La siguiente comprobación sigue entonces el nuevo intervalo, contado desde el cambio.
El ciclo actual mantiene su precio y sus comprobaciones incluidas. El nuevo precio rige desde el siguiente ciclo. Un intervalo más corto puede generar comprobaciones adicionales en el ciclo actual.
curl -X PATCH "https://handelsregister.ai/api/v1/account/monitors/mon_01m6b3m7945dn7cyvexzv41kjz" \ -H "x-api-key: TU_CLAVE_API" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "poll_interval_days": 30 }'
import uuid import requests response = requests.patch( "https://handelsregister.ai/api/v1/account/monitors/mon_01m6b3m7945dn7cyvexzv41kjz", headers={ "x-api-key": "TU_CLAVE_API", "Idempotency-Key": str(uuid.uuid4()), }, json={ "poll_interval_days": 30 }, ) data = response.json()
const response = await fetch("https://handelsregister.ai/api/v1/account/monitors/mon_01m6b3m7945dn7cyvexzv41kjz", { method: "PATCH", headers: { "x-api-key": "TU_CLAVE_API", "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json", }, body: JSON.stringify({ "poll_interval_days": 30 }), }); const data = await response.json();
1{2 "monitor": {3 "id": "mon_01m6b3m7945dn7cyvexzv41kjz",4 "type": "organization.signals",5 "entity_id": "94eb910fef13f94585c48c263fa446d4",6 "label": "Hetzner Online GmbH",7 "poll_interval_days": 30,8 "status": "initializing",9 "status_reason": null,10 "pricing_policy_version": "2026-08.v2",11 "baseline_completed_at": null,12 "activated_at": null,13 "last_succeeded_at": null,14 "next_poll_at": null,15 "created_at": "2026-11-01T08:29:13+00:00"16 },17 "meta": {18 "request_credit_cost": 0,19 "credits_remaining": 14520 }21}
Pausar, reanudar, archivar
POST …/{id}/pause detiene un monitor activo. El ciclo pagado sigue corriendo hasta su fin, y no se reembolsa nada.
POST …/{id}/resume reanuda un monitor pausado o con error. Volvemos a comprobar los endpoints de webhook, el saldo y el precio.
Dentro del ciclo pagado actual, reanudar no cuesta nada. Si el ciclo ha terminado, empieza ahora un ciclo nuevo al precio actual. meta.request_credit_cost muestra el importe.
Si, por ejemplo, falta un endpoint de webhook verificado, la API responde igualmente con 200, pero con meta.activated: false. El estado del monitor y status_reason indican el motivo.
Si el precio ha cambiado, un monitor activo se detiene al final del ciclo con pricing_consent_required. Con resume aceptas el nuevo precio.
DELETE …/{id} archiva el monitor definitivamente. Es irreversible y no reembolsa nada.
curl -X POST "https://handelsregister.ai/api/v1/account/monitors/mon_01m6b3m7945dn7cyvexzv41kjz/resume" \ -H "x-api-key: TU_CLAVE_API" \ -H "Idempotency-Key: $(uuidgen)"
import uuid import requests response = requests.post( "https://handelsregister.ai/api/v1/account/monitors/mon_01m6b3m7945dn7cyvexzv41kjz/resume", headers={ "x-api-key": "TU_CLAVE_API", "Idempotency-Key": str(uuid.uuid4()), }, ) data = response.json()
const response = await fetch("https://handelsregister.ai/api/v1/account/monitors/mon_01m6b3m7945dn7cyvexzv41kjz/resume", { method: "POST", headers: { "x-api-key": "TU_CLAVE_API", "Idempotency-Key": crypto.randomUUID(), }, }); const data = await response.json();
paused_configuration. Tras activar el endpoint de webhook, reanuda el monitor con resume.
Errores
Los errores tienen la estructura {"error": "…", "meta": {"message": "…"}}. En tu programa, comprueba el valor de error. El texto de meta.message está en inglés y puede cambiar. Los errores no cuestan nada.
| Estado | Causa | Qué puedes hacer |
|---|---|---|
| 400 |
api_key está en la URL. |
Envía la clave en el header x-api-key. |
| 400 |
El Idempotency-Key tiene un formato no válido. |
Corrige el formato, por ejemplo usa un UUID. |
| 401 | Ninguna clave API ni token, o uno no válido. |
Envía la clave en el header x-api-key. |
| 403 |
Al bearer token le falta el permiso account:read. |
Usa la clave API o un token con account:read. |
| 403 | La dirección de email de tu cuenta aún no está confirmada, o la cuenta está bloqueada. | Abre el enlace del email de confirmación. Si la cuenta está bloqueada, el soporte puede ayudarte. |
| 403 |
Al bearer token le falta el permiso monitoring:manage. |
Usa la clave API o el admin token. |
| 404 | Ningún monitor con este ID en tu cuenta. | Revisa el ID. |
| 409 |
Ya existe un monitor para esta empresa (duplicate_monitor). |
Usa el monitor existente o archívalo primero. |
| 409 |
El Idempotency-Key ya se usó con datos distintos, tiene más de 24 horas o aún se está procesando. |
Usa una clave nueva o espera un momento. |
| 422 |
Un valor no es válido: invalid_subject, invalid_interval, endpoint_required, monitor_limit o not_resumable. |
Corrige el valor. |
| 428 |
Falta el header Idempotency-Key. |
Envía el header. |
| 429 | Demasiadas solicitudes. |
Reintenta tras Retry-After. |
| 429 |
creation_rate_limited: demasiados monitores nuevos en 24 horas. |
Reintenta tras Retry-After. |
| 503 | Monitoring no está disponible temporalmente. | Reintenta un poco más tarde. |
1{2 "error": "duplicate_monitor",3 "meta": {4 "message": "You already have a monitor for this company.",5 "request_credit_cost": 0,6 "credits_remaining": 1457 }8}