Webhooks & Notifications
Get notified when background jobs finish — machine-readable webhooks for your systems, configurable in the dashboard or through the API.
Many Fiber operations (batch enrichments, lookups, searches, monitoring) run in the background. Instead of polling, you get told the moment a job finishes, success or failure, through two complementary channels:
| Channel | Audience | What it's for |
|---|---|---|
| Webhooks | Your systems | Machine-readable events delivered to your HTTPS endpoint |
| In-app notifications | Your team (in the Fiber app) | Human-readable alerts, org-wide — zero config |
Most events fire both channels at the same moment, so you can build on whichever fits the workflow.
Setting up webhooks
- Go to
fiber.ai/app/webhooks→ Set up webhooks. - Add Endpoint — must be HTTPS.
- Select the event types to receive. Save, and delivery starts immediately.
Delivery is fully managed for you: automatic retries with exponential
backoff, cryptographic signature verification, a self-service portal with
delivery logs, and one-click replay. Portal sessions are short-lived
links, so always enter through fiber.ai/app/webhooks rather than bookmarking
the portal URL itself.
Managing endpoints by API
Everything the portal does is also self-serve over the API: all operations free, rate-limited at 120/min for reads and 60/min for writes. Each operation name links to its full reference:
| Operation | What it does |
|---|---|
createWebhookEndpoint | Register an HTTPS endpoint with its event types; returns the signing secret |
listWebhookEndpoints / getWebhookEndpoint | Inspect configured endpoints |
updateWebhookEndpoint | Change URL, event filter, or enabled state |
deleteWebhookEndpoint | Remove an endpoint |
rotateWebhookEndpointSecret | Rotate the signing secret |
sendTestWebhookEvent | Fire an example payload of any event type at an endpoint |
listWebhookEventTypes | Discover the event catalog programmatically, with an example payload for every event |
Endpoints must be HTTPS (plain HTTP is rejected) and subscribe to at least one event type.
- The signing secret is shown only twice: when you create an endpoint and when you rotate its secret. Store it then; reads never return it.
- Pause without deleting. Update an endpoint with
disabled: trueto stop deliveries (during maintenance, say) andfalseto resume. Your configuration and event filter stay as they were. - Rotating a secret has a grace period. The old secret keeps verifying for a short window after rotation, so you can deploy the new one without dropping deliveries.
Event catalog
Enrichment
| Event | Fires when |
|---|---|
reveal.completed | A contact reveal finishes |
batch_live_enrich.completed | A batch live enrichment job finishes |
batch_contact_enrich.completed | A batch contact enrichment job finishes |
mosaic.completed | A file repair job finishes |
audience.enrichment_completed | An audience enrichment finishes |
audience.prospect_export_completed | A prospect CSV export finishes |
audience.company_export_completed | A company CSV export finishes |
Lookup
| Event | Fires when |
|---|---|
github_to_linkedin.completed | A GitHub→LinkedIn batch lookup finishes |
github_lookup.completed | A GitHub profile lookup finishes |
domain_lookup.completed | A domain lookup finishes |
social_media_lookup.completed | A social media lookup finishes |
Search
| Event | Fires when |
|---|---|
saved_search.run_upcoming | A saved search runs in ~1 day |
saved_search.run_completed | A saved search run finishes |
combined_search.completed | An async combined search finishes |
google_maps_search.completed | A Google Maps search finishes |
local_business_search.completed | A local business search finishes |
audience.build_completed | An audience build finishes |
Monitoring
| Event | Fires when |
|---|---|
tracker.signal_detected | A Tracker rule fires a signal |
tracker.list_run_upcoming | A tracker list refreshes in ~1 day (on request) |
tracker.list_run_completed | A tracker list finished a scheduled refresh (on request) |
job.changed | Tracked profiles changed jobs |
job_changes.profiles_added | Profiles added to a job-change list |
Other
| Event | Fires when |
|---|---|
depth_chart.completed | A company depth-chart generation finishes |
sales_nav_scrape.completed | A Sales Navigator people scrape finishes |
sales_nav_lite_scrape.completed | A Sales Navigator lite scrape finishes |
Tracker run heads-ups (tracker.list_run_upcoming,
tracker.list_run_completed) are turned on per organization; ask us to enable
them. Subscribing an endpoint alone won't start them.
Payload structure
Most completion events share one shape:
success— whether the job succeeded,- an identifier —
task_id,run_id,search_id, oraudience_iddepending on the operation, error— populated on failure.
A few events deviate, so don't assume the shape blindly:
job.changedcarries aprofilesarray (the people who moved, with movement details) and nosuccessorerrorfields. Each profile includeslistId, the job-change list that person was tracked on, so someone you track on several lists arrives once per list and you can attribute each move without matching LinkedIn URLs across your lists. It comes from job-change lists; new integrations should use Tracker's job-change rules andtracker.signal_detectedinstead.batch_live_enrich.completedreports per-outcome counts (completed/failed/not_found/malformed) instead of anerrorfield.- Heads-up events (
saved_search.run_upcoming,tracker.list_run_upcoming,tracker.list_run_completed) only ever sendsuccess: true; failures are never delivered on these event types.
Example (reveal.completed):
{
"task_id": "abc123",
"success": true,
"emails": [{ "emailAddress": "jane@company.com", "type": "work" }],
"phone_numbers": [{ "phoneNumber": "+1-555-0100", "type": "mobile" }],
"linkedin_url": "https://www.linkedin.com/in/jane-doe"
}Tracker signals use a richer envelope with the matched entity and rule details.
For the exact payload of any event, list the event types: each comes back
with a description, its group, and an examplePayload you can build your
parser against.
Verifying signatures
Every delivery carries svix-id, svix-timestamp, and svix-signature
headers. Always verify before trusting a payload: official libraries exist
for Node, Python, Go, Java, Ruby, Rust, PHP, and C#/.NET. The signing secret is
in the webhook portal.
import { Webhook } from "svix";
const wh = new Webhook("whsec_your_signing_secret"); // from the portal
app.post("/webhooks/fiber", (req, res) => {
try {
const payload = wh.verify(req.body, {
"svix-id": req.headers["svix-id"],
"svix-timestamp": req.headers["svix-timestamp"],
"svix-signature": req.headers["svix-signature"],
});
// verified — process payload
res.status(200).send("OK");
} catch {
res.status(400).send("Invalid signature");
}
});Retry behavior
A delivery is considered failed if your endpoint returns non-2xx (3xx redirects count as failures) or doesn't respond within 15 seconds. Retries then run with exponential backoff over roughly a day:
immediate → 5s → 5min → 30min → 2h → 5h → 10h → 10hAfter all retries the message is marked failed in the portal, where you can manually retry it.
Ordering and source IPs
- Delivery order isn't guaranteed. Retries and parallel delivery mean a
later event can arrive before an earlier one. Order events by their
timestamp (
occurredAton Tracker signals) rather than by arrival, and dedupe on the message ID. - Deliveries come from a published set of source IPs. If your firewall needs an allowlist, contact us for the current list.
In-app notifications
For humans, not systems: background jobs, scheduled runs, and credit alerts also surface in the dashboard's org-wide notification feed, with no configuration needed. Use webhooks when another system must act on the result; the feed is for your team. Full catalog and behavior: In-app notifications.
Testing
Test before you go live, all free:
- Send a test event over the API: pick an endpoint and an event type and we deliver an example payload of that type to it, signed like a real one. The response returns a message ID you can find in the portal's delivery log.
- Fire a real Tracker test signal: Tracker's test signals
run through your actual webhook, flagged
isDummy: true, so you can test your handler against real rules. - webhook.site: paste a unique URL as your endpoint and watch payloads live.
- Send Example: every event type has a "Send Example" button in the portal.
- Svix CLI — tunnel deliveries to local development:
svix listen http://localhost:3000/webhooks/fiberAdvice
- Acknowledge fast, process later. Return a 2xx immediately and handle the payload asynchronously; slow handlers trip the 15-second timeout and cause pointless retries.
- Make handlers idempotent. Retries mean you may receive the same event more
than once. The
svix-idheader is stable across retries of the same message, so dedupe on it. Tracker signals additionally carry a stableeventIdin the payload. - Verify signatures everywhere. Unverified endpoints are a spoofing risk.
- Prefer webhooks over polling for async operations: you learn about completion sooner and save the polling calls entirely.
Tracker
Watch companies and people for the changes that matter — 55 rule types, refresh cadences from daily to every six months, signals delivered by webhook and API.
In-app notifications
Every background job, scheduled run, and credit alert lands in a shared team inbox in the dashboard — zero setup, visible to your whole organization.