Skip to main content
A Loop is a webhook destination with a fixed object type. You create it once in the dashboard. Then every task attached to it gets POSTed to your URL when it settles. No polling.

Create a Loop

Go to Loops in the dashboard and create one. You choose:
  • Name. Anything that tells you what the Loop is for, like “Inbound signups”.
  • Object type. company or person. This decides what a record sent to the Loop gets enriched as.
  • Webhook URL. Must be https and publicly reachable. Loopback and private addresses are rejected.
On creation you get a signing secret, shown once. Store it. You need it to verify every webhook we send. If you lose it, delete the Loop and create a new one.

Direct request or Loop?

The two paths run the same enrichment and return the same task. They differ in who decides what gets enriched and where the result goes. Use a direct request when the caller is waiting for the answer. Use a Loop when the result should land somewhere on its own, like a CRM record or a queue.

Send records to a Loop

The body is the same input the matching direct endpoint takes. A company Loop accepts domain or linkedinUrl. A person Loop accepts linkedinUrl or email, plus the optional tie-break hints from reverse email lookup. You get the same task response as a direct request, with the same 200 or 202 semantics. Once the task settles, we also deliver it to the Loop’s webhook. A disabled Loop rejects new records with 409. Tasks already in flight still complete and deliver.

Attach a direct request to a Loop

You can also keep calling the direct endpoints and add loop_id to the body:
The endpoint decides the object type. The Loop only receives the result. Use a Loop whose object type matches the endpoint, so your receiver gets the payload shape it expects.

The webhook we send

event is one of:
  • task.succeeded. data carries the company or person.
  • task.failed. error carries the same code and fields you would see when polling. For a person Loop, an ambiguous email lookup arrives this way.
  • test. Sent when you press Send test event in the dashboard.
X-EnrichLoops-Delivery-Id stays the same across retries of one delivery. Use it to deduplicate. Respond with any 2xx to acknowledge. Anything else counts as a failure and we retry.

Verify the signature

Every webhook is signed with your Loop’s secret, using the same scheme as Stripe:
The signature covers {timestamp}.{raw request body}. Verify it like this:
Verify against the raw request body, before any JSON parsing. Re-serializing the parsed body and comparing will not match.

Retries

If your endpoint does not respond with a 2xx, we retry on this schedule: After the seventh attempt the delivery is marked failed. Delivery history and a manual retry button are in the dashboard under the Loop.

Manage Loops

Rename, disable, or delete a Loop from the dashboard. Disabling stops new records from being accepted. Tasks already in flight still complete and deliver.