Webhooks

Webhooks

Gemlead stuurt een HTTPS-request naar je server zodra een lead gevonden wordt, heet wordt, antwoordt of op je bericht reageert, of zodra Sam AI een antwoord klaar heeft, er een verstuurt of een gesprek aan jou overdraagt. Elk request is ondertekend, zodat je weet dat het van ons komt.

Een endpoint instellen

Voeg een endpoint toe in de app onder API, of met Een webhook-endpoint maken. Geef het een publieke HTTPS-URL en de gebeurtenistypen die je wilt ontvangen, en bewaar de secret uit de response om handtekeningen te verifiëren.

  • Alleen HTTPS, geen inloggegevens in de URL en geen privé-, loopback- of link-local-adres.
  • Maximaal 10 endpoints per account.
  • filters.persona_ids beperkt de gebeurtenissen die een endpoint ontvangt tot de leads van bepaalde persona's, ongeacht hun type.
  • Stuur een testgebeurtenis om je server te controleren voordat er echte gebeurtenissen binnenkomen.

Webhooks zitten in de abonnementen Business en Enterprise. Stapt het account over naar Free of Starter, dan blijven de endpoints bestaan maar versturen ze niets tot het account weer op Business of Enterprise staat.

POST/v1/webhook_endpoints
curl -X POST https://gemlead.ai/api/v1/webhook_endpoints \
  -H "Authorization: Bearer $GEMLEAD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/gemlead",
    "events": ["lead.hot", "reply.received"],
    "description": "CRM sync",
    "filters": {
      "persona_ids": ["lvWBPnytpS"]
    }
  }'

Gebeurtenistypen

Elke gebeurtenis heeft dezelfde envelop. Wat er in data staat, hangt af van het type.

TypeVerstuurd als
lead.createdGemlead vindt en scoort een nieuwe lead, ongeacht de score. Deze gebeurtenis komt één keer per lead, met de eerste score, en alleen binnen 3 dagen nadat de lead is gevonden, dus een oudere lead opnieuw scoren levert hem nooit op. Scoort een lead meteen 60 of hoger, dan komt er ook een lead.hot.
lead.hotDe score van een lead komt voor het eerst op 60 of hoger. Deze gebeurtenis komt één keer per lead, opnieuw scoren levert hem nooit nog eens op.
reply.receivedEen lead stuurt je een nieuw bericht, in een campagne of daarbuiten. Elk bericht levert deze gebeurtenis één keer op, als het minder dan 6 uur oud is. Komen er veel berichten van de lead tegelijk binnen, dan geldt dat alleen voor de 5 nieuwste.
reaction.receivedEen lead reageert met een emoji op een van je berichten. Elke emoji van de lead op een bericht levert deze gebeurtenis één keer op.
sam.suggestion.readySam AI heeft een nieuw antwoord klaarstaan dat jij kunt versturen, in een gesprek in de modus draft. Elke suggestie levert deze gebeurtenis één keer op, als ze minder dan 6 uur oud is.
sam.reply.sentEen antwoord van Sam AI wordt verstuurd vanaf je X-account, vanzelf in de modus auto of zodra je het in de app goedkeurt. Elk antwoord levert deze gebeurtenis één keer op, als het minder dan 6 uur oud is. Berichten die je zelf schrijft, leveren hem nooit op, die vind je terug in Een gesprek ophalen.
sam.handoffSam AI draagt een gesprek aan jou over, als hij zonder jou geen goed antwoord ziet, als de lead alleen een foto of een spraakbericht stuurde, of als zijn antwoord niet verstuurd kon worden. In de modus auto laat hij de volgende berichten van de lead daarna aan jou over. Elke overdracht levert deze gebeurtenis één keer op, als ze minder dan 6 uur oud is.

Het gebeurtenisobject

  • idstring
    Unieke ID van de gebeurtenis, evt_ gevolgd door 24 tekens. Staat ook in de header Gemlead-Event-Id.
  • objectstring
    Altijd event.
  • typestring
    Het gebeurtenistype.
    lead.createdlead.hotreply.receivedreaction.receivedsam.suggestion.readysam.reply.sentsam.handoff
  • created_atstring
    Wanneer de gebeurtenis plaatsvond, in ISO 8601.
  • account_idstring
    Het Gemlead-account waarop de gebeurtenis plaatsvond.
  • dataobject
    De inhoud van de gebeurtenis, die afhangt van het type.

lead.created

Gemlead vindt en scoort een nieuwe lead, ongeacht de score. Deze gebeurtenis komt één keer per lead, met de eerste score, en alleen binnen 3 dagen nadat de lead is gevonden, dus een oudere lead opnieuw scoren levert hem nooit op. Scoort een lead meteen 60 of hoger, dan komt er ook een lead.hot.

Data

lead.created
{
  "id": "evt_8kQ2vXr4LmT9wPz1Hc6YbN3d",
  "object": "event",
  "type": "lead.created",
  "created_at": "2026-11-05T14:03:40.117Z",
  "account_id": "a9PzK2vRtM",
  "data": {
    "object": {
      "id": "k3VnQ8wZpR",
      "object": "lead",
      "profile": {
        "x_user_id": "1592047713",
        "username": "mark_picks",
        "name": "Mark Ellis",
        "bio": "Free NBA picks every day. Sports fan first.",
        "followers_count": 2150,
        "following_count": 940,
        "location": "Denver, CO",
        "website": "https://markpicks.net",
        "profile_image_url": "https://pbs.twimg.com/profile_images/1592047713/mark_400x400.jpg",
        "verified": false,
        "url": "https://x.com/mark_picks"
      },
      "score": 38,
      "score_reason": "Shares free picks for fun and sells nothing yet, no sign of a paying community.",
      "hot": false,
      "status": "scored",
      "persona": {
        "id": "lvWBPnytpS",
        "name": "Tipsters"
      },
      "campaign": null,
      "conversation_id": null,
      "locked_to": null,
      "found_at": "2026-11-05T14:02:11.482Z",
      "scored_at": "2026-11-05T14:03:40.117Z",
      "updated_at": "2026-11-05T14:03:40.117Z",
      "metadata": {}
    }
  }
}

lead.hot

De score van een lead komt voor het eerst op 60 of hoger. Deze gebeurtenis komt één keer per lead, opnieuw scoren levert hem nooit nog eens op.

Data

lead.hot
{
  "id": "evt_8kQ2vXr4LmT9wPz1Hc6YbN3d",
  "object": "event",
  "type": "lead.hot",
  "created_at": "2026-11-05T14:03:40.117Z",
  "account_id": "a9PzK2vRtM",
  "data": {
    "object": {
      "id": "msgOtJ8dvT",
      "object": "lead",
      "profile": {
        "x_user_id": "1460283925",
        "username": "jane_builds",
        "name": "Jane Doe",
        "bio": "Runs a paid trading community. Daily setups, no hype.",
        "followers_count": 12400,
        "following_count": 380,
        "location": "Austin, TX",
        "website": "https://janedoe.com",
        "profile_image_url": "https://pbs.twimg.com/profile_images/1460283925/jane_400x400.jpg",
        "verified": true,
        "url": "https://x.com/jane_builds"
      },
      "score": 86,
      "score_reason": "Runs a paid trading community and asks how to collect payments for it.",
      "hot": true,
      "status": "scored",
      "persona": {
        "id": "lvWBPnytpS",
        "name": "Tipsters"
      },
      "campaign": null,
      "conversation_id": null,
      "locked_to": null,
      "found_at": "2026-11-05T14:02:11.482Z",
      "scored_at": "2026-11-05T14:03:40.117Z",
      "updated_at": "2026-11-05T14:03:40.117Z",
      "metadata": {}
    }
  }
}

reply.received

Een lead stuurt je een nieuw bericht, in een campagne of daarbuiten. Elk bericht levert deze gebeurtenis één keer op, als het minder dan 6 uur oud is. Komen er veel berichten van de lead tegelijk binnen, dan geldt dat alleen voor de 5 nieuwste.

Data

  • leadobject
    De lead die schreef.
  • messageobject
    Het nieuwe bericht, met direction op inbound.
  • campaignobject of null
    De campagne waarin de lead zit, met id, name en status.
  • conversation_idstring
    Gebruik deze ID met Een gesprek ophalen voor het hele gesprek.
reply.received
{
  "id": "evt_8kQ2vXr4LmT9wPz1Hc6YbN3d",
  "object": "event",
  "type": "reply.received",
  "created_at": "2026-11-05T14:03:40.117Z",
  "account_id": "a9PzK2vRtM",
  "data": {
    "lead": {
      "id": "msgOtJ8dvT",
      "object": "lead",
      "profile": {
        "x_user_id": "1460283925",
        "username": "jane_builds",
        "name": "Jane Doe",
        "bio": "Runs a paid trading community. Daily setups, no hype.",
        "followers_count": 12400,
        "following_count": 380,
        "location": "Austin, TX",
        "website": "https://janedoe.com",
        "profile_image_url": "https://pbs.twimg.com/profile_images/1460283925/jane_400x400.jpg",
        "verified": true,
        "url": "https://x.com/jane_builds"
      },
      "score": 86,
      "score_reason": "Runs a paid trading community and asks how to collect payments for it.",
      "hot": true,
      "status": "in_conversation",
      "persona": {
        "id": "lvWBPnytpS",
        "name": "Tipsters"
      },
      "campaign": {
        "id": "c7RkQ2wLxe",
        "name": "Tipsters warm intro",
        "status": "in_progress"
      },
      "conversation_id": "msgOtJ8dvT",
      "locked_to": null,
      "found_at": "2026-11-05T14:02:11.482Z",
      "scored_at": "2026-11-05T14:03:40.117Z",
      "updated_at": "2026-11-05T14:03:40.117Z",
      "metadata": {}
    },
    "message": {
      "id": "1985321409876543210",
      "object": "message",
      "direction": "inbound",
      "text": "Yes, I want to charge for my Discord. How does it work?",
      "created_at": "2026-11-06T08:12:44.000Z",
      "media": [],
      "reactions": [],
      "encrypted": false,
      "reply_to_message_id": null
    },
    "campaign": {
      "id": "c7RkQ2wLxe",
      "name": "Tipsters warm intro",
      "status": "in_progress"
    },
    "conversation_id": "msgOtJ8dvT"
  }
}

reaction.received

Een lead reageert met een emoji op een van je berichten. Elke emoji van de lead op een bericht levert deze gebeurtenis één keer op.

Data

  • leadobject
    De lead die reageerde.
  • messageobject
    Je bericht waarop de lead reageerde, met direction op outbound.
  • reactionobject
    De nieuwe reactie, met direction op inbound.
reaction.received
{
  "id": "evt_8kQ2vXr4LmT9wPz1Hc6YbN3d",
  "object": "event",
  "type": "reaction.received",
  "created_at": "2026-11-05T14:03:40.117Z",
  "account_id": "a9PzK2vRtM",
  "data": {
    "lead": {
      "id": "msgOtJ8dvT",
      "object": "lead",
      "profile": {
        "x_user_id": "1460283925",
        "username": "jane_builds",
        "name": "Jane Doe",
        "bio": "Runs a paid trading community. Daily setups, no hype.",
        "followers_count": 12400,
        "following_count": 380,
        "location": "Austin, TX",
        "website": "https://janedoe.com",
        "profile_image_url": "https://pbs.twimg.com/profile_images/1460283925/jane_400x400.jpg",
        "verified": true,
        "url": "https://x.com/jane_builds"
      },
      "score": 86,
      "score_reason": "Runs a paid trading community and asks how to collect payments for it.",
      "hot": true,
      "status": "in_conversation",
      "persona": {
        "id": "lvWBPnytpS",
        "name": "Tipsters"
      },
      "campaign": {
        "id": "c7RkQ2wLxe",
        "name": "Tipsters warm intro",
        "status": "in_progress"
      },
      "conversation_id": "msgOtJ8dvT",
      "locked_to": null,
      "found_at": "2026-11-05T14:02:11.482Z",
      "scored_at": "2026-11-05T14:03:40.117Z",
      "updated_at": "2026-11-05T14:03:40.117Z",
      "metadata": {}
    },
    "message": {
      "id": "1985329981234567890",
      "object": "message",
      "direction": "outbound",
      "text": "Happy to show you. Do you sell picks monthly or per event?",
      "created_at": "2026-11-06T08:20:03.000Z",
      "media": [],
      "reactions": [
        {
          "emoji": "👍",
          "direction": "inbound",
          "created_at": "2026-11-06T08:24:51.000Z"
        }
      ],
      "encrypted": false,
      "reply_to_message_id": "1985321409876543210"
    },
    "reaction": {
      "emoji": "👍",
      "direction": "inbound",
      "created_at": "2026-11-06T08:24:51.000Z"
    }
  }
}

sam.suggestion.ready

Sam AI heeft een nieuw antwoord klaarstaan dat jij kunt versturen, in een gesprek in de modus draft. Elke suggestie levert deze gebeurtenis één keer op, als ze minder dan 6 uur oud is.

Data

  • leadobject
    De lead aan wie Sam AI antwoordt.
  • conversation_idstring
    Gebruik deze ID met Sam AI van een gesprek ophalen om de suggestie opnieuw te lezen of de modus te wijzigen.
  • campaignobject of null
    De campagne waarin de lead zit, met id, name en status.
  • suggestionobject
    Het antwoord dat Sam AI klaar heeft staan.
sam.suggestion.ready
{
  "id": "evt_8kQ2vXr4LmT9wPz1Hc6YbN3d",
  "object": "event",
  "type": "sam.suggestion.ready",
  "created_at": "2026-11-05T14:03:40.117Z",
  "account_id": "a9PzK2vRtM",
  "data": {
    "lead": {
      "id": "msgOtJ8dvT",
      "object": "lead",
      "profile": {
        "x_user_id": "1460283925",
        "username": "jane_builds",
        "name": "Jane Doe",
        "bio": "Runs a paid trading community. Daily setups, no hype.",
        "followers_count": 12400,
        "following_count": 380,
        "location": "Austin, TX",
        "website": "https://janedoe.com",
        "profile_image_url": "https://pbs.twimg.com/profile_images/1460283925/jane_400x400.jpg",
        "verified": true,
        "url": "https://x.com/jane_builds"
      },
      "score": 86,
      "score_reason": "Runs a paid trading community and asks how to collect payments for it.",
      "hot": true,
      "status": "in_conversation",
      "persona": {
        "id": "lvWBPnytpS",
        "name": "Tipsters"
      },
      "campaign": {
        "id": "c7RkQ2wLxe",
        "name": "Tipsters warm intro",
        "status": "in_progress"
      },
      "conversation_id": "msgOtJ8dvT",
      "locked_to": null,
      "found_at": "2026-11-05T14:02:11.482Z",
      "scored_at": "2026-11-05T14:03:40.117Z",
      "updated_at": "2026-11-05T14:03:40.117Z",
      "metadata": {}
    },
    "conversation_id": "msgOtJ8dvT",
    "campaign": {
      "id": "c7RkQ2wLxe",
      "name": "Tipsters warm intro",
      "status": "in_progress"
    },
    "suggestion": {
      "messages": [
        "It takes two minutes. You set a price, members pay, and they get their Discord role right away.",
        "Want the link to set it up?"
      ],
      "stage": "answer_question",
      "why": "She asked how it works, so the reply explains it in one line and offers the link.",
      "replying_to_message_id": "1985321409876543210",
      "created_at": "2026-11-06T08:13:20.000Z"
    }
  }
}

sam.reply.sent

Een antwoord van Sam AI wordt verstuurd vanaf je X-account, vanzelf in de modus auto of zodra je het in de app goedkeurt. Elk antwoord levert deze gebeurtenis één keer op, als het minder dan 6 uur oud is. Berichten die je zelf schrijft, leveren hem nooit op, die vind je terug in Een gesprek ophalen.

Data

  • leadobject
    De lead aan wie Sam AI antwoordde.
  • conversation_idstring
    Gebruik deze ID met Een gesprek ophalen voor het hele gesprek.
  • campaignobject of null
    De campagne waarin de lead zit, met id, name en status.
  • messagesarray van strings
    De DM's die Sam AI verstuurde, op volgorde.
  • sent_bystring
    auto als Sam AI het zelf verstuurde, approved als je het in de app goedkeurde.
    autoapproved
  • replying_to_message_idstring of null
    Het bericht van de lead waarop het antwoordde.
  • sent_atstring
    Wanneer het verstuurd werd, in ISO 8601.
sam.reply.sent
{
  "id": "evt_8kQ2vXr4LmT9wPz1Hc6YbN3d",
  "object": "event",
  "type": "sam.reply.sent",
  "created_at": "2026-11-05T14:03:40.117Z",
  "account_id": "a9PzK2vRtM",
  "data": {
    "lead": {
      "id": "msgOtJ8dvT",
      "object": "lead",
      "profile": {
        "x_user_id": "1460283925",
        "username": "jane_builds",
        "name": "Jane Doe",
        "bio": "Runs a paid trading community. Daily setups, no hype.",
        "followers_count": 12400,
        "following_count": 380,
        "location": "Austin, TX",
        "website": "https://janedoe.com",
        "profile_image_url": "https://pbs.twimg.com/profile_images/1460283925/jane_400x400.jpg",
        "verified": true,
        "url": "https://x.com/jane_builds"
      },
      "score": 86,
      "score_reason": "Runs a paid trading community and asks how to collect payments for it.",
      "hot": true,
      "status": "in_conversation",
      "persona": {
        "id": "lvWBPnytpS",
        "name": "Tipsters"
      },
      "campaign": {
        "id": "c7RkQ2wLxe",
        "name": "Tipsters warm intro",
        "status": "in_progress"
      },
      "conversation_id": "msgOtJ8dvT",
      "locked_to": null,
      "found_at": "2026-11-05T14:02:11.482Z",
      "scored_at": "2026-11-05T14:03:40.117Z",
      "updated_at": "2026-11-05T14:03:40.117Z",
      "metadata": {}
    },
    "conversation_id": "msgOtJ8dvT",
    "campaign": {
      "id": "c7RkQ2wLxe",
      "name": "Tipsters warm intro",
      "status": "in_progress"
    },
    "messages": [
      "It takes two minutes. You set a price, members pay, and they get their Discord role right away.",
      "Want the link to set it up?"
    ],
    "sent_by": "auto",
    "replying_to_message_id": "1985321409876543210",
    "sent_at": "2026-11-06T08:14:05.000Z"
  }
}

sam.handoff

Sam AI draagt een gesprek aan jou over, als hij zonder jou geen goed antwoord ziet, als de lead alleen een foto of een spraakbericht stuurde, of als zijn antwoord niet verstuurd kon worden. In de modus auto laat hij de volgende berichten van de lead daarna aan jou over. Elke overdracht levert deze gebeurtenis één keer op, als ze minder dan 6 uur oud is.

Data

  • leadobject
    De lead die op een antwoord wacht.
  • conversation_idstring
    Gebruik deze ID met Een gesprek ophalen voor het hele gesprek.
  • campaignobject of null
    De campagne waarin de lead zit, met id, name en status.
  • reasonstring of null
    Waarom Sam AI het gesprek aan jou overdraagt, in zijn eigen woorden.
sam.handoff
{
  "id": "evt_8kQ2vXr4LmT9wPz1Hc6YbN3d",
  "object": "event",
  "type": "sam.handoff",
  "created_at": "2026-11-05T14:03:40.117Z",
  "account_id": "a9PzK2vRtM",
  "data": {
    "lead": {
      "id": "msgOtJ8dvT",
      "object": "lead",
      "profile": {
        "x_user_id": "1460283925",
        "username": "jane_builds",
        "name": "Jane Doe",
        "bio": "Runs a paid trading community. Daily setups, no hype.",
        "followers_count": 12400,
        "following_count": 380,
        "location": "Austin, TX",
        "website": "https://janedoe.com",
        "profile_image_url": "https://pbs.twimg.com/profile_images/1460283925/jane_400x400.jpg",
        "verified": true,
        "url": "https://x.com/jane_builds"
      },
      "score": 86,
      "score_reason": "Runs a paid trading community and asks how to collect payments for it.",
      "hot": true,
      "status": "in_conversation",
      "persona": {
        "id": "lvWBPnytpS",
        "name": "Tipsters"
      },
      "campaign": {
        "id": "c7RkQ2wLxe",
        "name": "Tipsters warm intro",
        "status": "in_progress"
      },
      "conversation_id": "msgOtJ8dvT",
      "locked_to": null,
      "found_at": "2026-11-05T14:02:11.482Z",
      "scored_at": "2026-11-05T14:03:40.117Z",
      "updated_at": "2026-11-05T14:03:40.117Z",
      "metadata": {}
    },
    "conversation_id": "msgOtJ8dvT",
    "campaign": {
      "id": "c7RkQ2wLxe",
      "name": "Tipsters warm intro",
      "status": "in_progress"
    },
    "reason": "She wants a call before she signs up."
  }
}

Levering

Gemlead stuurt elke gebeurtenis als POST met JSON en wacht 10 seconden op je antwoord. Elke 2xx telt als afgeleverd. Een redirect, elke andere status, een time-out of een verbindingsfout telt als mislukt, en dan wordt de gebeurtenis opnieuw verstuurd.

HeaderWaarde
Gemlead-SignatureDe tijdstempel en de handtekening, t=1762444800,v1=5f2b...
Gemlead-Event-IdDe id van de gebeurtenis, om gebeurtenissen over te slaan die je al hebt verwerkt.
Gemlead-Event-TypeHet type van de gebeurtenis.
User-AgentGemlead-Webhooks/1.0
Request
POST /webhooks/gemlead HTTP/1.1
Content-Type: application/json; charset=utf-8
User-Agent: Gemlead-Webhooks/1.0
Gemlead-Event-Id: evt_8kQ2vXr4LmT9wPz1Hc6YbN3d
Gemlead-Event-Type: lead.hot
Gemlead-Signature: t=1762444800,v1=58ca5e964b92d617c979d3f067cdc2035a1a1a9d3f848d7d927c2db09b8e9baa

Handtekeningen verifiëren

Iedereen kan een request naar je URL sturen. Controleer dat elk request van Gemlead komt voordat je het vertrouwt.

  1. Lees de ruwe body als bytes, vóór elke JSON-parsing. Parsen en opnieuw wegschrijven verandert de bytes.
  2. Splits de header Gemlead-Signature op komma's. t is een Unix-tijd in seconden, v1 is de handtekening.
  3. Bereken de HMAC SHA256 van t, een punt en de ruwe body, met als sleutel het volledige geheim van het endpoint, inclusief whsec_, en schrijf het resultaat in hex.
  4. Vergelijk het met elke v1 in constante tijd.
  5. Weiger een t die meer dan 5 minuten van je klok afwijkt, zodat een oud request niet opnieuw kan worden afgespeeld. Elke nieuwe poging wordt ondertekend met een verse t.

Antwoord met een 400 als de controle mislukt. Bewaar het geheim in een omgevingsvariabele zoals GEMLEAD_WEBHOOK_SECRET.

const crypto = require("crypto");
const express = require("express");

// rawBody: the request body exactly as received, before any JSON parsing.
function verifyGemleadSignature(rawBody, header, secret, toleranceSeconds = 300) {
  if (typeof header !== "string") return false;
  let timestamp = null;
  const signatures = [];
  for (const part of header.split(",")) {
    const [key, value] = part.split("=", 2).map((s) => (s || "").trim());
    if (key === "t") timestamp = value;
    if (key === "v1" && value) signatures.push(value);
  }
  if (!/^\d+$/.test(timestamp || "") || signatures.length === 0) return false;
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > toleranceSeconds) return false;
  const expected = crypto.createHmac("sha256", secret).update(`${timestamp}.`).update(rawBody).digest();
  return signatures.some((signature) => {
    const given = Buffer.from(signature, "hex");
    return given.length === expected.length && crypto.timingSafeEqual(given, expected);
  });
}

const app = express();

// The body must stay raw on this route.
app.post("/webhooks/gemlead", express.raw({ type: "application/json" }), (req, res) => {
  const ok = verifyGemleadSignature(
    req.body,
    req.get("Gemlead-Signature"),
    process.env.GEMLEAD_WEBHOOK_SECRET,
  );
  if (!ok) return res.status(400).send("Invalid signature");

  const event = JSON.parse(req.body.toString("utf8"));
  // Already handled? Skip it, retries send the same event.id again.
  if (event.type === "lead.created") {
    // event.data.object is the new lead, hot or not
  } else if (event.type === "lead.hot") {
    // event.data.object is the lead
  } else if (event.type === "reply.received") {
    // event.data.lead, event.data.message, event.data.campaign, event.data.conversation_id
  }
  res.sendStatus(200);
});

app.listen(3000);

Nieuwe pogingen

Mislukt een levering, dan probeert Gemlead het nog 7 keer, telkens na een langere wachttijd. Na de 8e poging, ongeveer 45 uur na de eerste, wordt de levering als mislukt gemarkeerd.

PogingVerstuurd
1Meteen
21 minuut na de vorige mislukte poging
35 minuten na de vorige mislukte poging
430 minuten na de vorige mislukte poging
52 uur na de vorige mislukte poging
66 uur na de vorige mislukte poging
712 uur na de vorige mislukte poging
824 uur na de vorige mislukte poging

Een endpoint dat 3 dagen op rij faalt, met minstens 8 mislukte pogingen, wordt uitgeschakeld. De status wordt disabled, de disabled_reason wordt failing en de leveringen die nog wachten, eindigen als mislukt. Herstel je server en zet het endpoint daarna weer aan in de app of met Een webhook-endpoint bijwerken, waarmee de telling opnieuw begint. Testgebeurtenissen worden één keer verstuurd en tellen nooit mee.

Leveringen opvragen toont per poging de statuscode en de fout, zodat je ziet wat je server heeft geantwoord.

Best practices

  • Antwoord binnen 10 seconden met een 2xx en doe het werk daarna in een queue.
  • Elke gebeurtenis komt minstens één keer aan. Gebruik de id van de gebeurtenis, ook in Gemlead-Event-Id, om een gebeurtenis over te slaan die je al hebt verwerkt.
  • Gebeurtenissen kunnen in een andere volgorde binnenkomen. Vergelijk created_at, of haal de lead opnieuw op voor de nieuwste stand.
  • Verifieer elke handtekening en weiger oude tijdstempels.
  • Als je het geheim vernieuwt, wordt het meteen vervangen. Deploy het nieuwe direct daarna, leveringen die intussen mislukken, worden opnieuw geprobeerd en met het nieuwe geheim ondertekend.
  • Gebeurtenissen en leveringen worden 30 dagen bewaard.