Getting started
From zero to a build card in your Teams channel in about five minutes. Install the app, pick where notifications land, create a subscription, and paste one URL into your CI/CD platform. That's the whole loop.
Your CI/CD platform sends a webhook to a private ingest URL we give you. We normalize it into a rich Adaptive Card and deliver it to the destination on your subscription — a Teams channel, a person's DM, or an incoming-webhook URL. One subscription = one pipeline → one place.
What you'll need
- A Microsoft Teams account, and a Teams admin to approve the app for your org (a one-time consent).
- A CI/CD, GitOps, or observability tool you can add a webhook to — GitHub Actions, GitLab, Jenkins, Azure DevOps, Bitbucket, CircleCI, Buildkite, Argo CD, TeamCity, Datadog, or anything that can POST JSON.
- Two minutes of that platform's admin's time to paste in a URL.
Step 1 · Install the app in Teams
Open Teams → Apps → search Per My Last Webhook → Add. (Or use the install link on our homepage.)
The first person from your organization to add it triggers a one-time admin consent — your Teams admin approves the app for the tenant. After that, anyone in your org can use it.
Not an admin? Add the app anyway — Teams will prompt your admin to approve it, or you can send them the consent link the app shows you.
Step 2 · Choose where cards go
Every subscription delivers to exactly one destination. Pick the one that fits:
In the channel, open … → Manage channel → Connectors/Apps (or @mention the bot) to add Per My Last Webhook. Once it's in the channel it shows up in the subscription form's channel picker. For a DM destination, the person just needs to open a 1:1 chat with the bot once.
Step 3 · Create your first subscription
Open the app's Subscriptions tab → New subscription.
Give it a name, pick your platform, and choose the destination from Step 2.
Save. You'll get an ingest URL with a secret key baked in — it looks like:
https://api.permylastwebhook.com/api/ingest/<org>/<sub>/github?key=<secret>
The key is shown once. Copy the full URL immediately. Lost it? Use Rotate key on the subscription to mint a fresh one (and update your platform).
Step 4 · Connect your platform
Paste that ingest URL into your platform's webhook settings. Jump to yours:
GitHub Actions
- Repo → Settings → Webhooks → Add webhook.
- Payload URL: your ingest URL. Content type:
application/json. - Events: Let me select individual events → check Workflow runs only.
- Add webhook. Prefer org-wide? Set it at Org → Settings → Webhooks instead.
GitLab
- Project (or Group) → Settings → Webhooks.
- URL: your ingest URL. Triggers: Pipeline events and Deployment events.
- Keep SSL verification on → Add webhook.
Jenkins
- Install the Notification Plugin (Manage Plugins).
- Job → Configure → Job Notifications → Add Endpoint.
- Format JSON, Protocol HTTP, Event Job Finalized, URL your ingest URL. Save.
Azure DevOps
- Project → Project Settings → Service Hooks → New Subscription → Web Hooks.
- Trigger: Run state changed (YAML) or Build completed (classic).
- URL: your ingest URL. Optionally filter by pipeline/branch/state. Save.
Bitbucket Pipelines
- Repo → Repository settings → Webhooks → Add webhook.
- URL: your ingest URL. Triggers → Build: Commit status created and updated.
CircleCI
- Project → Project Settings → Webhooks.
- Webhook URL: your ingest URL. Events: workflow-completed (recommended).
Buildkite
- Organization settings → Notification services → Add Webhook.
- Webhook URL: your ingest URL. Pick the build events you want delivered.
Argo CD
- Create the subscription with platform Argo CD and copy the ingest URL.
- In Argo CD's
argocd-notifications-cm, add a webhook service pointing at that URL plus a template that POSTs the app's sync/health status. - Subscribe your Applications to a trigger (e.g. on-deploy). Full config + template in the platform reference.
TeamCity
- Create the subscription with platform TeamCity and copy the ingest URL.
- Add a webhook to the build config (native Webhooks feature or the tcWebHooks plugin) with a JSON template posting the build name, number, result, branch, and commit. Template in the platform reference.
Datadog
- Create the subscription with platform Datadog and copy the ingest URL.
- Datadog → Integrations → Webhooks → add the URL with a JSON payload (title, alert status, link), then reference
@webhook-<name>in your monitor. Payload in the platform reference.
Grafana
- Create the subscription with platform Grafana and copy the ingest URL.
- Grafana → Alerting → Contact points → add a Webhook contact point with that URL (no template needed), then attach it to a notification policy. Reference.
Drone CI
- Create the subscription with platform Drone and copy the ingest URL.
- Add a Drone webhook (global or per-repo) pointing at that URL — the payload is normalized automatically. Reference.
Sentry
- Create the subscription with platform Sentry and copy the ingest URL.
- Sentry → Alerts → create an alert rule with a webhook action posting title + level + project to that URL. Reference.
PagerDuty
- Create the subscription with platform PagerDuty and copy the ingest URL.
- PagerDuty → Integrations → Generic Webhooks (v3) → point a new webhook at that URL and subscribe to incident events. Reference.
Prometheus Alertmanager
- Create the subscription with platform Alertmanager and copy the ingest URL.
- Add a
webhook_configsreceiver withurl= that URL and route alerts to it (no template). Reference.
Octopus Deploy
- Create the subscription with platform Octopus and copy the ingest URL.
- Octopus → Configuration → Subscriptions → add a deployment-event subscription posting project/environment/release/state to that URL. Reference.
Anything else (generic)
Any tool that can POST JSON works via the generic platform. Create the subscription
with a small field mapping (which JSON paths map to title / status / link), then point
the tool's webhook at your ingest URL. Datadog monitors, custom scripts, home-grown CI — all fair game.
GitHub, GitLab, CircleCI and Buildkite can sign payloads with a shared secret for an extra integrity check. It's optional — the secret key in your ingest URL already authenticates every call. See the platform reference for the signing setup.
Step 5 · Fire a test card
Don't want to wait for a real build? On the subscription, click Test — it sends a synthetic card straight through your delivery path so you can confirm the wiring. Then trigger a real pipeline run and watch the card land, live.
Jump to Troubleshooting — 90% of the time it's the channel not having the bot, a filter hiding the event, or a webhook pointed at the wrong URL.
Next steps
Troubleshooting
The card never arrived
- Channel destination: is the bot actually in that channel? Re-add it, then re-pick it on the subscription.
- Status filter: a filter or quiet-hours window may be dropping the event by design. Loosen it and re-test.
- Wrong URL / key: confirm the platform's webhook uses the exact ingest URL. Rotated the key? Update the platform.
- Platform event type: we accept specific events (e.g. GitHub Workflow runs only). Sending others returns an error.
Can't sign in / "not installed" / access denied
Open the app's Diagnostics tab and click Run checks. It walks the exact sign-in gate — token validity → tenant consent → your admin role — and tells you which step failed and how to fix it (with the matching AADSTS code for consent/redirect issues).
"This person hasn't added the app" on a DM subscription
DMs need the recipient to have opened a 1:1 chat with the bot once (that's how Teams lets a bot message them). Ask them to search for the app in Teams and say "hi" — they'll then appear in the DM picker.
Email hello@permylastwebhook.com with your org name and what you tried — we'll get you unblocked.