markdown · 3061 bytes Raw Blame History

API overview

shithub exposes a small REST API at /api/v1/. The user-facing API is PAT-authenticated, JSON-bodied, and CSRF-exempt. The Actions runner API under the same prefix uses runner registration tokens plus per-job JWTs instead of PATs.

Status. The API is intentionally narrow today. Endpoints currently shipped: GET /api/v1/user, the /api/v1/repos/{owner}/{repo}/check-runs family, and the /api/v1/user/starred* stars endpoints. Other sections of this reference (Issues, Pull requests, Webhooks, etc.) describe the planned shape and will land in subsequent sprints. Pages that document planned-only endpoints carry a banner.

Authentication

Every API request requires a personal access token. See Personal access tokens for how to create one. Runner endpoints documented in Actions runner API are the exception; they reject PATs and require runner credentials.

Authorization: Bearer shp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Authorization: token shp_… is also accepted as a synonym.

A request with no Authorization header — or with an invalid / expired / revoked PAT — returns 401 Unauthorized with:

{"error": "unauthenticated"}

A request whose PAT lacks the scope a route requires returns 403 Forbidden with:

{"error": "insufficient scope"}

Scopes

Every route declares the scope(s) a token must hold. See scopes table.

Scopes are grants only — a token cannot do something the underlying user cannot. Holding repo does not let a token push to a repo the user has no access to.

Conventions

  • Base URL: https://<your-instance>/api/v1/
  • Content type: application/json; charset=utf-8 for request bodies and responses.
  • Error responses: {"error": "<short message>"} with a conventional HTTP status.
  • Cache-Control: every API response sets no-store.
  • Pagination: list endpoints accept ?per_page= (default 30, max 100) and return a Link: header with next, prev, first, last URLs (RFC 5988). Cursor pagination on hot lists uses ?cursor=… and returns the next cursor in the Link: header.
  • Body cap: request bodies are capped at 256 KiB. Larger payloads return 413.
  • Rate limits: every response includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers (Unix timestamp). Exceeding the limit returns 429.

Versioning

The path prefix /api/v1/ is the version. Backwards-incompatible changes will land under /api/v2/. Additions (new endpoints, new fields on responses) are not breaking and land under v1.

Date format

All timestamps are RFC 3339 UTC: 2026-05-09T16:30:00Z.

ID stability

Numeric IDs are stable for the life of the row; reusing a name slot doesn't reuse the ID. URLs that take a {owner} and {repo} will redirect after a rename — but external callers should prefer numeric IDs where the API exposes them.

View source
1 # API overview
2
3 shithub exposes a small REST API at `/api/v1/`. The user-facing API is
4 PAT-authenticated, JSON-bodied, and CSRF-exempt. The Actions runner API
5 under the same prefix uses runner registration tokens plus per-job JWTs
6 instead of PATs.
7
8 > **Status.** The API is intentionally narrow today. Endpoints
9 > currently shipped: `GET /api/v1/user`, the
10 > `/api/v1/repos/{owner}/{repo}/check-runs` family, and the
11 > `/api/v1/user/starred*` stars endpoints. Other sections of this
12 > reference (Issues, Pull requests, Webhooks, etc.) describe the
13 > **planned** shape and will land in subsequent sprints. Pages
14 > that document planned-only endpoints carry a banner.
15
16 ## Authentication
17
18 Every API request requires a personal access token. See
19 [Personal access tokens](../user/personal-access-tokens.md) for
20 how to create one. Runner endpoints documented in
21 [Actions runner API](actions-runner.md) are the exception; they reject
22 PATs and require runner credentials.
23
24 ```
25 Authorization: Bearer shp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
26 ```
27
28 `Authorization: token shp_…` is also accepted as a synonym.
29
30 A request with no `Authorization` header — or with an invalid /
31 expired / revoked PAT — returns `401 Unauthorized` with:
32
33 ```json
34 {"error": "unauthenticated"}
35 ```
36
37 A request whose PAT lacks the scope a route requires returns
38 `403 Forbidden` with:
39
40 ```json
41 {"error": "insufficient scope"}
42 ```
43
44 ## Scopes
45
46 Every route declares the scope(s) a token must hold. See
47 [scopes table](../user/personal-access-tokens.md#scopes).
48
49 Scopes are **grants only** — a token cannot do something the
50 underlying user cannot. Holding `repo` does not let a token push
51 to a repo the user has no access to.
52
53 ## Conventions
54
55 - **Base URL:** `https://<your-instance>/api/v1/`
56 - **Content type:** `application/json; charset=utf-8` for
57 request bodies and responses.
58 - **Error responses:** `{"error": "<short message>"}` with a
59 conventional HTTP status.
60 - **Cache-Control:** every API response sets `no-store`.
61 - **Pagination:** list endpoints accept `?per_page=` (default 30,
62 max 100) and return a `Link:` header with `next`, `prev`,
63 `first`, `last` URLs (RFC 5988). Cursor pagination on hot lists
64 uses `?cursor=…` and returns the next cursor in the `Link:`
65 header.
66 - **Body cap:** request bodies are capped at 256 KiB. Larger
67 payloads return `413`.
68 - **Rate limits:** every response includes `X-RateLimit-Limit`,
69 `X-RateLimit-Remaining`, and `X-RateLimit-Reset` headers (Unix
70 timestamp). Exceeding the limit returns `429`.
71
72 ## Versioning
73
74 The path prefix `/api/v1/` is the version. Backwards-incompatible
75 changes will land under `/api/v2/`. Additions (new endpoints, new
76 fields on responses) are not breaking and land under v1.
77
78 ## Date format
79
80 All timestamps are RFC 3339 UTC: `2026-05-09T16:30:00Z`.
81
82 ## ID stability
83
84 Numeric IDs are stable for the life of the row; reusing a name
85 slot doesn't reuse the ID. URLs that take a `{owner}` and `{repo}`
86 will redirect after a rename — but external callers should
87 prefer numeric IDs where the API exposes them.