Azure DevOps integration

Two paths into ActivityLog from Azure DevOps:

  1. Service Hooks (webhooks) — recommended for operational events: code pushes, PRs, work items, builds, releases. Real-time per event.
  2. 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 retentionGenerate → 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.