Outgoing webhooks
Send ADO Pilot review and billing events to your own HTTPS endpoint — configure the URL, choose events, and validate delivery with a test send.
Last updated
Send ADO Pilot events — review completions, credit alerts, and plan renewals — to your own HTTPS endpoint so you can fan them out to Slack, PagerDuty, an analytics warehouse, or any custom automation.
Requirements
- HTTPS only. ADO Pilot refuses to save plain
http://URLs, and refuses to deliver to non-HTTPS endpoints even if you bypass the form. - Public reachability. Your endpoint must accept connections from the public internet — ADO Pilot does not support delivering to private or internal network addresses.
- Five-second response budget. Your handler must respond
2xxwithin 5 seconds. Anything slower is treated as a failure and is not retried. - Org-admin role. Only org admins can save webhook settings or send a test request.
Configure the endpoint
Webhook configuration isn't exposed in the dashboard yet. Once it ships, you'll configure it under Settings then Notifications, where you'll set your endpoint and choose which events to deliver (see the table below). We'll publish the exact steps here when that UI is live.
A URL that doesn't parse as https:// will be rejected rather than saved — see Requirements above.
Supported events
ADO Pilot will emit five outgoing webhook events once webhook delivery ships. Each event fires once per occurrence — there are no duplicate deliveries for the same trigger.
| Event | Triggered when |
|---|---|
review.completed | A pull request review finishes and a PASS, ADVISORY, or FAIL status check has been posted. |
review.failed | A review enters a terminal failure state (for example, an internal processing error or quota exhaustion). |
credit.low | Your organization's review credit (RC) consumption first crosses 80% of the plan's included RCs. |
credit.exhausted | Your organization runs out of RCs — either the hard-block quota is hit or the auto-overage cap is hit. |
plan.renewed | Stripe processes a subscription renewal: RCs reset and a new billing period begins. |
Test your endpoint
A test-send control is planned for the dashboard, but it isn't available yet. Once it ships, triggering it will send a single request to your saved endpoint.
The test payload is intentionally minimal:
{
"event": "review.completed.test",
"orgId": "your-org-id",
"timestamp": "2026-05-05T14:30:00.000Z",
"test": true
}
If your endpoint replies 2xx within 5 seconds, the dashboard will show Delivered (HTTP NNN) with the status code your endpoint returned — for example Delivered (HTTP 200) or Delivered (HTTP 204). Anything else will surface as an inline error — connection refused, TLS failure, timeout, or an HTTP 4xx/5xx from your handler.
Production payloads
Each event below shows a representative JSON body and a field reference. Every field on every payload is provisional pending PM/eng confirmation — see the warning at the top of this page.
review.completed
Fires when a review reaches a terminal verdict.
{
"event": "review.completed",
"orgId": "org-12345",
"timestamp": "2026-05-05T14:35:22.000Z",
"reviewId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"prId": 42,
"projectId": "ado-proj-guid-or-slug",
"repositoryId": "ado-repo-guid-or-slug",
"verdict": "ADVISORY",
"findingCounts": {
"blocker": 0,
"warning": 2,
"suggestion": 5
},
"durationMs": 180000,
"creditsUsed": 1
}
| Field | Type | Notes |
|---|---|---|
event | string | Always "review.completed". |
orgId | string | Your ADO Pilot organization ID. |
timestamp | string | ISO 8601 UTC; emitted when the review was finalized. |
reviewId | string | Unique review identifier; correlates to the PR thread in ADO. |
prId | number | Pull request number in the ADO repository. |
projectId | string | ADO project GUID or slug. |
repositoryId | string | ADO repository GUID or slug. |
verdict | string | "PASS", "ADVISORY", or "FAIL". |
findingCounts | object | Counts of blocker, warning, and suggestion findings. |
durationMs | number | Milliseconds from queued to completed. |
creditsUsed | number | RCs charged for this review. |
review.failed
Fires when a review enters a terminal failure state — for example, an internal processing error, tenant-inactive status, or quota exhaustion.
{
"event": "review.failed",
"orgId": "org-12345",
"timestamp": "2026-05-05T14:40:10.000Z",
"reviewId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"prId": 42,
"projectId": "ado-proj-guid-or-slug",
"repositoryId": "ado-repo-guid-or-slug",
"errorType": "quota_exceeded",
"errorMessage": "Review quota exhausted — upgrade your plan to continue.",
"durationMs": 5000
}
| Field | Type | Notes |
|---|---|---|
event | string | Always "review.failed". |
orgId | string | Your organization ID. |
timestamp | string | ISO 8601 UTC at the moment of failure. |
reviewId | string | Unique review identifier. |
prId | number | Pull request number. |
projectId | string | ADO project GUID or slug. |
repositoryId | string | ADO repository GUID or slug. |
errorType | string | Machine-readable category, e.g. "quota_exceeded", "auth_error", "rate_limit". |
errorMessage | string | Human-readable description; safe to surface in alerts. |
durationMs | number | Milliseconds from queued to failure. |
credit.low
Fires once per billing period the first time RC consumption crosses 80% of the included plan credits.
{
"event": "credit.low",
"orgId": "org-12345",
"timestamp": "2026-05-05T14:45:33.000Z",
"usagePercent": 82,
"rcConsumed": 410,
"rcIncluded": 500,
"billingPeriod": "2026-05"
}
| Field | Type | Notes |
|---|---|---|
event | string | Always "credit.low". |
orgId | string | Your organization ID. |
timestamp | string | ISO 8601 UTC at the moment the threshold was crossed. |
usagePercent | number | RC consumption as a percentage of rcIncluded. |
rcConsumed | number | RCs consumed this period (includes any overage already accrued). |
rcIncluded | number | RCs included in your current plan tier. |
billingPeriod | string | YYYY-MM for the current Stripe billing period. |
credit.exhausted
Fires when the organization runs out of usable RCs — either the hard-block quota is hit, or the auto-overage cap is reached.
{
"event": "credit.exhausted",
"orgId": "org-12345",
"timestamp": "2026-05-05T14:50:01.000Z",
"rcConsumed": 500,
"rcIncluded": 500,
"overageCapReached": true,
"overageCap": 100,
"billingPeriod": "2026-05"
}
| Field | Type | Notes |
|---|---|---|
event | string | Always "credit.exhausted". |
orgId | string | Your organization ID. |
timestamp | string | ISO 8601 UTC at the moment the limit was hit. |
rcConsumed | number | Total RCs used this period. |
rcIncluded | number | RCs included in your plan. |
overageCapReached | boolean | true if the auto-overage cap was hit; false if the hard-block quota ran out. |
overageCap | number | The cap configured in Billing; 0 for hard-block plans. |
billingPeriod | string | YYYY-MM. |
plan.renewed
Fires when Stripe processes a subscription renewal — RCs reset, and a new billing period begins.
{
"event": "plan.renewed",
"orgId": "org-12345",
"timestamp": "2026-05-05T15:00:00.000Z",
"planTier": "team",
"rcIncluded": 400,
"billingPeriodStart": "2026-06-05",
"billingPeriodEnd": "2026-07-05",
"invoiceUrl": "https://invoice.stripe.com/i/acct_xxx/inv_yyy"
}
| Field | Type | Notes |
|---|---|---|
event | string | Always "plan.renewed". |
orgId | string | Your organization ID. |
timestamp | string | ISO 8601 UTC when the renewal was processed. |
planTier | string | "starter", "team", "business", or "enterprise". |
rcIncluded | number | RCs included in the new billing period. |
billingPeriodStart | string | ISO YYYY-MM-DD; first day of the new period. |
billingPeriodEnd | string | ISO YYYY-MM-DD; last day of the new period. |
invoiceUrl | string | HTTPS link to the Stripe-hosted invoice. |
Delivery semantics
- ADO Pilot sends each event once. There are no automatic retries on failure.
- If your endpoint is unreachable, slow, or returns a non-
2xxstatus, the event is dropped — it is not queued for later replay. - Monitor your endpoint health and alert on consecutive failures so you notice silently-broken integrations.
Troubleshooting
Saving an endpoint URL fails. A URL that isn't a well-formed https:// address will be rejected — paste a full URL that starts with https://. (An empty value is allowed and clears the configured endpoint.)
The test reports a 5-second timeout. Your endpoint accepted the connection but did not respond in time. Check downstream services your handler depends on; consider returning 2xx immediately and processing asynchronously.
The test returns an HTTP 4xx or 5xx. Your endpoint received the request but rejected it. Inspect your server logs — common causes are missing route handlers, body-parser misconfiguration, or auth middleware blocking unauthenticated requests.
Summary
Outgoing webhooks will let you forward five ADO Pilot events — review.completed, review.failed, credit.low, credit.exhausted, and plan.renewed — to any HTTPS endpoint you control, once the feature ships (see the callout at the top of this page for current status). Configuration will live under Settings then Notifications, and a test-send control will let you verify delivery before you depend on it. Non-HTTPS URLs will be rejected outright. Each event will fire once with a 5-second response budget and no retries, so plan to monitor your endpoint and alert on failures. Payload schemas on this page are provisional — pin to a published version once one exists, and watch the changelog for field renames or additions before general availability.