Events / activity feed
Read-only activity feed over the domain_events table. Mirrors
GitHub's /repos/{o}/{r}/events and /users/{username}/events
endpoints.
Endpoints
GET /api/v1/repos/{owner}/{repo}/events[?page=&per_page=]
GET /api/v1/users/{username}/events[?page=&per_page=]
Both are paginated; Link: headers emit next/prev only
(no last) since domain_events is append-only and high-churn
— we don't compute a cheap total count.
Auth & visibility
| Endpoint | Scope | Visibility |
|---|---|---|
| repo feed | repo:read (gates on ActionRepoRead) |
All events for the repo, including non-public rows |
| user feed | user:read |
Only events flagged public=true |
The user feed is intentionally narrow — it matches gh, which
never surfaces private-repo activity on a public user feed. A
private push by alice into a private repo will not appear on
/users/alice/events even when alice herself is the caller.
Event shape
{
"id": 7142,
"kind": "pushed",
"public": true,
"actor_id": 42,
"repo_id": 17,
"source": { "kind": "repo", "id": 17 },
"payload": { "ref": "refs/heads/trunk", "commits": 3 },
"created_at": "2026-05-12T18:00:00Z"
}
kindis the canonical event name (pushed,forked,starred,repo_created,issued,commented, …). The vocabulary is open-ended; clients should pass through unknown kinds rather than 4xx.payloadis opaque JSON whose shape varies by kind. Treat it as a free-form object; don't depend on specific keys unless documented elsewhere.source.{kind,id}ties the event back to the entity it was fired from (most commonly the repo itself; for issue/PR-level events, the issue or pull row id).
Errors
404— repo not visible / user doesn't exist.403— PAT lacks the required scope.
View source
| 1 | # Events / activity feed |
| 2 | |
| 3 | Read-only activity feed over the `domain_events` table. Mirrors |
| 4 | GitHub's `/repos/{o}/{r}/events` and `/users/{username}/events` |
| 5 | endpoints. |
| 6 | |
| 7 | ## Endpoints |
| 8 | |
| 9 | ``` |
| 10 | GET /api/v1/repos/{owner}/{repo}/events[?page=&per_page=] |
| 11 | GET /api/v1/users/{username}/events[?page=&per_page=] |
| 12 | ``` |
| 13 | |
| 14 | Both are paginated; `Link:` headers emit `next`/`prev` only |
| 15 | (no `last`) since `domain_events` is append-only and high-churn |
| 16 | — we don't compute a cheap total count. |
| 17 | |
| 18 | ## Auth & visibility |
| 19 | |
| 20 | | Endpoint | Scope | Visibility | |
| 21 | |----------|-------|------------| |
| 22 | | repo feed | `repo:read` (gates on `ActionRepoRead`) | All events for the repo, including non-public rows | |
| 23 | | user feed | `user:read` | **Only** events flagged `public=true` | |
| 24 | |
| 25 | The user feed is intentionally narrow — it matches gh, which |
| 26 | never surfaces private-repo activity on a public user feed. A |
| 27 | private push by alice into a private repo will not appear on |
| 28 | `/users/alice/events` even when alice herself is the caller. |
| 29 | |
| 30 | ## Event shape |
| 31 | |
| 32 | ```json |
| 33 | { |
| 34 | "id": 7142, |
| 35 | "kind": "pushed", |
| 36 | "public": true, |
| 37 | "actor_id": 42, |
| 38 | "repo_id": 17, |
| 39 | "source": { "kind": "repo", "id": 17 }, |
| 40 | "payload": { "ref": "refs/heads/trunk", "commits": 3 }, |
| 41 | "created_at": "2026-05-12T18:00:00Z" |
| 42 | } |
| 43 | ``` |
| 44 | |
| 45 | - `kind` is the canonical event name (`pushed`, `forked`, |
| 46 | `starred`, `repo_created`, `issued`, `commented`, …). The |
| 47 | vocabulary is open-ended; clients should pass through unknown |
| 48 | kinds rather than 4xx. |
| 49 | - `payload` is opaque JSON whose shape varies by kind. Treat it |
| 50 | as a free-form object; don't depend on specific keys unless |
| 51 | documented elsewhere. |
| 52 | - `source.{kind,id}` ties the event back to the entity it was |
| 53 | fired from (most commonly the repo itself; for issue/PR-level |
| 54 | events, the issue or pull row id). |
| 55 | |
| 56 | ## Errors |
| 57 | |
| 58 | - `404` — repo not visible / user doesn't exist. |
| 59 | - `403` — PAT lacks the required scope. |