
Handle Origin repository webhooks
Subscribe to repository.created, repository.deleted, repository.pushed, and repository.metadata.updated. Official reference: llms-full.txt → Events. OpenAPI: RepositoryCreatedWebhookPayload, RepositoryDeletedWebhookPayload, RepositoryPushWebhookPayload, RepositoryMetadataUpdatedWebhookPayload.
Origin is in Early Beta and subject to change. Subscribe when you configure the app's webhook events list. Subscribing needs repository:metadata:read for created / deleted / metadata.updated (and the push event per the Events table). Delivery uses the same signed envelope as other Origin webhooks.
Events
event.type |
When it fires |
|---|---|
repository.created |
A repository is created. |
repository.deleted |
A repository is deleted (product delete, or stopping sync on an inbound mirror). |
repository.pushed |
One or more refs change in a push on a native Origin repo or an outbound mirror. |
repository.metadata.updated |
A repository's default branch changes. |
Origin does not deliver repository.pushed for repositories it mirrors in from GitHub (GitHub owns those pushes). repository.deleted is delivered for a GitHub-mirrored repo when Cursor-side sync stops.
Payload fields
repository.created
| Field | Meaning |
|---|---|
repository |
Full created Repo snapshot (id, name, fullName, owner, defaultBranch, cloneUrl, timestamps) |
repository.deleted
| Field | Meaning |
|---|---|
repository |
Reference only (id, name, owner) — the repo no longer resolves through the API |
deletedAt |
When the repository was deleted |
repository.pushed
| Field | Meaning |
|---|---|
repository |
Repository reference |
refUpdates |
Refs in this push (capped at 100), each with ref, before, after, created / deleted / forced, optional headCommit |
refUpdatesCount |
Total ref updates in the atomic push (may exceed refUpdates.length when capped) |
pushedAt |
When Origin observed the push |
pusher |
Principal that pushed; absent when Origin itself pushed (for example a merge advancing the base ref) |
repository.metadata.updated
| Field | Meaning |
|---|---|
repository |
Full post-write Repo snapshot (no delta, no updating actor) |
Sample repository.deleted event.payload:
{
"repository": {
"id": "repo_01k2ja2000e0080000000000q4",
"name": "rocket",
"owner": {
"slug": "acme",
"id": "ns_01k2ja2000e0080000000000p3",
"type": "team"
}
},
"deletedAt": "2026-08-03T08:15:00Z"
}
Sample repository.pushed event.payload:
{
"repository": {
"id": "repo_01k2ja2000e0080000000000q4",
"name": "rocket",
"owner": {
"slug": "acme",
"id": "ns_01k2ja2000e0080000000000p3",
"type": "team"
}
},
"refUpdates": [
{
"ref": "refs/heads/add-telemetry",
"before": "5c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c0d",
"after": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4",
"created": false,
"deleted": false,
"forced": false,
"headCommit": {
"sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4",
"message": "Add launch telemetry"
}
}
],
"pushedAt": "2026-08-02T14:45:00Z",
"pusher": {
"user": {
"id": "user_01k2ja2000e0080000000000c3",
"email": "jane@acme.dev"
}
},
"refUpdatesCount": 1
}
Receiver tips
- Branch on
event.type. On deleted, drop local caches keyed byrepository.id— follow-up Get Repo calls will 404. - On metadata.updated, compare successive snapshots (or refetch Get Repo) to see what moved; the payload has no delta.
- On pushed, there is no commits array — use each
refUpdates[].headCommittip metadata, then fetch commits/contents as needed. - Keep the receiver answering within the 10-second delivery deadline.
Pitfalls
- Do not expect
repository.pushedon inbound GitHub mirrors; subscribe on GitHub for those pushes. - A merge that advances the base ref still delivers
repository.pushedwith nopusher. - Pull-request lifecycle events (
pull_request.created,head_ref.pushed, …) are a separate family from these repository events.