/v1/account/webhook-endpoints

account/webhook-endpoints

Webhookuri: unde trimite Monitoring noile Signals și cum le verifici.

Costuri și limite

Costuri și limite
Ce Credite
Gestionarea endpointurilor webhook și a livrărilor gratuit

Limită: 30 cereri pe minut. Creare, modificare și ștergere: 10 pe minut. Verificare, test și secret nou: 6 pe minut.

Token admin sau cheie API

Endpointuri

Metodă
Metodă Cale Scop Acces
GET /v1/account/webhook-endpoints Toate endpointurile webhook, fără cele arhivate. Cheie API sau token admin
POST /v1/account/webhook-endpoints Creează un endpoint webhook. Token admin
POST /v1/account/webhook-endpoints/{id}/verify Verificare. Cheie API sau token admin
POST /v1/account/webhook-endpoints/{id}/test Trimite un mesaj de test. Cheie API sau token admin
POST /v1/account/webhook-endpoints/{id}/rotate-secret Secret de semnare nou. Token admin
POST /v1/account/webhook-endpoints/{id}/enable Activare. Token admin
POST /v1/account/webhook-endpoints/{id}/disable Dezactivare. Token admin
DELETE /v1/account/webhook-endpoints/{id} Arhivare. Token admin
GET /v1/account/webhook-deliveries Ultimele 50 livrări. Cheie API sau token admin
POST /v1/account/webhook-deliveries/{id}/retry Retrimite o livrare eșuată. Cheie API sau token admin
GET /v1/account/webhook-events Ultimele 50 evenimente. Cheie API sau token admin

Creează un endpoint webhook

curl -X POST "https://handelsregister.ai/api/v1/account/webhook-endpoints" \
  -H "Authorization: Bearer TOKENUL_TAU_ADMIN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "CRM-Sync",
    "url": "https://hooks.example.com/handelsregister",
    "headers": {
        "X-Receiver-Token": "TOKENUL_TAU_RECEPTOR"
    }
}'
Parametri
Nume Tip Descriere Exemplu
Idempotency-KeyHeader șir de caractereobligatoriu O valoare unică per operație, ideal un UUID. Vezi Idempotency-Key.Limite: 1 până la 128 caractere req-20260802-01
nameBody șir de caractereobligatoriu Un nume pentru propria ta referință.Limite: 1 până la 120 caractere CRM-Sync
urlBody șir de caractere (uri)obligatoriu Adresa serverului tău: accesibilă public, https pe portul 443, cu nume de host în loc de adresă IP.Limite: 1 până la 2.048 caractere https://hooks.example.com/handelsregister
headersBody obiectopțional Headere personalizate trimise cu fiecare mesaj, de ex. un token pentru serverul tău.Limite: cel mult 10 intrări {"X-Receiver-Token":"TOKENUL_TAU_RECEPTOR"}
1{2  "endpoint": {3    "id": "wep_01m6b3j1g0cdz98hw8zdefbf52",4    "name": "CRM-Sync",5    "url": "hooks.example.com/…",6    "status": "pending_verification",7    "verified_at": null,8    "header_names": [9      "X-Receiver-Token"10    ],11    "consecutive_failures": 0,12    "created_at": "2026-11-01T08:28:01+00:00"13  },14  "signing_secret": "whsec_…",15  "meta": {16    "message": "Endpoint created. Store the signing secret now — it is shown only once.",17    "request_credit_cost": 0,18    "credits_remaining": 14519  }20}
201 · Răspuns exemplu: un endpoint webhook nou, secretul scurtat aici

Verificare

1{2  "id": "msg_01m6b3jsqq7ntwzkdj099ayraz",3  "type": "endpoint.verification",4  "timestamp": "2026-11-01T08:28:26.743Z",5  "schema_version": 1,6  "data": {7    "challenge": "189fb34b2af819bb13cb47d9806dbf30"8  }9}
Mesajul pe care serverul tău îl primește la verificare
curl -X POST "https://handelsregister.ai/api/v1/account/webhook-endpoints/wep_01m6b3j1g0cdz98hw8zdefbf52/verify" \
  -H "x-api-key: CHEIA_TA_API" \
  -H "Idempotency-Key: $(uuidgen)"
1{2  "verified": true,3  "endpoint": {4    "id": "wep_01m6b3j1g0cdz98hw8zdefbf52",5    "name": "CRM-Sync",6    "url": "hooks.example.com/…",7    "status": "active",8    "verified_at": "2026-11-01T08:28:26+00:00",9    "header_names": [10      "X-Receiver-Token"11    ],12    "consecutive_failures": 0,13    "created_at": "2026-11-01T08:28:01+00:00"14  },15  "meta": {16    "request_credit_cost": 0,17    "credits_remaining": 14518  }19}
200 · Răspuns exemplu la o verificare reușită
1{2  "delivery": {3    "id": "del_01m6b3jsyrnc3sz1mt31dq6107",4    "message_id": "msg_01m6b3jsynxzhvagm7n2nq7mpv",5    "event_id": "evt_01m6b3jsynxzhvagm7n2nq7mpt",6    "event_type": "endpoint.test",7    "endpoint_id": "wep_01m6b3j1g0cdz98hw8zdefbf52",8    "status": "succeeded",9    "attempts": 1,10    "last_status_code": 200,11    "last_error_category": null,12    "next_attempt_at": "2026-11-01T08:28:26+00:00",13    "succeeded_at": "2026-11-01T08:28:26+00:00",14    "created_at": "2026-11-01T08:28:26+00:00"15  },16  "meta": {17    "request_credit_cost": 0,18    "credits_remaining": 14519  }20}
200 · Răspuns exemplu la un mesaj de test

Verifică semnătura

Header
Header Semnificație
webhook-id ID-ul mesajului (msg_…). Rămâne același la reîncercări. Folosește-l ca să recunoști duplicatele.
webhook-timestamp Momentul acestei încercări de livrare în secunde Unix.
webhook-signature Una sau mai multe semnături de forma v1,<Base64>, separate prin spații.
import base64, hashlib, hmac, time

def verify_webhook(secret: str, headers: dict, body: bytes) -> bool:
    msg_id = headers["webhook-id"]
    timestamp = headers["webhook-timestamp"]
    # Respinge mesajele mai vechi de cinci minute
    if abs(time.time() - int(timestamp)) > 300:
        return False
    key = base64.b64decode(secret.removeprefix("whsec_"))
    signed = f"{msg_id}.{timestamp}.".encode() + body
    expected = base64.b64encode(hmac.new(key, signed, hashlib.sha256).digest()).decode()
    # În timpul unei rotații a secretului, headerul conține două semnături
    for part in headers["webhook-signature"].split(" "):
        version, _, signature = part.partition(",")
        if version == "v1" and hmac.compare_digest(signature, expected):
            return True
    return False

Payload

Câmp
Câmp Semnificație
id ID-ul mesajului, egal cu headerul webhook-id.
event_id ID-ul evenimentului (evt_…).
type Tipul evenimentului, vezi mai jos.
timestamp Când am detectat evenimentul, în UTC.
schema_version Versiunea structurii, momentan 1.
data Datele evenimentului.
Tipuri de evenimente
Tip de eveniment Semnificație
organization.signal.detected Un monitor a găsit un semnal nou. data.signal are aceeași structură ca un semnal în signals, plus data.monitor și, la data.links.signal, linkul către semnal în API.
organization.signal.sample Un exemplu din istoricul real al companiei, trimis din Cont › Monitoring. Aceeași structură ca mai sus, plus data.sample: true.
endpoint.test Mesaj de test prin /test.
endpoint.verification Challenge la verificare.
1{2  "id": "msg_01m65pqg9x0176cteqvtxw68sa",3  "event_id": "evt_01m65pqg9sx7mwmw0edc1mfbbe",4  "type": "organization.signal.sample",5  "timestamp": "2026-10-30T06:07:37.000Z",6  "schema_version": 1,7  "data": {8    "monitor": {9      "id": "mon_01m65pn3vm11sjjp1j076cbvec",10      "type": "organization.signals"11    },12    "sample": true,13    "signal": {14      "event": {15        "id": "36c7c8fddf99bb0299d6815bcaa01013",16        "topic": "TRANSFORMATIONS",17        "topic_name": {18          "de": "Umwandlungen & M&A",19          "en": "Transformations & M&A"20        },21        "occurred_on": "2022-12-22",22        "announced_on": "2023-08-10",23        "date_basis": "SOURCE_EVENT"24      },25      "organization": {26        "type": "ORGANIZATION",27        "entity_id": "94eb910fef13f94585c48c263fa446d4",28        "current_profile": {29          "name": "Hetzner Online GmbH",30          "registration": {31            "register_type": "HRB",32            "register_number": "6089",33            "court": "Ansbach",34            "register_locality": "Ansbach",35            "registration_authority_id": "D3201",36            "register_entity_name": "Ansbach HRB 6089"37          },38          "legal_form": {39            "name": {40              "de": "Gesellschaft mit beschränkter Haftung"41            },42            "short": {43              "de": "GmbH"44            }45          },46          "seat": {47            "city": "Gunzenhausen"48          },49          "status": {50            "code": "ACTIVE"51          }52        }53      },54      "parties": {55        "counterparty": {56          "entity": {57            "type": "ORGANIZATION",58            "entity_id": "dd4d2d6854b2dbd1ffce74e669f3852e",59            "current_profile": {60              "name": "Headtrip GmbH",61              "registration": {62                "register_type": "HRB",63                "register_number": "33432",64                "court": "Nürnberg",65                "register_locality": "Nuremberg",66                "registration_authority_id": "D3310",67                "register_entity_name": "Nürnberg HRB 33432"68              },69              "legal_form": {70                "name": {71                  "de": "Gesellschaft mit beschränkter Haftung"72                },73                "short": {74                  "de": "GmbH"75                }76              },77              "seat": {78                "city": "Nürnberg"79              },80              "status": {81                "code": "INACTIVE"82              }83            }84          },85          "relationship": "TRANSFERRING_COMPANY"86        }87      },88      "register_entry": {89        "entry_number": "3",90        "entry_date": "2023-08-10",91        "description_text": "Verschmelzung zur Aufnahme der Headtrip GmbH",92        "context": "PRIMARY",93        "flags": []94      },95      "source": {96        "kind": "COMMERCIAL_REGISTER"97      },98      "details": {99        "schema": "TRANSFORMATION",100        "kind": "MERGER",101        "specifics": {102          "merger_target": "ABSORPTION"103        },104        "direction": "INCOMING",105        "is_cross_border": false,106        "resolution_date": "2022-12-22",107        "agreement_date": "2022-12-22"108      }109    },110    "links": {111      "signal": "https://handelsregister.ai/api/v1/signals/36c7c8fddf99bb0299d6815bcaa01013"112    }113  }114}
Mesaj exemplu pentru Hetzner Online GmbH, Ansbach HRB 6089: fuziunea Headtrip GmbH, Nürnberg HRB 33432, trimis ca exemplu din istoric

Livrări și reîncercări

Livrăm fiecare mesaj cel puțin o dată, dar nu într-o ordine fixă. Recunoaște duplicatele după webhook-id. Răspunde repede și procesează mesajul abia după aceea.
Statusul unei livrări
Status Semnificație
withheld Așteaptă până se facturează verificarea.
pending Așteaptă să fie trimisă.
in_flight Se trimite chiar acum.
retry_wait Așteaptă următoarea încercare.
succeeded Livrată.
exhausted Toate încercările au eșuat.
blocked_endpoint Endpointul webhook nu poate primi nimic momentan.
cancelled Anulată, de exemplu pentru că mesajul a expirat.

Activare, dezactivare, arhivare

curl -X POST "https://handelsregister.ai/api/v1/account/webhook-endpoints/wep_01m6b3j1g0cdz98hw8zdefbf52/disable" \
  -H "Authorization: Bearer TOKENUL_TAU_ADMIN" \
  -H "Idempotency-Key: $(uuidgen)"

Erori

Erori
Status Cauză Ce poți face
400 api_key se află în URL. Trimite cheia în headerul x-api-key.
400 URL-ul nu este permis ca destinație, un header nu este permis, s-a atins numărul maxim sau endpointul webhook nu este activ. meta.message indică motivul. Corectează valoarea sau verifică mai întâi.
400 Idempotency-Key are un format invalid. Corectează formatul, de exemplu folosește un UUID.
401 Nicio cheie API sau token ori unul invalid. Trimite cheia în headerul x-api-key.
403 Bearer tokenului îi lipsește dreptul account:read. Folosește cheia API sau un token cu account:read.
403 Adresa de e-mail a contului tău nu este încă confirmată sau contul este blocat. Deschide linkul din e-mailul de confirmare. Dacă contul este blocat, te poate ajuta suportul.
403 Acest apel are nevoie de tokenul admin. O cheie API nu ajunge, nici alt token. Trimite-l cu Authorization: Bearer și tokenul admin.
403 Bearer tokenului îi lipsește dreptul monitoring:manage. Folosește cheia API sau tokenul admin.
404 Niciun endpoint webhook sau livrare cu acest ID. Verifică ID-ul.
409 Idempotency-Key a fost deja folosit cu alte date, este mai vechi de 24 de ore sau încă se procesează. Folosește o cheie nouă sau așteaptă puțin.
422 O valoare lipsește sau este invalidă, de ex. name sau url. errors numește câmpul. Corectează valoarea și reîncearcă cu o cheie nouă.
422 Verificarea a eșuat. Verifică headerul challenge și statusul 2xx, apoi reîncearcă cu o cheie nouă.
428 Lipsește headerul Idempotency-Key. Trimite headerul.
429 Prea multe cereri. Reîncearcă după Retry-After.
503 Verificarea, testarea și retrimiterea sunt temporar indisponibile. Reîncearcă puțin mai târziu.
1{2  "error": "invalid_request",3  "meta": {4    "message": "The endpoint is not active.",5    "request_credit_cost": 0,6    "credits_remaining": 1457  }8}
400 · Un endpoint webhook care nu este încă verificat nu poate primi un mesaj de test