Overview
Webhooks enable you to receive real-time notifications when important events occur in Explorium’s data ecosystem. This guide walks you through setting up v2 webhooks to receive push notifications for the business and prospect events you monitor. Unlike v1’s single partner-level webhook, v2 webhooks are first-class, addressable resources:- Multiple webhooks — up to 10 per tenant. Creating one never overrides another.
- Tenant-scoped — resolved from your API key; you never pass a tenant or partner ID.
- Addressed by
webhook_id— server-generated and immutable (e.g.wh_9f2c81ab). Event enrollments bind to it explicitly. - Per-webhook secrets — each webhook has its own HMAC secret, rotatable independently.
Quick Start
- Register a webhook — create a destination for event deliveries
- Implement a secure receiver — validate and process incoming events
- Test connectivity — verify the webhook is configured correctly
- Enroll for events — subscribe entities, binding each enrollment to a webhook
- Process events — receive and handle real-time events as they occur
Step 1: Register Your Webhook
POST /v2/webhooks — only name and webhook_url are required.
Request
Response (201)
Optional Registration Parameters
Webhook Limits
- Up to 10 webhooks per tenant;
namemust be unique within your scope - Creating a webhook never overrides an existing one — that v1 behavior survives only on the v1 endpoint
- Your legacy v1 partner-level webhook appears read-only in List webhooks, flagged
legacy: true; v1 enrollments keep delivering to it with no action required
Step 2: Implement Your Webhook Handler
Your webhook handler needs to:- Accept HTTP POST requests
- Validate the signature to ensure event authenticity
- Process incoming event data based on the event type and enrollment key
Example Implementation (Python with FastAPI)
Python
timestamp.payload, computed with the secret of the delivering webhook — the payload’s webhook_id tells you which secret to verify with. This prevents unauthorized systems from sending fake events to your endpoint.
Step 3: Test Webhook Connectivity
POST /v2/webhooks/{webhook_id}/check_connectivity — targeted at one webhook; no request body is needed for a basic check.
Response
Advanced Testing
Add asimulation block to push realistic mock events — useful for validating your event handling logic end to end:
Request
event_name— the event type to simulatenumber_of_events— how many simulated events to deliverevent_time(optional) — the event timestamp to stamp on the simulated events
Step 4: Enroll for Events
Once a webhook is set up, enroll entities for monitoring — every v2 enrollment binds to a webhook explicitly viawebhook_id.
- Businesses:
POST /v2/businesses/events/enrollments - Prospects:
POST /v2/prospects/events/enrollments
Request
Response (201)
Key Enrollment Parameters
webhook_id: the delivery destination. The binding is strict — the webhook must exist in your scope and beactive. Unknown IDs return404; a missingwebhook_idor wrong scope/status returns422. Events are never silently delivered elsewhere.enrollment_key: a custom identifier included in every event notification — use it to group enrollments by customer, campaign, or business process and route events accordingly.business_ids/prospect_ids: entities to monitor, up to 1,000 per request. There is no limit on the total enrolled across multiple requests.
Managing enrollments
Each enrollment has a server-generatedenrollment_id and a status — active (delivering) or paused (retained, delivering nothing; set when its webhook is force-deleted). PATCH .../enrollments/{enrollment_id} updates webhook_id, enrollment_key, event_types, or the entity list — re-pointing a paused enrollment to an active webhook reactivates it without re-enrolling entities.
Event Payload Structure
Delivered payloads name their delivery source —webhook_id, tenant_id, partner_id, and enrollment_id — so a shared handler can route without relying on enrollment_key alone:
JSON
Key Fields
webhook_id: the webhook this event was delivered through — also selects the secret for signature verificationenrollment_key: the identifier you provided during enrollmentenrollment_id: the enrollment that triggered this deliveryevent_id: a unique identifier for this specific eventevent_name: the type of event that was triggeredentity_type: either “business” or “prospect”data: event-specific data (varies by event type)
Using Webhooks with Claude Code Routines
Claude Code routines can run automatically in response to an external HTTP request through an API trigger. You can point an Explorium webhook directly at a routine’s trigger URL so that every Explorium event fires the routine — and, with the rightpayload_format, the event data is delivered straight into the routine for processing. No relay or intermediate service is required.
How it works
A routine’s API trigger exposes a fire URL of the form:- Requires an
Authorization: Bearer <token>header (generated when you create the routine) and ananthropic-version: 2023-06-01header. - Injects the request body’s
textfield into the routine as its input, and ignores other top-level fields.
text field, Explorium’s default event object isn’t consumed by the routine on its own. Setting payload_format to stringified_json tells Explorium to deliver the event in a routine-compatible shape:
text value is the complete Explorium event object serialized as a JSON string, so the routine can parse it and act on the event.
Step 1 — Create the routine
In claude.ai → Code → Routines, create a routine and choose the API trigger (“Trigger from your own code by sending a POST request”). Copy:- the trigger’s fire URL, and
- the token generated for the trigger.
Step 2 — Register the webhook
Register the routine’s fire URL as a dedicated webhook, supplying the required headers andpayload_format: "stringified_json":
webhook_id.
The
anthropic-version header is required — without it the routine endpoint rejects the delivery with a 400 error. Each event is delivered as a separate POST, so one routine run is triggered per event.Step 3 — Test it
Use the connectivity endpoint to push simulated events to your routine:"request_status": "success" response means the routine accepted the events. Open the routine’s sessions in claude.ai to see each event rendered and processed.
Managing Your Webhooks
Deleting a webhook that active enrollments reference fails with a conflict unless you pass
?force=true — then the affected enrollments are set to paused (entity lists preserved, IDs returned in affected_enrollment_ids) and can be re-pointed to another webhook later. Enrollments are never silently re-pointed.
Best Practices
- One webhook per destination or use case — CRM sync, ops alerts, and automation each get their own webhook, secret, and enrollments.
- Use the
enrollment_keyeffectively: structure keys to match your internal systems and use cases. - Validate all signatures: verify every event with the secret of the
webhook_idit arrived through. - Set up monitoring: detect delivery failures on your endpoint, and use
status: "disabled"to pause a destination without deleting it. - Use proper Content-Type: accept and respond with
application/json.
Frequently Asked Questions
How many webhooks can I register?
How many webhooks can I register?
Up to 10 per tenant. Each is addressed by its own
webhook_id, and creating a new one never overrides an existing one.What happened to the v1 single-webhook model?
What happened to the v1 single-webhook model?
The v1 endpoints keep working unchanged, including their register-overrides behavior. Your existing partner-level webhook appears read-only in
GET /v2/webhooks flagged legacy: true, and v1 enrollments keep delivering to it with zero action required.How do I rotate a webhook secret?
How do I rotate a webhook secret?
POST /v2/webhooks/{webhook_id}/rotate_secret — it returns a new secret for that webhook only. In v1 you had to re-register; in v2 rotation never touches other webhooks.Is there a limit to how many businesses or prospects I can enroll?
Is there a limit to how many businesses or prospects I can enroll?
Each enrollment request is limited to 1,000 IDs, but there’s no limit on the total enrolled across multiple requests.
What happens to enrollments when I delete their webhook?
What happens to enrollments when I delete their webhook?
The delete fails with a conflict unless you pass
?force=true. Forced deletion pauses the affected enrollments — delivery stops, entity lists are preserved — and you can re-point them to another webhook via PATCH without re-enrolling.How do I differentiate between different monitoring use cases?
How do I differentiate between different monitoring use cases?
Two levers: separate webhooks per destination, and the
enrollment_key on each enrollment. Both arrive in every event payload, alongside webhook_id and enrollment_id.Can I trigger a Claude Code routine from a webhook?
Can I trigger a Claude Code routine from a webhook?
Yes. Register a dedicated webhook pointing at the routine’s API-trigger fire URL, pass the routine’s
Authorization and anthropic-version: 2023-06-01 headers via headers, and set payload_format to stringified_json. See Using Webhooks with Claude Code Routines.