Your AI Connector Docs

Webhooks API

Webhooks lader platformen give besked til dine andre systemer i det øjeblik, der sker noget — en ny kontakt, et svar, en booket aftale og mere. Denne API administrerer selve abonnementerne: hvilke URL’er der modtager hvilke hændelser. For information om, hvordan du modtager og verificerer de payloads, dit endpoint modtager, se Webhooks.

Alle stier herunder er relative til API’ets base-URL:

https://api.youraiconnector.com/v1

Enhver anmodning skal godkendes. Se Godkendelse for de fire accepterede metoder. Eksemplerne her bruger X-API-Key-headeren (og én forespørgselsparameter-form til cURL).

Bemærk: Webhooks skal være aktiveret for din konto. Hvis de ikke er det, returnerer disse slutpunkter en 403.


Hvordan abonnementer adresseres

Hvert abonnement har et id og et valgfrit name. Begge kan bruges som {webhookId} i stien til opdatering, sletning, test, sundhedstjek og genaktivering.

Foretræk navnet. Abonnements-id’er er positionelle, så de kan ændre sig, efter et andet abonnement er slettet. Hvis du angiver et stabilt name, når du opretter et abonnement, så adressér det ved navn for at undgå overraskelser.


List abonnementer

GET /webhooks

cURL

curl "https://api.youraiconnector.com/v1/webhooks?apiKey=YOUR_API_KEY"

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/webhooks", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/webhooks",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()

Svar

{
  "success": true,
  "webhooks": [
    {
      "id": "0",
      "name": "Order updates hook",
      "url": "https://hooks.example.com/incoming",
      "subscribed_to": ["Contact Created", "Replies"],
      "subscribed_to_tags": [],
      "created_at": "2026-06-09T12:00:00.000Z",
      "signing_enabled": true,
      "signing_secret_created_at": "2026-07-15T09:30:00.000Z",
      "retries_enabled": true,
      "enabled": true,
      "apply_to_sub_accounts": false
    }
  ]
}

signing_enabled og retries_enabled er tilvalg pr. abonnement, som begge er deaktiveret, medmindre du aktiverer dem. Se Signerede payloads og Forsøg igen.

apply_to_sub_accounts er tilvalget for bureau-arv — se Ét abonnement til alle klientkonti. Deaktiveret som standard og inaktivt på konti, der ikke har nogen klientkonti.

enabled er abonnementets tænd/sluk-knap — se Slukning af et abonnement. Slukkede abonnementer er stadig angivet her.

Selve signeringshemmeligheden er aldrig inkluderet her — læs den fra GET /webhooks/{id}/signing-secret.


List abonnerbare hændelsestyper

Returnerer de præcise strenge, du kan bruge i subscribed_to. Brug dette til at finde gyldige hændelsesnavne i stedet for at hardcode dem.

GET /webhooks/events

cURL

curl "https://api.youraiconnector.com/v1/webhooks/events" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/webhooks/events", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/webhooks/events",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()

Svar

Svaret er {"success": true, "events": [...]}, hvor events i øjeblikket indeholder 22 præcise strenge: Contact Created, Human Alerted, Appointment Booked, Replies, Reads, Deliveries, Credits Spent, Credits Recharged, Low Credit Balance, Contact Paused, Contact Do Not Disturb, Contact Unarchived, New Message, Contact Resumed, Chat Concluded, Task Created, Task Updated, Task Completed, Daily Summary Created, Channel Connected, Broadcast Started og Broadcast Completed (Channel Connected accepteres i subscribed_to, men intet udsender det i dag, så byg ikke mod det).

For hvad hver hændelse betyder, og den event-kode den sender i payloaden, se De 22 Webhook-hændelser. Dette endpoint er den autoritative liste til enhver tid — læs den live frem for at hardcode navnene.


Opret et abonnement

POST /webhooks

Felt Påkrævet Beskrivelse
url Ja HTTPS-URL, der modtager hændelses-payloads via POST. Skal være offentligt tilgængelig.
subscribed_to Ja Et ikke-tomt array af hændelsesnavne (se /webhooks/events).
name Nej Et visningsnavn. Kan også bruges som {webhookId} senere. Standard er et tidsstemplet navn.
subscribed_to_tags Nej Tag-ID’er, der indsnævrer, hvilke tags der producerer en besked om samtaleresumé. Det begrænser ikke abonnementets hændelser til disse tags — for at få en anmodning, når et specifikt tag tilføjes, skal du indstille en webhook-URL på det pågældende tag under fanen Tags for agenten (eller kampagnen).
retries_enabled Nej Boolesk værdi, standard er false. Tilmeld dig genforsøg af mislykkede leveringer.
generate_signing_secret Nej Boolesk værdi, standard er false. Opret en HMAC signaturhemmelighed sammen med abonnementet. Hemmeligheden returneres én gang som et signing_secret på øverste niveau i svaret.
enabled Nej Boolesk værdi, standard er true. Send false for at oprette abonnementet i deaktiveret tilstand. Se Deaktivering af et abonnement.
apply_to_sub_accounts Nej Boolesk værdi, standard er false. På en bureaukonto gør true, at dette abonnement også modtager hændelser fra alle klientkonti — se Ét abonnement til alle klientkonti.

URL-regler: URL’en skal bruge https:// og være offentligt tilgængelig. Almindelig http://, localhost, private netværksadresser og interne platformadresser afvises med en 400.

cURL

curl -X POST "https://api.youraiconnector.com/v1/webhooks?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.example.com/incoming",
    "subscribed_to": ["Contact Created", "Replies"],
    "name": "Order updates hook"
  }'

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/webhooks", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    url: "https://hooks.example.com/incoming",
    subscribed_to: ["Contact Created", "Replies"],
    name: "Order updates hook",
  }),
});
const data = await res.json();

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/webhooks",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "url": "https://hooks.example.com/incoming",
        "subscribed_to": ["Contact Created", "Replies"],
        "name": "Order updates hook",
    },
)
data = res.json()

Svar

{
  "success": true,
  "webhook_id": "1",
  "webhook": {
    "id": "1",
    "name": "Order updates hook",
    "url": "https://hooks.example.com/incoming",
    "subscribed_to": ["Contact Created", "Replies"],
    "subscribed_to_tags": [],
    "created_at": "2026-06-09T12:00:00.000Z"
  }
}

Opdater et abonnement

Angiv mindst én af url, subscribed_to, name, subscribed_to_tags, retries_enabled, enabled eller apply_to_sub_accounts. Udeladte felter beholder deres nuværende værdier. subscribed_to og subscribed_to_tags er erstatninger, ikke fletninger.

PUT /webhooks/{webhookId}

Opdatering af et abonnement forstyrrer aldrig dets signeringshemmelighed — administrer den via ruterne for signeringshemmeligheder.

Når URL’en ændres, genaktiveres levering til den nye URL automatisk, hvilket giver et tidligere fejlbehæftet slutpunkt en frisk start.

cURL

curl -X PUT "https://api.youraiconnector.com/v1/webhooks/Order%20updates%20hook" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.example.com/v2/incoming",
    "subscribed_to": ["Replies", "Chat Concluded"]
  }'

JavaScript

const res = await fetch(
  `https://api.youraiconnector.com/v1/webhooks/${encodeURIComponent("Order updates hook")}`,
  {
    method: "PUT",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      url: "https://hooks.example.com/v2/incoming",
      subscribed_to: ["Replies", "Chat Concluded"],
    }),
  }
);
const data = await res.json();

Python

import requests

res = requests.put(
    "https://api.youraiconnector.com/v1/webhooks/Order updates hook",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "url": "https://hooks.example.com/v2/incoming",
        "subscribed_to": ["Replies", "Chat Concluded"],
    },
)
data = res.json()

Svar

{
  "success": true,
  "webhook_id": "0",
  "webhook": {
    "id": "0",
    "name": "Order updates hook",
    "url": "https://hooks.example.com/v2/incoming",
    "subscribed_to": ["Replies", "Chat Concluded"],
    "subscribed_to_tags": [],
    "created_at": "2026-06-09T12:00:00.000Z"
  }
}

Et ukendt id eller navn returnerer 404 med { "success": false, "error": "Webhook not found" }.


Slet et abonnement

Fjerner abonnementet, så dets URL stopper med at modtage nyttelaster. Dets leverings-sundhedstællere nulstilles, så gen-tilføjelse af den samme URL senere starter med en ren historik.

DELETE /webhooks/{webhookId}

cURL

curl -X DELETE "https://api.youraiconnector.com/v1/webhooks/0" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/webhooks/0", {
  method: "DELETE",
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();

Python

import requests

res = requests.delete(
    "https://api.youraiconnector.com/v1/webhooks/0",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()

Svar

{
  "success": true
}

Send en test-nyttelast

Sender en eksempel-nyttelast til abonnementets URL, så du kan verificere din modtager ende-til-ende. Send eventuelt en event for at styre, hvilken begivenhedstype eksemplet simulerer. Testleveringer påvirker aldrig abonnementets sundhedstællere.

POST /webhooks/{webhookId}/test

Svaret returnerer altid 200 og rapporterer resultatet med et delivered-flag — en mislykket test returnerer ikke en fejlstatus. Når delivered er false, inkluderer svaret detaljer om fejlen.

Felt Påkrævet Beskrivelse
event Nej Begivenhedstype der skal simuleres (skal være en af /webhooks/events). Standard er en leveringsbegivenhed.

cURL

curl -X POST "https://api.youraiconnector.com/v1/webhooks/0/test?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "event": "Contact Created" }'

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/webhooks/0/test", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ event: "Contact Created" }),
});
const data = await res.json();

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/webhooks/0/test",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"event": "Contact Created"},
)
data = res.json()

Svar (leveret)

{
  "success": true,
  "webhook_id": "0",
  "delivered": true
}

Svar (fejlet)

{
  "success": true,
  "webhook_id": "0",
  "delivered": false,
  "failure_type": "permanent",
  "status_code": 404,
  "error_message": "Request failed with status code 404"
}

failure_type er en af permanent, temporary, timeout, network eller unknown.


Tjek leveringsstatus

Returnerer leveringsstatus-posten for abonnementets URL: hvor mange leveringer der er lykkedes og fejlet, om levering i øjeblikket er sat på pause efter gentagne fejl, samt detaljer om den seneste fejl. Returnerer "health": null, når der endnu ikke er forsøgt nogen leveringer.

GET /webhooks/{webhookId}/health

cURL

curl "https://api.youraiconnector.com/v1/webhooks/0/health" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/webhooks/0/health", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/webhooks/0/health",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()

Svar

{
  "success": true,
  "webhook_id": "0",
  "url": "https://hooks.example.com/incoming",
  "health": {
    "consecutive_failures": 0,
    "total_failures": 2,
    "total_successes": 120,
    "is_disabled": false,
    "disabled_at": null,
    "disabled_reason": null,
    "last_failure": null,
    "last_success_at": "2026-06-09T12:00:00.000Z",
    "created_at": "2026-05-01T08:00:00.000Z",
    "updated_at": "2026-06-09T12:00:00.000Z"
  }
}

Når is_disabled er true, er levering til URL’en automatisk blevet sat på pause efter gentagne fejl. Reparer din modtager, og genaktiver den derefter (nedenfor).


Genaktiver levering

Genoptager levering for en webhook, hvis URL automatisk blev sat på pause efter gentagne fejl. Dette nulstiller pause-flaget og tællere for fejl, men forsøger ikke en levering — brug test-endepunktet bagefter for at bekræfte, at din modtager er sund igen.

POST /webhooks/{webhookId}/reenable

cURL

curl -X POST "https://api.youraiconnector.com/v1/webhooks/0/reenable?apiKey=YOUR_API_KEY"

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/webhooks/0/reenable", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/webhooks/0/reenable",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()

Svar

{
  "success": true,
  "webhook_id": "0"
}

Slukning af et abonnement

enabled er abonnementets egen tænd/sluk-knap. Hvis du slukker for den, stoppes leveringer, mens URL’en, event-listen og signeringshemmeligheden bevares intakte.

# Off
curl -X PUT "https://api.youraiconnector.com/v1/webhooks/0?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"enabled": false}'

# Back on
curl -X PUT "https://api.youraiconnector.com/v1/webhooks/0?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"enabled": true}'
  • Fravær betyder tændt. Et abonnement oprettet før dette felt eksisterede, har ingen enabled-værdi gemt og leverer normalt. GET /webhooks rapporterer altid en konkret boolesk værdi.
  • Slukkede abonnementer er stadig angivet af GET /webhooks — det er sådan, du finder dem for at tænde for dem igen.
  • Et genforsøg, der er sat i kø før slukningen, genoptages ikke: genforsøget genlæser abonnementet på afsendelsestidspunktet og annulleres, hvis det er slukket.
  • Intet, der er undertrykt, mens det var slukket, afspilles igen, når du tænder for det igen.

Adskilt fra den automatiske deaktivering efter gentagne fejl, som rapporteres af GET /webhooks/{id}/health som is_disabled og ryddes med POST /webhooks/{id}/reenable. enabled er kontoens kontakt; is_disabled er vores. Ingen af dem tilsidesætter den anden — et abonnement skal både være tændt og ikke automatisk deaktiveret for at levere.


Ét abonnement til alle klientkonti (bureauer)

På en bureaukonto skal du indstille apply_to_sub_accounts: true på et abonnement (ved oprettelse eller via PUT), hvorefter det også modtager hændelser, der sker på hver af bureauets klientkonti — ét endpoint dækker hele bureauet i stedet for at skulle genoprette abonnementet på hver klientkonto.

curl -X PUT "https://api.youraiconnector.com/v1/webhooks/0?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"apply_to_sub_accounts": true}'

Sådan fungerer det:

  • user-blokken adskiller kontiene. Hver payloads user-blok identificerer den konto, hvor hændelsen rent faktisk fandt sted, så din modtager kan rute pr. klient.
  • Bureauabonnementets egne indstillinger gælder overalt. Dets hændelsesliste, signaturhemmelighed og genforsøgs-tilvalg bruges også til de arvede leveringer.
  • En klientkontos eget abonnement til samme URL vinder. Hvis en klientkonto har sit eget abonnement, der peger på samme URL, bruges det til den kontos hændelser — den samme hændelse leveres aldrig to gange til ét endpoint.
  • Klientkonti ser det ikke. Arvede abonnementer vises ikke på en klientkontos egen webhook-liste, og klienten kan ikke deaktivere dem — kun bureauet administrerer dem.
  • Leveringsstatus spores pr. klientkonto. Et endpoint, der bliver ved med at fejle, deaktiveres automatisk for den konto, hvis leveringer fejlede, ikke for hele bureauet.
  • subscribed_to_tags nedarves ikke. Tag-listen refererer til bureauets egne tags, som ikke findes på klientkonti — indsnævring af samtaleresumé gælder kun for bureauets egne hændelser.
  • Inaktivt andre steder. På en konto uden klientkonti gemmes flaget fint, men gør intet.

Headere ved hver levering

Disse tre headere sendes ved hver levering, uanset om abonnementet er signeret eller ej:

Header Betydning
X-Webhook-Delivery Stabilt ID for den logiske hændelse. Identisk på tværs af genforsøg – brug det til deduplikering.
X-Webhook-Attempt Forsøgsnummer (1-baseret).
X-Webhook-Event Hændelsesnavnet.

Signerede payloads

Signering er valgfri, deaktiveret som standard og indstilles pr. abonnement. Når et abonnement har en signeringshemmelighed, indeholder hver levering to ekstra headere ud over de tre, der sendes ved hver levering (X-Webhook-Delivery, X-Webhook-Attempt og X-Webhook-Event):

Header Betydning
X-Webhook-Signature v1=<hex> — HMAC-SHA256 af strengen "<timestamp>.<raw request body>", kodet med den webhook-specifikke signeringshemmelighed, som du opretter og roterer på GET/POST/DELETE /v1/webhooks/{webhookId}/signing-secret.
X-Webhook-Timestamp Sendetidspunkt, Unix-sekunder. Bundet til signaturen, så det kan ikke ændres uafhængigt.

For at verificere skal du genberegne HMAC-SHA256 over den rå body med din hemmelighed og sammenligne den med headeren. Verificer mod den request-body. Gen-serialisering af parsede JSON-data ændrer bytes og ødelægger sammenligningen. Afvis leveringer, hvis tidsstempel ligger uden for et friskhedsvindue (300 sekunder er en fornuftig standard) for at forhindre replay-angreb, og sammenlign med en timing-sikker funktion.

Se Signerede Payloads for fuldstændige eksempler på verificering i Node og Python.

Signering er ikke det samme som API-autentificering. Selve REST API’et autentificerer med API-nøgler frem for OAuth (OAuth 2.1 findes til MCP-servere, som du registrerer som bot-værktøjer), og der findes endnu ingen officielle npm- eller PyPI SDK-pakker – kald endpoints med en hvilken som helst HTTP-klient.

Læs signeringshemmeligheden

GET /webhooks/{id}/signing-secret

curl "https://api.youraiconnector.com/v1/webhooks/0/signing-secret?apiKey=YOUR_API_KEY"

Svar

{
  "success": true,
  "webhook_id": "0",
  "signing_enabled": true,
  "signing_secret": "whsec_1a2b3c...",
  "signing_secret_created_at": "2026-07-15T09:30:00.000Z"
}

Når signering er deaktiveret, er signing_enabled lig med false og signing_secret er lig med null.

Generer eller roter signeringshemmeligheden

POST /webhooks/{id}/signing-secret

Opretter en hemmelighed (aktiverer signering) eller erstatter den eksisterende. Returnerer den nye hemmelighed.

curl -X POST "https://api.youraiconnector.com/v1/webhooks/0/signing-secret?apiKey=YOUR_API_KEY"

Svar

{
  "success": true,
  "webhook_id": "0",
  "signing_enabled": true,
  "signing_secret": "whsec_9f8e7d...",
  "signing_secret_created_at": "2026-07-15T10:00:00.000Z"
}

Rotation træder i kraft med det samme — den næste levering signeres kun med den nye hemmelighed. Accepter begge hemmeligheder kortvarigt, mens du udruller ændringen til et live-endepunkt.

Du kan også oprette en hemmelighed ved oprettelse ved at sende "generate_signing_secret": true til POST /webhooks; svaret indeholder derefter et signing_secret-felt på øverste niveau.

Deaktiver signering

DELETE /webhooks/{id}/signing-secret

curl -X DELETE "https://api.youraiconnector.com/v1/webhooks/0/signing-secret?apiKey=YOUR_API_KEY"

Svar

{
  "success": true,
  "webhook_id": "0",
  "signing_enabled": false
}

Alle tre ruter til signeringshemmeligheder kræver redigerings-tilladelse til integrationer, inklusive GET — hemmeligheden er en legitimation, der kan forfalske leveringer, så den eksponeres ikke for skrivebeskyttede roller.


Forsøg igen

Valgfrit, deaktiveret som standard, og indstilles pr. abonnement via den boolske værdi retries_enabledPOST /webhooks eller PUT /webhooks/{id}.

curl -X PUT "https://api.youraiconnector.com/v1/webhooks/0?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"retries_enabled": true}'

Når det er aktiveret, forsøges en mislykket levering igen efter 1m, 5m, 30m og 2t fra det første forsøg (ca. 2t 40m dækning).

  • Forsøges igen: 5xx-svar, timeouts og forbindelsesfejl.
  • Forsøges ikke igen: alle 4xx. Modtageren afviser selve anmodningen, så en uændret gentagelse vil blot reproducere afvisningen.

Forsøg gør duplikeret levering mulig — et slutpunkt, der har behandlet en hændelse, men fik timeout før svar, vil se den igen. Brug X-Webhook-Delivery til deduplikering, da det er konstant på tværs af forsøg. Dette er grunden til, at forsøg er valgfrie.

Tællerne for delivery-health tæller en hel levering, ikke hvert forsøg: en fejl registreres kun, når alle forsøg er opbrugt, så aktivering af gentagne forsøg får ikke den automatiske deaktivering til at udløses hurtigere.


Fejl

Alle fejl bruger standard-konvolutten:

{
  "success": false,
  "error": "Webhook not found"
}

Almindelige tilfælde: en URL, der ikke er tilladt, en tom/ugyldig subscribed_to eller manglende felter returnerer 400; et ukendt id eller navn returnerer 404; og en 403 betyder, at webhooks ikke er aktiveret for din konto. Se Fejl for den fulde liste.


Næste skridt