Webhooks
Receive real-time HTTP notifications when workflows complete
Receive instant HTTP POST notifications when your workflows complete. Webhooks enable real-time integrations with CRMs, Slack, data pipelines, and other external systems without polling the API.
Overview
When a workflow run completes, Linkt can send an HTTP POST request to a URL you specify. The webhook payload contains details about the run including timing, credits used, and IDs of created resources.
Supported Workflows
Webhooks are available for all workflow types:
| Workflow | Task Type | Use Case |
|---|---|---|
| Search | search | Discover new companies and contacts matching your ICP |
| Ingest | ingest | Import and enrich entities from CSV files |
| Signal | signal-topic, signal-csv, signal-sheet | Monitor for business signals and events |
Use Cases
- CRM Integration — Automatically sync discovered entities or detected signals to your CRM
- Slack/Teams Alerts — Notify your team when workflows complete or signals are detected
- Data Pipelines — Trigger downstream processing when new entities are enriched
- Custom Dashboards — Push real-time updates to monitoring systems
Configuring Webhooks
Add the webhook_url field to your task configuration. The URL must use HTTPS.
Search Task with Webhook
Receive a notification when a search workflow completes:
Ingest Task with Webhook
Receive a notification when CSV enrichment completes:
Signal Task with Webhook
Receive a notification when signal monitoring completes:
URL Requirements
| Requirement | Description |
|---|---|
| HTTPS Required | Webhook URLs must use https:// |
| No Localhost | Cannot use localhost, 127.0.0.1, or ::1 |
| Public Endpoint | URL must be publicly accessible |
| 30s Timeout | Endpoint must respond within 30 seconds |
HTTPS Only
Webhook URLs must use HTTPS for security. HTTP URLs will be rejected when creating the task.
Event Types
Each workflow type has its own set of event types:
Search Events
| Event Type | Description |
|---|---|
run.search.completed | Search workflow completed successfully |
run.search.failed | Search workflow failed with an error |
run.search.crashed | Search workflow crashed unexpectedly |
run.search.cancelled | Search workflow was cancelled |
Ingest Events
| Event Type | Description |
|---|---|
run.ingest.completed | Ingest workflow completed successfully |
run.ingest.failed | Ingest workflow failed with an error |
run.ingest.crashed | Ingest workflow crashed unexpectedly |
run.ingest.cancelled | Ingest workflow was cancelled |
Signal Events
| Event Type | Description |
|---|---|
run.signal.completed | Signal workflow completed successfully |
run.signal.failed | Signal workflow failed with an error |
run.signal.crashed | Signal workflow crashed unexpectedly |
run.signal.cancelled | Signal workflow was cancelled |
Webhook Payload
When a workflow completes, Linkt sends a POST request with a JSON payload. The payload structure is consistent across all workflow types, with some flow-specific fields.
Common Payload Structure
Common Fields
Envelope Fields
| Field | Type | Description |
|---|---|---|
event_type | string | Event type (e.g., run.search.completed) |
timestamp | string | ISO 8601 timestamp when event was generated |
data | object | Event payload data |
Data Fields
| Field | Type | Description |
|---|---|---|
run_id | string | Unique run identifier |
run_name | string | Run display name |
icp_name | string | Associated ICP name |
icp_id | string | Associated ICP ID |
user_email | string | User who created the task |
user_first_name | string | User's first name |
started_at | string | Run start timestamp (ISO 8601) |
ended_at | string | Run end timestamp (ISO 8601) |
duration_seconds | float | Total duration in seconds |
duration_formatted | string | Human-readable duration (e.g., "9 minutes") |
credits_used | float | Credits consumed by the run |
error_message | string | Error details (for failed runs, otherwise null) |
resources | object | Created/updated resource IDs |
Resources Field
| Field | Type | Description |
|---|---|---|
entities_created | array | IDs of newly created entities |
entities_updated | array | IDs of updated entities |
signals_created | array | IDs of newly created signals (signal workflows only) |
Search Workflow Payload
Search workflows create and update entities:
Use the entity IDs in resources.entities_created to fetch full entity details via the API.
Ingest Workflow Payload
Ingest workflows primarily update existing entities:
Signal Workflow Payload
Signal workflows include additional signal-specific fields:
Signal-Specific Fields
| Field | Type | Description |
|---|---|---|
total_signals | integer | Total signals detected |
signal_breakdown | object | Signal counts by type |
Building Webhook Endpoints
Your webhook endpoint should accept POST requests and respond quickly.
Requirements
- Accept POST requests with
Content-Type: application/json - Respond with 2xx status within 30 seconds
- Handle retries idempotently (same webhook may be delivered multiple times)
Python Example (Flask)
Node.js Example (Express)
Retry Behavior
If your webhook endpoint is unavailable or returns an error, Linkt automatically retries delivery.
Retry Policy
| Attempt | Delay | Cumulative Time |
|---|---|---|
| 1 (initial) | — | 0s |
| 2 | 2s | 2s |
| 3 | 4s | 6s |
| 4 | 8s | 14s |
| 5 | 16s | 30s |
| 6 | 32s | 62s |
Retriable Errors
| Error Type | Retried? | Description |
|---|---|---|
| 5xx Server Errors | Yes | Server errors (500, 502, 503, etc.) |
| Timeout | Yes | No response within 30 seconds |
| Connection Error | Yes | Failed to connect to endpoint |
| 4xx Client Errors | No | Bad request, unauthorized, not found |
Webhook Failures Don't Block Workflows
Webhook delivery failures are logged but do not affect workflow completion. Your entities and signals are still created and available via the API even if the webhook fails.
Handling Duplicate Deliveries
Due to retries, your endpoint may receive the same webhook multiple times. Implement idempotent handling:
Best Practices
Respond Quickly
Return a 2xx response immediately and process webhooks asynchronously:
Log Everything
Log webhook payloads for debugging:
Validate Payloads
Verify required fields exist before processing:
Troubleshooting
Webhook Not Received
- Check URL is HTTPS — HTTP URLs are rejected
- Verify endpoint is public — Linkt cannot reach private networks
- Check firewall rules — Allow incoming POST requests
- Review server logs — Look for incoming requests
Receiving Duplicate Webhooks
Duplicates occur during retries. Implement idempotent handling using run_id as a deduplication key.
Timeouts
If your endpoint takes longer than 30 seconds:
- Respond immediately with 200
- Process webhook data asynchronously
- Use a task queue (Celery, RQ, Bull, etc.)
Next Steps
- Tasks — Task configuration reference
- Runs — Understanding run lifecycle
- Execution — Monitoring workflow execution
- Search Guides — Discovery workflow tutorials
- Ingest Guides — CSV import tutorials
- Signal Guides — Signal monitoring tutorials