curl --request PUT \
--url https://intentleads.si/api/v1/webhooks/removals \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"url": "https://app.example.com/hooks/intent-leads"
}
'const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({url: 'https://app.example.com/hooks/intent-leads'})
};
fetch('https://intentleads.si/api/v1/webhooks/removals', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://intentleads.si/api/v1/webhooks/removals"
payload = { "url": "https://app.example.com/hooks/intent-leads" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text){
"webhook": {
"id": "5b1d0a7e-3c2f-4e0b-9a51-2f6c8d7e9a10",
"url": "https://app.example.com/hooks/intent-leads",
"status": "ok",
"failing_since": null,
"last_attempt_at": "2026-11-12T09:15:02.118Z",
"last_status": 200,
"last_error": null,
"last_success_at": "2026-11-12T09:15:02.118Z",
"created_at": "2026-11-11T14:00:00.000Z",
"updated_at": "2026-11-11T14:00:00.000Z",
"sending_removals_since": "2026-11-11T14:00:00.000Z",
"pending": 0,
"failed_attempts": 0
},
"secret": "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
}{
"error": "invalid_url",
"message": "url must start with https://."
}{
"error": "unauthorized",
"message": "Send a valid API key as: Authorization: Bearer il_live_…"
}{
"error": "admin_key_required",
"message": "This needs an admin API key. Owners create one under Settings → API keys."
}{
"error": "internal_error",
"message": "Something went wrong. Try again."
}Set the webhook (legacy)
Legacy. Kept so existing integrations keep working. It manages one endpoint that receives every event; use /api/v1/webhooks to have several and pick their events.
Sets or changes the URL. The signing secret comes back when the webhook is first set and when you send "rotate_secret": true; it’s always available from GET /api/v1/webhooks/{id}/secret.
Admin key required. Standard keys get 403 admin_key_required.
curl --request PUT \
--url https://intentleads.si/api/v1/webhooks/removals \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"url": "https://app.example.com/hooks/intent-leads"
}
'const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({url: 'https://app.example.com/hooks/intent-leads'})
};
fetch('https://intentleads.si/api/v1/webhooks/removals', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://intentleads.si/api/v1/webhooks/removals"
payload = { "url": "https://app.example.com/hooks/intent-leads" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text){
"webhook": {
"id": "5b1d0a7e-3c2f-4e0b-9a51-2f6c8d7e9a10",
"url": "https://app.example.com/hooks/intent-leads",
"status": "ok",
"failing_since": null,
"last_attempt_at": "2026-11-12T09:15:02.118Z",
"last_status": 200,
"last_error": null,
"last_success_at": "2026-11-12T09:15:02.118Z",
"created_at": "2026-11-11T14:00:00.000Z",
"updated_at": "2026-11-11T14:00:00.000Z",
"sending_removals_since": "2026-11-11T14:00:00.000Z",
"pending": 0,
"failed_attempts": 0
},
"secret": "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
}{
"error": "invalid_url",
"message": "url must start with https://."
}{
"error": "unauthorized",
"message": "Send a valid API key as: Authorization: Bearer il_live_…"
}{
"error": "admin_key_required",
"message": "This needs an admin API key. Owners create one under Settings → API keys."
}{
"error": "internal_error",
"message": "Something went wrong. Try again."
}Authorizations
Headers
Only with an organization key: the workspace to act in (its id; ?workspace=<id> works too). Lanes, leads, exports, lists, websites and webhooks live in workspaces. Without it, an organization key acts in its only workspace, or gets 400 workspace_required (with the list of workspaces) when it has several. Workspace keys don't need it. On keys, team and activity it switches from the organization's own to that workspace's.