tenseleyflow/shithub / c1b73b6

Browse files

docs/api: document JSON error envelope, X-OAuth-Scopes, rate limits, meta

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
c1b73b679648f695821bdfa9689c38a61854211b
Parents
7f5534e
Tree
8a39993

1 changed file

StatusFile+-
M docs/public/api/overview.md 54 9
docs/public/api/overview.mdmodified
@@ -29,17 +29,30 @@ Authorization: Bearer shp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
29
 `Authorization: token shp_…` is also accepted as a synonym.
29
 `Authorization: token shp_…` is also accepted as a synonym.
30
 
30
 
31
 A request with no `Authorization` header — or with an invalid /
31
 A request with no `Authorization` header — or with an invalid /
32
-expired / revoked PAT — returns `401 Unauthorized` with:
32
+expired / revoked PAT — returns `401 Unauthorized` with the
33
+canonical JSON error envelope. The response also carries a
34
+`WWW-Authenticate: Bearer realm="shithub", error="invalid_token"`
35
+challenge so HTTP-aware clients can reauthenticate cleanly.
33
 
36
 
34
 ```json
37
 ```json
35
-{"error": "unauthenticated"}
38
+{"error": "invalid token"}
36
 ```
39
 ```
37
 
40
 
38
 A request whose PAT lacks the scope a route requires returns
41
 A request whose PAT lacks the scope a route requires returns
39
-`403 Forbidden` with:
42
+`403 Forbidden` with the required scope surfaced in the
43
+`X-Accepted-OAuth-Scopes` response header. The token's actual
44
+scopes are echoed on every PAT-authenticated response (including
45
+errors) via `X-OAuth-Scopes`, so clients can build precise
46
+"missing scope X, present scopes Y, Z" error messages without
47
+parsing the body:
40
 
48
 
41
-```json
49
+```
42
-{"error": "insufficient scope"}
50
+HTTP/1.1 403 Forbidden
51
+X-OAuth-Scopes: user:read
52
+X-Accepted-OAuth-Scopes: repo:write
53
+Content-Type: application/json; charset=utf-8
54
+
55
+{"error":"token lacks required scope: repo:write"}
43
 ```
56
 ```
44
 
57
 
45
 ## Scopes
58
 ## Scopes
@@ -60,15 +73,47 @@ to a repo the user has no access to.
60
   conventional HTTP status.
73
   conventional HTTP status.
61
 - **Cache-Control:** every API response sets `no-store`.
74
 - **Cache-Control:** every API response sets `no-store`.
62
 - **Pagination:** list endpoints accept `?per_page=` (default 30,
75
 - **Pagination:** list endpoints accept `?per_page=` (default 30,
63
-  max 100) and return a `Link:` header with `next`, `prev`,
76
+  max 100) and return an RFC 8288 `Link:` header with `next`,
64
-  `first`, `last` URLs (RFC 5988). Cursor pagination on hot lists
77
+  `prev`, `first`, `last` URLs. URLs are absolute and use the
65
-  uses `?cursor=…` and returns the next cursor in the `Link:`
78
+  instance's configured public base URL. Forward-only feeds emit
79
+  only `next` / `prev` (no `first` / `last`) when totals are
80
+  expensive to compute. Cursor pagination on hot lists uses
81
+  `?cursor=…` and returns the next cursor in the same `Link:`
66
   header.
82
   header.
67
 - **Body cap:** request bodies are capped at 256 KiB. Larger
83
 - **Body cap:** request bodies are capped at 256 KiB. Larger
68
   payloads return `413`.
84
   payloads return `413`.
69
 - **Rate limits:** every response includes `X-RateLimit-Limit`,
85
 - **Rate limits:** every response includes `X-RateLimit-Limit`,
70
   `X-RateLimit-Remaining`, and `X-RateLimit-Reset` headers (Unix
86
   `X-RateLimit-Remaining`, and `X-RateLimit-Reset` headers (Unix
71
-  timestamp). Exceeding the limit returns `429`.
87
+  timestamp). Exceeding the limit returns `429` with the canonical
88
+  error envelope, a `Retry-After` header (seconds), and
89
+  `X-RateLimit-Remaining: 0`. Defaults: 5000 / hour for PAT
90
+  callers (keyed by token id) and 60 / hour for anonymous callers
91
+  (keyed by remote IP). Operators tune via
92
+  `SHITHUB_RATELIMIT__API__AUTHED_PER_HOUR` and
93
+  `SHITHUB_RATELIMIT__API__ANON_PER_HOUR`.
94
+- **Request id:** every response echoes `X-Request-Id`. If the
95
+  caller sends one (matching `[a-z0-9/:_-]{1,128}`) it's reused;
96
+  otherwise the server generates a fresh 16-byte hex id. Quote
97
+  this id in support reports — it correlates against the server
98
+  logs.
99
+
100
+## Capability discovery
101
+
102
+`GET /api/v1/meta` is unauthenticated and returns the server's
103
+version stamp plus a list of feature capability strings. Clients
104
+use it to gate optional features without trial-and-error:
105
+
106
+```json
107
+{
108
+  "version": "v0.2.0",
109
+  "commit": "abc1234",
110
+  "built_at": "2026-05-12T03:00:00Z",
111
+  "capabilities": ["pat-auth", "check-runs", "stars", "actions-lifecycle"]
112
+}
113
+```
114
+
115
+New capability identifiers are appended as feature batches land;
116
+existing entries are stable.
72
 
117
 
73
 ## Versioning
118
 ## Versioning
74
 
119