
Handle Origin installation webhooks
Origin always delivers the five installation.* events to the app itself. They do not appear in the app's selectable webhook events list. Official reference: llms-full.txt → Events. OpenAPI schemas: InstallationCreatedWebhookPayload, InstallationUpdatedWebhookPayload, InstallationSuspendedWebhookPayload, InstallationUnsuspendedWebhookPayload, InstallationDeletedWebhookPayload.
Origin is in Early Beta and subject to change. Delivery uses the same signed envelope as other Origin webhooks.
Events
event.type |
When it fires |
|---|---|
installation.created |
The app is installed on a namespace. |
installation.updated |
Scopes, repository selection, or the owner namespace slug change. |
installation.suspended |
The installation is suspended. |
installation.unsuspended |
A suspended installation is restored. |
installation.deleted |
The app is uninstalled. |
Shared payload fields
| Field | Meaning |
|---|---|
installation |
Snapshot matching Get App Installation field names |
installation.id |
Installation id (inst_…) |
installation.appId |
Same value as app.id |
installation.target |
Owner namespace (slug, id, type) |
installation.repoSelectionMode |
How repositories are selected |
installation.repositories |
Selected repository references (may include mirrors) |
installation.scopes |
Granted scopes |
installation.repositoriesCount |
Count of selected repositories |
installation.installedBy |
User who installed (or last re-consented); may be omitted if the user record is unreadable |
installation.createdAt / installation.updatedAt |
Timestamps (updatedAt on created/updated) |
installation.suspendedAt |
Set while suspended; omitted while active |
installation.deletedAt |
Present on installation.deleted snapshots |
app |
id and optional displayName |
Sample installation.created event.payload:
{
"installation": {
"id": "inst_01k2ja2000e0080000000000b2",
"appId": "app_01k2ja2000e0080000000000a1",
"target": {
"slug": "acme",
"id": "ns_01k2ja2000e0080000000000p3",
"type": "team"
},
"repoSelectionMode": "selected",
"repositories": [
{
"id": "repo_01k2ja2000e0080000000000q4",
"name": "rocket",
"owner": {
"slug": "acme",
"id": "ns_01k2ja2000e0080000000000p3",
"type": "team"
}
}
],
"scopes": [
"repository:contents:read",
"repository:pull_requests:read"
],
"repositoriesCount": 1,
"createdAt": "2026-08-01T09:30:00Z",
"updatedAt": "2026-08-01T09:30:00Z",
"installedBy": {
"id": "user_01k2ja2000e0080000000000c3",
"email": "jane@acme.dev"
}
},
"app": {
"id": "app_01k2ja2000e0080000000000a1",
"displayName": "CI Status Bot"
}
}
Receiver tips
- Verify the signature, then branch on
event.type. - On
created/updated, persistinstallation.id,target,scopes, and the repository list before minting installation access tokens. - On
suspended, stop scheduling work that needs that installation; onunsuspended, resume. - On
deleted, drop stored tokens for that installation — Origin invalidates them beforeexpiresAt. - Mirrored repositories may appear in the selected arrays; delivery does not widen what the installation can call on those mirrors.
Pitfalls
- Do not expect to toggle these five events in Create App / Update App
events— Origin always sends them. - Treat selected repository arrays as the set your app can reach, then still honor mirror read-only rules on the REST and Git surfaces.
- Keep the receiver answering within the 10-second delivery deadline.