Deploy webhooks
Run a project's test plan when your own CI, Railway or Coolify finishes a deploy.
A deploy webhook is a URL that starts runs. Any tool that can send an HTTP request when a deploy finishes can call it: your own CI, Railway or Coolify. Each deploy webhook belongs to one project and runs one of its test plans in one of its environments, against the deployed URL when the deploy sends one.
Use it for hosts that have no Autonomy integration of their own. For Vercel, Netlify and Expo EAS, use their integrations instead.
Create a deploy webhook
Owners and admins only.
- Open Organization → Integrations → Deploy webhooks.
- Under New deploy webhook, fill in:
- Name: for example "Railway · Staging".
- Project: whose tests run.
- Environment: runs use its values and sign-ins, and its URL when the deploy doesn't send one (Railway does not).
- Test plan: what runs on each deploy. With None, deploys are recorded but nothing runs.
- Click Create deploy webhook.
- Copy the URL and the Secret right away. "Copy these now — the secret isn't shown again."
Each deploy webhook has its own URL and secret. Put them in your tool's secret store, never in a repository.
To change the secret, click Replace secret: Autonomy shows a new one once, and the old one stops working immediately. To stop a deploy webhook, click Remove.
Authenticate the request
Autonomy accepts one of three ways to prove a request comes from you. If a request carries more than one, every one must match. A wrong secret, or a URL that names no deploy webhook, gets 401 Unauthorized.
| Sender | How to send the secret |
|---|---|
| Your own CI | Sign the raw request body with HMAC-SHA256, using the secret as the key, and send X-Autonomy-Signature: sha256=<hex digest>. |
| Railway | Add the header Authorization: Bearer <secret>. |
| Coolify | Coolify can't send headers: use the URL with ?token=<secret> added. |
Signing is the safest choice. A secret in the URL can end up in logs, so use ?token= only for tools that can't send headers.
Your own CI
Send a JSON body when a deploy finishes:
| Field | Required | Meaning |
|---|---|---|
id | Yes | Your deploy's ID. Each deploy and state runs once. |
status | Yes | ready (or success, succeeded) starts the runs. building, failed, error, canceled and cancelled are recorded only. |
url | No | The deployed URL. Runs test it instead of the environment's web URL. Must be a public HTTPS address. |
branch | No | The branch that was deployed. |
commit | No | The commit SHA. |
pullRequest | No | The pull request number. |
context | No | preview, production or branch. |
body=$(jq -nc \
--arg id "$DEPLOY_ID" \
--arg url "$PREVIEW_URL" \
--arg branch "$BRANCH" \
--arg commit "$COMMIT_SHA" \
'{id: $id, status: "ready", url: $url, branch: $branch, commit: $commit, context: "preview"}')
signature=$(printf '%s' "$body" \
| openssl dgst -sha256 -hmac "$AUTONOMY_DEPLOY_WEBHOOK_SECRET" \
| sed 's/^.* //')
curl -fsS -X POST "$AUTONOMY_DEPLOY_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-H "X-Autonomy-Signature: sha256=$signature" \
--data "$body"Sign the exact bytes you send. Re-encoding the JSON after signing changes the body and the signature no longer matches.
Railway
- In your Railway project, add a webhook and paste the deploy webhook URL.
- Add the header
Authorization: Bearer <secret>.
Railway sends deployment events. A successful deployment starts the runs; failed, crashed and removed deployments are recorded only. Railway doesn't send the deployed URL, so runs test the deploy webhook's environment. Every Railway environment that sends to the URL runs against that one environment, so only send deploys of the Railway environment it matches.
Coolify
In Coolify's webhook notification settings, paste the deploy webhook URL with ?token=<secret> at the end.
A deployment_success event starts the runs against the deployed address, or the preview address for a pull request deploy. deployment_failed is recorded only, and other Coolify events are ignored.
What happens on each deploy
- A ready deploy starts the test plan in the environment, against the deployed URL when the deploy sent one.
- Each deploy runs once. A request repeated for the same deploy and state doesn't start a second run.
- Nothing runs if the project or environment is archived, or the test plan is archived or no longer in the project.
- Runs appear on the project's Runs page like any other run, and send the notifications you set up.
A deploy webhook doesn't post a GitHub check. For a check on each pull request, see Pull request testing.
Troubleshooting
The request gets 401
The secret doesn't match or the URL is wrong. Check that you copied the whole URL, that a signature is computed over the exact body you send, and that the secret wasn't replaced since. If in doubt, click Replace secret and update your tool.
The request succeeds but no run starts
Check that the deploy webhook has a Test plan, that status says the deploy is ready, and that the project, environment and test plan aren't archived. The deploy webhook's row shows when it last received a deploy.
The runs tested the wrong address
Without a url, runs use the environment's web URL. Send url in your body, or point the environment at the right address.
Didn’t find it?