HTTP routes
Windmill supports HTTP Routes as triggers to execute runnables (scripts or flows) whenever the route is hit by an external HTTP request, and it can also serve static files or websites.
This feature is ideal for integrating with third-party services, custom webhooks, or internal systems where events are sent via HTTP.
How it works
You define a custom HTTP route with a specific method (GET, POST, PUT, PATCH, DELETE).
When the route is called, Windmill triggers the selected script or flow.
Each route can be protected with various authentication mechanisms, ranging from simple API keys to advanced HMAC signature validation or even fully custom logic.
Among the supported authentication mechanisms, there's also Windmill Auth, which uses a JWT token to authenticate requests and ensure you have read access to the route and the runnable. You can generate your personal Windmill JWT token directly from your user settings and use it to securely access your HTTP routes.
You can configure the route to run:
- Synchronously: Wait for the script to complete and return the result.
- Asynchronously: Return a job ID immediately; the script runs in the background.
- Sync SSE: Return a Server-Sent Events stream. Useful when the runnable returns a stream. Works identically to the
/run_and_streamendpoint of SSE stream webhooks.
For more on streaming in Windmill, see Streaming.
Creating an HTTP route
Windmill supports two ways to create HTTP routes:
- Manual creation, where you define a path, method, and bind it to a runnable.
- Automatic generation from an OpenAPI specification, enabling batch creation.
To create a route manually:
- Navigate to the Custom HTTP routes page.
- Click the New route button.
- Fill in the route configuration fields
- Click Save to create the route.
Generate routes from an OpenAPI specification
Windmill can generate HTTP routes directly from an OpenAPI 2.0+ specification in JSON or YAML format.
You can provide the specification in one of three ways:
- Paste raw content
- Upload a file
- Provide a public URL
To generate routes:
- Navigate to the Custom HTTP routes page.
- Click the From OpenAPI spec button.
- Pick a folder for the generated routes.
- Choose your input method and provide the OpenAPI spec.
- Click Generate HTTP routes.
Behavior and limitations:
- If a path object has a
summaryfield, it will be used as suffix for the trigger path.- If the
summaryexceeds 255 characters, it will be automatically truncated to fit the maximum allowed length.
- If the
- If no
summaryis defined, Windmill generates a unique route path automatically. - Generated routes do not include a script or flow binding (
script_path) by default.- This means requests to the route will return an error until a runnable is attached.
- You can:
- Save routes immediately without modifying them.
- Edit any route before or after saving, to assign a runnable, change route path, etc.
- External
$refreferences (e.g., referencing outside the spec) are not supported.- You must resolve them beforehand.
- Only internal references (e.g.,
#/components/...) are supported.
You can use :param in the route path and access these as params in a preprocessor.
ℹ️ Only workspace admins can create routes.
Once created, all properties of a route except the HTTP path can be modified by any user with write access to the route.
Learn more about Admins workspace.
Workspace prefix
On Windmill Cloud, all HTTP routes are automatically prefixed by the workspace_id (e.g., {workspace_id}/{path}).
This ensures that different workspaces can define the same route paths independently.
On self-hosted Windmill, you can optionally enable the workspace prefix setting to achieve the same behavior.
When workspace prefix is enabled:
- Multiple workspaces can define the same route path without conflict.
- HTTP triggers can be deployed across different workspaces if no conflicting route exists.
When workspace prefix is disabled (on self-hosted):
- Route paths will be globally unique across the entire instance.
- A route path cannot be reused by another workspace unless it is first deleted.
Example:
If workspace A creates the route /webhooks/github, then without workspace prefix, no other workspace can create /webhooks/github.
With workspace prefix enabled, workspace A could have /workspace_a/webhooks/github and workspace B could have /workspace_b/webhooks/github.
Select a script or flow
- Pick the runnable to be triggered when the route is called.
- Use the “Create from template” button to generate a boilerplate if needed.
Example script:
export async function main(/* args from the request body */) {
// your code here
}
With a preprocessor:
export async function preprocessor(
event: {
kind: 'http',
body: { // assuming the body contains name and age parameters
name: string,
age: number,
},
raw_string: string | null,
route: string;
path: string;
method: string;
params: Record<string, string>;
query: Record<string, string>;
headers: Record<string, string>;
}
) {
if (event.kind === 'http') {
const { name, age } = event.body;
return {
user_id: event.params.id,
name,
age,
};
}
throw new Error(`Expected trigger of kind 'http', but received: ${event.kind}`);
}
export async function main(user_id: string, name: string, age: number) {
// Do something
}
Generate routes from an OpenAPI specification
Windmill can generate HTTP routes directly from an OpenAPI 2.0+ specification in JSON or YAML format.
You can provide the specification in one of three ways:
- Paste raw content
- Upload a file
- Provide a public URL
To generate routes
- Navigate to the Custom HTTP routes page.
- Click the From OpenAPI spec button.
- Pick a folder for the generated routes.
- Choose your input method and provide the OpenAPI spec.
- Click Generate HTTP routes.
Behavior and limitations
- If a path object has a
summaryfield, it will be used as suffix for the trigger path.- If the
summaryexceeds 255 characters, it will be automatically truncated to fit the maximum allowed length.
- If the
- If no
summaryis defined, Windmill generates a unique route path automatically. - Generated routes do not include a script or flow binding (
script_path) by default.- This means requests to the route will return an error until a runnable is attached.
- You can:
- Save routes immediately without modifying them.
- Edit any route before or after saving, to assign a runnable, change route path, etc.
- External
$refreferences (e.g., referencing outside the spec) are not supported.- You must resolve them beforehand.
- Only internal references (e.g.,
#/components/...) are supported.
Generate an OpenAPI specification from HTTP routes and webhooks
Windmill supports generating a compliant OpenAPI 3.1 specification from your existing HTTP routes and webhook triggers.
How it works
You can export a unified OpenAPI specification that includes:
- HTTP routes and webhook triggers (filtered by path or type)
- Route metadata:
summary,description, async/sync behavior - Security models for supported authentication types
- Parameter inference (e.g.,
:idbecomes an OpenAPIpathparameter) - Auto-generated
servers,components, and reusable definitions
To generate a spec
- Go to Custom HTTP routes
- Click To OpenAPI spec
- (Optional) Provide API metadata:
- Title and version (default to
"Windmill API"and"1.0.0"if omitted) - Description, contact info, and license are also supported
- Title and version (default to
- Add filters to include specific routes or webhooks:
- HTTP Routes: by folder, path, and route pattern
- Webhooks: by kind (
scriptorflow) and path
- Choose output format: YAML or JSON
- Click Generate OpenAPI document
You can then:
- Preview and copy the document
- Download it
- Copy a ready-made
cURLcommand to call the generation API
Security mapping
The OpenAPI document reflects security as follows:
-
HTTP Routes:
- ✅
Windmill Auth→ JWT bearer scheme (bearerFormat: JWT) - ✅
Basic Auth→ HTTP Basic auth scheme
- ✅