
# Webhooks

Webhooks låter <span data-t="appName">Your AI Connector</span> automatiskt meddela dina andra affärsverktyg när något viktigt händer — en ny kontakt skapas, en tid bokas, ett meddelande tas emot. Istället för att manuellt kontrollera efter uppdateringar får dina anslutna system en omedelbar avisering i samma ögonblick som något sker.


---

## Vad är webhooks?

Se en webhook som ett automatiskt textmeddelande mellan två appar. När något händer i <span data-t="appName">Your AI Connector</span> (som att en ny kontakt registrerar sig) skickar plattformen omedelbart en avisering till ett annat system som du valt. Du anger en webbadress (kallad "webhook-URL") dit dessa aviseringar ska skickas — denna tillhandahålls vanligtvis av ditt CRM, din automatiseringsplattform eller din utvecklare.

> **Webhooks skickar endast data UT ur <span data-t="appName">Your AI Connector</span>.** En webhook är en enkelriktad gata *från* <span data-t="appName">Your AI Connector</span> *till* dina andra verktyg. Det finns **ingen webhook-URL som skickar leads, kontakter eller meddelanden IN i plattformen.** För att skicka in ett nytt lead — från ett webbformulär, ditt CRM eller GoHighLevel — gör ditt system istället ett **API-anrop**. Se [API-åtkomst](api-access.md) (åtgärden *Skapa en kontakt*) och [Funnels](funnels.md). Det enda du behöver för den inkommande riktningen är din **API-nyckel**, som finns i sin egen sektion — se [API-åtkomst](api-access.md#generating-your-api-key). Sidan **Webhooks** som beskrivs här är uteslutande för den utgående riktningen.

::: note
**Obs:** Att ställa in webhooks innebär viss teknisk konfiguration. Om du inte känner dig bekväm med detta, dela den här sidan med din utvecklare eller använd en automatiseringsplattform som Zapier, Make eller Pabbly, vilka tillhandahåller webhook-URL:er utan att någon kodning krävs.
:::


Vanliga användningsområden inkluderar:

- Synkronisering av nya kontakter till ditt CRM.
- Utlösning av ett arbetsflöde i Zapier, Make eller Pabbly när en tagg läggs till.
- Meddela ditt team i Slack när en människa behöver ta över.
- Uppdatering av ditt kalendersystem när en tid bokas.
- Loggning av konversationssammanfattningar till din databas.

---

## Konfigurera webhooks

1. Klicka på **Inställningar** (kugghjulsikonen) i sidofältet till vänster.
2. Under gruppen **Integrationer** i inställningsmenyn, klicka på **Webhooks**.


På ett konto där inga webhooks har konfigurerats ännu ser sidan ut så här:


3. Klicka på **New webhook** längst upp till höger. Ett formulär öppnas direkt på sidan:


4. Fyll i:
   - **Endpoint-URL** — webbadressen som <span data-t="appName">Your AI Connector</span> ska skicka händelseaviseringar till. Du får denna från ditt externa system (CRM, automatiseringsplattform eller egen server).
   - **Namn** — en etikett som du känner igen senare (t.ex. "Slack-varningar" eller "CRM-synk"). Endast för din egen referens.

> **Din webhook-URL måste vara en publikt nåbar `https://`-adress.** Vanliga `http://`-adresser, `localhost` eller adresser i privata nätverk samt interna plattformsadresser avvisas när du sparar. För att testa från din egen maskin, använd en publik tunnel (webhook.site eller ngrok) istället för localhost.

5. Under **Events**, klicka på de händelser du vill att denna webhook ska ta emot — alla 22 listas i [De 22 webhook-händelserna](#the-22-webhook-events).
6. *(Valfritt)* Aktivera **Försök igen vid misslyckad leverans** om du vill att <span data-t="appName">Your AI Connector</span> ska fortsätta försöka vid ett tillfälligt fel — se [Försök igen vid misslyckade leveranser](#retrying-failed-deliveries).
7. Klicka på **Skapa webhook**. Den visas i listan under formuläret, och du kan när som helst klicka på **Test** på dess rad för att skicka ett exempel-payload till din slutpunkt.

> **Behörighet krävs.** Att lägga till, redigera eller testa webhooks kräver "redigera"-behörighet för Integrationer (teammedlemmar med endast läsbehörighet ser ett meddelande om skrivskydd istället för formuläret).

> **Signering av en webhook** kräver att den redan är sparad — öppna raden för en befintlig webhook för att redigera den, så visas panelen **Signeringshemlighet** längst ner i redigeringsformuläret. Ett helt nytt, osparat utkast har ännu inget signeringsalternativ — se [Signerade nyttolaster](#signed-payloads-verifying-a-webhook-really-came-from-us) nedan.

---

## En webhook för alla dina klientkonton (byråer)

Om du driver en byrå behöver du inte återskapa samma webhook på varje klientkonto. På byråkontot har webhook-formuläret en extra växlingsknapp: **Utlös även för alla klientkonton**. Aktivera den så tar denna webhook även emot händelser som sker på alla klientkonton under din byrå – en slutpunkt, hela byrån.

Så här fungerar det:

- **`user`-blocket talar om för dig vilken klient en händelse tillhör.** Varje avisering innehåller redan ett `user`-block som identifierar kontot där händelsen inträffade, så att din automatisering kan dirigera per klient.
- **Din webhooks egna inställningar gäller överallt.** De händelser du valt, signeringshemligheten och inställningen för att försöka igen används även för leveranser till klientkonton.
- **Inga dubbla leveranser.** Om ett klientkonto har en egen webhook som pekar på samma URL, används den för det kontots händelser istället – samma händelse anländer aldrig två gånger till en slutpunkt.
- **Klienter ser den inte.** Webhooken visas inte på klientkontots egen sida för webhooks, och klienter kan inte stänga av den – det är du som hanterar den.
- **Tillförlitlighet spåras per klientkonto.** Om din slutpunkt fortsätter att misslyckas stängs den av automatiskt för det konto vars leveranser misslyckades (se [Webhook-tillförlitlighet](#webhook-reliability)), inte för hela byrån på en gång.

Växlingsknappen visas endast för byråkonton. Det går även att ställa in detta via API:et – se fältet `apply_to_sub_accounts` i [Webhooks API](../api/webhooks.md#one-subscription-for-all-client-accounts-agencies).

---

## Tillgängliga utlösande händelser

Du kan aktivera eller inaktivera var och en av de 22 webhook-händelserna oberoende av varandra. När en händelse utlöses skickar <span data-t="appName">Your AI Connector</span> ett meddelande till din webhook-URL med relevant data. Varje händelse, vad den betyder och den `event`-kod som placeras i payloaden listas tillsammans i [De 22 webhook-händelserna](#the-22-webhook-events) längre ner på denna sida.

> **Bra att veta:** **Task Created**, **Task Updated** och **Task Completed** är fullt valbara och sparas korrekt. **Daily Summary Created** är också ett nyligen tillagt alternativ. Se [Task Completed Webhook](#task-completed-webhook) nedan för den nyttolastens form.

---

## Taggbaserade webhook-utlösare

`subscribed_to_tags` begränsar inte en webhooks händelser till en tagg. Den begränsar bara vilka taggar som skapar ett meddelande om konversationssammanfattning. För att få en förfrågan när en specifik tagg tillämpas, ställ in en webhook-URL på den taggen under fliken **Tags** för agenten (eller kampanjen).

Själva webhook-formuläret har ingen taggväljare, varken när du skapar en ny webhook eller när du redigerar en, så `subscribed_to_tags` kan endast läsas eller ändras via [Webhooks API](../api/webhooks.md), eller genom att fråga supporten.

> **Bra att veta:** att redigera en befintlig webhook som har en `subscribed_to_tags`-lista (döpa om den, ändra dess händelser, växla försök) rensar inte längre den listan — eftersom formuläret inte har någon taggväljare att skicka tillbaka, lämnar sparande från denna sida nu den befintliga listan orörd. (Detta var en verklig bugg före **21 juli 2026**: sparande från webhook-formuläret brukade radera listan eftersom den alltid skickade en tom tagglista. Om en webhook förlorade sin `subscribed_to_tags`-lista före det datumet måste den konfigureras om via API:et.)

### Generera sammanfattning för taggade kontakter

Där en webhook har en `subscribed_to_tags`-lista kan du aktivera **Generate Summary**. När det är aktiverat genererar <span data-t="appName">Your AI Connector</span> automatiskt en konversationssammanfattning för kontakten när en av dessa taggar tillämpas, och inkluderar den i webhook-datan — full kontext utan en separat förfrågan.

---

## Testa din webhook

1. Öppna **Inställningar → Integrationer → Webhooks**.
2. Klicka på **Testa** på raden för din webhook.
3. Kontrollera ditt externa system för att bekräfta att det tog emot testdatan.
4. Granska dataformatet för att säkerställa att ditt system kan tolka det korrekt.

För ett fullständigt test från början till slut, skicka ett meddelande som skulle utlösa en av dina konfigurerade händelser (en sändning eller ett inkommande meddelande på en ansluten kanal) och verifiera att webhooken utlöses med den verkliga datan.

::: tip
**Tips:** Använd ett verktyg som [webhook.site](https://webhook.site) eller [RequestBin](https://requestbin.com) under utvecklingen för att inspektera rå webhook-data innan du ansluter ditt produktionssystem.
:::


### Vad som räknas som en lyckad leverans

Oavsett om du klickar på **Test** eller om händelsen utlöses på riktigt, skickar vi samma sak:

- En **POST**-förfrågan (aldrig GET), med brödtexten som JSON och `Content-Type: application/json`.
- Rubrikerna som listas under [Signed Payloads](#signed-payloads-verifying-a-webhook-really-came-from-us). Signaturrubriker inkluderas endast när du har angett en signeringshemlighet.

Vi betraktar leveransen som lyckad när:

- Din slutpunkt svarar med **valfri 2xx-status** (200, 201, 204 — allt är okej).
- Den svarar **inom 30 sekunder**.

Några saker som förvånar folk:

- **Svarskroppen ignoreras.** Du behöver inte returnera någon specifik JSON. Ett tomt 200-svar räcker.
- **Omdirigeringar räknas som ett fel.** Vi följer dem inte, så en 301 eller 302 (inklusive en omdirigering för avslutande snedstreck, eller http till https) registreras som en misslyckad leverans. Spara den slutgiltiga URL:en, inte en som omdirigerar.
- **Frågesträngar stöds fullt ut.** `https://your-app.com/hook?token=abc123` skickas exakt som du sparade den, så att placera en token i frågesträngen fungerar lika bra som att placera den i sökvägen.
- **Din URL måste vara `https://` och offentligt tillgänglig.** Adresser som tillhör <span data-t="appName">Your AI Connector</span>:s egen infrastruktur avvisas, men dina egna slutpunkter på Google Cloud Functions, Cloud Run, App Engine, Firebase Hosting eller någon annanstans går bra.
- **En brandvägg eller ett skyddslager mot botar framför din slutpunkt kan blockera oss.** Det vanligaste fallet är Cloudflare: om din zon har "Bot Fight Mode" eller en hanterad utmaning aktiverad, får vår förfrågan en "Just a moment..."-utmaningssida med en 403 istället för att nå din server — och en server-till-server-förfrågan kan aldrig klara en webbläsarutmaning, så både **Test**-knappen och verkliga händelser misslyckas på samma sätt. Test-knappen kommer att berätta för dig när detta händer ("Cloudflare is showing a bot challenge to our request"). Åtgärda det i Cloudflare med en Security / WAF-regel som hoppar över utmaningar för din webhook-sökväg (eller för användaragenten `Webhook-Delivery/1.0`), och klicka sedan på **Test** igen.
- **Om din brandvägg istället behöver en IP-tillåtelselista** (till exempel Cloudflares gratisplan, där vanligt "Bot Fight Mode" inte kan hoppas över av en WAF-regel, men en IP Access Rule inställd på "Allow" körs före den), kan vi hjälpa till: varje leverans, oavsett om den kommer från **Test**-knappen eller en live-händelse, skickas från en fast IPv4-adress (inga intervall, ingen IPv6, ingen rotation). Kontakta supporten så ger vi dig adressen som ska läggas till i tillåtelselistan. Behåll [signaturverifiering](#signed-payloads-verifying-a-webhook-really-came-from-us) som din faktiska förtroendekontroll, eftersom den validerar varje nyttolast oavsett var den kom ifrån.
- **Testresultatet berättar exakt vad din slutpunkt svarade.** Ett misslyckat test visar nu den verkliga orsaken (HTTP-statusen din slutpunkt returnerade, en timeout, eller att vi inte kunde nå adressen alls) istället för ett generiskt fel, och ett test på en sparad webhook skickas signerat när signering är aktiverat, precis som en live-händelse.

### Använda n8n, Make eller Zapier ("Test-URL" vs "Produktions-URL")

Automationsplattformar ger dig vanligtvis två olika webhook-adresser, vilket ofta skapar förvirring:

- En **Test-URL** (i n8n innehåller den `/webhook-test/`). Denna tar endast emot data medan du aktivt bevakar arbetsytan och precis har klickat på **Lyssna efter testhändelse** (eller **Testa arbetsflöde**). Den fångar en enskild händelse och slutar sedan lyssna — så att klicka på **Testa** i <span data-t="appName">Your AI Connector</span> flera gånger i rad fångar bara den första, och endast om lyssningsfönstret är aktivt vid just det ögonblicket. För att testa: klicka på **Lyssna efter testhändelse** i n8n först, gå sedan tillbaka till <span data-t="appName">Your AI Connector</span> och klicka på **Testa** en gång.
- En **Produktions-URL** (i n8n innehåller den `/webhook/`, ingen `-test`). Detta är den du ska klistra in i <span data-t="appName">Your AI Connector</span> för live-händelser. Den fungerar bara när ditt arbetsflöde är inställt på **Aktivt**. Om arbetsflödet inte är aktivt avvisar n8n förfrågan med ett "404 / webhook not registered"-fel, trots att <span data-t="appName">Your AI Connector</span> skickade datan korrekt.

Kort sagt: testa med test-URL:en medan du lyssnar, men för att webbhooken ska fortsätta fungera för riktiga kontakter, spara **Produktions-URL:en** i <span data-t="appName">Your AI Connector</span> och se till att arbetsflödet är **Active**.

---

## Dataformat för webhook

När en webhook utlöses skickar <span data-t="appName">Your AI Connector</span> strukturerad data (JSON) till din webhook-URL. Om du använder en automatiseringsplattform som Zapier eller Make, tolkar den denna data åt dig automatiskt. Om du bygger en egen integration:

```json
{
  "event": "contactCreated",
  "contact": { "id": "<contact-id>", "first_name": "Jane", "...": "..." },
  "campaign": { "id": "<campaign-id>", "name": "AI Receptionist", "status": "Live" },
  "agent": { "id": "<agent-id>", "name": "Front Desk" },
  "user": { "id": "<account-id>", "email": "owner@example.com" }
}
```

| Fält | Beskrivning |
|---|---|
| `event` | Den exakta händelsesträngen som utlöste meddelandet (till exempel `contactCreated`, `booked`). Detta är **inte** visningsetiketten som visas i händelselistan; varje etikett och dess matchande kod finns i [De 22 webhook-händelserna](#the-22-webhook-events). |
| `contact` | Kontakten som händelsen rör, eller `null` för händelser som inte är kopplade till en kontakt (såsom `creditsRecharged`). |
| `campaign` | Kampanjen som kontakten tillhör, eller `null` om det inte finns någon. |
| `agent` | Agenten som hanterar konversationen, eller `null` om det inte finns någon. |
| `user` | Grundläggande identitetsinformation för kontot som äger datan. |

> **`campaign` eller `agent` — vanligtvis en, inte båda.** Om ditt konto använder agenter ligger dina kontakter hos en agent snarare än en kampanj, så `campaign` anländer som `null` och `agent` talar om för dig vilken som hanterade den. Äldre kampanjbaserade konton ser det omvända. Läs den som är ifylld; anta inte att `campaign` alltid finns där.

> **`agent`-blocket anlände den 15 augusti 2026.** Det placeras tillsammans med `campaign` bland händelser kopplade till en konversation — en avslutad chatt, stör ej, återupptagning, arkivering, AI-paus, ett nytt meddelande, en konversationssammanfattning och den webhook du kan ställa in på en tagg — och innehåller den hanterande agentens `id` och `name`, eller `null` när ingen agent är involverad. Det är rent additivt: varje fält du redan tar emot är oförändrat, så en mottagare du byggde före det datumet fortsätter att fungera utan att något behöver uppdateras.

Vissa händelser lägger till sitt eget extra block på toppnivå. Till exempel lägger **Appointment Booked** till ett `appointment`-block (se [Appointment Booked Webhook](#appointment-booked-webhook)), **New Message** lägger till ett fullständigt `message`-block med texten (se [New Message Webhook](#new-message-webhook)), och **Deliveries** och **Reads** lägger till ett kort `message`-block med endast meddelandets ID och status (se [Deliveries and Reads Webhook](#deliveries-and-reads-webhook)).

> **Deliveries och Reads talar om vilket meddelande det gäller, men inte vad det innehöll.** De innehåller ett `message`-block med meddelandets `id` och `status` — och det `id` är samma `messageId` som [send message endpoint](../api/messages.md#send-a-message) returnerar, så att du kan matcha en leverans- eller läskvitto med det exakta meddelande du skickade — men inget meddelandeinnehåll. **Replies** innehåller inget `message`-block alls. Om du behöver orden som skickades eller togs emot, prenumerera på **New Message** utöver dessa.

> **Två saker att veta innan du skriver din mottagare.** Det finns inget `timestamp`-fält och ingen `data`-omslutare. Varje block ligger på toppnivå i JSON-objektet, som visas ovan.

### De 22 webhook-händelserna

De 22 webhook-händelserna, med visningsetiketten du kryssar i appen och `event`-koden som skickas i payloaden. `event`-koden är en kort sträng som **inte** matchar visningsetiketten, så matcha din mottagare mot koden, inte etiketten:

| Visningsnamn (i appen) | `event`-kod i nyttolasten | Vad det betyder |
|---|---|---|
| Contact Created | `contactCreated` | En ny kontakt läggs till i ditt konto (manuellt, via import eller via API). |
| Contact Paused | `contact_paused` | En kontaktkonversation pausas (boten slutar svara). |
| Contact Resumed | `contact_resumed` | En pausad kontaktkonversation återupptas. |
| Contact Do Not Disturb | `contact_do_not_disturb_changed` | En kontakts "Stör ej"-inställning aktiveras. |
| Contact Unarchived | `contact_unarchived` | En arkiverad kontakt skickar ett nytt meddelande, vilket gör att de återgår till din aktiva inkorg. |
| New Message | `new_message` | Alla meddelanden som läggs till i en konversation på valfri kanal — både meddelanden som din kontakt skickar till dig och meddelanden som din AI eller ditt team skickar till dem. Detta är den enda händelsen som innehåller den faktiska meddelandetexten (se [New Message Webhook](#new-message-webhook)). |
| Replies | `replied` | En kontakt svarar på ett meddelande. |
| Reads | `read` | En kontakt läser ett meddelande (på kanaler som stöder läskvitton). Innehåller ID för meddelandet som lästes — se [Deliveries and Reads Webhook](#deliveries-and-reads-webhook). |
| Deliveries | `delivered` eller `undelivered` | Ett meddelande har levererats till en kontakt (`undelivered` när leveransen misslyckas). Innehåller meddelandets ID — se [Deliveries and Reads Webhook](#deliveries-and-reads-webhook). |
| Human Alerted | `humanAlerted` | AI-boten avgör att den inte kan hantera en konversation och flaggar den för mänsklig uppmärksamhet. |
| Chat Concluded | `chat_concluded` | AI-boten avgör att en konversation har nått sitt slut (bokning gjord, lead diskvalificerad, etc.). |
| Appointment Booked | `booked` | En kontakt bokar en tid via bokningssystemet. |
| Credits Spent | `creditsSpent` | Krediter dras från ditt konto. |
| Credits Recharged | `creditsRecharged` | Krediter läggs till på ditt konto via automatisk påfyllning eller manuellt köp. |
| Low Credit Balance | `lowCreditBalance` vid en **Test**-leverans, `Low Credit Balance` vid en riktig | En tidig varning om att ditt kreditsaldo har sjunkit under din varningsgräns (100 krediter om du inte ställt in en egen). Riktar sig till byråer vars underkonton alla spenderar från en gemensam pott. Den innehåller `balance`, `threshold` och `account_email` istället för ett kontaktblock, skickas högst en gång var 24:e timme så länge saldot förblir lågt, och återaktiveras så snart saldot går över gränsen igen. |
| Task Created | `taskCreated` | En uppgift skapas. |
| Task Updated | `taskUpdated` | En uppgift ändras utan att flyttas till ett slutförandestadium. |
| Task Completed | `taskCompleted` | En uppgift flyttas till ett stadium som konfigurerats som ett slutförandestadium. |
| Daily Summary Created | `dailySummaryCreated` | Din dagliga sammanfattningsrapport genereras. |
| Channel Connected | `channelConnected` | **Skickas inte ännu — valbar, men inget skickar den idag. Bygg inte mot den.** Avsedd för när en meddelandekanal har anslutits. |
| Broadcast Started | `broadcastStarted` | Ett utskick börjar skickas (dess status ändras till Sending). Utlöses en gång per start, inklusive när ett pausat utskick återupptas. Innehåller ett `broadcast`-block istället för ett kontaktblock: id, namn, kanal, status, föregående status, listan den riktar sig till (`list_id`, `list_name`, `is_smart_list`), `scheduled_at`, `total_contacts`. |
| Broadcast Completed | `broadcastCompleted` | Ett utskick avslutas (dess status ändras till Sent eller Failed). Samma `broadcast`-block plus `completed_at` och, när tillgängligt, `completion_summary` (`total_sent`, `permanently_failed`, `unique_replied`, `failure_rate`, `had_errors`). Använd dessa två för att koppla en Smart Broadcast-lista till externa verktyg. |

Två koder till visas aldrig i den listan eftersom du inte prenumererar på dem: `contact_tags_updated`, skickas av en webhook-URL inställd på en enskild tagg, och `summary_generated`, skickas när en chattsammanfattning skrivs för en tagg i en webhooks `subscribed_to_tags`-lista.

> **Kanal ansluten skickas ännu inte.** Den visas i händelselistan, men ingenting skickar den idag. Bygg inte mot den.

Taggbaserade och uppgiftsbaserade aviseringar använder sina egna separata former. Se [Contact Tags Updated](#contact-tags-updated-webhook) och [Task Completed](#task-completed-webhook).

---

## Webhook för skapad kontakt

Skickas när händelsen **Kontakt skapad** utlöses (en ny kontakt läggs till manuellt, via import eller via API).

### Händelsenamn

`contactCreated`

### Nyttolastformat

```json
{
  "event": "contactCreated",
  "contact": {
    "id": "<contact-id>",
    "email": "jane@example.com",
    "phone_number": "+15551234567",
    "first_name": "Jane",
    "last_name": "Smith",
    "human_alerted": false,
    "human_alert_reason": null,
    "is_bot_active": true,
    "ad_referral": null
  },
  "campaign": {
    "id": "<campaign-id>",
    "name": "AI Receptionist",
    "status": "Live"
  },
  "agent": {
    "id": "<agent-id>",
    "name": "Front Desk"
  },
  "user": {
    "id": "<account-id>",
    "email": "owner@example.com",
    "first_name": "Alex",
    "last_name": "Doe"
  }
}
```

| Fält | Beskrivning |
|---|---|
| `event` | Alltid `contactCreated` för denna händelse. |
| `contact.id` | Det unika ID:t för den nya kontakten. |
| `contact.email` / `contact.phone_number` | Kontaktens e-post och telefon, om kända (båda kan vara tomma beroende på kanal). |
| `contact.first_name` / `contact.last_name` | Kontaktens namn, om känt. |
| `contact.human_alerted` / `contact.human_alert_reason` | Huruvida kontakten är flaggad för mänsklig uppmärksamhet, och varför. |
| `contact.is_bot_active` | Huruvida AI-boten för närvarande är aktiv på denna kontakt. |
| `contact.ad_referral` | Meta Click-to-WhatsApp-annonsattribuering, eller `null` — se [Click-to-WhatsApp Ad Attribution](click-to-whatsapp-attribution.md). |
| `campaign` | Kampanjen som kontakten skapades under, eller `null`. |
| `agent` | Agenten som tilldelats kontakten, eller `null`. |
| `user` | Grundläggande identitetsinformation för kontot som äger kontakten. |

> **"Test"-exemplet och en verklig händelse ser något annorlunda ut.** Testknappen skickar platshållardata (John Doe, en exempelkampanj). En verklig "Kontakt skapad"-händelse innehåller kontaktens faktiska uppgifter, och vissa fält kan vara tomma beroende på kanal.

---

## Webhook för nytt meddelande

Denna webhook utlöses varje gång ett meddelande läggs till i en konversation, på vilken kanal som helst. Den täcker båda riktningarna: meddelanden din kontakt skickar till dig, och meddelanden din AI, ditt team eller en kampanj skickar till dem. Det är den enda webhooken som inkluderar meddelandetexten, så det är den du ska använda när du vill spegla konversationer i ett externt system.

### Händelsenamn

`new_message`

### Nyttolastformat

```json
{
  "event": "new_message",
  "contact": {
    "id": "<contact-id>",
    "email": "jane@example.com",
    "phone_number": "+15551234567",
    "first_name": "Jane",
    "last_name": "Smith",
    "human_alerted": false,
    "human_alert_reason": null,
    "is_bot_active": true,
    "ad_referral": null
  },
  "agent": {
    "id": "<agent-id>",
    "name": "Front Desk"
  },
  "user": {
    "id": "<account-id>",
    "email": "owner@example.com",
    "first_name": "Alex",
    "last_name": "Doe"
  },
  "message": {
    "id": "<message-id>",
    "body": "Hi, are you open on Saturday?",
    "direction": "inbound",
    "status": "received",
    "created_at": "2026-07-30T17:27:06.000Z",
    "channel": "whatsapp_web"
  }
}
```

| Fält | Beskrivning |
|---|---|
| `event` | Alltid `new_message` för denna händelse. Observera att detta är den exakta strängen som skickas — det är inte visningsnamnet "New Message". |
| `contact` | Kontakten vars konversation meddelandet tillhör. Samma form som i [Contact Created](#contact-created-webhook). |
| `agent` | Agenten som hanterar konversationen (`id` och `name`), eller `null` om ingen agent är inblandad. |
| `user` | Grundläggande identitetsinformation för kontot som äger konversationen. |
| `message.id` | Meddelandets unika ID. |
| `message.body` | Meddelandetexten. Tom för ett meddelande som endast innehåller en bilaga (bild, röstmeddelande, dokument). |
| `message.direction` | `inbound` för ett meddelande från kontakten, `outbound` för ett som skickats av din AI eller av ditt team från inkorgen, och `outbound-api` för ett som skickats av en kampanj, ett utskick, en mall eller via API:et. |
| `message.status` | Var meddelandet befinner sig i sin livscykel: `received` för inkommande, och `queued` / `sent` / `delivered` / `read` / `failed` / `undelivered` för utgående. Detta är statusen vid det ögonblick meddelandet skapades, så ett utgående meddelande anländer vanligtvis här som `queued` eller `sent` och når `delivered` efteråt — använd händelserna **Deliveries** och **Reads** om du behöver dessa senare övergångar. De innehåller samma `message.id` som detta block, så att du kan matcha övergången till detta meddelande (se [Deliveries and Reads Webhook](#deliveries-and-reads-webhook)). |
| `message.created_at` | När meddelandet skapades, i UTC (ISO 8601). |
| `message.channel` | Kanalen meddelandet gick igenom, till exempel `whatsapp`, `whatsapp_web`, `sms`, `instagram`, `messenger`, `telegram`, `email` eller `custom`. |

> **Det finns fortfarande inget `campaign`-block i denna nyttolast.** New Message skickar `contact`, `agent`, `user` och `message`. `agent`-blocket lades till den **15 augusti 2026** och talar om för dig vilken agent som hanterar konversationen; om du även behöver kampanjkontext, slå upp kontakten via API:et med `contact.id`.

> **Interna AI-poster utlöser inte denna webhook.** Utöver riktiga meddelanden sparar plattformen sina egna bokföringsrader i en konversation (AI:ns verktygsanrop och interna tur-poster). Dessa skickas aldrig — du tar endast emot meddelanden som genuint skickats eller tagits emot.

---

## Deliveries and Reads Webhook

Dessa två händelser rapporterar vad som hände med ett meddelande efter att det lämnade <span data-t="appName">Your AI Connector</span>: **Deliveries** utlöses när ett meddelande når kontakten (eller misslyckas med att göra det), och **Reads** utlöses när kontakten öppnar det, på de kanaler som stöder läskvitton.

Båda innehåller ett `message`-block med ID för det meddelande händelsen gäller, så att du kan matcha uppdateringen med det exakta meddelande du skickade.

### Händelsenamn

`delivered` och `undelivered` för **Deliveries**, `read` för **Reads**.

### Nyttolastformat

```json
{
  "event": "delivered",
  "contact": {
    "id": "<contact-id>",
    "email": "jane@example.com",
    "phone_number": "+15551234567",
    "first_name": "Jane",
    "last_name": "Smith",
    "ad_referral": null
  },
  "campaign": {
    "id": "<campaign-id>",
    "name": "AI Receptionist",
    "status": "Live"
  },
  "agent": {
    "id": "<agent-id>",
    "name": "Front Desk"
  },
  "user": {
    "id": "<account-id>",
    "email": "owner@example.com",
    "first_name": "Alex",
    "last_name": "Doe"
  },
  "message": {
    "id": "<message-id>",
    "status": "delivered"
  }
}
```

| Fält | Beskrivning |
|---|---|
| `event` | `delivered` eller `undelivered` för **Deliveries**, `read` för **Reads**. |
| `contact` | Kontakten som meddelandet skickades till. |
| `campaign` | Kampanjen som kontakten tillhör, eller `null`. |
| `agent` | Agenten som hanterar konversationen, eller `null`. |
| `user` | Grundläggande identitetsinformation för kontot som äger datan. |
| `message.id` | ID för meddelandet som denna uppdatering gäller. Det är samma värde som [send message endpoint](../api/messages.md#send-a-message) returnerar som `messageId`, och samma `message.id` som en [New Message](#new-message-webhook)-notis innehåller. |
| `message.status` | Den nya statusen, alltid samma sträng som `event` (`delivered`, `undelivered` eller `read`). |

> **Hur man matchar en uppdatering med meddelandet du skickade.** Lagra det `messageId` du får tillbaka när du skickar ett meddelande via API:et. När en **Deliveries**- eller **Reads**-notis anländer, sök upp det lagrade ID:t mot `message.id` i nyttolasten — det är ditt leverans- eller läskvitto för just det meddelandet.

> **Det finns ingen meddelandetext här.** `message`-blocket innehåller endast ID och status. Prenumerera på [New Message](#new-message-webhook) om du även behöver innehållet.

> **`message`-blocket finns endast när vi vet vilket meddelande det var.** Vid sällsynta uppdateringar som vi inte kan koppla till ett lagrat meddelande utelämnas blocket helt istället för att skickas tomt — kontrollera därför att `message` existerar innan du läser `message.id`.

> **En notis per statusändring.** Ett enskilt utgående meddelande skapar normalt en `delivered`-notis och sedan, på kanaler med läskvitton, en `read`-notis. Ett misslyckat utskick skapar `undelivered` istället.

---

## Appointment Booked Webhook

Utlöses när en kontakt bokar en tid. Den utlöses på samma sätt oavsett om AI:n bokade den under en konversation, om du bokade den för hand eller om den kom in via API:et.

### Händelsenamn

`booked`

### Nyttolastformat

```json
{
  "event": "booked",
  "contact": {
    "id": "<contact-id>",
    "email": "jane@example.com",
    "phone_number": "+15551234567",
    "first_name": "Jane",
    "last_name": "Smith"
  },
  "campaign": {
    "id": "<campaign-id>",
    "name": "AI Receptionist",
    "status": "Live"
  },
  "user": {
    "id": "<account-id>",
    "email": "owner@example.com"
  },
  "appointment": {
    "appointment_id": "<appointment-id>",
    "start_time": "2026-07-20T15:00:00.000Z",
    "end_time": "2026-07-20T15:30:00.000Z",
    "status": "confirmed",
    "room_name": "Room 1",
    "description": "Discovery call",
    "summary": "30 min intro",
    "google_calendar_event_id": null,
    "event": {
      "id": "<service-id>",
      "event_name": "Intro Call",
      "slot_duration": 30,
      "location": "Zoom",
      "meeting_link": "https://...",
      "event_type": "online"
    }
  }
}
```

| Fält | Beskrivning |
|---|---|
| `event` | Alltid `booked` för denna händelse. |
| `contact` | Personen som bokade. `email` och `phone_number` kan vara tomma beroende på kanal. |
| `appointment.appointment_id` | Det unika ID:t för bokningen. |
| `appointment.start_time` / `end_time` | Start och slut för den bokade tiden, i UTC (ISO 8601). |
| `appointment.status` | Bokningens nuvarande status. |
| `appointment.room_name` | Rummet bokningen placerades i, om det används. |
| `appointment.description` / `summary` | Detaljer i fritext som fångats vid bokningen. |
| `appointment.google_calendar_event_id` | Google Calendars ID för den synkroniserade händelsen. Det är ofta `null` i Appointment Booked-webhooken, eftersom kalenderhändelsen skapas i samma ögonblick som meddelandet skickas — hämta bokningen igen via dess `appointment_id` en stund senare om du behöver den, och förvänta dig ett permanent `null` på konton utan ansluten Google Kalender. |
| `appointment.event` | Tjänsten som bokades: namn, tidslängd, plats, möteslänk, typ. |

> **`google_calendar_event_id` är ofta `null` i denna webhook, och det är normalt.** Google Calendar-händelsen skapas i samma ögonblick som denna avisering går ut, så ID:t är oftast inte klart än. Hämta bokningen igen via dess `appointment_id` en stund senare om du behöver det. Det förblir `null` permanent om kontot inte har någon Google Calendar ansluten, så vänta inte på det för evigt.

> **"Test"-knappen inkluderar inte `appointment`-blocket.** Använd den för att bekräfta att din slutpunkt svarar, gör sedan en riktig bokning för att se hela nyttolasten.

> **Två fall där denna webhook inte utlöses:** möten som importerats från en extern kalender och bokningar som kommer in via Formitable-integrationen.

---

## Webhook för uppdaterade kontakttaggar

Utlöses när en tagg **appliceras** på en kontakt, och den taggen har en webhook-URL konfigurerad för agenten eller kampanjen som kontakten tillhör.

### Händelsenamn

`contact_tags_updated`

### När den utlöses

- En tagg appliceras på en kontakt som har en tilldelad agent, en tilldelad kampanj eller båda.
- Minst en av de applicerade taggarna har en webhook-URL inställd under fliken Taggar för den agenten eller kampanjen.

Om kontakten har båda och kampanjens taggar har webhook-URL:er, vinner dessa; annars används agentens.

Om flera taggar med olika webhook-URL:er appliceras i samma uppdatering skickas en förfrågan per URL, där varje förfrågan endast innehåller de taggar som är kopplade till den URL:en.

**Att ta bort en tagg skickar aldrig en förfrågan.** De flesta använder dessa URL:er för en åtgärd — ta in en deposition, boka en tid, meddela en säljare — så att en tagg som tas bort från en kontakt tidigare kunde köra om den åtgärden. Det går inte längre. En borttagning visas fortfarande i `removed_tags` när den sker i samma uppdatering som en applicering som går till samma URL, så en automatisering som läser båda arrayerna behåller hela bilden; vad den aldrig kommer att se är en förfrågan som enbart orsakas av en borttagning. (Ändrat **12 augusti 2026**. Före det datumet skickade även borttagningar en förfrågan.)

### Nyttolastformat

```json
{
  "event": "contact_tags_updated",
  "contact": {
    "id": "<contact-id>",
    "email": "jane@example.com",
    "phone_number": "+15551234567",
    "first_name": "Jane",
    "last_name": "Smith",
    "human_alerted": false,
    "is_bot_active": true,
    "ad_referral": {
      "ctwa_clid": "ARAbc123...",
      "source_id": "120210000000000",
      "source_type": "ad",
      "source_url": "https://fb.me/xxxx",
      "headline": "Get 20% off today",
      "body": "Message us now to claim your discount",
      "channel": "whatsapp"
    }
  },
  "added_tags": ["qualified-lead"],
  "removed_tags": ["new-lead"],
  "agent": {
    "id": "<agent-id>",
    "name": "Front Desk"
  },
  "user": {
    "email": "owner@example.com",
    "first_name": "Alex",
    "last_name": "Doe"
  }
}
```

| Fält | Beskrivning |
|---|---|
| `event` | Alltid `contact_tags_updated` för denna webhook. |
| `contact.id` | Det unika ID:t för kontakten vars taggar ändrades. |
| `contact.email` / `contact.phone_number` | Kontaktens e-post/telefon, om känd. |
| `contact.first_name` / `contact.last_name` | Kontaktens namn. |
| `contact.human_alerted` | Huruvida kontakten för närvarande är flaggad för mänsklig uppmärksamhet. |
| `contact.is_bot_active` | Huruvida AI-boten för närvarande är aktiv i denna kontakts konversation. |
| `contact.ad_referral` | Finns endast när kontakten först nådde dig via en Meta Click-to-WhatsApp (CTWA)-annons eller inlägg. `null` annars. |
| `added_tags` | Array med taggnamn som applicerats i denna uppdatering. Aldrig tom — en applicering är det som utlöser begäran. |
| `removed_tags` | Array med taggnamn som tagits bort i samma uppdatering, om några. En borttagning i sig skickar ingenting. |
| `agent` | Agenten som hanterar kontaktens konversation (`id` och `name`), eller `null` om ingen agent är involverad. Lades till **15 augusti 2026**. |
| `user` | Grundläggande identitetsinformation för kontot som äger kontakten. |

### Testa en tagg-webhook

Bredvid fältet för webhook-URL på fliken Taggar finns en **Testa**-knapp. Den skickar omedelbart en exempelnyttolast till den URL:en, så att du kan bekräfta att din automatisering tar emot den innan du väntar på en riktig konversation.

Testet skickar samma `contact_tags_updated`-form som visas ovan, med en platshållarkontakt, med taggen du testar i `added_tags` och en tom `removed_tags`. Det din automatisering ser i testet är vad den kommer att se i produktion.

Två saker att känna till:

- **Spara taggen först.** Testet letar upp taggen via dess sparade namn, så en helt ny tagg eller en osparad namnändring kan inte testas än. Knappen förblir gråmarkerad tills namnet på skärmen matchar det sparade.
- **Ett misslyckat test räknas inte mot din webhook.** Tester bidrar aldrig till den automatiska avstängningen efter upprepade fel som beskrivs i [Webhook Reliability](#webhook-reliability).

Om testet misslyckas talar meddelandet om för dig vad din slutpunkt svarade (till exempel en `404` eller `500`), vilket oftast räcker för att upptäcka en felaktig URL eller ett arbetsflöde som inte är aktiverat.

---

## Webhook för slutförd uppgift

> **Endast för referens.** Uppgifts-webhooks (som data) dokumenteras här för utvecklare; händelserna **Task Created**, **Task Updated** och **Task Completed** är valbara i den vanliga händelselistan i webhook-formuläret precis som alla andra händelser — se [Tillgängliga utlösningshändelser](#available-trigger-events) och [De 22 webhook-händelserna](#the-22-webhook-events).

Denna nyttolast skickas när en uppgift övergår till ett stadium markerat som ett slutförandestadium. En uppgift som flyttas mellan stadier som inte är slutförandestadier skickar istället `taskUpdated`-formatet.

### Händelsenamn

`taskCompleted`

### När den utlöses

- En uppgift uppdateras.
- Dess `stage`-värde ändrades jämfört med dess tidigare värde.
- Det nya stadiet är konfigurerat som ett slutförandestadium i kontots inställningar för uppgiftsstadier.

### Nyttolastformat

```json
{
  "event": "taskCompleted",
  "contact": {
    "email": "jane@example.com",
    "phone_number": "+15551234567",
    "first_name": "Jane",
    "last_name": "Smith",
    "human_alerted": false,
    "human_alert_reason": null
  },
  "user": {
    "email": "owner@example.com",
    "first_name": "Alex",
    "last_name": "Doe"
  },
  "message": {
    "id": "<task-id>",
    "title": "Follow up with Jane",
    "description": "Confirm pricing and send proposal",
    "type": "follow_up",
    "priority": "high",
    "stage": "<stage-id>",
    "due_date": "2026-01-20T15:00:00Z",
    "source": "ai",
    "source_detail": "<source-detail>",
    "campaign_id": "<campaign-id>",
    "linked_human_alert": "<human-alert-id>",
    "tags": ["qualified-lead"],
    "notes": "Customer requested a callback"
  }
}
```

| Fält | Beskrivning |
|---|---|
| `event` | Alltid `taskCompleted` för denna webhook. Samma nyttolastformat skickas som `taskUpdated` när en uppgift ändras utan att gå in i ett slutförandestadium. |
| `contact` | Kontakten kopplad till uppgiften, om någon. `null` när den inte är kopplad. |
| `contact.human_alert_reason` | Anledningen till att kontakten flaggades för mänsklig uppmärksamhet, om tillämpligt. |
| `user` | Grundläggande identitetsinformation för kontot som äger uppgiften. |
| `message.id` | Det unika ID:t för uppgiften. |
| `message.title` / `description` | Uppgiftens titel och beskrivning. |
| `message.type` | Uppgiftstypen (till exempel `follow_up`, `call`, `custom`). |
| `message.priority` | Uppgiftens prioritet (`low`, `medium`, `high`). |
| `message.stage` | ID:t för stadiet som uppgiften nu befinner sig i. |
| `message.due_date` | Uppgiftens förfallodatum, om det är inställt. |
| `message.source` | Vad som skapade uppgiften (`ai`, `manual`, `api`). |
| `message.source_detail` | Ytterligare detaljer om källan. |
| `message.campaign_id` | ID:t för den kopplade kampanjen, eller `null`. |
| `message.linked_human_alert` | ID:t för den kopplade mänskliga varningen, om någon. |
| `message.tags` | Taggar som tillämpats på uppgiften. |
| `message.notes` | Fritextanteckningar om uppgiften. |

---

## Stänga av (eller ta bort) en webhook

Varje webhook har en på/av-knapp direkt på sin rad. Att stänga **av** en gör att den slutar ta emot händelser, men behåller allt du konfigurerat — URL:en, händelserna, eventuella signeringshemligheter. Slå på den igen så fortsätter den där den slutade; ingenting som hände medan den var avstängd levereras i efterhand.

Använd den när du vill att leveranser ska göra uppehåll en stund: din slutpunkt byggs om, du felsöker en störande integration eller pausar en automatisering.

Att **ta bort** en webhook (papperskorgsikonen på dess rad) tar bort den permanent, inklusive dess signeringshemlighet. Om du bara vill att leveranser ska upphöra, stäng av den istället — ta bort är för när du är helt klar med slutpunkten.

> **Detta är inte samma sak som att en webhook stängs av automatiskt.** Om vi inaktiverar din webhook efter upprepade fel (se [Webhook-tillförlitlighet](#webhook-reliability)), kommer reglaget ovan inte att aktivera den igen. När din slutpunkt har åtgärdats, redigera webhooken och spara den med en ändrad URL (alla URL-ändringar återaktiverar den), eller anropa [återaktiveringsslutpunkten](../api/webhooks.md) via API:et — eller kontakta supporten så aktiverar vi den åt dig.

---

## Signerade nyttolaster (Verifiera att en webhook verkligen kom från oss)

Vem som helst som får reda på din webhook-URL kan skicka en falsk förfrågan till den. Om du agerar på webhooks automatiskt — uppdaterar fakturering, skapar CRM-poster — låter aktivering av **signering** dig verifiera att varje förfrågan verkligen kom från oss.

Signering är **valfritt och avstängt som standard**, och du aktiverar det per webhook från den webhookens redigeringsvy (öppna en sparad webhooks rad).

### Aktivera signering

1. Öppna webhooken (Inställningar → Integrationer → Webhooks → klicka på din webhooks rad).
2. I avsnittet **Signeringshemlighet**, klicka på **Generera**.
3. Kopiera hemligheten (den börjar med `whsec_`) och lagra den i ditt mottagande system. Behandla den som ett lösenord.

Du kan när som helst återvända för att visa, kopiera, rotera eller stänga av hemligheten från samma panel.

### Vad vi skickar

När signering är aktiverad bär varje leverans för den webhooken dessa två extra HTTP-huvuden:

| Huvud | Betydelse |
|---|---|
| `X-Webhook-Signature` | Signaturen, i formen `v1=<hex>`. |
| `X-Webhook-Timestamp` | När vi skickade den, som en Unix-tidsstämpel i sekunder. |

Dessa tre finns med i **varje** leverans, signerad eller ej:

| Huvud | Betydelse |
|---|---|
| `X-Webhook-Delivery` | Ett unikt ID för denna händelse. Förblir detsamma vid återförsök, så det är vad du använder för deduplicering. |
| `X-Webhook-Attempt` | Vilket försök detta är (`1` är det första försöket). |
| `X-Webhook-Event` | Händelsenamnet, så att du kan dirigera utan att läsa brödtexten. |

### Hur man verifierar

Signaturen är en HMAC-SHA256 av strängen `<timestamp>.<raw request body>`, med din signeringshemlighet som nyckel.

**Verifiera mot den råa förfrågningskroppen — de exakta bytes du tog emot.** Om ditt ramverk tolkar JSON-koden och serialiserar om den innan kontroll, kan bytes ändras och signaturen kommer inte att matcha.

Node.js-exempel:

```js
const crypto = require("crypto");

function verify(rawBody, headers, secret) {
  const timestamp = headers["x-webhook-timestamp"];
  const signature = headers["x-webhook-signature"]; // "v1=<hex>"

  // Reject anything older than 5 minutes so a captured request can't be replayed later.
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;

  const expected = crypto.createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest("hex");

  return crypto.timingSafeEqual(Buffer.from(signature.replace("v1=", "")), Buffer.from(expected));
}
```

Python-exempel:

```python
import hashlib, hmac, time

def verify(raw_body: bytes, headers, secret: str) -> bool:
    timestamp = headers["X-Webhook-Timestamp"]
    signature = headers["X-Webhook-Signature"].replace("v1=", "")

    # Reject anything older than 5 minutes so a captured request can't be replayed later.
    if abs(time.time() - int(timestamp)) > 300:
        return False

    expected = hmac.new(secret.encode(), f"{timestamp}.".encode() + raw_body, hashlib.sha256).hexdigest()

    return hmac.compare_digest(signature, expected)
```

> **Jämför signaturer med en tidsäker funktion** (`timingSafeEqual` / `compare_digest`), inte `==`. Det kostar ingenting och undviker en subtil klass av attacker.

### Rotera hemligheten

Klicka på **Rotera** för att ersätta hemligheten. Växlingen sker omedelbart: nästa leverans signeras endast med den nya hemligheten. Om din slutpunkt är aktiv, acceptera **både** den gamla och den nya hemligheten i några minuter medan du distribuerar den nya.

Att stänga av signering innebär helt enkelt att signaturhuvuden inte längre skickas.

---

## Försök igen vid misslyckade leveranser

Som standard görs inga nya försök för en leverans som misslyckas — om ditt system är nere vid det tillfället går händelsen förlorad.

Aktivera **Försök igen vid misslyckade leveranser** för en webhook (i formuläret för att skapa/redigera) så fortsätter vi försöka:

| Försök | När |
|---|---|
| 1 | Omedelbart |
| 2 | 1 minut senare |
| 3 | 5 minuter senare |
| 4 | 30 minuter senare |
| 5 | 2 timmar senare |

Det sträcker sig över ungefär **2 timmar och 40 minuter**, så en webhook kan överleva ett underhållsfönster eller ett kort avbrott på din sida.

**Vad som görs nytt försök för:** tillfälliga problem — om din server returnerar ett 5xx-fel, en timeout eller ett anslutningsfel.

**Vad som inte gör det:** om din slutpunkt avvisar själva förfrågan (vilken 4xx som helst), försöker vi inte igen — att skicka samma förfrågan igen skulle bara leda till samma avvisande.

**Vilka händelser som görs om:** tagg-webhooks (`contact_tags_updated`), de tre uppgiftshändelserna och den dagliga sammanfattningen. Resten skickas en gång, så för dem har växeln inget att agera på. Varje händelse bär fortfarande `X-Webhook-Delivery`, så en dedupliceringsregel täcker alla.

> **Aktivera endast försök igen om din slutpunkt är idempotent.** Försök igen innebär att samma händelse kan anlända mer än en gång. Använd `X-Webhook-Delivery`-huvudet för att känna igen en upprepning: det förblir detsamma vid varje försök för en händelse, så att du säkert kan ignorera ett ID som du redan har hanterat.

Försök igen-funktionen interagerar med den automatiska avstängningen efter upprepade fel (se [Webhook-tillförlitlighet](#webhook-reliability)) på det sätt du förväntar dig: felräknaren räknar en **hel leverans**, först efter att varje försök har förbrukats — inte varje enskilt försök.

---

## Webhook-tillförlitlighet

- <span data-t="appName">Your AI Connector</span> skickar webhooks via en säker anslutning (HTTPS). Se till att webbadressen du anger använder HTTPS.
- Om ditt system returnerar ett fel anses leveransen ha misslyckats.
- Övervaka ditt mottagande systems drifttid för att undvika att missa händelser.
- För kritiska arbetsflöden, aktivera [Försök igen vid misslyckad leverans](#retrying-failed-deliveries) och överväg även en reservmekanism.

> **Webhooks stängs av automatiskt efter upprepade fel.** Om din webhook-URL misslyckas upprepade gånger (cirka 5 fel i rad, eller 3 i rad för konfigurationsfel), slutar <span data-t="appName">Your AI Connector</span> automatiskt att skicka händelser till den URL:en. För att återaktivera den när din slutpunkt fungerar igen: redigera webhooken och spara den med en ändrad URL (alla URL-ändringar återaktiverar den), eller använd [återaktiveringsslutpunkten](../api/webhooks.md) via API:et — att spara med samma URL räcker inte. Supporten kan också återaktivera den åt dig.

---

## Felsökning

| Problem | Lösning |
|---|---|
| Webhook utlöses inte | Kontrollera först att webhooken inte är avstängd (**off**) på sin rad. Bekräfta sedan att rätt händelser är valda och att din URL är nåbar från internet. |
| Test-händelse fungerar men riktiga händelser gör det inte | Se till att den specifika händelsetypen är aktiverad. Om du förväntade dig en begäran när en tagg läggs till, notera att `subscribed_to_tags` inte begränsar en webhooks händelser till en tagg — den begränsar bara vilka taggar som genererar ett meddelande om konversationssammanfattning. För att få en begäran när en specifik tagg läggs till, ställ in en webhook-URL på den taggen under fliken **Taggar** för agenten (eller kampanjen) — se [Webhook för uppdaterade kontakttaggar](#contact-tags-updated-webhook). |
| Inget kommer fram till n8n / Make / Zapier | Du använder förmodligen plattformens **Test-URL**, som bara lyssnar efter en enskild händelse precis efter att du klickat på "Lyssna efter testhändelse". För live-händelser, spara **Produktions-URL** och växla arbetsflödet till **Aktivt**. |
| Tar emot dubbletthändelser | Kontrollera om det finns flera webhooks som pekar på samma URL. Om **Försök igen vid misslyckade leveranser** är aktiverat, förväntas en upprepning när din slutpunkt accepterade en händelse men misslyckades med att svara i tid — avduplicera på `X-Webhook-Delivery`. |
| Signaturkontroll misslyckas alltid | Nästan alltid för att brödtexten serialiserades om före kontrollen. Verifiera mot den **råa** begärans brödtext, signera `<timestamp>.<body>`, och bekräfta att du använder den aktuella hemligheten om du nyligen roterade den. |
| Försök igen sker inte | Försök igen är avstängt om det inte aktiverats på den specifika webhooken. Vi försöker inte igen vid 4xx-svar. |
| Blocket `campaign` är alltid `null` | Förväntat om ditt konto använder agenter: kontakter tillhör en agent snarare än en kampanj. Läs blocket `agent` istället — se [Dataformat för webhooks](#webhook-data-format). |
| Data är tom eller felaktig | Verifiera att ditt mottagande system accepterar JSON. Kontrollera dina serverloggar för tolkningsfel. |
| Webhook-URL returnerar fel | Testa din URL med ett verktyg som Postman eller [webhook.site](https://webhook.site). |
| Webhook slutade utlösas helt efter ett avbrott | Upprepade fel inaktiverar automatiskt en webhook. Att spara om den aktiverar den inte igen — fixa din slutpunkt och kontakta sedan supporten. |
| Spara eller Testa ger ett behörighetsfel | Du behöver behörigheten "redigera" för integrationer. Be kontoinnehavaren att bevilja den. |
| En webhooks `subscribed_to_tags`-lista kom tillbaka tom | `subscribed_to_tags` begränsar inte en webhooks händelser till en tagg — den begränsar bara vilka taggar som genererar ett meddelande om konversationssammanfattning. Redigering från webhook-formuläret rensar inte längre den listan (fixat 21 juli 2026). Om en webhook förlorade sin lista före det datumet, ställ in `subscribed_to_tags` igen via [Webhooks API](../api/webhooks.md) — se [Taggbaserade webhook-utlösare](#tag-based-webhook-triggers). |

---

## Nästa steg

- [GoHighLevel-integration](ghl-integration.md) — använd webhooks för att integrera <span data-t="appName">Your AI Connector</span> med GHL.
- [API-åtkomst](api-access.md) — kombinera webhooks med API:et för kraftfull automatisering.
- [Använda taggar för att märka kontakter](../get-started/creating-tags.md) — ställ in taggar som utlöser dina webhooks.
