Set Up Webhooks for Lead Intake and Event Processing
Configure inbound and outbound webhooks in AgentFlow to receive lead submissions and send qualified lead events to your downstream systems securely.
Webhooks are AgentFlow’s primary event interface — they are how leads arrive from your forms and tools, and how qualified lead decisions leave AgentFlow and reach your CRM, automation platform, or internal services. Understanding both directions of webhook flow lets you build a reliable, auditable pipeline from first contact to downstream action.
An inbound webhook lets any external tool POST lead data directly into AgentFlow’s qualification pipeline.
AgentFlow only accepts inbound webhook connections over HTTPS. Plain HTTP endpoints are rejected at the transport layer. Ensure your sending tool or service supports HTTPS and that your network path does not terminate TLS before the request reaches AgentFlow.
1
Locate your inbound endpoint URL
In your AgentFlow dashboard, navigate to Settings → Webhooks → Inbound. Copy the unique endpoint URL assigned to your workspace. This URL is specific to your account — treat it as a credential and do not publish it.
2
Structure your payload
Send a POST request with Content-Type: application/json. AgentFlow expects the following fields at minimum:
{ "name": "Jordan Ellis", "email": "jordan.ellis@stacklane.co", "company": "Stacklane", "message": "We're evaluating tools to handle inbound demo requests at scale. Currently doing it manually.", "source": "website_contact_form", "timestamp": "2024-11-14T08:44:00Z"}
Field
Required
Description
name
Yes
Full name of the lead
email
Yes
Lead’s email address — used as the primary identifier
company
Recommended
Company or organization name
message
Recommended
The lead’s inquiry text — strongly improves scoring quality
source
Recommended
Where the lead originated (form name, channel, campaign)
timestamp
Recommended
ISO 8601 submission timestamp from the sending system
Additional fields you include are stored on the lead record and surfaced in the operator dashboard, but they do not affect required validation.
3
Authenticate your inbound requests
AgentFlow verifies inbound webhook authenticity using a shared secret. Find your inbound webhook secret in Settings → Webhooks → Inbound → Signing Secret.Include a signature header with every POST:
AgentFlow rejects requests with missing, malformed, or invalid signatures. It also rejects requests where the X-AgentFlow-Timestamp is more than five minutes old, protecting against replay attacks.
4
Test your inbound connection
Send a test POST to your inbound endpoint and check the Inbound Logs panel in the dashboard. A successful intake shows status received and triggers the qualification pipeline. An authentication failure shows status rejected with a reason code.
AgentFlow sends outbound webhook events to your configured URL whenever a lead reaches a terminal qualification state. Your downstream system receives the event and acts on it — creating a CRM record, triggering a Zapier zap, or notifying a Slack channel.
1
Register your destination URL
Navigate to Settings → Webhooks → Outbound. Enter the URL you want AgentFlow to POST events to. This must be an HTTPS endpoint that is publicly reachable by AgentFlow’s servers.
During initial setup, point your destination URL at a webhook inspection tool like Webhook.site so you can inspect the exact payload and headers before wiring up your production system.
2
Select the event types to receive
AgentFlow can send three outbound event types. Subscribe to only the events your downstream system needs to act on:
Event type
When it fires
lead.qualified
An operator approved the lead, or it met the auto-approve score threshold
lead.rejected
An operator rejected the lead, or it fell below the auto-reject threshold
lead.review_requested
The lead score fell in the manual-review range and is awaiting operator action
3
Verify outbound event signatures
Every outbound request from AgentFlow includes an X-AgentFlow-Signature header. Verify this signature in your receiving service before processing the payload to confirm the event genuinely originated from AgentFlow.Your outbound signing secret is available at Settings → Webhooks → Outbound → Signing Secret.
Signature verification (pseudocode)
def verify_agentflow_signature(request_body: bytes, timestamp: str, signature_header: str, secret: str) -> bool: """ Verify an outbound AgentFlow webhook signature. Args: request_body: The raw request body bytes (do not parse JSON first) timestamp: Value of the X-AgentFlow-Timestamp header signature_header: Value of the X-AgentFlow-Signature header (e.g. "sha256=abc123...") secret: Your outbound webhook signing secret from AgentFlow settings Returns: True if the signature is valid; False otherwise """ # 1. Reject requests where the timestamp is more than 5 minutes old if abs(current_unix_time() - int(timestamp)) > 300: return False # 2. Reconstruct the signed content: timestamp + "." + raw body signed_content = f"{timestamp}.{request_body.decode('utf-8')}" # 3. Compute the expected HMAC-SHA256 signature expected = "sha256=" + hmac_sha256(key=secret, message=signed_content) # 4. Compare using a constant-time equality check to prevent timing attacks return constant_time_compare(expected, signature_header)
Always use a constant-time string comparison when checking signatures. Standard string equality (==) is vulnerable to timing attacks that can allow an attacker to forge valid signatures incrementally.
4
Return a 2xx response quickly
AgentFlow considers a delivery successful when your endpoint returns any 2xx HTTP status code within ten seconds. If your processing takes longer than that, return 200 OK immediately and handle the event asynchronously in a background job or queue.If AgentFlow receives a non-2xx response or the request times out, it retries delivery with exponential backoff. Check your Outbound Logs to see delivery attempts and response codes.
Both inbound and outbound endpoints must use HTTPS. Never accept or send webhook traffic over plain HTTP — payloads contain lead PII and should be encrypted in transit.
Verify every signature
Validate the X-AgentFlow-Signature header on every inbound event your service receives. Reject any request that fails signature verification before touching the payload.
Reject stale timestamps
Check that X-AgentFlow-Timestamp is within five minutes of your server’s current time. Stale timestamp rejection prevents replay attacks where an attacker resends a previously captured valid request.
Design for idempotency
Use the lead_id field as a deduplication key. AgentFlow may retry delivery on timeout or transient failure — your handler should safely ignore or skip duplicate events with the same lead_id and event type.
The signature on your inbound request failed validation. Confirm you are signing the raw JSON body (not a re-serialized version) with your inbound signing secret, and that the X-AgentFlow-Timestamp value matches the one used in the signed content string. Regenerate your signing secret in settings and update your sender if the issue persists.
The payload is missing a required field or a field value failed format validation. Check that name and email are present and that email is a valid address format. Review the error body in the response for a field-level description.
Outbound: My endpoint is not receiving events
First, confirm the destination URL is correct and publicly reachable — not a local development address. Check the Outbound Logs panel for delivery attempts. If attempts show a connection error, verify that your server’s firewall or hosting provider is not blocking inbound requests from AgentFlow’s IP ranges.
Outbound: I'm receiving events but processing them twice
Your handler is likely not idempotent. Use lead_id plus the event type as a composite deduplication key. Store processed event IDs in a cache or database and skip events you have already handled. AgentFlow may deliver the same event more than once in retry scenarios.
Outbound: Signature verification is always failing
Confirm you are reading the raw request body bytes — not the parsed JSON object — before computing the expected signature. Parsing and re-serializing JSON can change whitespace or key ordering, producing a different byte sequence than the one AgentFlow signed. Also verify you are using the outbound signing secret, not the inbound one.