How to use SourceLoop Outgoing Webhooks
Forward every new or updated SourceLoop lead to your backend, Slack, Zapier, or Make. Up to 5 endpoints, signed deliveries, per-event subscriptions.
On this page
- When to use an Outgoing Webhook
- What gets sent
- Before you start
- Step 1: Open the Outgoing Webhooks page
- Step 2: Add the endpoint
- Step 3: Verify the receiver works
- Step 4: Sign-verify on your receiver
- Common downstream patterns
- Slack alert on every new lead
- Zapier / Make routing
- Server-side enrichment
- Custom CRM sync
- Monitor and debug deliveries
- What’s next
SourceLoop’s Outgoing Webhooks are the reverse direction of Incoming Webhooks. Every time a lead is created or edited in the Contacts Hub, SourceLoop fires a POST to every endpoint you’ve subscribed to that event type. Use this to alert your team in Slack the moment a lead comes in, hand qualified leads to Zapier / Make for routing, sync custom fields to a homegrown CRM, or trigger any backend workflow you want.
When to use an Outgoing Webhook
Outgoing Webhooks are right when:
- You want real-time alerts (Slack, Discord, Microsoft Teams, email tools that accept webhooks)
- You’re routing leads through Zapier, Make, n8n, Pipedream, or any low-code workflow tool
- You’re syncing leads into a CRM or backend that SourceLoop doesn’t natively support
- You need to enrich leads server-side (Clearbit, Apollo, ZoomInfo) before pushing them to your team
They’re not the right fit when:
- A native CRM integration covers your use case (HubSpot / Salesforce / Pipedrive ship with deeper field mapping, status sync, and bidirectional update handling)
- You want to pull data on a schedule rather than receive pushes (use the Contacts Hub CSV export or the Conversion API instead)
What gets sent
Each delivery is a JSON POST containing the full lead record at the moment of the event. The payload includes everything you’d see on the lead’s row in the Contacts Hub:
| Field group | Examples |
|---|---|
| Identity | email, name, phone, company, country, city |
| Conversion | type (Web form / Meeting / Chat / Payment / Subscription / API / CRM Import / Custom), source provider (intercom-webhook / stripe / hubspot-form / etc.), occurred_at, received_at |
| Lifecycle | status (New / Contacted / In Progress / Converted / Lost), qualified (yes / no / not set), lead score |
| Revenue | expected_revenue, revenue (in workspace currency) |
| First-touch attribution | first_channel, first_source, first_medium, first_campaign, first_keyword, first_content, first_landing_page |
| Last-touch attribution | latest_channel, latest_source, latest_medium, latest_campaign, latest_keyword, latest_content, latest_landing_page |
| Click IDs | gclid, msclkid, fbclid, li_fat_id, gbraid, wbraid, epik, rdt_cid |
| Technical | browser, device_type, os |
| Flags | is_spam, is_duplicate |
| Free text | notes |
| Custom data | every field your form / API / CRM sent that doesn’t map to the above |
And these HTTP headers on every delivery:
Content-Type: application/json
X-Webhook-Secret: <the secret you configured or SourceLoop generated>
X-Webhook-Event: created | updated
The X-Webhook-Event value tells your receiver which subscription matched (created for New Lead, updated for Updated Lead).
Before you start
You’ll need:
- A SourceLoop workspace with at least one captured lead to test against (free trial)
- Admin or Owner role in SourceLoop
- An HTTPS endpoint that accepts POST requests (Slack incoming webhook, Zapier “Catch Webhook” URL, your own server, etc.)
Step 1: Open the Outgoing Webhooks page
- Sign in to SourceLoop.
- Open Setup -> Outgoing Webhooks in the left sidebar.
You’ll see a form to add a new webhook and (if any exist) a table listing the ones already configured.
Step 2: Add the endpoint
Fill the form:
- Webhook URL — the URL on your receiving server. For Slack, paste an incoming-webhook URL from your workspace’s app config. For Zapier / Make, paste the trigger’s “Catch Webhook” URL. For your own backend, any HTTPS endpoint that returns 2xx works.
- Events — tick New Lead, Updated Lead, or both depending on what your downstream needs.
- Secret (optional) — leave blank to have SourceLoop auto-generate one, or paste a string you’ve chosen. Whatever value lands here is what arrives on the
X-Webhook-Secretheader for every delivery. - Click Add Webhook.
The new endpoint shows up in the table below with its URL, subscribed events, status (Active by default), and a copy button for the secret.
Step 3: Verify the receiver works
The cleanest way to test: trigger a real lead.
- Open your site in an incognito window.
- Submit a form, book a meeting, or fire whatever triggers a SourceLoop conversion.
- Within seconds, your endpoint should receive the POST.
If you’d rather test without a real lead, edit any existing lead in the Contacts Hub (change status, add a note) and watch for the Updated Lead webhook to fire.
To inspect the actual headers and body your endpoint receives, point your URL temporarily at a service like webhook.site or requestbin.com, trigger a lead, and read the captured request. Once you know the shape, switch the URL to your real endpoint.
Step 4: Sign-verify on your receiver
The X-Webhook-Secret header carries the exact secret you set (or that SourceLoop generated). On your receiving server, compare the incoming header to the expected value and reject anything that doesn’t match.
Node.js / Express:
app.post("/sourceloop-webhook", express.json(), (req, res) => {
const got = req.header("X-Webhook-Secret");
if (got !== process.env.SOURCELOOP_WEBHOOK_SECRET) {
return res.status(401).end();
}
const event = req.header("X-Webhook-Event"); // "created" or "updated"
const lead = req.body;
// ...your logic here
res.status(200).end();
});
Python / Flask:
@app.post("/sourceloop-webhook")
def sourceloop_webhook():
got = request.headers.get("X-Webhook-Secret", "")
if got != os.environ["SOURCELOOP_WEBHOOK_SECRET"]:
return "", 401
event = request.headers.get("X-Webhook-Event") # "created" or "updated"
lead = request.json
# ...your logic here
return "", 200
Common downstream patterns
Slack alert on every new lead
Slack’s incoming-webhook URL accepts a POST body, but it expects Slack’s own format ({text: "..."}), not SourceLoop’s lead JSON. Two options:
- Wrap the lead in a Zap / Make scenario. Point SourceLoop at a Catch Webhook trigger, transform the body into a Slack message, post it. Cleanest.
- Use a small middleware function. Cloudflare Worker, Vercel Edge Function, or AWS Lambda that accepts SourceLoop’s payload and forwards a Slack-shaped message.
Zapier / Make routing
Zapier’s “Webhooks by Zapier -> Catch Hook” trigger accepts SourceLoop’s payload as-is. Map the lead fields into the next Zap step (add to Google Sheets, create a task in Asana, send to Mailchimp, whatever).
Server-side enrichment
POST the SourceLoop payload into your backend, look up the company via Clearbit / Apollo / ZoomInfo, then forward the enriched lead onward to your CRM. Use Updated Lead as the next-stage trigger so your CRM sees the enriched record.
Custom CRM sync
If your CRM doesn’t have a native SourceLoop integration, build a thin shim: receive the POST, map the lead fields to your CRM’s contact model, call your CRM’s API to upsert. Use the X-Webhook-Event header to decide whether to create (created) or update (updated).
Monitor and debug deliveries
Setup -> Outgoing Webhooks shows a Recent Webhook Logs table beneath the webhook list, every delivery with:
| Column | What it shows |
|---|---|
| URL | Which endpoint received the request |
| Event | New Lead or Updated Lead |
| Response code | HTTP status your endpoint returned |
| Response body | First few hundred characters of your endpoint’s response, useful for reading error messages |
| Error | Network-level failure (DNS, TLS, timeout) if the request didn’t reach your server at all |
| Sent at | Delivery timestamp |
The most common failures:
- 401 / 403 from your endpoint — your server rejected the request. Usually a wrong secret check or missing auth header. Compare the
X-Webhook-Secretagainst your expected value. - 404 — wrong URL. Recopy from your downstream tool.
- 5xx — your server errored. Check your application logs and fix the handler; SourceLoop currently doesn’t auto-retry, so the missed event won’t be sent again unless you re-trigger it (e.g., re-save the lead).
- Network error — usually a TLS / DNS issue, an HTTPS-only endpoint receiving from an HTTP URL, or a downstream that’s been offline too long.
What’s next
- Receive leads into SourceLoop from any tool: How to use SourceLoop Incoming Webhooks for the reverse direction.
- Native CRM sync instead of webhooks: Connect HubSpot, Connect Salesforce, or Connect Pipedrive cover the bidirectional field-mapping case.
- Browse leads sent by webhooks in the UI: Contacts (Leads) table walks through the same data your webhook receives.
Frequently asked questions
-
How quickly are outgoing webhooks delivered?
Webhooks fire within seconds of the triggering event. New lead webhooks fire the moment SourceLoop creates the lead in the Contacts Hub; updated lead webhooks fire whenever an editable field on the lead changes (status, qualified, lead score, expected revenue, revenue, notes, or a custom field).
-
What's the difference between New Lead and Updated Lead?
New Lead fires once per contact, on the initial conversion (the form submit, meeting booking, chat handle, payment, or CRM import that created the row). Updated Lead fires every time an editable field changes afterwards, manually in the UI, via API, via CRM sync, or by a teammate's edit. Subscribe to one or both depending on what your downstream system needs.
-
How do I verify a webhook is really from SourceLoop?
Every delivery carries an X-Webhook-Secret header containing the secret you set (or that SourceLoop auto-generated) when you created the endpoint. Compare the header to the expected secret on your receiving server. The header is sent as a literal value, not an HMAC; if you need an HMAC-signed delivery for SOC 2 / PCI compliance, contact [email protected].
-
Will I get the same webhook twice if a field is edited multiple times?
Yes, one Updated Lead webhook fires per save. There's no client-side dedup. If you don't want to react to repeat edits, key your downstream logic on the lead's id and the changed fields (the full lead payload is sent each time, so you can diff).
-
How many endpoints can I configure?
Up to five active webhook endpoints per workspace. Each can subscribe to New Lead, Updated Lead, or both. If you need more, fan out from a single SourceLoop webhook into a router like Zapier or your own backend.
-
What happens if my endpoint is down or returns an error?
SourceLoop attempts one delivery per event and logs the response in the Recent Webhook Logs table at the bottom of Setup -> Outgoing Webhooks. There's currently no automatic retry on 5xx; build idempotent receivers so that re-sending a missed event later (manually re-saving the lead, or contacting support to replay) is safe.
-
Can I limit which leads get sent (e.g., only paid leads, only qualified ones)?
Subscribing to events is all-or-nothing per endpoint today. To filter, accept every delivery on your side and ignore the ones that don't match. Common filter fields, lead type (web form / meeting / chat / payment), qualified flag, lead score, status, or any custom field, are all on the payload.
-
Where do I see what's been sent?
Setup -> Outgoing Webhooks shows a Recent Webhook Logs table with the URL, event, response code, response body, error message, and timestamp for every delivery attempt. Use it to confirm a delivery happened and to diagnose 4xx / 5xx responses from your endpoint.