API reference
Webhook endpoints
A webhook endpoint is a URL of yours that receives Gemlead's events as they happen. You can have 10 per account. Read Webhooks for the events, their payloads and how to verify a signature.
The webhook endpoint object
A URL of yours that Gemlead sends events to. See Webhooks for the events and how to verify them.
Attributes
- idstringUnique identifier for the endpoint.
- objectstringAlways
webhook_endpoint. - urlstringThe HTTPS URL events are sent to.
- descriptionstring or nullYour note about the endpoint.
- eventsarray of stringsThe event types sent to it.
lead.createdlead.hotreply.receivedreaction.receivedsam.suggestion.readysam.reply.sentsam.handoff - statusstringWhether events are sent to it.
enableddisabled - filtersobjectWhich events it gets, by the lead's persona. They apply to every event type.
- disabled_reasonstring or nullWhy it is disabled.
manualwhen you turned it off,failingwhen Gemlead did after 3 days of failures in a row and at least 8 failed attempts.nullwhile enabled.manualfailing - secretstringThe signing secret,
whsec_and 32 characters. Only in the responses of create and roll secret. - created_atstringWhen the endpoint was created, ISO 8601.
- updated_atstringWhen the endpoint last changed, ISO 8601.
{
"id": "wh3LpX9dKe",
"object": "webhook_endpoint",
"url": "https://example.com/webhooks/gemlead",
"description": "CRM sync",
"events": ["lead.hot", "reply.received"],
"status": "enabled",
"filters": {
"persona_ids": ["lvWBPnytpS"]
},
"disabled_reason": null,
"created_at": "2026-09-14T09:21:05.300Z",
"updated_at": "2026-11-06T07:45:12.904Z"
}List webhook endpoints
read scopeReturns your webhook endpoints, without their secrets.
Query parameters
- limitintegerHow many objects to return, from 1 to 100. Defaults to 25.
- cursorstringThe
next_cursorof the previous page, to get the page after it. See Pagination.
Returns
A list of webhook endpoint objects.
curl https://gemlead.ai/api/v1/webhook_endpoints \
-H "Authorization: Bearer $GEMLEAD_API_KEY"{
"object": "list",
"data": [
{
"id": "wh3LpX9dKe",
"object": "webhook_endpoint",
"url": "https://example.com/webhooks/gemlead",
"description": "CRM sync",
"events": ["lead.hot", "reply.received"],
"status": "enabled",
"filters": {
"persona_ids": ["lvWBPnytpS"]
},
"disabled_reason": null,
"created_at": "2026-09-14T09:21:05.300Z",
"updated_at": "2026-11-06T07:45:12.904Z"
}
],
"has_more": false,
"next_cursor": null
}Create a webhook endpoint
write scopeRegisters a URL for one or more event types. Store the secret of the response, it is the only time you see it.
Body parameters
- urlstringRequiredAn HTTPS URL that answers on the public internet.
- eventsarray of stringsRequiredThe event types to send.
lead.createdlead.hotreply.receivedreaction.receivedsam.suggestion.readysam.reply.sentsam.handoff - descriptionstringA note for yourself.
- filtersobjectWhich events to send, by the lead's persona.
Returns
The new webhook endpoint object with its secret.
Errors
- A required parameter is missing.
paramnames it. - A parameter has a value the API does not accept.
paramnames it. - The body has a field this endpoint does not take.
- 400url_invalidThe URL is not HTTPS, has credentials in it, or points to a private address.
- The account already has 10 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"]
}
}'{
"id": "wh3LpX9dKe",
"object": "webhook_endpoint",
"url": "https://example.com/webhooks/gemlead",
"description": "CRM sync",
"events": ["lead.hot", "reply.received"],
"status": "enabled",
"filters": {
"persona_ids": ["lvWBPnytpS"]
},
"disabled_reason": null,
"created_at": "2026-09-14T09:21:05.300Z",
"updated_at": "2026-11-06T07:45:12.904Z",
"secret": "whsec_4QeX7nP2kR9tLm3Vb8YzC1dF6hJ0sWuA"
}Retrieve a webhook endpoint
read scopeReturns one webhook endpoint, without its secret.
Path parameters
- idstringRequiredThe webhook endpoint's ID.
Returns
Errors
- No webhook endpoint with this ID on the key's account.
curl https://gemlead.ai/api/v1/webhook_endpoints/wh3LpX9dKe \
-H "Authorization: Bearer $GEMLEAD_API_KEY"{
"id": "wh3LpX9dKe",
"object": "webhook_endpoint",
"url": "https://example.com/webhooks/gemlead",
"description": "CRM sync",
"events": ["lead.hot", "reply.received"],
"status": "enabled",
"filters": {
"persona_ids": ["lvWBPnytpS"]
},
"disabled_reason": null,
"created_at": "2026-09-14T09:21:05.300Z",
"updated_at": "2026-11-06T07:45:12.904Z"
}Update a webhook endpoint
write scopeChanges an endpoint. Set status to enabled to turn back on an endpoint Gemlead disabled. Turning it on or giving it a new url starts its failure count again.
Path parameters
- idstringRequiredThe webhook endpoint's ID.
Body parameters
- urlstringA new HTTPS URL.
- eventsarray of stringsThe event types to send.
lead.createdlead.hotreply.receivedreaction.receivedsam.suggestion.readysam.reply.sentsam.handoff - descriptionstringA note for yourself.
- statusstringTurn the endpoint on or off.
enableddisabled - filtersobjectWhich events to send, by the lead's persona.
Returns
The updated webhook endpoint object.
Errors
- No webhook endpoint with this ID on the key's account.
- A parameter has a value the API does not accept.
paramnames it. - The body has a field this endpoint does not take.
- 400url_invalidThe URL is not HTTPS, has credentials in it, or points to a private address.
curl -X PATCH \
https://gemlead.ai/api/v1/webhook_endpoints/wh3LpX9dKe \
-H "Authorization: Bearer $GEMLEAD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"status": "enabled"
}'{
"id": "wh3LpX9dKe",
"object": "webhook_endpoint",
"url": "https://example.com/webhooks/gemlead",
"description": "CRM sync",
"events": ["lead.hot", "reply.received"],
"status": "enabled",
"filters": {
"persona_ids": ["lvWBPnytpS"]
},
"disabled_reason": null,
"created_at": "2026-09-14T09:21:05.300Z",
"updated_at": "2026-11-06T07:45:12.904Z"
}Delete a webhook endpoint
write scopeDeletes an endpoint. Deliveries still waiting for a retry are dropped.
Path parameters
- idstringRequiredThe webhook endpoint's ID.
Returns
An object with the endpoint's id and deleted set to true.
Errors
- No webhook endpoint with this ID on the key's account.
curl -X DELETE \
https://gemlead.ai/api/v1/webhook_endpoints/wh3LpX9dKe \
-H "Authorization: Bearer $GEMLEAD_API_KEY"{
"id": "wh3LpX9dKe",
"object": "webhook_endpoint",
"deleted": true
}Roll the signing secret
write scopeReplaces the endpoint's secret at once, the old one stops working. Deliveries that fail meanwhile are retried, signed with the new secret.
Path parameters
- idstringRequiredThe webhook endpoint's ID.
Returns
The webhook endpoint object with its new secret.
Errors
- No webhook endpoint with this ID on the key's account.
curl -X POST \
https://gemlead.ai/api/v1/webhook_endpoints/wh3LpX9dKe/roll_secret \
-H "Authorization: Bearer $GEMLEAD_API_KEY"{
"id": "wh3LpX9dKe",
"object": "webhook_endpoint",
"url": "https://example.com/webhooks/gemlead",
"description": "CRM sync",
"events": ["lead.hot", "reply.received"],
"status": "enabled",
"filters": {
"persona_ids": ["lvWBPnytpS"]
},
"disabled_reason": null,
"created_at": "2026-09-14T09:21:05.300Z",
"updated_at": "2026-11-06T07:45:12.904Z",
"secret": "whsec_4QeX7nP2kR9tLm3Vb8YzC1dF6hJ0sWuA"
}Send a test event
write scopeSends a sample event of the endpoint's first event type, with data.test set to true and IDs starting with test_. One attempt, no retry.
Path parameters
- idstringRequiredThe webhook endpoint's ID.
Returns
A webhook delivery object with the status and status_code your endpoint answered.
Errors
- No webhook endpoint with this ID on the key's account.
curl -X POST \
https://gemlead.ai/api/v1/webhook_endpoints/wh3LpX9dKe/test \
-H "Authorization: Bearer $GEMLEAD_API_KEY"{
"id": "dL5qW1zXa8",
"object": "webhook_delivery",
"endpoint_id": "wh3LpX9dKe",
"event_id": "evt_8kQ2vXr4LmT9wPz1Hc6YbN3d",
"event_type": "lead.hot",
"status": "succeeded",
"attempts": 1,
"status_code": 200,
"error": null,
"test": true,
"next_attempt_at": null,
"last_attempt_at": "2026-11-06T07:45:12.904Z",
"created_at": "2026-11-06T07:45:12.904Z"
}The webhook delivery object
One event sent to one endpoint, with its attempts and your server's last answer.
Attributes
- idstringUnique identifier for the delivery.
- objectstringAlways
webhook_delivery. - endpoint_idstringThe endpoint it was sent to.
- event_idstringThe event sent, the
idyour server received. - event_typestringThe event's type.
lead.createdlead.hotreply.receivedreaction.receivedsam.suggestion.readysam.reply.sentsam.handoff - statusstring
pendingwhile attempts are left, thensucceededorfailed.pendingsucceededfailed - attemptsintegerAttempts made so far, 8 at most.
- status_codeinteger or nullThe HTTP status of your last answer.
nullwhen there was none, after a timeout or a connection error. - errorstring or nullWhat went wrong on the last attempt, like the status and the start of your answer, or a timeout.
- testboolean
truefor a test event. - next_attempt_atstring or nullWhen the next attempt is due, while
pending. - last_attempt_atstring or nullWhen the last attempt was made.
- created_atstringWhen the delivery was created, ISO 8601.
{
"id": "dR7mK2pVn4",
"object": "webhook_delivery",
"endpoint_id": "wh3LpX9dKe",
"event_id": "evt_3Hn7QpW2xZk9LmR4tV8bYc1D",
"event_type": "reply.received",
"status": "pending",
"attempts": 2,
"status_code": 503,
"error": "HTTP 503: Service Unavailable",
"test": false,
"next_attempt_at": "2026-11-06T08:18:10.000Z",
"last_attempt_at": "2026-11-06T08:13:10.000Z",
"created_at": "2026-11-06T08:12:10.000Z"
}List deliveries
read scopeReturns the endpoint's latest deliveries, newest first, test events included. Deliveries are kept 30 days.
Path parameters
- idstringRequiredThe webhook endpoint's ID.
Query parameters
- limitintegerHow many deliveries to return, from 1 to 100. 25 by default.
Returns
A list of webhook delivery objects. This list has no next_cursor, raise limit to see more.
Errors
- No webhook endpoint with this ID on the key's account.
- A parameter has a value the API does not accept.
paramnames it.
curl -G \
https://gemlead.ai/api/v1/webhook_endpoints/wh3LpX9dKe/deliveries \
-H "Authorization: Bearer $GEMLEAD_API_KEY" \
-d limit=10{
"object": "list",
"data": [
{
"id": "dR7mK2pVn4",
"object": "webhook_delivery",
"endpoint_id": "wh3LpX9dKe",
"event_id": "evt_3Hn7QpW2xZk9LmR4tV8bYc1D",
"event_type": "reply.received",
"status": "pending",
"attempts": 2,
"status_code": 503,
"error": "HTTP 503: Service Unavailable",
"test": false,
"next_attempt_at": "2026-11-06T08:18:10.000Z",
"last_attempt_at": "2026-11-06T08:13:10.000Z",
"created_at": "2026-11-06T08:12:10.000Z"
},
{
"id": "dL5qW1zXa8",
"object": "webhook_delivery",
"endpoint_id": "wh3LpX9dKe",
"event_id": "evt_8kQ2vXr4LmT9wPz1Hc6YbN3d",
"event_type": "lead.hot",
"status": "succeeded",
"attempts": 1,
"status_code": 200,
"error": null,
"test": true,
"next_attempt_at": null,
"last_attempt_at": "2026-11-06T07:45:12.904Z",
"created_at": "2026-11-06T07:45:12.904Z"
}
],
"has_more": false,
"next_cursor": null
}