Skip to main content
Webhooks allow you to receive real-time notifications when workflow sessions complete. When a session finishes, Simplex sends a POST request to your configured webhook URL with the complete session results.

Setting up webhooks

You can configure webhooks in two ways:

Global webhook (Dashboard)

Set a global webhook URL for your organization on the Dashboard Settings page. This webhook will receive notifications for all workflow sessions in your organization.

Per-request webhook (API)

When running a workflow via the API, you can specify a custom webhook URL in the Run Workflow request. This is useful for testing with ngrok or routing different workflows to different endpoints.

Webhook payload structure

When a session completes, Simplex will send a POST request to your webhook URL with the following payload:
string
Workflow ID of the session
string
required
Session ID of the session
object
Metadata set in the workflow definition
object
Custom metadata you provided when starting the session
boolean
required
Indicates if the session completed successfully
string
Text description of what the agent accomplished
object
Structured output fields set during workflow execution
string
Presigned URL to download a screenshot of the final browser state
array
Outputs of any scrapers ran during workflow execution
array
Metadata for files downloaded during the session

Structured Output

The structured_output field contains custom data fields that can be defined in your workflow configuration. When you define structured output fields in your workflow, the agent will extract and return these specific pieces of information in addition to the standard response. For example, if your workflow defines structured output fields for extracting form submission results:
This allows you to programmatically access specific data extracted during the workflow execution without having to parse the agent_response text. The fields available in structured_output depend on what you’ve defined in your workflow configuration.

Testing Locally

Testing with ngrok

When developing locally, you can use ngrok to create a public URL that forwards to your local development server:
  1. Install ngrok if you haven’t already
  2. Start your local webhook server (e.g., on port 3000)
  3. Run ngrok to expose your local server:
  4. Use the generated ngrok URL in your webhook configuration:
Your local server will now receive webhook notifications when the workflow completes.

Webhook security

Simplex signs all webhook requests using HMAC-SHA256 to ensure authenticity. You should always verify the signature before processing webhook data.

Finding your webhook secret

Your webhook secret is available on the Dashboard Settings page. Keep this secret secure and never commit it to version control.

How signing works

Each webhook request includes an X-Simplex-Signature header containing an HMAC-SHA256 signature of the request body:
The signature is computed as:

Verifying webhooks

The Simplex TypeScript SDK includes a built-in verifySimplexWebhook() function that handles signature verification for you.

Installation

Best practices

1. Always verify signatures

Never process webhook data without first verifying the signature. This ensures the request actually came from Simplex and hasn’t been tampered with.

2. Respond quickly

Your webhook endpoint should acknowledge receipt within 30 seconds to prevent retries from the Simplex server. If you need to perform long-running operations (like processing large files or making external API calls), respond with a 200 OK immediately and process the data asynchronously.

3. Handle errors gracefully

Return appropriate HTTP status codes:
  • 200 - Webhook received and verified successfully
  • 401 - Signature verification failed
  • 500 - Server error

4. Use environment variables

Store your webhook secret in environment variables, never in code:

5. Test with ngrok

Use ngrok to test webhooks locally before deploying to production:
Then update your webhook URL in the Simplex dashboard to the ngrok URL.

Troubleshooting

”Invalid signature” errors

Cause: The most common cause is parsing the request body as JSON before verification. Solution: Always use the raw request body:
  • Express: Use express.raw({ type: 'application/json' })
  • Next.js: Disable bodyParser in API route config

Webhook not receiving requests

  1. Check that your webhook URL is correct in the Dashboard Settings
  2. Ensure your endpoint is publicly accessible (use ngrok for local testing)
  3. Verify your server is running and responding to POST requests

Missing X-Simplex-Signature header

Ensure you’re reading headers correctly. Header names are case-insensitive in HTTP, but some frameworks may normalize them:
  • X-Simplex-Signature
  • x-simplex-signature

Need help?

If you have questions about webhooks or need help with integration, reach out to us on Slack or at support@simplex.sh.