Deployment webhooks
Trigger Smoketest tests from CI, deployment hooks, and custom infrastructure.
Deployment webhooks are incoming URLs that queue Smoketest runs after your app deploys. A webhook can target one test or every current test with a project tag.
Create a webhook
- Open Project → Automations.
- Create a webhook and choose a test or tag target.
- Optionally bind a mapped GitHub repository so calls with
commitShacreate a GitHub check. - Copy the trigger URL. The full secret URL is only shown when the webhook is created or regenerated.
The URL has this shape:
https://api.smoketest.sh/v1/deployment-webhooks/<webhookId>/<secret>Trigger parameters
Call the trigger URL with POST. The simplest form uses query parameters and no request body:
curl -sf -X POST -G "$SMOKETEST_DEPLOYMENT_WEBHOOK_URL" \
--data-urlencode "targetUrl=https://preview.example.com" \
--data-urlencode "commitSha=abc123" \
--data-urlencode "branch=main" \
--data-urlencode "externalId=deploy-123"All parameters are optional.
| Parameter | Type | Description |
|---|---|---|
targetUrl | string | Run-only URL override. Use this for preview or staging deployments without changing the saved test URL. |
commitSha | string | Commit SHA for GitHub check creation when the webhook is bound to a mapped repository. |
branch | string | Branch name shown on the GitHub check. |
baseBranch | string | Base branch metadata for GitHub check details. |
prNumber | number | Pull request number metadata for GitHub check details. |
externalId | string | Idempotency key for CI systems that retry webhook calls. |
You can also send the same fields as a JSON body for existing integrations. Query parameters win when both query and JSON body values are provided. Unknown JSON fields are ignored, including environment; deployment webhooks do not select Smoketest variable environments in v1.
Response
{
"received": true,
"status": "queued",
"deliveryId": "018f1111-abcd-7000-8000-abc123456789",
"count": 2,
"runIds": [
"018f2222-abcd-7000-8000-abc123456789",
"018f3333-abcd-7000-8000-abc123456789"
],
"checkId": "018f4444-abcd-7000-8000-abc123456789",
"links": {
"dashboardIntegrations": "https://smoketest.sh/dashboard/run-triggers",
"runs": [
"https://smoketest.sh/runs/018f2222-abcd-7000-8000-abc123456789"
],
"check": "https://smoketest.sh/github/checks/018f4444-abcd-7000-8000-abc123456789"
}
}Statuses:
| Status | Meaning |
|---|---|
queued | One or more runs were queued. |
empty | The webhook targeted a tag with no current tests. |
processing | A duplicate idempotent request found a delivery that is still processing. |
error | The delivery failed before queueing runs. |
CI examples
GitHub Actions
name: Smoketest
on:
deployment_status:
jobs:
smoketest:
if: github.event.deployment_status.state == 'success'
runs-on: ubuntu-latest
steps:
- name: Trigger Smoketest
run: |
curl -sf -X POST -G "$SMOKETEST_DEPLOYMENT_WEBHOOK_URL" \
-H "Idempotency-Key: ${{ github.event.deployment.id }}" \
--data-urlencode "targetUrl=${{ github.event.deployment_status.environment_url }}" \
--data-urlencode "commitSha=${{ github.sha }}" \
--data-urlencode "branch=${{ github.ref_name }}" \
--data-urlencode "externalId=${{ github.event.deployment.id }}"
env:
SMOKETEST_DEPLOYMENT_WEBHOOK_URL: ${{ secrets.SMOKETEST_DEPLOYMENT_WEBHOOK_URL }}GitLab CI
smoketest:
stage: test
script:
- |
curl -sf -X POST -G "$SMOKETEST_DEPLOYMENT_WEBHOOK_URL" \
-H "Idempotency-Key: $CI_PIPELINE_ID" \
--data-urlencode "targetUrl=$CI_ENVIRONMENT_URL" \
--data-urlencode "commitSha=$CI_COMMIT_SHA" \
--data-urlencode "branch=$CI_COMMIT_REF_NAME" \
--data-urlencode "externalId=$CI_PIPELINE_ID"Jenkins or shell
curl -sf -X POST -G "$SMOKETEST_DEPLOYMENT_WEBHOOK_URL" \
-H "Idempotency-Key: ${BUILD_TAG}" \
--data-urlencode "targetUrl=${DEPLOYMENT_URL}" \
--data-urlencode "commitSha=${GIT_COMMIT}" \
--data-urlencode "branch=${BRANCH_NAME}" \
--data-urlencode "externalId=${BUILD_TAG}"CI and pipeline guides
Use these when your pipeline knows the deployment URL, commit SHA, branch, and retry identity.
Trigger Smoketest after a deployment status or deploy job succeeds.
Run Smoketest after GitLab environment deployments and review apps.
Add Smoketest as a Pipeline stage after deployment.
Queue Smoketest runs from Bitbucket deployment steps.
Trigger Smoketest from CircleCI workflows after deploy jobs.
Add a Smoketest command step after Buildkite deploys.
Call Smoketest from Azure Pipelines deployment jobs.
Use Drone or Woodpecker pipeline variables to trigger Smoketest.
Connect custom infrastructure, SSH deploys, cron, or private orchestrators.
Deployment platform guides
Use native platform webhooks for basic fixed-URL testing. Use the CI path when you need dynamic preview URLs, idempotency, or GitHub checks.
Run Smoketest after Vercel production and preview deployments.
Connect Netlify deploy notifications or CI-controlled deploys.
Run Smoketest after Render deploy-ended events or deploy hooks.
Trigger Smoketest from Railway webhooks or CI deploys.
Connect Coolify deployment notifications or GitHub Actions deploys.
Run Smoketest after flyctl deploys and review apps.
Trigger Smoketest after Pages or Workers deployments.
Run Smoketest after Heroku releases are live.
Call Smoketest from Dokku CI deploys or post-deploy hooks.
Add Smoketest after CapRover CLI or CI deployments.
Add Smoketest to server deployment scripts.
Run Smoketest after rollouts or healthy GitOps syncs.
GitHub checks
To create GitHub checks from deployment webhooks:
- Install the Smoketest GitHub App.
- Map the repository to the same project as the webhook.
- Select that repository in the webhook form.
- Send
commitShaas a query parameter or JSON body field.
Smoketest creates one aggregate check named Smoketest / <webhook name>, links queued runs, and finishes the check when all linked runs reach a terminal state.
Idempotency
Use either the Idempotency-Key header or externalId query parameter or JSON body field. If more than one is provided, the header wins. Duplicate calls with the same key return the original delivery and do not queue more runs.
Troubleshooting
| Response | Cause |
|---|---|
401 | The webhook ID or secret is invalid. |
403 | The webhook is disabled. |
400 | The JSON body is malformed or a supported field has an invalid type or empty value. |
422 | targetUrl is not an absolute http or https URL, billing blocks enqueueing, or the target cannot run. |