Webhooks
Send events from any platform into the Warpflow Signals pipeline using custom webhooks with sync or async processing.
Overview
Custom webhooks are the primary way to send data into Warpflow from any system that can make HTTP requests — form builders, CRMs, scheduling tools, monitoring systems, or your own backend.
Every webhook event flows through the same pipeline as GHL, Twilio, and email messages: normalize → classify → score → route → execute actions.
Endpoint
POST https://api.warpflow.ai/api/v1/webhook/custom/{tenant_id}/{source_id}
Authorization: Bearer <api_key>
Content-Type: application/json| Parameter | Description |
|---|---|
tenant_id | Your tenant identifier |
source_id | A logical name for the event source (e.g., typeform, calendly, hubspot, internal-crm). Used for filtering and analytics |
Payload format
{
"contact": {
"name": "Jane Doe",
"phone": "+15551234567",
"email": "jane@example.com",
"external_id": "crm-12345"
},
"content": {
"body": "I need a quote for a kitchen remodel. Budget is $40k.",
"subject": "Quote Request"
},
"channel": "webhook",
"source": "typeform",
"metadata": {
"form_id": "abc123",
"submitted_at": "2026-02-22T14:30:00Z"
}
}Field reference
| Field | Required | Description |
|---|---|---|
contact.name | No | Contact's full name |
contact.phone | No* | Phone number (E.164 format preferred) |
contact.email | No* | Email address |
contact.external_id | No | Your system's ID for this contact (used for identity resolution) |
content.body | Yes | The message or event content. This is what gets classified and scored |
content.subject | No | Subject line (useful for form submissions and email-like events) |
channel | No | Defaults to "webhook". Override if you want routing rules to match on channel |
source | No | Defaults to the source_id from the URL path |
metadata | No | Arbitrary key-value pairs. Stored with the lead but not processed by the pipeline |
*At least one of phone, email, or external_id is needed for contact resolution. If none are provided, a new anonymous contact is created.
Processing modes
Async mode (default)
The event is queued for full pipeline processing. The endpoint returns immediately with a confirmation.
curl -X POST \
https://api.warpflow.ai/api/v1/webhook/custom/acme/typeform \
-H "Authorization: Bearer wf_acme_abc123" \
-H "Content-Type: application/json" \
-d '{
"contact": { "name": "Jane Doe", "email": "jane@example.com" },
"content": { "body": "I need a quote for a kitchen remodel" }
}'Response (202):
{
"success": true,
"message": "Event queued for processing",
"lead_id": "lead_abc123"
}The full pipeline runs in the background: classify → score → route → reply → CRM updates. Results are visible in the dashboard and via the conversations API.
Sync mode
Add ?mode=sync to get an immediate response with classification, score, matched rules, and generated reply. The pipeline runs synchronously and returns everything in one call.
curl -X POST \
"https://api.warpflow.ai/api/v1/webhook/custom/acme/typeform?mode=sync" \
-H "Authorization: Bearer wf_acme_abc123" \
-H "Content-Type: application/json" \
-d '{
"contact": { "name": "Jane Doe", "email": "jane@example.com" },
"content": { "body": "I need a quote for a kitchen remodel. Budget is $40k." }
}'Response (200):
{
"success": true,
"lead_id": "lead_abc123",
"classification": {
"intent": "quote_request",
"urgency": "medium",
"sentiment": "positive",
"summary": "Kitchen remodel quote request with $40k budget",
"confidence": 0.92
},
"score": {
"value": 78,
"tier": "hot",
"buying_signals": ["stated_budget", "specific_project"],
"recommended_actions": ["immediate_follow_up", "schedule_consultation"]
},
"matched_rules": [
{ "name": "Hot leads - immediate response", "actions": ["send_template", "escalate"] }
],
"reply": {
"body": "Hi Jane! Thanks for reaching out about your kitchen remodel...",
"guardrail_passed": true
}
}When to use sync mode:
- Form submission acknowledgments (show the user a relevant response)
- Real-time lead qualification (score before routing in your own system)
- Testing and development (see exactly what the pipeline produces)
When to use async mode:
- High-volume event streams
- Events where you don't need an immediate response
- Production webhook integrations (Zapier, n8n, etc.)
Example payloads for common sources
Form submission (Typeform, JotForm, Gravity Forms)
{
"contact": {
"name": "John Smith",
"email": "john@example.com",
"phone": "+15559876543"
},
"content": {
"body": "Service: Dental implants. Insurance: Delta Dental PPO. Preferred time: mornings.",
"subject": "New Patient Form"
},
"source": "typeform"
}Scheduling event (Calendly, Acuity)
{
"contact": {
"name": "Sarah Johnson",
"email": "sarah@example.com"
},
"content": {
"body": "Booked a free consultation for estate planning on March 5 at 2pm",
"subject": "New Appointment"
},
"source": "calendly",
"metadata": {
"event_type": "free_consultation",
"scheduled_time": "2026-03-05T14:00:00Z"
}
}CRM contact update (HubSpot, Salesforce)
{
"contact": {
"email": "existing@client.com",
"external_id": "hubspot-contact-789"
},
"content": {
"body": "Deal stage changed to 'Proposal Sent'. Deal value: $12,000."
},
"source": "hubspot"
}Chat widget (Intercom, Drift, custom)
{
"contact": {
"name": "Anonymous Visitor",
"external_id": "chat-session-456"
},
"content": {
"body": "How much does a roof replacement cost for a 2,000 sq ft house?"
},
"source": "live-chat"
}Rate limits
Custom webhook requests are rate-limited per tenant. If you exceed the limit, you'll receive a 429 response with a Retry-After header.
For high-volume integrations, use async mode — it's more efficient and handles backpressure gracefully.
Error responses
| Status | Meaning |
|---|---|
| 200 | Sync mode — processed successfully |
| 202 | Async mode — queued for processing |
| 400 | Invalid payload (missing content.body, malformed JSON) |
| 401 | Missing or invalid API key |
| 404 | Unknown tenant_id |
| 429 | Rate limited — retry after the specified delay |
| 500 | Server error — contact support if persistent |
Next steps
- Authentication — set up API keys
- Integration Recipes — common patterns with full examples
- Zapier Integration — use webhooks from Zapier
- API Reference — browse all endpoints