Guides
Webhooks
Receive new signal events at your endpoint the moment they happen — no polling. Configure once in Settings; VeilStrat POSTs outbound with your webhook auth key.
Overview
There is no customer POST /webhooks API. Firehose is outbound only: we POST to your HTTPS URL when a subscribed signal type is written. Delivery is forward-only from the moment you save.
Recommended pattern: webhook + dossier
company.id + signalId), then enrich with GET /companies/{id}. Avoid polling large searches.Set up a webhook
Endpoint URL
http://127.0.0.1:8787/… or an ngrok URL.Authentication key
Authorization: Bearer <key> on every POST.Signal types
Test endpoint
Owner + Pro only
Event types
Hiring
hiringFunding
fundingFunding + AI
funding_aiWebsite AI
webTool adoption
toolHiring velocity
velocityUnsubscribed types are never delivered. Subscribe only to what your handler supports.
Headers & delivery
POST /your-path HTTP/1.1
Authorization: Bearer <your-webhook-auth-key>
Content-Type: application/json
Accept: application/jsonSuccess
Retries
Concurrency
Queue cap
REST budgets
Payload
{
"eventId": "wh_<signalId>_created_<unix>",
"type": "hiring",
"action": "created",
"occurredAt": "2026-08-20T09:15:00Z",
"signalId": "<uuid>",
"company": {
"id": "<uuid>",
"name": "Example Co",
"domain": "example.com",
"logo": null
},
"signal": {
"label": "Hiring AI SDR roles",
"confidence": 75,
"jobTitle": "AI SDR"
}
}Field reference
| Field | Type | Description |
|---|---|---|
| eventId | string | Stable id for dedupe; reused on retries |
| type | string | Public signal slug (hiring, funding, …) |
| action | string | Usually created (sometimes updated) |
| occurredAt | string | ISO timestamp of the event |
| signalId | string | UUID of the signal row |
| company | object | id, name, domain, logo — use id for dossier |
| signal | object | Type-specific fields (label, confidence, …) |
Verifying requests
Compare Authorization: Bearer to your saved webhook auth key using a constant-time compare. Reject missing or wrong values with non-2xx so we retry (or stop after the attempt budget).
Dedupe on eventId — handlers must be idempotent.
Local testing
node scripts/firehose-webhook-receiver.mjs \
--port 8787 \
--host 127.0.0.1 \
--secret 'your-webhook-auth-key' \
--capture-file /tmp/veilstrat-webhook-last.jsonSettings Send test works without Inngest. Live delivery after Save requires the Inngest Dev Server locally.
Best practices
- Return 2xx quickly; do heavy work asynchronously.
- Store and rotate webhook keys like production secrets.
- Missed history is not self-serve — contact support for manual replay.
- Continue with All endpoints and Rate limits.