Welcome to the Webhooks API
Webhooks push real-time signal data to your own HTTPS endpoint the moment events happen — funding rounds, acquisitions, job changes, new hires, newly discovered companies, and newly discovered investors. Instead of polling, your system receives a signedPOST with the full event payload.
Webhooks are a first-class API resource: you can create, list, retrieve, update, rotate the signing secret of, test, and delete them entirely over REST, plus list delivery attempts and replay failed ones. Anything you do in the dashboard for webhooks is doable via the API now.
Create Webhook
Subscribe an endpoint to event types and receive the signing secret.
List Webhooks
Retrieve every active webhook for your team.
Send Test Event
Fire a signed
system.test event without waiting for a real signal.List Deliveries
Inspect recent delivery attempts and their status.
Key Features
- API-first: Full CRUD plus test, delivery listing, and retry — no dashboard required.
- Signed payloads: Every delivery carries an HMAC-SHA256 signature so you can verify authenticity.
- Secret rotation: Rotate the signing secret in place without recreating the webhook.
- Event subscriptions: Subscribe each webhook to exactly the event types you care about.
- Delivery visibility: List delivery attempts with status, response code, and stored response body.
- Manual retry: Replay a failed delivery; it reuses the original
event_idso you can dedupe. - Dashboard parity: The same webhook is fully manageable from the dashboard and the API.
Authentication
Every request needs an API key (ff_live_…) belonging to a team with an active or trialing subscription. Pass it as a Bearer token in the Authorization header. Get your key from the dashboard at trysignalbase.com/workspace/api.
https://www.trysignalbase.com/api/v2. A key is bound to one team; all webhooks it creates belong to that team and are visible to every team member. Request bodies may use snake_case (canonical) or camelCase (endpointUrl, eventTypes, rotateSecret).
Response Envelope
Every endpoint returns a consistent JSON envelope. Success:pagination is present only on list endpoints. meta.creditsUsed reflects the credits this request consumed.
Error:
The Webhook Resource
Event Types
Subscribe to these inevent_types when you create or update a webhook:
Two additional event types may appear on the receiving side but are not regular subscriptions:
system.test— delivered only by the Send Test Event endpoint. It is accepted inevent_typesfor convenience but never fires automatically.dashboard.push— delivered when a teammate uses the dashboard Push button to send selected companies/investors/contacts to a webhook. Personal data is GDPR-masked (last names masked, personal emails filtered) before delivery.
Filters
filters is an optional string-to-string map that narrows which events are delivered, applied to every *.created event the subscription is registered for. Only the keys below are recognized — any other key is silently ignored (it does not narrow anything), so the key names matter. All values are strings.
investor.created is filtered differently. Investor events carry an investor profile, not a company signal, so only two keys apply — countries (matched against the investor’s operating countries) and search (substring match on the investor’s name or type, e.g. "vc" or "sequoia"). Every other key (categories, teamSize, funding, date ranges, …) is ignored for investor events and does not narrow them.
Important behaviours:
- Use
funding(notround) to filter funding rounds. The webhook filter key names differ from the REST query params — e.g. the round-type key here isfunding, and amount usesfundingAmount/acquisitionAmountranges rather thanamount_min/amount_max. A wrong key like{ "round": "seed" }is ignored and you’ll receive the full firehose. - Multiple keys combine with AND — an event must satisfy every filter to be delivered.
- Type-specific keys drop other types. If a subscription listens to several event types and you set a
funding-only key (funding,roundFlavor,fundingAmount,healthScore), non-funding events (e.g.hiring.created) won’t match and won’t be delivered. Prefer one webhook per event type when using type-specific filters.
Credits & Limits
Webhook management, reads, and creation are all free; only successful deliveries (including a successful manual retry) consume credits. If your team’s API credit balance reaches zero, deliveries stop.
The Delivery Your Endpoint Receives
Each delivery is an HTTPPOST with Content-Type: application/json and User-Agent: Signalbase-Webhooks/1.0.
Body envelope — every delivery has the same four top-level keys.
data holds the full signal object, whose shape depends on event_type (see Payload by event type below).
The delivered body is canonical JSON with object keys sorted alphabetically at every level (note the
data, event_id, event_type, timestamp order above). The signature is computed over those exact bytes — so always verify against the raw request body you received, never a re-serialized copy.Payload by event type
Every company signal payload shares a common envelope insidedata:
signal—{ id, type, externalId, occurredAt, discoveredAt, active }company— the full company object (ornullfor some events);headquartersCountryis an ISO-style country codeemployees— array of{ id, name, title, linkedinUrl, email }(may be empty)sources— array of{ url, sourceType, author, title, content, validationScore, validationReasoning, publishedAt }
investor.created: investors are profiles, not company signals, so its data contains a single investor object and none of the envelope keys above (see its tab below). Monetary amount fields are whole currency units (integers, not cents); currency tells you which currency, as an ISO 4217 code (e.g. USD, EUR). See Amounts & Currency.
Person names in
job_change.created payloads are GDPR-masked (first name + last initial, e.g. "Jordan M."), matching the masking applied across the REST API. Use personLinkedinUrl as the stable identifier for a person.investor.created payloads, type is the original scraped value (free text, e.g. VC, Corporate VC, Solo angel — see Investor Types), countries is an array of ISO 3166-1 alpha-2 codes, and ticketSizeMin / ticketSizeMax are whole USD amounts. Nullable fields are null, and countries may be empty.
For dashboard.push, data instead contains companies, investors, and contacts arrays (contacts GDPR-masked) plus a meta block describing the push.
Verifying the Signature
The signature isHMAC-SHA256(raw_body, secret), hex-encoded, sent in X-Webhook-Signature. The secret is the value returned when you created (or last rotated) the webhook.
Delivery & Retry Contract
- Success = any HTTP
2xxfrom your endpoint. Any other status, or a network error, is a failure (a network error is recorded withresponse_status: 0). - One attempt per event. The current release does not automatically retry failed deliveries on a schedule. Build idempotent handlers and reconcile gaps yourself.
- Manual retry is available: list failed deliveries with List Deliveries (
?status=failed) and replay them with Retry Delivery. - Idempotency:
event_id(also sent asX-Webhook-ID) is stable across the original delivery and any retries, so you can safely dedupe. - Response storage: the first 1000 characters of your response body are stored per delivery for debugging.
- Respond quickly — acknowledge with
2xx, then process asynchronously.
Full Lifecycle Over the API
A vendor can onboard end-to-end without opening the dashboard:Dashboard Parity & Migration
Everything above is also available without code under Workspace → Webhooks in the dashboard. Because the dashboard and the REST API share one code path, a webhook created in the UI is fully manageable via the API and vice versa.- Webhooks are editable in place. To change a URL or event list, use Update Webhook (or the dashboard Edit button) — you no longer need to delete and recreate. The signing secret is preserved across edits unless you pass
rotate_secret: true. - Retrieve existing config: vendors who configured webhooks through the dashboard can list and manage them immediately via List Webhooks — no migration step required. Only
secret_previewis exposed for pre-existing webhooks; rotate the secret if you need a fresh full value.
Error Handling
Errors return a non-2xx status with{ success: false, error, code }.
