Webhook Endpoints
Webhook endpoints handle incoming HTTP requests and can trigger workflows or activities in response. They run as WASM components, just like activities, but export an HTTP handler instead of named functions.
A handler receives a request and returns a response. It can call a workflow or activity directly — blocking until the result is ready — or schedule one as fire-and-forget without waiting. Join sets are not available inside webhook handlers. URL path parameters are exposed as environment variables inside the handler.
Implementation
For language-specific implementation details, see:
- JS Webhooks — JavaScript handler,
obelisk.call,obelisk.schedule, fetch, path parameters - Rust Components — Rust/WASM handler using
wstd, WIT imports,cargo generatetemplates - HTTP Client (Rust) — Making outbound HTTP requests from Rust activities and webhooks
Example — Stargazers demo
The webhook endpoint in the stargazers demo repository shows a real-world integration with GitHub, covering:
- Setting a shared secret and passing it as an environment variable
- Verifying the request signature using HMAC
- Creating a tunnel to expose the local HTTP server
- Testing
Configuration
Associating Webhook Endpoints with HTTP Servers
Webhook endpoints don't listen for HTTP requests directly. Instead, they are associated with an
[[http_server]] instance defined in your deployment configuration. This association is established
using the http_server field within the [[webhook_endpoint]] or [[webhook_endpoint_js]]
configuration.
[[http_server]]
name = "my_server"
listening_addr = "0.0.0.0:9000"
[[webhook_endpoint_wasm]]
name = "my_endpoint"
http_server = "my_server"
# ... other webhook endpoint settings ...Routes Configuration
Each webhook endpoint must define one or more routes. These routes determine which incoming HTTP requests will be handled by that endpoint.
[[webhook_endpoint_wasm]]
name = "my_endpoint"
http_server = "my_server"
routes = [
{ methods = ["GET"], route = "/users/{id}" }, # Route with method
"/products/*", # Route without method (wildcard)
"/status", # Route without method (exact match)
]Route Syntax and Matching
Obelisk supports several ways to define routes:
-
Static Routes: Match exact URL paths.
-
"/": Matches only the root path. -
"/path": Matches the exact path/path.
-
-
Wildcard Routes: Match path prefixes.
"/path/*": Matches any path that starts with/path/, including/path/,/path/subpath,/path/a/b/c, etc.
-
Parameterized Routes: Capture parts of the path as parameters.
"/status/:PARAM1/:PARAM2": Matches paths like/status/123/abc. The values123andabcwill be available to the webhook endpoint as environment variables namedPARAM1andPARAM2, respectively.
-
Method-Specific Routes: These routes combine an HTTP method (or methods) with a path. Method-specific routes have higher priority than routes without methods.
-
{ methods = ["GET"], route = "/path/*" }: A wildcard route restricted to onlyGETrequests. -
{ methods = ["POST", "PUT"], route = "/resource" }: A static route restricted toPOSTorPUTrequests.
-
-
Matching All Paths
""or"/*"— Match all paths
Route Priority and Matching Order
When an incoming HTTP request arrives, Obelisk checks the configured routes to determine which webhook endpoint should handle it. The matching process follows these rules:
-
Method-Specific Routes First: Obelisk first tries to match the request against routes that specify HTTP methods (e.g.,
{ methods = ["GET"], route = "/path" }). -
First Match Wins (Within Priority): Within each priority level (method-specific or not), the first route that matches the request wins. The order of routes in the routes list matters.