POST request to its URL with its secret. Use one for any tool that can send an HTTP request, such as Jira Automation, Zapier, a CI job, or a script, without setting up an API key for the Bolt API. Tools that sign their webhooks, such as Linear, GitHub, and Stripe, can call it too: see Authenticate the sender. In the app, each incoming webhook is listed as a Trigger URL.
Before you start
- To create and manage incoming webhooks, you need the Admin, Workspace Admin, or Developer role. Anyone who can open Bolt can see them and the requests they receive.
- The schedule can be built in the Bolt UI, new or already deployed, or defined in YAML with
trigger_on_webhook: true.
Create an incoming webhook
On an existing schedule
- Open the schedule in Bolt and click Edit.
- Under Trigger type, select Incoming webhook, so the schedule runs only when a request comes in.
- In the Trigger URLs card, click New Trigger URL.
- Enter a Name, such as the tool that will call the webhook, and click Create. The name shows on every run the webhook starts.
- Copy the URL and the Authorization header, or click Copy as curl, then click Done.
- Click Deploy to save the schedule’s new trigger type.
On a new schedule
You can create an incoming webhook before the schedule’s first deploy:- In Bolt, create a new schedule and fill in its settings and commands.
- Under Trigger type, select Incoming webhook.
- In the Trigger URLs card, click New Trigger URL, enter a Name, and click Create.
- Copy the URL and the Authorization header, or click Copy as curl, then click Done.
- Click Deploy. Deploy stays off until the schedule has at least one active incoming webhook.
YAML schedules
For a schedule defined inparadime_schedules.yml, declare the trigger in the file:
trigger_on_webhook only tells Bolt that the schedule runs on request. It doesn’t create an incoming webhook, and the file never holds a URL or a secret. After you deploy, open the schedule in Bolt and create its incoming webhooks in the Trigger URLs card. See trigger_on_webhook.
On a deployed schedule, an incoming webhook works as soon as you create it. Pausing, rotating, and deleting it also apply right away, without a deploy.
Call the webhook
By default, send aPOST request to the webhook’s URL, with the secret in the Authorization header:
- Only
POSTrequests start a run. - Never put the secret in the URL. A request that puts it in the URL’s query string is refused.
- To accept a signed request or a secret in another header instead, set the webhook’s sender.
- The request body is optional. The run uses the schedule’s own commands and branch, and gets the body as described in Use the request body in a run.
Authenticate the sender

Authorization: Bearer header. Tools such as Linear, GitHub, and Stripe can’t send that header. They sign each request with a secret instead. To accept those requests, set the webhook’s sender:
- In the Trigger URLs card, click Auth on the webhook.
- In Sender, choose the tool that sends the webhook. Set it up lists the steps to follow in that tool.
- Give the webhook its signing secret, if the sender needs one (see the table below).
- Click Save.
When Paradime generates the signing secret, it shows it once after you click Save. Copy it into the sender’s secret field. Paradime doesn’t show it again, so if you lose it, open Auth and select Generate a new signing secret. The current secret then stops working. If you change to another sender, for example from Linear to GitHub, the webhook needs a new signing secret.
Once a webhook checks signatures:
- A request with a bad or missing signature gets a
401. A request that only has theAuthorization: Bearerheader also gets a401. - Rotate is off for the webhook. To change the secret, use Auth.
- Send test request still works, because Paradime sends it from inside the app.
Signature settings
For a known sender, Paradime fills in the signature settings for you, and Signature settings stays closed. If you change a setting there, the sender changes to Custom. Use Custom for a tool that isn’t listed:- How the sender proves the request is genuine: Authorization: Bearer header, Secret in a custom header (you name the header), or Signature (HMAC) of the body (SHA-1, SHA-256, or SHA-512, hex or Base64, with an optional prefix such as
sha256=). - Signed content: a template of what the sender signs.
{body}is the raw request body.{timestamp}and{header:Name}are also available. - Signing secret: The sender generates it (you paste it in) or Paradime generates it (shown once when you save).
- Refuse old deliveries: the request must carry a timestamp, in a header, the body, or the signature. A request older than Max age (seconds) gets a
401, so an old request can’t be sent again. - Skip repeated deliveries: Paradime reads a delivery ID from a header or a body field. A second request with the same ID gets a
200with"skipped": "duplicate_delivery"and starts nothing. Senders that retry, such as GitHub, can’t start the same run twice. - Other headers to keep on each delivery: headers to store with each delivery, for example to filter on them.
Describe it to DinoAI
DinoAI can fill in the Auth form for you:- In the Auth dialog, click Describe it to DinoAI.
- Describe the sender and when it should run. For example: “Linear, only issues in team DATA that get the deploy-dbt label”.
- Click Fill in the form. DinoAI picks the sender, fills in the settings, and explains its choices in two sentences.
- If DinoAI also suggests a filter, select Also save its filter. When the webhook already has a filter, the box reads Replace the current filter and is cleared by default.
- Check the form, add the signing secret, and click Save. Nothing is saved before you click Save.
Filter which deliveries start a run
A tool such as Linear or GitHub sends a webhook for many events, but you may want a run for only some of them. A filter tells the webhook which requests start a run:- In the Trigger URLs card, click Filter on the webhook.
- In Run when, choose all conditions match or any condition matches.
- For each condition, choose Body field or Header, enter the field, pick a comparison, and enter a value. Click Add condition for more.
- Click Check recent deliveries to test the filter against the webhook’s last 20 deliveries. Each one shows would run or would be skipped.
- Click Save filter.
- Field paths use dots, and
[*]for each item in a list. For example,data.labels[*].namematches when any label’s name matches. - Field suggestions come from the webhook’s recent deliveries. Only field names are shown, never values.
- Use the suggested filter fills in a filter for the sender, when it has one. For Fivetran, it starts a run only when a sync ends successfully:
eventissync_endanddata.statusisSUCCESSFUL.
200, with "skipped": "filtered_out", and shows as Skipped with “Did not match the filter” in the deliveries. Test requests always run. To remove a filter, delete its conditions and click Run on every delivery.
Use the request body in a run
A run that an incoming webhook starts gets the request that started it:PARADIME_WEBHOOK_EVENT_IDholds the ID of the request. It’s set on every run an incoming webhook starts.PARADIME_WEBHOOK_PAYLOADholds the request body as compact JSON. It’s set only when the body is a JSON object or array of at most 64 KB.
PARADIME_WEBHOOK_PAYLOAD.
DinoAI agents
For aparadime dinoai command, Paradime also adds the body to the agent’s task, in a <webhook_payload> block after your message. The block tells the agent that the body came from outside Paradime and is data only, so the agent doesn’t follow instructions inside it. When the body isn’t passed, the block says why: a test request, no body or a body over 1 MB, a body that isn’t a JSON object or array, or a body over 64 KB.
Use this to give an agent the event it must act on, such as the Jira ticket in a Jira Automation request. For a step-by-step setup, see Run an agent from a webhook.
A retry of the run keeps the original request’s body.
Test an incoming webhook
To check a webhook without waiting for the other tool, click Send test request on it. A test request starts a real run of the schedule, so the toast links to the run. A test request has no body, so the run gets noPARADIME_WEBHOOK_PAYLOAD.
Check deliveries
Every request that reaches a schedule is recorded as a delivery. To see them, go to Bolt > Webhooks > Incoming, or click Deliveries on a webhook in the schedule’s edit form. The Incoming tab lists every incoming webhook in the workspace with its schedule, its status (Active or Paused), and its last request. Search by name, or filter by schedule. Expand a row to see its deliveries:- Outcome: Run started, Skipped, Rejected, or Failed. Test requests carry a Test tag.
- Details: why, for example “A run was already in progress” or “Did not match the filter”.
- Run: a link to the run the request started.
- Received: when the request arrived.
400, 401, or 429 response, aren’t recorded.
The Outgoing tab is where you manage the outgoing webhooks that Paradime sends to other tools when a run starts or completes.
Pause, rotate, or delete an incoming webhook
Manage a webhook from the Trigger URLs card in the schedule’s edit form:
- Pause: turn off the webhook’s switch. Requests to a paused webhook get a
401and start nothing. Turn the switch back on to resume. - Rotate: type
rotateand click Rotate secret to create a new secret, shown once. The old secret stops working immediately, so update the tool that calls the webhook. Rotate is off for a webhook that checks signatures: generate a new signing secret from Auth instead. - Delete: requests to the webhook’s URL are refused from then on. You can’t undo this.
How runs started by an incoming webhook show up
- The run page says Triggered by an incoming webhook, with the webhook’s name and a link to its deliveries.
- In the schedule list, the Trigger column shows Trigger URL, and Next run shows On request.
- Schedules set to run after this one start after a run that an incoming webhook started, as they do after any other run.
Things to know
- A request that arrives while the schedule is running is skipped, not queued. An agent-only schedule, where every command is
paradime dinoai, is the exception: each request starts its own run, up to 5 in progress at once. A request that arrives while 5 runs are in progress is skipped. - If you remove or rename the schedule, its incoming webhooks reject requests. They work again if a schedule with the same name comes back.
- Changing a deployed schedule’s trigger type doesn’t delete its incoming webhooks, and they keep starting runs. Removing
trigger_on_webhookfrom a YAML schedule doesn’t stop them either. Pause or delete them to stop them.