Docs / Platform reference

Platform reference

For every platform the recipe is the same: create a subscription, copy its ingest URL, and paste it into the platform's webhook config. This page has the exact events we accept, the setup steps, optional signing, and how each platform's states map to card statuses.

Optional signing

The secret key in your ingest URL already authenticates every call. Several platforms can additionally sign the payload with a shared secret for integrity — that secret is configured by whoever operates your deployment. It's optional and called out per platform below.

GitHub Actions

Accepts: the workflow_run event only (other events are rejected).

  1. Repo → Settings → Webhooks → Add webhook.
  2. Payload URL: your ingest URL. Content type: application/json.
  3. EventsLet me select individual events → check Workflow runs only.
  4. Add webhook. For all repos at once, configure it at Org → Settings → Webhooks.

Signing (optional): set a webhook secret; we verify X-Hub-Signature-256.

action + conclusion              → status
requested / in_progress          → started
completed + success/neutral/skip → success
completed + failure/timed_out    → failure
completed + cancelled            → cancelled

GitLab

Accepts: Pipeline events (object_kind: pipeline) and Deployment events.

  1. Project (or Group) → Settings → Webhooks.
  2. URL: your ingest URL. Triggers: Pipeline events + Deployment events.
  3. Keep SSL verification on → Add webhook. Group webhooks apply to all child projects.

Signing (optional): a secret token, sent verbatim in X-Gitlab-Token.

pipeline status              → status        deployment status → status
pending / running            → started        running           → deployment_started
success                      → success        success           → deployment_success
failed                       → failure        failed / canceled → deployment_failure
canceled / skipped / manual  → cancelled

Jenkins

Accepts: the Notification Plugin payload (the de-facto Jenkins standard).

  1. Install the Notification Plugin (Manage Plugins).
  2. Job → Configure → Job Notifications → Add Endpoint.
  3. Format JSON · Protocol HTTP · Event Job Finalized (or All Events for started cards) · URL your ingest URL. Save.
phase / status                 → status
STARTED / QUEUED               → started
FINALIZED + SUCCESS            → success
FINALIZED + UNSTABLE           → unstable
FINALIZED + ABORTED            → cancelled
FINALIZED + FAILURE/NOT_BUILT  → failure

Azure DevOps

Accepts: run-state-changed (YAML pipelines) and build.complete (classic).

  1. Project → Project Settings → Service Hooks → New Subscription → Web Hooks.
  2. Trigger: Run state changed (YAML) or Build completed (classic). Optionally filter by pipeline/branch/state.
  3. URL: your ingest URL. Save.
state / result                       → status
inProgress / queued / notStarted     → started
result=succeeded                     → success
result=partiallySucceeded            → unstable
result=canceled                      → cancelled
any other terminal result            → failure

Bitbucket Pipelines

Accepts: repo:commit_status_created / updated events.

  1. Repo → Repository settings → Webhooks → Add webhook.
  2. URL: your ingest URL. Triggers → Build: Commit status created + updated.

Bitbucket Cloud doesn't sign payloads — the ingest-URL key is the authentication on that path.

commit_status.state → status
INPROGRESS          → started
SUCCESSFUL          → success
FAILED              → failure
STOPPED             → cancelled

CircleCI

Accepts: v2 workflow-completed (preferred) and job-completed.

  1. Project → Project Settings → Webhooks.
  2. Webhook URL: your ingest URL. Events: workflow-completed.

Signing (optional): a secret; we verify Circleci-Signature: v1=… (HMAC-SHA256).

status                            → status
success                           → success
failed / error / unauthorized     → failure
canceled / not_run / on_hold      → cancelled

Buildkite

Accepts: build.scheduled/started/running/finished events.

  1. Organization settings → Notification services → Add Webhook.
  2. Webhook URL: your ingest URL. Pick the build events you want.

Signing (optional): a token verified against BUILDKITE_WEBHOOK_TOKEN.

event / build.state                       → status
scheduled / started / running             → started
passed                                    → success
failed                                    → failure
canceled / skipped / not_run / blocked    → cancelled

Argo CD

Accepts: a purpose-built notification payload (Argo CD notifications are template-driven, so you define the body). Argo CD is a CD tool, so events render as deployment cards.

In your argocd-notifications-cm ConfigMap, add a webhook service, a template that POSTs the app's status, and a trigger — then annotate the Applications you want notified:

service.webhook.pmlw: |
  url: <your ingest URL>
  headers: [{ name: Content-Type, value: application/json }]

template.pmlw-deploy: |
  webhook:
    pmlw:
      method: POST
      body: |
        {
          "app": "{{.app.metadata.name}}",
          "project": "{{.app.spec.project}}",
          "syncStatus": "{{.app.status.sync.status}}",
          "healthStatus": "{{.app.status.health.status}}",
          "operationPhase": "{{.app.status.operationState.phase}}",
          "revision": "{{.app.status.sync.revision}}",
          "appUrl": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}"
        }

trigger.on-deploy: |
  - when: app.status.operationState.phase in ['Succeeded','Failed','Error','Running']
    send: [pmlw-deploy]

Then on each Application: notifications.argoproj.io/subscribe.on-deploy.pmlw: "".

operationPhase / health / sync    → status
Succeeded                         → deployment_success
Failed / Error                    → deployment_failure
Running / Terminating             → deployment_started
(no phase) Degraded / Missing     → deployment_failure
(no phase) Progressing / Suspended→ deployment_started
(no phase) Healthy + Synced       → deployment_success

TeamCity

Accepts: a purpose-built JSON payload. TeamCity webhooks — the native Webhooks build feature or the tcWebHooks plugin — are template-driven, so you map TeamCity build parameters into these fields:

  1. On the build configuration, add a webhook (native feature or tcWebHooks) with URL = your ingest URL.
  2. Set the payload template to produce this JSON:
{
  "buildName": "<project> :: <build config>",
  "buildNumber": "128",
  "buildResult": "success",       // success | failure | running | canceled | unstable
  "branch": "main",
  "commitSha": "<vcs revision>",
  "buildUrl": "<server>/build/<id>"
}
buildResult      → status
success          → success
running          → started
unstable         → unstable
canceled         → cancelled
failure / error  → failure

Datadog

Accepts: a purpose-built JSON payload built from Datadog's webhook template variables. Datadog is observability, so a monitor alert renders as a status card.

  1. Datadog → Integrations → Webhooks → New. URL = your ingest URL.
  2. Set the Payload to:
{
  "title": "$EVENT_TITLE",
  "alertStatus": "$ALERT_STATUS",
  "priority": "$PRIORITY",
  "tags": "$TAGS",
  "eventUrl": "$LINK",
  "id": "$ID",
  "date": "$DATE"
}
  1. In each monitor's notification message, add @webhook-<name> to fire it.
alertStatus      → status
Recovery / OK    → success
Warn / No Data   → unstable
Alert            → failure

Grafana

Accepts: the Grafana unified-alerting webhook payload — it's fixed, so no template is needed. status: firing → failure, resolved → success.

  1. Grafana → Alerting → Contact points → Add contact point → type Webhook.
  2. URL: your ingest URL. Save, then attach it to a notification policy.
status    → status
firing    → failure
resolved  → success

Drone CI

Accepts: Drone's build webhook payload — fixed, no template.

  1. Add a webhook (global via DRONE_WEBHOOK_ENDPOINT, or repo settings) → URL: your ingest URL.
build.status         → status
success              → success
running / pending    → started
killed / skipped     → cancelled
failure / error      → failure

Sentry

Accepts: a purpose-built JSON payload (Sentry's webhook shapes vary by integration, so you define the body in an alert rule's webhook action).

  1. Sentry → Alerts → Create Alert Rule → add a webhook / internal-integration action with your ingest URL.
  2. Send this JSON:
{
  "title": "<issue title>",
  "level": "error",          // fatal | error | warning | info
  "status": "unresolved",    // unresolved | resolved | ignored
  "project": "<project>",
  "environment": "production",
  "url": "<issue url>"
}
status / level             → status
status resolved            → success
status ignored             → cancelled
level warning              → unstable
fatal / error / (default)  → failure

PagerDuty

Accepts: the PagerDuty v3 generic-webhook payload (fixed — no template). Incident lifecycle maps onto a status.

  1. PagerDuty → Integrations → Generic Webhooks (v3) → New Webhook.
  2. Webhook URL: your ingest URL. Subscribe to incident events.
event_type / status       → status
incident.resolved         → success
incident.acknowledged     → started
incident.triggered / etc. → failure

Prometheus Alertmanager

Accepts: the Alertmanager webhook_configs payload (fixed — no template). status: firing → failure, resolved → success.

route:
  receiver: pmlw
receivers:
  - name: pmlw
    webhook_configs:
      - url: <your ingest URL>

Octopus Deploy

Accepts: a purpose-built JSON payload (Octopus subscription webhooks are event-category driven, so you shape the body). Octopus is a CD tool → deployment cards.

  1. Octopus → Configuration → Subscriptions → new subscription for deployment events, with a webhook to your ingest URL.
  2. Body:
{
  "project": "Web Storefront",
  "environment": "Production",
  "release": "2.3.0",
  "state": "Success",   // Success | Failed | Executing | Queued | Canceled
  "deploymentUrl": "<deployment url>"
}
state                       → status
Success                     → deployment_success
Executing / Queued          → deployment_started
Failed / TimedOut / Canceled→ deployment_failure

Generic JSON

Anything that can POST JSON works via the generic platform. When you create the subscription, supply a field mapping — declarative paths into the payload for title, status, link, summary, and optional facts, plus a statusMap that maps your raw status strings to success / failure / running / neutral. Then point the tool's webhook at your ingest URL. Great for Datadog monitors, custom scripts, or any CI we don't have a dedicated normalizer for yet.

Don't see your tool?

The generic platform covers most cases. Want a first-class normalizer for a tool we don't list yet? Tell us — it's a mechanical add and we prioritize by demand.

▣ StartPER MY LAST WEBHOOKC:\DOCS\PLATFORMSStatus: 200 OK