For GitHub events such as pull requests, issues, and comments, OpenHands Enterprise has a built-in
integration that needs no webhook registration. See
GitHub Event Automations.
Built-In vs. Custom Integrations
Custom Webhooks
For services other than GitHub, such as Linear, Stripe, or Slack, register a custom webhook first, then create automations that use it.Two-phase workflow for custom webhooks:
- Webhook registration (one-time setup): You execute the curl command yourself to register the webhook. This keeps your signing secrets secure—the agent provides the command but never handles your credentials directly.
- Automation creation (repeatable): Once the webhook is registered, the agent can create, update, and manage automations for that webhook source conversationally—no manual curl commands needed.
Before You Start on Agent Canvas
The external service sends events to your automation service over the internet, so a custom webhook needs a URL that the service can reach. A backend running onlocalhost is not reachable, so make it publicly reachable first:
- Expose the Canvas ingress. Run Agent Canvas with
--publicand put a tunnel such as ngrok in front of its ingress (port8000by default). The bundled launcher starts both Agent Server and the Automation service behind this address. See VM / Self-Hosted Installation for the commands. - Use the ingress URL and its API key. Commands on this page call
<Canvas ingress URL>/api/automation/v1/...with the shared key in theX-Session-API-Keyheader. Use the Host / Base URL from Manage Backends only if it points to this combined ingress. A standalone Agent Server does not serve/api/automation/*; its URL alone cannot receive automation webhooks.
Walkthrough: Linear Integration
This example sets up a Linear webhook that auto-triages new issues. The registration command has a tab for the local Agent Canvas and one for OpenHands Enterprise.
Step 1: Get Your Webhook Secret from Linear
Linear provides the webhook signing secret—you cannot configure your own.- Go to Linear Settings → API → Webhooks
- Click New webhook
- Copy the signing secret that Linear displays (you’ll need this in the next step)
- Leave the webhook URL blank for now—you’ll get it from OpenHands
Step 2: Register the Webhook with OpenHands
- Local Agent Canvas
- OpenHands Enterprise
Export your public Canvas ingress URL, its shared API key, and the webhook secret from Step 1:Then register the webhook:
The
webhook_url in the response is built from the automation service’s own address, so on a local backend it can start with http://localhost. External services can’t reach that address. In Step 3, keep the path (/api/automation/v1/events/<org_id>/linear) and replace the beginning with your public Canvas ingress URL.Understanding event_key_expr
Understanding event_key_expr
The With
event_key_expr is a JMESPath expression that extracts the event type from incoming webhook payloads. This extracted value is what you match against in the automation’s on field.For example, Linear sends payloads like:event_key_expr: "type", the system extracts "Issue" as the event type. Then in your automation, you set on: "Issue" to match it.Step 3: Complete the Linear Webhook Configuration
- Return to the Linear webhook you started in Step 1
- Paste the
webhook_urlfrom the previous step. On a local Agent Canvas, use the public version of the URL, as described in the note above - Select which events to send (e.g., Issues, Comments)
- Save the webhook
Step 4: Create the Automation
Now the webhook is registered, the agent can create automations for you end-to-end. Just describe what you want. On Agent Canvas, you can do this in the setup assistant:- Source:
linear(your registered webhook) - Event:
Issue(Linear’s event type) - Filter:
action == 'create'
Filtering Events
Filters let you narrow which events trigger your automation. They use JMESPath expressions to match fields in the event payload—so you can trigger only on specific labels, users, branches, or other conditions.OpenHands extends standard JMESPath with custom functions including
icontains (case-insensitive string match) and glob (wildcard path matching). It also supports ! (negation), && (AND), and || (OR) as boolean operators. These extensions are not part of the JMESPath specification.contains(...)— match a specific labelicontains(...)— case-insensitive mention in a comment bodyglob(...)— match repos in your org with wildcards==— exact match (e.g., push to main branch only)&&— combine multiple conditions
Custom Webhook Parameters
When registering any custom webhook, these parameters define how OpenHands processes incoming events:Common Services
These are example configurations for popular services. Always verify with each service’s webhook documentation, as signature headers and payload formats may change.Next Steps
New to automations? Start with the Automations Overview for the bigger picture, including cron-based scheduling and general concepts.- Automations Overview — Cron-based automations and general concepts
- GitHub Event Automations — Built-in GitHub integration for OpenHands Enterprise
- Managing Automations — Update, disable, or delete automations

