markdown · 5838 bytes Raw Blame History

Users

Get the authenticated user

GET /api/v1/user

Required scope: user:read.

Returns the user record for the account that owns the authenticating PAT.

Response

{
  "id": 42,
  "username": "alice",
  "name": "Alice Example",
  "email_verified": true,
  "created_at": "2026-05-09T16:30:00Z"
}
Field Type Notes
id int64 Stable numeric ID.
username string Account username; URL-safe slug.
name string Display name; may be empty if not set.
email_verified bool Whether the primary email has been verified.
created_at string RFC 3339 UTC timestamp of account creation.

Errors

Status When
401 PAT missing/invalid/expired/revoked.
403 PAT lacks user:read scope.
404 User record not found (suspended or deleted between auth and lookup).

Get a user by username

Planned. GET /api/v1/users/{username} is not shipped yet.

Update the authenticated user

Planned. PATCH /api/v1/user is not shipped yet.

List the authenticated user's repos

GET /api/v1/user/repos ships in S50 §2 — see the Repositories page for the full shape and a list of related endpoints.

Email addresses

List the authenticated user's emails

GET /api/v1/user/emails

Required scope: user:read.

Returns every email address attached to the authenticating user. Use ?verified=true (or ?verified=false) to filter to a single verification state. Omit the query parameter to list both.

Response

[
  {
    "id": 7,
    "email": "alice+primary@example.test",
    "primary": true,
    "verified": true
  },
  {
    "id": 8,
    "email": "alice+work@example.test",
    "primary": false,
    "verified": false
  }
]
Field Type Notes
id int64 Stable per-row id.
email string The email address as stored.
primary bool Marks the account's primary delivery address.
verified bool true once a verification link has been clicked.

Errors

Status When
401 PAT missing/invalid/expired/revoked.
403 PAT lacks user:read scope.

Planned. POST and DELETE /api/v1/user/emails are not shipped yet — use /settings/account in the web UI to add or remove addresses for now.

SSH keys

SSH authentication keys for git-over-SSH. Signing keys live at a separate /user/ssh_signing_keys surface (not yet shipped).

List SSH keys

GET /api/v1/user/keys

Required scope: user:read.

Returns the authenticated user's authentication keys (signing keys are not returned here). Paginated via ?per_page= and ?page=; the response carries the standard Link: header.

Response

[
  {
    "id": 12,
    "title": "laptop",
    "key": "ssh-ed25519 AAAA…",
    "fingerprint": "SHA256:abc…",
    "key_type": "ssh-ed25519",
    "verified": true,
    "read_only": false,
    "created_at": "2026-05-12T04:00:00Z"
  }
]

Get a single SSH key

GET /api/v1/user/keys/{id}

Required scope: user:read.

404 when the id does not belong to the authenticating user, or when it is a signing key (use the signing-key surface).

Add an SSH key

POST /api/v1/user/keys

Required scope: user:write.

Request body

{ "title": "laptop", "key": "ssh-ed25519 AAAA…" }
Field Type Notes
title string 1–80 characters; user-visible label.
key string The contents of your .pub file (no leading comment, no trailing data).

Returns 201 on success with the same shape as the list endpoint.

Errors

Status When
401 PAT missing/invalid.
403 PAT lacks user:write scope.
422 Title invalid, blob unparseable, key already registered, or per-user cap hit.

Delete an SSH key

DELETE /api/v1/user/keys/{id}

Required scope: user:write.

Returns 204 No Content on success, 404 when the id does not belong to the authenticating user.

Stars

The starred-repos surface for the authenticating user.

List starred repos

GET /api/v1/user/starred

Required scope: user:read.

Returns the list of (owner, repo) pairs the user has starred, most-recent first. Pagination via ?cursor=… and ?per_page=.

Star a repo

PUT /api/v1/user/starred/{owner}/{repo}

Required scope: user (write).

Idempotent: starring an already-starred repo returns 204 and does not duplicate the row. Returns 404 if the repo doesn't exist or the user can't see it.

Unstar a repo

DELETE /api/v1/user/starred/{owner}/{repo}

Required scope: user (write).

Idempotent: unstarring a not-starred repo returns 204.

View source
1 # Users
2
3 ## Get the authenticated user
4
5 ```
6 GET /api/v1/user
7 ```
8
9 Required scope: `user:read`.
10
11 Returns the user record for the account that owns the
12 authenticating PAT.
13
14 ### Response
15
16 ```json
17 {
18 "id": 42,
19 "username": "alice",
20 "name": "Alice Example",
21 "email_verified": true,
22 "created_at": "2026-05-09T16:30:00Z"
23 }
24 ```
25
26 | Field | Type | Notes |
27 |------------------|---------|------------------------------------------------------|
28 | `id` | int64 | Stable numeric ID. |
29 | `username` | string | Account username; URL-safe slug. |
30 | `name` | string | Display name; may be empty if not set. |
31 | `email_verified` | bool | Whether the primary email has been verified. |
32 | `created_at` | string | RFC 3339 UTC timestamp of account creation. |
33
34 ### Errors
35
36 | Status | When |
37 |-------:|-------------------------------------|
38 | 401 | PAT missing/invalid/expired/revoked. |
39 | 403 | PAT lacks `user:read` scope. |
40 | 404 | User record not found (suspended or deleted between auth and lookup). |
41
42 ## Get a user by username
43
44 > **Planned.** `GET /api/v1/users/{username}` is not shipped yet.
45
46 ## Update the authenticated user
47
48 > **Planned.** `PATCH /api/v1/user` is not shipped yet.
49
50 ## List the authenticated user's repos
51
52 `GET /api/v1/user/repos` ships in S50 §2 — see the
53 [Repositories](repos.md) page for the full shape and a list of
54 related endpoints.
55
56 ## Email addresses
57
58 ### List the authenticated user's emails
59
60 ```
61 GET /api/v1/user/emails
62 ```
63
64 Required scope: `user:read`.
65
66 Returns every email address attached to the authenticating user.
67 Use `?verified=true` (or `?verified=false`) to filter to a single
68 verification state. Omit the query parameter to list both.
69
70 #### Response
71
72 ```json
73 [
74 {
75 "id": 7,
76 "email": "alice+primary@example.test",
77 "primary": true,
78 "verified": true
79 },
80 {
81 "id": 8,
82 "email": "alice+work@example.test",
83 "primary": false,
84 "verified": false
85 }
86 ]
87 ```
88
89 | Field | Type | Notes |
90 |------------|--------|---------------------------------------------------|
91 | `id` | int64 | Stable per-row id. |
92 | `email` | string | The email address as stored. |
93 | `primary` | bool | Marks the account's primary delivery address. |
94 | `verified` | bool | `true` once a verification link has been clicked. |
95
96 #### Errors
97
98 | Status | When |
99 |-------:|-------------------------------------|
100 | 401 | PAT missing/invalid/expired/revoked. |
101 | 403 | PAT lacks `user:read` scope. |
102
103 > **Planned.** `POST` and `DELETE /api/v1/user/emails` are not
104 > shipped yet — use `/settings/account` in the web UI to add or
105 > remove addresses for now.
106
107 ## SSH keys
108
109 SSH authentication keys for git-over-SSH. Signing keys live at a
110 separate `/user/ssh_signing_keys` surface (not yet shipped).
111
112 ### List SSH keys
113
114 ```
115 GET /api/v1/user/keys
116 ```
117
118 Required scope: `user:read`.
119
120 Returns the authenticated user's authentication keys (signing
121 keys are not returned here). Paginated via `?per_page=` and
122 `?page=`; the response carries the standard `Link:` header.
123
124 #### Response
125
126 ```json
127 [
128 {
129 "id": 12,
130 "title": "laptop",
131 "key": "ssh-ed25519 AAAA…",
132 "fingerprint": "SHA256:abc…",
133 "key_type": "ssh-ed25519",
134 "verified": true,
135 "read_only": false,
136 "created_at": "2026-05-12T04:00:00Z"
137 }
138 ]
139 ```
140
141 ### Get a single SSH key
142
143 ```
144 GET /api/v1/user/keys/{id}
145 ```
146
147 Required scope: `user:read`.
148
149 404 when the id does not belong to the authenticating user, or
150 when it is a signing key (use the signing-key surface).
151
152 ### Add an SSH key
153
154 ```
155 POST /api/v1/user/keys
156 ```
157
158 Required scope: `user:write`.
159
160 #### Request body
161
162 ```json
163 { "title": "laptop", "key": "ssh-ed25519 AAAA…" }
164 ```
165
166 | Field | Type | Notes |
167 |---------|--------|--------------------------------------------------------------------------|
168 | `title` | string | 1–80 characters; user-visible label. |
169 | `key` | string | The contents of your `.pub` file (no leading comment, no trailing data). |
170
171 Returns `201` on success with the same shape as the list endpoint.
172
173 #### Errors
174
175 | Status | When |
176 |-------:|------------------------------------------------------------------------------|
177 | 401 | PAT missing/invalid. |
178 | 403 | PAT lacks `user:write` scope. |
179 | 422 | Title invalid, blob unparseable, key already registered, or per-user cap hit. |
180
181 ### Delete an SSH key
182
183 ```
184 DELETE /api/v1/user/keys/{id}
185 ```
186
187 Required scope: `user:write`.
188
189 Returns `204 No Content` on success, `404` when the id does not
190 belong to the authenticating user.
191
192 ## Stars
193
194 The starred-repos surface for the authenticating user.
195
196 ### List starred repos
197
198 ```
199 GET /api/v1/user/starred
200 ```
201
202 Required scope: `user:read`.
203
204 Returns the list of `(owner, repo)` pairs the user has starred,
205 most-recent first. Pagination via `?cursor=…` and `?per_page=`.
206
207 ### Star a repo
208
209 ```
210 PUT /api/v1/user/starred/{owner}/{repo}
211 ```
212
213 Required scope: `user` (write).
214
215 Idempotent: starring an already-starred repo returns `204` and
216 does not duplicate the row. Returns `404` if the repo doesn't
217 exist or the user can't see it.
218
219 ### Unstar a repo
220
221 ```
222 DELETE /api/v1/user/starred/{owner}/{repo}
223 ```
224
225 Required scope: `user` (write).
226
227 Idempotent: unstarring a not-starred repo returns `204`.