curl --request POST \
--url https://api.enrik.ai/v1/webhook-event-deliveries/{id}/redeliver \
--header 'Authorization: Bearer <token>' \
--header 'Idempotency-Key: <idempotency-key>'import requests
url = "https://api.enrik.ai/v1/webhook-event-deliveries/{id}/redeliver"
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>"
}
response = requests.post(url, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Idempotency-Key': '<idempotency-key>', Authorization: 'Bearer <token>'}
};
fetch('https://api.enrik.ai/v1/webhook-event-deliveries/{id}/redeliver', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.enrik.ai/v1/webhook-event-deliveries/{id}/redeliver",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Idempotency-Key: <idempotency-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.enrik.ai/v1/webhook-event-deliveries/{id}/redeliver"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.enrik.ai/v1/webhook-event-deliveries/{id}/redeliver")
.header("Idempotency-Key", "<idempotency-key>")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.enrik.ai/v1/webhook-event-deliveries/{id}/redeliver")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "0199a1b2-0000-7000-8000-000000000538",
"subscriptionId": "0199a1b2-0000-7000-8000-000000000538",
"eventId": "0199a1b2-0000-7000-8000-00000000a538",
"eventType": "companyDiscoveryJob.terminal",
"state": "pending",
"attemptCount": 1,
"nextAttemptAt": "2026-10-07T08:00:00.000Z",
"expiresAt": "2026-10-10T08:00:00.000Z",
"lastAttemptAt": "2026-10-07T08:00:00.000Z",
"lastResponseStatus": 204,
"lastErrorCode": null,
"deliveredAt": null,
"createdAt": "2026-10-07T08:00:00.000Z",
"updatedAt": "2026-10-07T08:00:00.000Z"
}{
"error": {
"code": "malformed_json",
"message": "Bad Request",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}{
"error": {
"code": "unauthenticated",
"message": "Unauthorized",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}{
"error": {
"code": "insufficient_scope",
"message": "Forbidden",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}{
"error": {
"code": "not_found",
"message": "Not Found",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}{
"error": {
"code": "conflict",
"message": "Conflict",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}{
"error": {
"code": "validation_error",
"message": "Unprocessable Entity",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}{
"error": {
"code": "rate_limited",
"message": "Too many requests",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}{
"error": {
"code": "internal_error",
"message": "Internal Server Error",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}{
"error": {
"code": "service_unavailable",
"message": "Service Unavailable",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}{
"error": {
"code": "not_found",
"message": "Not found",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}Redeliver an event
Owners and admins only. Sends the same event id and body again with a fresh retry budget and a 72-hour window. Refused with 409 while the delivery is pending or in flight, when the subscription or destination is not active, or when the event is 27 days old or older. Validated before commit. The required Idempotency-Key answers a retry with the first answer for 24 hours instead of sending the event again.
curl --request POST \
--url https://api.enrik.ai/v1/webhook-event-deliveries/{id}/redeliver \
--header 'Authorization: Bearer <token>' \
--header 'Idempotency-Key: <idempotency-key>'import requests
url = "https://api.enrik.ai/v1/webhook-event-deliveries/{id}/redeliver"
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>"
}
response = requests.post(url, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Idempotency-Key': '<idempotency-key>', Authorization: 'Bearer <token>'}
};
fetch('https://api.enrik.ai/v1/webhook-event-deliveries/{id}/redeliver', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.enrik.ai/v1/webhook-event-deliveries/{id}/redeliver",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Idempotency-Key: <idempotency-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.enrik.ai/v1/webhook-event-deliveries/{id}/redeliver"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.enrik.ai/v1/webhook-event-deliveries/{id}/redeliver")
.header("Idempotency-Key", "<idempotency-key>")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.enrik.ai/v1/webhook-event-deliveries/{id}/redeliver")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "0199a1b2-0000-7000-8000-000000000538",
"subscriptionId": "0199a1b2-0000-7000-8000-000000000538",
"eventId": "0199a1b2-0000-7000-8000-00000000a538",
"eventType": "companyDiscoveryJob.terminal",
"state": "pending",
"attemptCount": 1,
"nextAttemptAt": "2026-10-07T08:00:00.000Z",
"expiresAt": "2026-10-10T08:00:00.000Z",
"lastAttemptAt": "2026-10-07T08:00:00.000Z",
"lastResponseStatus": 204,
"lastErrorCode": null,
"deliveredAt": null,
"createdAt": "2026-10-07T08:00:00.000Z",
"updatedAt": "2026-10-07T08:00:00.000Z"
}{
"error": {
"code": "malformed_json",
"message": "Bad Request",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}{
"error": {
"code": "unauthenticated",
"message": "Unauthorized",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}{
"error": {
"code": "insufficient_scope",
"message": "Forbidden",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}{
"error": {
"code": "not_found",
"message": "Not Found",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}{
"error": {
"code": "conflict",
"message": "Conflict",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}{
"error": {
"code": "validation_error",
"message": "Unprocessable Entity",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}{
"error": {
"code": "rate_limited",
"message": "Too many requests",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}{
"error": {
"code": "internal_error",
"message": "Internal Server Error",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}{
"error": {
"code": "service_unavailable",
"message": "Service Unavailable",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}{
"error": {
"code": "not_found",
"message": "Not found",
"requestId": "5b1d3c1e-8d6f-4f2a-9a57-3a9b1f2c7d10"
}
}Authorizations
An Enrik API key, sent as Authorization: Bearer <key>. A key reaches public operations only, and only those whose scopes it holds. A few parameters need a scope beyond their operation’s, which the parameter names. The scopes:
setup:read: Read the workspace setup and its company profile.setup:run: Change the setup: confirm the company profile, authorize sponsored drafting and background company research, choose what to set up and complete setup.workspace:read: Read the workspace’s own profile: its health summary and setup state.crm:read: Read companies with their signals, contacts and the saved views over them.crm:write: Create, update and restore companies and contacts, and create, update and delete saved views.crm:delete: Delete companies and contacts.twin:read: Read the Company Twin: structured company knowledge and its signals.discovery:read: Read ICP profiles, ICP assessments, discovery briefs, discovery jobs, candidates and the signal library.discovery:write: Create and change ICP profiles, discovery briefs and signal-definition drafts, and review discovery candidates.discovery:run: Create, start and cancel discovery jobs, and edit a draft one. Uses provider budget.enrichment:read: Read the enrichment configuration and its results, including a record’s enrichment, formula and custom-API cells.enrichment:run: Launch and cancel enrichment. Spends enrichment credits.automation:read: Read workflows and agents with their run history, including a record’s agent cells.automation:run: Run existing workflows and agents.exports:read: Read export jobs and the fields an export can carry.exports:run: Create, preview, start, cancel and archive CSV exports of companies, contacts and candidates, and download the file. Also needscrm:read. Delivering an export to a webhook destination stays in the app.integrations:read: Read connections, field mappings, CRM sync jobs and webhook destinations.webhooks:read: Read webhook subscriptions, the event types they can name and their delivery log.webhooks:write: Subscribe a receiver URL to webhook events; edit, test, pause, resume and archive a subscription and rotate its signing secret; redeliver an event. Only workspace owners and admins can grant it.reporting:read: Read analytics and dashboards.assistant:read: Read the Assistant: its threads, messages and pending approvals.assistant:run: Converse with the Assistant. Uses the workspace’s AI quota.assistant:write: Approve or reject the changes the Assistant proposes.
Headers
A key you choose for this request, such as a UUID. Retrying with the same key returns the first result instead of doing the work twice.
1 - 200Path Parameters
The event delivery’s id.
^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$Response
One event on its way to one subscription: state and last outcome, never a body.
One event on its way to one subscription: state and last outcome, never a body.
The delivery id, also sent as X-Enrik-Delivery-Id.
The subscription the event is delivered to.
The event id, also sent as X-Enrik-Event-Id; the same on every attempt.
The event type.
companyDiscoveryJob.terminal, company.created, company.updated, company.deleted, company.restored, contact.created, contact.updated, contact.deleted, contact.restored, companySignal.created Where the delivery is: pending or in flight, or ended (delivered, failed, canceled, expired).
pending, delivering, delivered, failed, canceled, expired HTTP attempts so far, redeliveries included.
When the next attempt is due; null once the delivery ended.
^((\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\d|3[01])|(0[469]|11)-(0[1-9]|[12]\d|30)|(02)-(0[1-9]|1\d|2[0-8])))T([01]\d|2[0-3]):[0-5]\d(:[0-5]\d(\.\d+)?)?Z$When the delivery stops being attempted.
^((\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\d|3[01])|(0[469]|11)-(0[1-9]|[12]\d|30)|(02)-(0[1-9]|1\d|2[0-8])))T([01]\d|2[0-3]):[0-5]\d(:[0-5]\d(\.\d+)?)?Z$When the last attempt started, if any.
^((\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\d|3[01])|(0[469]|11)-(0[1-9]|[12]\d|30)|(02)-(0[1-9]|1\d|2[0-8])))T([01]\d|2[0-3]):[0-5]\d(:[0-5]\d(\.\d+)?)?Z$The HTTP status the receiver last answered; null without an answer.
Why the last attempt failed; null when it succeeded or none was made.
http_status, timeout, network_error, egress_blocked, redirect_blocked, response_too_large, retries_exhausted, subscription_inactive, destination_inactive, signing_secret_missing, workspace_deleted When the receiver accepted it, if it did.
^((\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\d|3[01])|(0[469]|11)-(0[1-9]|[12]\d|30)|(02)-(0[1-9]|1\d|2[0-8])))T([01]\d|2[0-3]):[0-5]\d(:[0-5]\d(\.\d+)?)?Z$When the delivery was created.
^((\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\d|3[01])|(0[469]|11)-(0[1-9]|[12]\d|30)|(02)-(0[1-9]|1\d|2[0-8])))T([01]\d|2[0-3]):[0-5]\d(:[0-5]\d(\.\d+)?)?Z$When it last changed.
^((\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\d|3[01])|(0[469]|11)-(0[1-9]|[12]\d|30)|(02)-(0[1-9]|1\d|2[0-8])))T([01]\d|2[0-3]):[0-5]\d(:[0-5]\d(\.\d+)?)?Z$Was this page helpful?