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-runsfamily, 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-8for 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 aLink:header withnext,prev,first,lastURLs (RFC 5988). Cursor pagination on hot lists uses?cursor=…and returns the next cursor in theLink: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, andX-RateLimit-Resetheaders (Unix timestamp). Exceeding the limit returns429.
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. |