Azure DevOps integration
Two paths into ActivityLog from Azure DevOps:
- Service Hooks (webhooks) — recommended for operational events: code pushes, PRs, work items, builds, releases. Real-time per event.
- Event Grid — alternative for org-level admin events via Service Bus relay or custom topic. Same destination endpoint as webhooks.
Both land in a single ActivityLog system using one alw_… URL token.
Quick path — Service Hooks
1. Mint a webhook URL token
In ActivityLog portal → Systems → New System named devops (or your preferred name) → New Token → check URL token → pick 1825-day retention → Generate → copy.
Your full URL:
https://api.activitylog.com/api/v1/webhooks/alw_REPLACE_WITH_YOUR_TOKEN
See 53-ingest-webhooks.md for the underlying webhook contract.
2. Configure ADO Service Hooks
In your ADO project → Project Settings → Service hooks → + Create subscription. For each event type you want, repeat:
| Service | Trigger | Action URL |
|---|---|---|
| Web Hooks | Code pushed | https://api.activitylog.com/api/v1/webhooks/alw_REPLACE_WITH_YOUR_TOKEN |
| Web Hooks | Pull request created | same |
| Web Hooks | Pull request updated | same |
| Web Hooks | Work item created | same |
| Web Hooks | Work item updated | same |
| Web Hooks | Build completed | same |
| Web Hooks | Release deployment completed | same |
Settings on each subscription:
- Basic authentication: leave blank.
- Resource details to send: All.
- Messages to send: All.
- Detailed messages to send: All.
Click Test before saving — you should see HTTP 201 in the response.
3. Verify in ActivityLog
Trigger one of the events (push a commit, open a PR) and check the Messages page in the portal. The event should appear within a couple of seconds, tagged with type: "git.push" / pullrequest.created / etc.
Event types you'll see
Each ADO event becomes one Message. The type field captures the source event name.
| ADO event | ActivityLog type |
Notes |
|---|---|---|
| Code pushed | git.push |
One message per push |
| Pull request created | pullrequest.created |
Includes PR title, source/target branch in body |
| Pull request updated | pullrequest.updated |
Status changes, new commits |
| Pull request merged | pullrequest.merged |
Captured as an updated event with status |
| Work item created | workitem.created |
Includes ID, title, type, area path |
| Work item updated | workitem.updated |
Includes diff of changed fields |
| Build completed | build.complete |
Pipeline ref, result, queue/start/finish times |
| Release deployment | ms.vss-release.deployment-completed-event |
Environment, release name, result |
For the full catalogue with metadata keys per event, see ../../../ActivityLog-Integrations/DevOps/SPEC.md.
Storage mode
DevOps webhooks ship in Mode 2 (structured event payload) by default on Pro and Enterprise — the full 3–18 KB ADO-curated JSON payload is stored as-is in body. This preserves source-curated context (commit lists, PR descriptions, build pipeline refs) that would be lost if we re-projected.
On the Free tier, payloads are auto-projected down to ~1 KB lean metadata (event_type, actor, target, summary). The full payload is discarded — Free can't store 18 KB ADO payloads without blowing the 16 KB body cap. See 53-ingest-webhooks.md.
Event Grid alternative
If you have an Event Grid topic that already aggregates ADO events (some Fyin-internal setups do this for cross-subscription auditing), the same webhook URL accepts Event Grid's array-of-events format. No code change in the receiver — see ../Event-Grid-Ingest.md for the handshake details.
Audit log API (admin events)
Service Hooks don't cover org-level admin events (project creation, permission changes, policy changes). For those, the ADO Audit Log API is the canonical source. Pulling that into ActivityLog is not built today — tracked as a future integration. For now, customers who need admin-event audit pull via Azure Function or scheduled script and POST to the webhook URL.
Retries and idempotency
ADO retries failed webhook deliveries up to 25 times with exponential backoff. Our endpoint accepts the same (systemId, sourceEventId) collapse rule as native ingest, so retries land as no-ops (HTTP 201 returned with the original message id).
For ADO Service Hooks the canonical idempotency key is the event's id field (a GUID); our receiver derives sourceEventId from it automatically — you don't need to configure anything.
Subscription health monitoring
ADO silently disables a Service Hook after repeated failures (10 consecutive). If you see events dry up, check Project Settings → Service hooks → History tab for the affected subscription and re-enable / re-test.
Operator-facing: the DevOpsSubscriptionMonitor (planned) automates the re-enable. Tracked in the DevOps SPEC.
What's next
| Goal | Doc |
|---|---|
| Webhook endpoint behavior in detail | 53-ingest-webhooks.md |
| Full ADO event catalogue + metadata schema | ../../../ActivityLog-Integrations/DevOps/SPEC.md |
| Cross-source query: ADO + Teams + Claude together | 60-query-api.md |
Troubleshooting
ADO subscription test shows 404 webhook-not-found. The token in the URL is wrong or revoked. Re-copy from the portal Systems → token detail page.
Events stop appearing after a stretch of working fine. Check the Service Hook history in ADO — most likely the subscription was disabled after a transient outage. Re-enable and re-test.
I want PR comment bodies and commit diffs. Not stored today (Mode 3 territory — we'd need to negotiate the body-cap and PII tradeoffs). If you have a use case, file a ticket.