fizzy-cli 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/release.yml +29 -0
- package/.github/workflows/tests.yml +24 -0
- package/AGENTS.md +33 -0
- package/CHANGELOG.md +63 -0
- package/Makefile +20 -9
- package/README.md +88 -1
- package/bin/fizzy +0 -0
- package/bin/fizzy-darwin-amd64 +0 -0
- package/bin/fizzy-darwin-arm64 +0 -0
- package/bin/fizzy-linux-amd64 +0 -0
- package/bin/fizzy-linux-arm64 +0 -0
- package/bin/fizzy-windows-amd64.exe +0 -0
- package/cmd/account.go +14 -0
- package/cmd/account_list.go +44 -0
- package/cmd/account_list_test.go +118 -0
- package/cmd/board.go +38 -12
- package/cmd/board_create.go +60 -0
- package/cmd/board_create_test.go +158 -0
- package/cmd/board_list.go +18 -32
- package/cmd/board_list_test.go +115 -0
- package/cmd/board_test.go +92 -0
- package/cmd/card.go +24 -0
- package/cmd/card_close.go +46 -0
- package/cmd/card_close_test.go +92 -0
- package/cmd/card_create.go +73 -0
- package/cmd/card_create_test.go +206 -0
- package/cmd/card_delete.go +46 -0
- package/cmd/card_delete_test.go +92 -0
- package/cmd/card_list.go +53 -0
- package/cmd/card_list_test.go +148 -0
- package/cmd/card_reopen.go +46 -0
- package/cmd/card_reopen_test.go +92 -0
- package/cmd/card_show.go +46 -0
- package/cmd/card_show_test.go +92 -0
- package/cmd/card_update.go +74 -0
- package/cmd/card_update_test.go +147 -0
- package/cmd/column.go +14 -0
- package/cmd/column_create.go +80 -0
- package/cmd/column_create_test.go +196 -0
- package/cmd/column_list.go +44 -0
- package/cmd/column_list_test.go +138 -0
- package/cmd/login.go +61 -4
- package/cmd/login_test.go +98 -0
- package/cmd/root.go +15 -4
- package/cmd/use.go +85 -0
- package/cmd/use_test.go +186 -0
- package/docs/API.md +1168 -0
- package/go.mod +23 -2
- package/go.sum +43 -0
- package/internal/api/client.go +463 -0
- package/internal/app/app.go +49 -0
- package/internal/colors/colors.go +32 -0
- package/internal/config/config.go +69 -0
- package/internal/testutil/client.go +26 -0
- package/internal/ui/account_list.go +14 -0
- package/internal/ui/account_selector.go +63 -0
- package/internal/ui/board_list.go +14 -0
- package/internal/ui/card_list.go +14 -0
- package/internal/ui/card_show.go +23 -0
- package/internal/ui/column_list.go +28 -0
- package/internal/ui/format.go +14 -0
- package/main.go +1 -1
- package/package.json +1 -1
package/docs/API.md
ADDED
|
@@ -0,0 +1,1168 @@
|
|
|
1
|
+
# Fizzy API
|
|
2
|
+
|
|
3
|
+
Fizzy has an API that allows you to integrate your application with it or to create
|
|
4
|
+
a bot to perform various actions for you.
|
|
5
|
+
|
|
6
|
+
## Authentication
|
|
7
|
+
|
|
8
|
+
To use the API you'll need an access token. To get one, go to your profile, then,
|
|
9
|
+
in the API section, click on "Personal access tokens" and then click on
|
|
10
|
+
"Generate new access token".
|
|
11
|
+
|
|
12
|
+
Give it a description and pick what kind of permission you want the access token to have:
|
|
13
|
+
- `Read`: allows reading data from your account
|
|
14
|
+
- `Read + Write`: allows reading and writing data to your account on your behalf
|
|
15
|
+
|
|
16
|
+
Then click on "Generate access token".
|
|
17
|
+
|
|
18
|
+
<details>
|
|
19
|
+
<summary>Access token generation guide with screenshots</summary>
|
|
20
|
+
|
|
21
|
+
| Step | Description | Screenshot |
|
|
22
|
+
|:----:|-------------|:----------:|
|
|
23
|
+
| 1 | Go to your profile | <img width="400" alt="Profile page with API section" src="https://github.com/user-attachments/assets/49e7e12b-2952-4220-84fd-cef99b13bc04" /> |
|
|
24
|
+
| 2 | In the API section click on "Personal access token" | <img width="400" alt="Personal access tokens page" src="https://github.com/user-attachments/assets/2f026ea0-416f-4fbe-a097-61313f24f180" /> |
|
|
25
|
+
| 3 | Click on "Generate a new access token" | <img width="400" alt="Generate new access token dialog" src="https://github.com/user-attachments/assets/d766f047-8628-416d-8e21-b89522f6c0d9" /> |
|
|
26
|
+
| 4 | Give it a description and assign it a permission | <img width="400" alt="Access token created" src="https://github.com/user-attachments/assets/49b8e350-d152-4946-8aad-e13260b983fd" /> |
|
|
27
|
+
</details>
|
|
28
|
+
|
|
29
|
+
> [!IMPORTANT]
|
|
30
|
+
> __An access token is like a password, keep it secret and do not share it with anyone.__
|
|
31
|
+
> Any person or application that has your access token can perform actions on your behalf.
|
|
32
|
+
|
|
33
|
+
To authenticate a request using your access token, include it in the `Authorization` header:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
curl -H "Authorization: Bearer put-your-access-token-here" -H "Accept: application/json" https://app.fizzy.do/my/identity
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Caching
|
|
40
|
+
|
|
41
|
+
Most endpoints return [ETag](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/ETag) and [Cache-Control](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control) headers. You can use these to avoid re-downloading unchanged data.
|
|
42
|
+
|
|
43
|
+
### Using ETags
|
|
44
|
+
|
|
45
|
+
When you make a request, the response includes an `ETag` header:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
HTTP/1.1 200 OK
|
|
49
|
+
ETag: "abc123"
|
|
50
|
+
Cache-Control: max-age=0, private, must-revalidate
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
On subsequent requests, include the ETag value in the `If-None-Match` header:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
GET /1234567/cards/42.json
|
|
57
|
+
If-None-Match: "abc123"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
If the resource hasn't changed, you'll receive a `304 Not Modified` response with no body, saving bandwidth and processing time:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
HTTP/1.1 304 Not Modified
|
|
64
|
+
ETag: "abc123"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
If the resource has changed, you'll receive the full response with a new ETag.
|
|
68
|
+
|
|
69
|
+
__Example in Ruby:__
|
|
70
|
+
|
|
71
|
+
```ruby
|
|
72
|
+
# Store the ETag from the response
|
|
73
|
+
etag = response.headers["ETag"]
|
|
74
|
+
|
|
75
|
+
# On next request, send it back
|
|
76
|
+
headers = { "If-None-Match" => etag }
|
|
77
|
+
response = client.get("/1234567/cards/42.json", headers: headers)
|
|
78
|
+
|
|
79
|
+
if response.status == 304
|
|
80
|
+
# Nothing to do, the card hasn't changed
|
|
81
|
+
else
|
|
82
|
+
# The card has changed, process the new data
|
|
83
|
+
end
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Error Responses
|
|
87
|
+
|
|
88
|
+
When a request fails, the API response will communicate the source of the problem through the HTTP status code.
|
|
89
|
+
|
|
90
|
+
| Status Code | Description |
|
|
91
|
+
|-------------|-------------|
|
|
92
|
+
| `400 Bad Request` | The request was malformed or missing required parameters |
|
|
93
|
+
| `401 Unauthorized` | Authentication failed or access token is invalid |
|
|
94
|
+
| `403 Forbidden` | You don't have permission to perform this action |
|
|
95
|
+
| `404 Not Found` | The requested resource doesn't exist or you don't have access to it |
|
|
96
|
+
| `422 Unprocessable Entity` | Validation failed (see error response format above) |
|
|
97
|
+
| `500 Internal Server Error` | An unexpected error occurred on the server |
|
|
98
|
+
|
|
99
|
+
If a request contains invalid data for fields, such as entering a string into a number field, in most cases the API will respond with a `500 Internal Server Error`. Clients are expected to perform some validation on their end before making a request.
|
|
100
|
+
|
|
101
|
+
A validation error will produce a `422 Unprocessable Entity` response, which will sometimes be accompanied by details about the error:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"avatar": ["must be a JPEG, PNG, GIF, or WebP image"]
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Pagination
|
|
110
|
+
|
|
111
|
+
All endpoints that return a list of items are paginated. The page size can vary from endpoint to endpoint,
|
|
112
|
+
and we use a dynamic page size where initial pages return fewer results than later pages.
|
|
113
|
+
|
|
114
|
+
If there are more results to fetch, the response will include a `Link` header with a `rel="next"` link to the next page of results:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
curl -H "Authorization: Bearer put-your-access-token-here" -H "Accept: application/json" -v http://fizzy.localhost:3006/686465299/cards
|
|
118
|
+
# ...
|
|
119
|
+
< link: <http://fizzy.localhost:3006/686465299/cards?page=2>; rel="next"
|
|
120
|
+
# ...
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## List parameters
|
|
124
|
+
|
|
125
|
+
When an endpoint accepts a list of values as a parameter, you can provide multiple values by repeating the parameter name:
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
?tag_ids[]=tag1&tag_ids[]=tag2&tag_ids[]=tag3
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
List parameters always end with `[]`.
|
|
132
|
+
|
|
133
|
+
## File Uploads
|
|
134
|
+
|
|
135
|
+
Some endpoints accept file uploads. To upload a file, send a `multipart/form-data` request instead of JSON.
|
|
136
|
+
You can combine file uploads with other parameters in the same request.
|
|
137
|
+
|
|
138
|
+
__Example using curl:__
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
curl -X PUT \
|
|
142
|
+
-H "Authorization: Bearer put-your-access-token-here" \
|
|
143
|
+
-F "user[name]=David H. Hansson" \
|
|
144
|
+
-F "user[avatar]=@/path/to/avatar.jpg" \
|
|
145
|
+
http://fizzy.localhost:3006/686465299/users/03f5v9zjw7pz8717a4no1h8a7
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Rich Text Fields
|
|
149
|
+
|
|
150
|
+
Some fields accept rich text content. These fields accept HTML input, which will be sanitized to remove unsafe tags and attributes.
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"card": {
|
|
155
|
+
"title": "My card",
|
|
156
|
+
"description": "<p>This is <strong>bold</strong> and this is <em>italic</em>.</p><ul><li>Item 1</li><li>Item 2</li></ul>"
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Attaching files to rich text
|
|
162
|
+
|
|
163
|
+
To attach files (images, documents) to rich text fields, use ActionText's direct upload flow:
|
|
164
|
+
|
|
165
|
+
#### 1. Create a direct upload
|
|
166
|
+
|
|
167
|
+
First, request a direct upload URL by sending file metadata:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
curl -X POST \
|
|
171
|
+
-H "Authorization: Bearer put-your-access-token-here" \
|
|
172
|
+
-H "Content-Type: application/json" \
|
|
173
|
+
-d '{
|
|
174
|
+
"blob": {
|
|
175
|
+
"filename": "screenshot.png",
|
|
176
|
+
"byte_size": 12345,
|
|
177
|
+
"checksum": "GQ5SqLsM7ylnji0Wgd9wNA==",
|
|
178
|
+
"content_type": "image/png"
|
|
179
|
+
}
|
|
180
|
+
}' \
|
|
181
|
+
https://app.fizzy.do/123456/rails/active_storage/direct_uploads
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
The `checksum` is a Base64-encoded MD5 hash of the file content.
|
|
185
|
+
The direct upload endpoint is scoped to your account (replace `/123456` with your account slug).
|
|
186
|
+
|
|
187
|
+
__Response:__
|
|
188
|
+
|
|
189
|
+
```json
|
|
190
|
+
{
|
|
191
|
+
"id": "abc123",
|
|
192
|
+
"key": "abc123def456",
|
|
193
|
+
"filename": "screenshot.png",
|
|
194
|
+
"content_type": "image/png",
|
|
195
|
+
"byte_size": 12345,
|
|
196
|
+
"checksum": "GQ5SqLsM7ylnji0Wgd9wNA==",
|
|
197
|
+
"direct_upload": {
|
|
198
|
+
"url": "https://storage.example.com/...",
|
|
199
|
+
"headers": {
|
|
200
|
+
"Content-Type": "image/png",
|
|
201
|
+
"Content-MD5": "GQ5SqLsM7ylnji0Wgd9wNA=="
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
"signed_id": "eyJfcmFpbHMi..."
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
#### 2. Upload the file
|
|
209
|
+
|
|
210
|
+
Upload the file directly to the provided URL with the specified headers:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
curl -X PUT \
|
|
214
|
+
-H "Content-Type: image/png" \
|
|
215
|
+
-H "Content-MD5: GQ5SqLsM7ylnji0Wgd9wNA==" \
|
|
216
|
+
--data-binary @screenshot.png \
|
|
217
|
+
"https://storage.example.com/..."
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
#### 3. Reference the file in rich text
|
|
221
|
+
|
|
222
|
+
Use the `signed_id` from step 1 to embed the file in your rich text using an `<action-text-attachment>` tag:
|
|
223
|
+
|
|
224
|
+
```json
|
|
225
|
+
{
|
|
226
|
+
"card": {
|
|
227
|
+
"title": "Card with image",
|
|
228
|
+
"description": "<p>Here's a screenshot:</p><action-text-attachment sgid=\"eyJfcmFpbHMi...\"></action-text-attachment>"
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
The `sgid` attribute should contain the `signed_id` returned from the direct upload response.
|
|
234
|
+
|
|
235
|
+
## Identity
|
|
236
|
+
|
|
237
|
+
An Identity represents a person using Fizzy.
|
|
238
|
+
|
|
239
|
+
### `GET /my/identity`
|
|
240
|
+
|
|
241
|
+
Returns a list of accounts the identity has access to, including the user for each account.
|
|
242
|
+
|
|
243
|
+
```json
|
|
244
|
+
{
|
|
245
|
+
"accounts": [
|
|
246
|
+
{
|
|
247
|
+
"id": "03f5v9zjskhcii2r45ih3u1rq",
|
|
248
|
+
"name": "37signals",
|
|
249
|
+
"slug": "/897362094",
|
|
250
|
+
"created_at": "2025-12-05T19:36:35.377Z",
|
|
251
|
+
"user": {
|
|
252
|
+
"id": "03f5v9zjw7pz8717a4no1h8a7",
|
|
253
|
+
"name": "David Heinemeier Hansson",
|
|
254
|
+
"role": "owner",
|
|
255
|
+
"active": true,
|
|
256
|
+
"email_address": "david@example.com",
|
|
257
|
+
"created_at": "2025-12-05T19:36:35.401Z",
|
|
258
|
+
"url": "http://fizzy.localhost:3006/users/03f5v9zjw7pz8717a4no1h8a7"
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
"id": "03f5v9zpko7mmhjzwum3youpp",
|
|
263
|
+
"name": "Honcho",
|
|
264
|
+
"slug": "/686465299",
|
|
265
|
+
"created_at": "2025-12-05T19:36:36.746Z",
|
|
266
|
+
"user": {
|
|
267
|
+
"id": "03f5v9zppzlksuj4mxba2nbzn",
|
|
268
|
+
"name": "David Heinemeier Hansson",
|
|
269
|
+
"role": "owner",
|
|
270
|
+
"active": true,
|
|
271
|
+
"email_address": "david@example.com",
|
|
272
|
+
"created_at": "2025-12-05T19:36:36.783Z",
|
|
273
|
+
"url": "http://fizzy.localhost:3006/users/03f5v9zppzlksuj4mxba2nbzn"
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
]
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Boards
|
|
281
|
+
|
|
282
|
+
Boards are where you organize your work - they contain your cards.
|
|
283
|
+
|
|
284
|
+
### `GET /:account_slug/boards`
|
|
285
|
+
|
|
286
|
+
Returns a list of boards that you can access in the specified account.
|
|
287
|
+
|
|
288
|
+
__Response:__
|
|
289
|
+
|
|
290
|
+
```json
|
|
291
|
+
[
|
|
292
|
+
{
|
|
293
|
+
"id": "03f5v9zkft4hj9qq0lsn9ohcm",
|
|
294
|
+
"name": "Fizzy",
|
|
295
|
+
"all_access": true,
|
|
296
|
+
"created_at": "2025-12-05T19:36:35.534Z",
|
|
297
|
+
"url": "http://fizzy.localhost:3006/897362094/boards/03f5v9zkft4hj9qq0lsn9ohcm",
|
|
298
|
+
"creator": {
|
|
299
|
+
"id": "03f5v9zjw7pz8717a4no1h8a7",
|
|
300
|
+
"name": "David Heinemeier Hansson",
|
|
301
|
+
"role": "owner",
|
|
302
|
+
"active": true,
|
|
303
|
+
"email_address": "david@example.com",
|
|
304
|
+
"created_at": "2025-12-05T19:36:35.401Z",
|
|
305
|
+
"url": "http://fizzy.localhost:3006/897362094/users/03f5v9zjw7pz8717a4no1h8a7"
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
]
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### `GET /:account_slug/boards/:board_id`
|
|
312
|
+
|
|
313
|
+
Returns the specified board.
|
|
314
|
+
|
|
315
|
+
__Response:__
|
|
316
|
+
|
|
317
|
+
```json
|
|
318
|
+
{
|
|
319
|
+
"id": "03f5v9zkft4hj9qq0lsn9ohcm",
|
|
320
|
+
"name": "Fizzy",
|
|
321
|
+
"all_access": true,
|
|
322
|
+
"created_at": "2025-12-05T19:36:35.534Z",
|
|
323
|
+
"url": "http://fizzy.localhost:3006/897362094/boards/03f5v9zkft4hj9qq0lsn9ohcm",
|
|
324
|
+
"creator": {
|
|
325
|
+
"id": "03f5v9zjw7pz8717a4no1h8a7",
|
|
326
|
+
"name": "David Heinemeier Hansson",
|
|
327
|
+
"role": "owner",
|
|
328
|
+
"active": true,
|
|
329
|
+
"email_address": "david@example.com",
|
|
330
|
+
"created_at": "2025-12-05T19:36:35.401Z",
|
|
331
|
+
"url": "http://fizzy.localhost:3006/897362094/users/03f5v9zjw7pz8717a4no1h8a7"
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### `POST /:account_slug/boards`
|
|
337
|
+
|
|
338
|
+
Creates a new Board in the account.
|
|
339
|
+
|
|
340
|
+
| Parameter | Type | Required | Description |
|
|
341
|
+
|-----------|------|----------|-------------|
|
|
342
|
+
| `name` | string | Yes | The name of the board |
|
|
343
|
+
| `all_access` | boolean | No | Whether any user in the account can access this board. Defaults to `true` |
|
|
344
|
+
| `auto_postpone_period` | integer | No | Number of days of inactivity before cards are automatically postponed |
|
|
345
|
+
| `public_description` | string | No | Rich text description shown on the public board page |
|
|
346
|
+
|
|
347
|
+
__Request:__
|
|
348
|
+
|
|
349
|
+
```json
|
|
350
|
+
{
|
|
351
|
+
"board": {
|
|
352
|
+
"name": "My new board",
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
__Response:__
|
|
358
|
+
|
|
359
|
+
Returns `201 Created` with a `Location` header pointing to the new board:
|
|
360
|
+
|
|
361
|
+
```
|
|
362
|
+
HTTP/1.1 201 Created
|
|
363
|
+
Location: /897362094/boards/03f5v9zkft4hj9qq0lsn9ohcm.json
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### `PUT /:account_slug/boards/:board_id`
|
|
367
|
+
|
|
368
|
+
Updates a Board. Only board administrators can update a board.
|
|
369
|
+
|
|
370
|
+
| Parameter | Type | Required | Description |
|
|
371
|
+
|-----------|------|----------|-------------|
|
|
372
|
+
| `name` | string | No | The name of the board |
|
|
373
|
+
| `all_access` | boolean | No | Whether any user in the account can access this board |
|
|
374
|
+
| `auto_postpone_period` | integer | No | Number of days of inactivity before cards are automatically postponed |
|
|
375
|
+
| `public_description` | string | No | Rich text description shown on the public board page |
|
|
376
|
+
| `user_ids` | array | No | Array of *all* user IDs who should have access to this board (only applicable when `all_access` is `false`) |
|
|
377
|
+
|
|
378
|
+
__Request:__
|
|
379
|
+
|
|
380
|
+
```json
|
|
381
|
+
{
|
|
382
|
+
"board": {
|
|
383
|
+
"name": "Updated board name",
|
|
384
|
+
"auto_postpone_period": 14,
|
|
385
|
+
"public_description": "This is a **public** description of the board.",
|
|
386
|
+
"all_access": false,
|
|
387
|
+
"user_ids": [
|
|
388
|
+
"03f5v9zppzlksuj4mxba2nbzn",
|
|
389
|
+
"03f5v9zjw7pz8717a4no1h8a7"
|
|
390
|
+
]
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
__Response:__
|
|
396
|
+
|
|
397
|
+
Returns `204 No Content` on success.
|
|
398
|
+
|
|
399
|
+
### `DELETE /:account_slug/boards/:board_id`
|
|
400
|
+
|
|
401
|
+
Deletes a Board. Only board administrators can delete a board.
|
|
402
|
+
|
|
403
|
+
__Response:__
|
|
404
|
+
|
|
405
|
+
Returns `204 No Content` on success.
|
|
406
|
+
|
|
407
|
+
## Cards
|
|
408
|
+
|
|
409
|
+
Cards are tasks or items of work on a board. They can be organized into columns, tagged, assigned to users, and have comments.
|
|
410
|
+
|
|
411
|
+
### `GET /:account_slug/cards`
|
|
412
|
+
|
|
413
|
+
Returns a paginated list of cards you have access to. Results can be filtered using query parameters.
|
|
414
|
+
|
|
415
|
+
__Query Parameters:__
|
|
416
|
+
|
|
417
|
+
| Parameter | Description |
|
|
418
|
+
|-----------|-------------|
|
|
419
|
+
| `board_ids[]` | Filter by board ID(s) |
|
|
420
|
+
| `tag_ids[]` | Filter by tag ID(s) |
|
|
421
|
+
| `assignee_ids[]` | Filter by assignee user ID(s) |
|
|
422
|
+
| `creator_ids[]` | Filter by card creator ID(s) |
|
|
423
|
+
| `closer_ids[]` | Filter by user ID(s) who closed the cards |
|
|
424
|
+
| `card_ids[]` | Filter to specific card ID(s) |
|
|
425
|
+
| `indexed_by` | Filter by: `all` (default), `closed`, `not_now`, `stalled`, `postponing_soon`, `golden` |
|
|
426
|
+
| `sorted_by` | Sort order: `latest` (default), `newest`, `oldest` |
|
|
427
|
+
| `assignment_status` | Filter by assignment status: `unassigned` |
|
|
428
|
+
| `creation` | Filter by creation date: `today`, `yesterday`, `thisweek`, `lastweek`, `thismonth`, `lastmonth`, `thisyear`, `lastyear` |
|
|
429
|
+
| `closure` | Filter by closure date: `today`, `yesterday`, `thisweek`, `lastweek`, `thismonth`, `lastmonth`, `thisyear`, `lastyear` |
|
|
430
|
+
| `terms[]` | Search terms to filter cards |
|
|
431
|
+
|
|
432
|
+
__Response:__
|
|
433
|
+
|
|
434
|
+
```json
|
|
435
|
+
[
|
|
436
|
+
{
|
|
437
|
+
"id": "03f5vaeq985jlvwv3arl4srq2",
|
|
438
|
+
"number": 1,
|
|
439
|
+
"title": "First!",
|
|
440
|
+
"status": "published",
|
|
441
|
+
"description": "Hello, World!",
|
|
442
|
+
"description_html": "<div class=\"action-text-content\"><p>Hello, World!</p></div>",
|
|
443
|
+
"image_url": null,
|
|
444
|
+
"tags": ["programming"],
|
|
445
|
+
"golden": false,
|
|
446
|
+
"last_active_at": "2025-12-05T19:38:48.553Z",
|
|
447
|
+
"created_at": "2025-12-05T19:38:48.540Z",
|
|
448
|
+
"url": "http://fizzy.localhost:3006/897362094/cards/4",
|
|
449
|
+
"board": {
|
|
450
|
+
"id": "03f5v9zkft4hj9qq0lsn9ohcm",
|
|
451
|
+
"name": "Fizzy",
|
|
452
|
+
"all_access": true,
|
|
453
|
+
"created_at": "2025-12-05T19:36:35.534Z",
|
|
454
|
+
"url": "http://fizzy.localhost:3006/897362094/boards/03f5v9zkft4hj9qq0lsn9ohcm",
|
|
455
|
+
"creator": {
|
|
456
|
+
"id": "03f5v9zjw7pz8717a4no1h8a7",
|
|
457
|
+
"name": "David Heinemeier Hansson",
|
|
458
|
+
"role": "owner",
|
|
459
|
+
"active": true,
|
|
460
|
+
"email_address": "david@example.com",
|
|
461
|
+
"created_at": "2025-12-05T19:36:35.401Z",
|
|
462
|
+
"url": "http://fizzy.localhost:3006/897362094/users/03f5v9zjw7pz8717a4no1h8a7"
|
|
463
|
+
}
|
|
464
|
+
},
|
|
465
|
+
"creator": {
|
|
466
|
+
"id": "03f5v9zjw7pz8717a4no1h8a7",
|
|
467
|
+
"name": "David Heinemeier Hansson",
|
|
468
|
+
"role": "owner",
|
|
469
|
+
"active": true,
|
|
470
|
+
"email_address": "david@example.com",
|
|
471
|
+
"created_at": "2025-12-05T19:36:35.401Z",
|
|
472
|
+
"url": "http://fizzy.localhost:3006/897362094/users/03f5v9zjw7pz8717a4no1h8a7"
|
|
473
|
+
},
|
|
474
|
+
"comments_url": "http://fizzy.localhost:3006/897362094/cards/4/comments"
|
|
475
|
+
},
|
|
476
|
+
]
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### `GET /:account_slug/cards/:card_number`
|
|
480
|
+
|
|
481
|
+
Returns a specific card by its number.
|
|
482
|
+
|
|
483
|
+
__Response:__
|
|
484
|
+
|
|
485
|
+
Same as the card object in the list response.
|
|
486
|
+
|
|
487
|
+
### `POST /:account_slug/boards/:board_id/cards`
|
|
488
|
+
|
|
489
|
+
Creates a new card in a board.
|
|
490
|
+
|
|
491
|
+
| Parameter | Type | Required | Description |
|
|
492
|
+
|-----------|------|----------|-------------|
|
|
493
|
+
| `title` | string | Yes | The title of the card |
|
|
494
|
+
| `description` | string | No | Rich text description of the card |
|
|
495
|
+
| `status` | string | No | Initial status: `published` (default), `drafted` |
|
|
496
|
+
| `image` | file | No | Header image for the card |
|
|
497
|
+
| `tag_ids` | array | No | Array of tag IDs to apply to the card |
|
|
498
|
+
| `created_at` | datetime | No | Override creation timestamp (ISO 8601 format) |
|
|
499
|
+
| `last_active_at` | datetime | No | Override last activity timestamp (ISO 8601 format) |
|
|
500
|
+
|
|
501
|
+
__Request:__
|
|
502
|
+
|
|
503
|
+
```json
|
|
504
|
+
{
|
|
505
|
+
"card": {
|
|
506
|
+
"title": "Add dark mode support",
|
|
507
|
+
"description": "We need to add dark mode to the app"
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
__Response:__
|
|
513
|
+
|
|
514
|
+
Returns `201 Created` with a `Location` header pointing to the new card.
|
|
515
|
+
|
|
516
|
+
### `PUT /:account_slug/cards/:card_number`
|
|
517
|
+
|
|
518
|
+
Updates a card.
|
|
519
|
+
|
|
520
|
+
| Parameter | Type | Required | Description |
|
|
521
|
+
|-----------|------|----------|-------------|
|
|
522
|
+
| `title` | string | No | The title of the card |
|
|
523
|
+
| `description` | string | No | Rich text description of the card |
|
|
524
|
+
| `status` | string | No | Card status: `drafted`, `published` |
|
|
525
|
+
| `image` | file | No | Header image for the card |
|
|
526
|
+
| `tag_ids` | array | No | Array of tag IDs to apply to the card |
|
|
527
|
+
| `last_active_at` | datetime | No | Override last activity timestamp (ISO 8601 format) |
|
|
528
|
+
|
|
529
|
+
__Request:__
|
|
530
|
+
|
|
531
|
+
```json
|
|
532
|
+
{
|
|
533
|
+
"card": {
|
|
534
|
+
"title": "Add dark mode support (Updated)"
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
__Response:__
|
|
540
|
+
|
|
541
|
+
Returns the updated card.
|
|
542
|
+
|
|
543
|
+
### `DELETE /:account_slug/cards/:card_number`
|
|
544
|
+
|
|
545
|
+
Deletes a card. Only the card creator or board administrators can delete cards.
|
|
546
|
+
|
|
547
|
+
__Response:__
|
|
548
|
+
|
|
549
|
+
Returns `204 No Content` on success.
|
|
550
|
+
|
|
551
|
+
### `POST /:account_slug/cards/:card_number/closure`
|
|
552
|
+
|
|
553
|
+
Closes a card.
|
|
554
|
+
|
|
555
|
+
__Response:__
|
|
556
|
+
|
|
557
|
+
Returns `204 No Content` on success.
|
|
558
|
+
|
|
559
|
+
### `DELETE /:account_slug/cards/:card_number/closure`
|
|
560
|
+
|
|
561
|
+
Reopens a closed card.
|
|
562
|
+
|
|
563
|
+
__Response:__
|
|
564
|
+
|
|
565
|
+
Returns `204 No Content` on success.
|
|
566
|
+
|
|
567
|
+
### `POST /:account_slug/cards/:card_number/not_now`
|
|
568
|
+
|
|
569
|
+
Moves a card to "Not Now" status.
|
|
570
|
+
|
|
571
|
+
__Response:__
|
|
572
|
+
|
|
573
|
+
Returns `204 No Content` on success.
|
|
574
|
+
|
|
575
|
+
### `POST /:account_slug/cards/:card_number/triage`
|
|
576
|
+
|
|
577
|
+
Moves a card from triage into a column.
|
|
578
|
+
|
|
579
|
+
| Parameter | Type | Required | Description |
|
|
580
|
+
|-----------|------|----------|-------------|
|
|
581
|
+
| `column_id` | string | Yes | The ID of the column to move the card into |
|
|
582
|
+
|
|
583
|
+
__Response:__
|
|
584
|
+
|
|
585
|
+
Returns `204 No Content` on success.
|
|
586
|
+
|
|
587
|
+
### `DELETE /:account_slug/cards/:card_number/triage`
|
|
588
|
+
|
|
589
|
+
Sends a card back to triage.
|
|
590
|
+
|
|
591
|
+
__Response:__
|
|
592
|
+
|
|
593
|
+
Returns `204 No Content` on success.
|
|
594
|
+
|
|
595
|
+
### `POST /:account_slug/cards/:card_number/taggings`
|
|
596
|
+
|
|
597
|
+
Toggles a tag on or off for a card. If the tag doesn't exist, it will be created.
|
|
598
|
+
|
|
599
|
+
| Parameter | Type | Required | Description |
|
|
600
|
+
|-----------|------|----------|-------------|
|
|
601
|
+
| `tag_title` | string | Yes | The title of the tag (leading `#` is stripped) |
|
|
602
|
+
|
|
603
|
+
__Response:__
|
|
604
|
+
|
|
605
|
+
Returns `204 No Content` on success.
|
|
606
|
+
|
|
607
|
+
### `POST /:account_slug/cards/:card_number/assignments`
|
|
608
|
+
|
|
609
|
+
Toggles assignment of a user to/from a card.
|
|
610
|
+
|
|
611
|
+
| Parameter | Type | Required | Description |
|
|
612
|
+
|-----------|------|----------|-------------|
|
|
613
|
+
| `assignee_id` | string | Yes | The ID of the user to assign/unassign |
|
|
614
|
+
|
|
615
|
+
__Response:__
|
|
616
|
+
|
|
617
|
+
Returns `204 No Content` on success.
|
|
618
|
+
|
|
619
|
+
### `POST /:account_slug/cards/:card_number/watch`
|
|
620
|
+
|
|
621
|
+
Subscribes the current user to notifications for this card.
|
|
622
|
+
|
|
623
|
+
__Response:__
|
|
624
|
+
|
|
625
|
+
Returns `204 No Content` on success.
|
|
626
|
+
|
|
627
|
+
### `DELETE /:account_slug/cards/:card_number/watch`
|
|
628
|
+
|
|
629
|
+
Unsubscribes the current user from notifications for this card.
|
|
630
|
+
|
|
631
|
+
__Response:__
|
|
632
|
+
|
|
633
|
+
Returns `204 No Content` on success.
|
|
634
|
+
|
|
635
|
+
## Comments
|
|
636
|
+
|
|
637
|
+
Comments are attached to cards and support rich text.
|
|
638
|
+
|
|
639
|
+
### `GET /:account_slug/cards/:card_number/comments`
|
|
640
|
+
|
|
641
|
+
Returns a paginated list of comments on a card, sorted chronologically (oldest first).
|
|
642
|
+
|
|
643
|
+
__Response:__
|
|
644
|
+
|
|
645
|
+
```json
|
|
646
|
+
[
|
|
647
|
+
{
|
|
648
|
+
"id": "03f5v9zo9qlcwwpyc0ascnikz",
|
|
649
|
+
"created_at": "2025-12-05T19:36:35.534Z",
|
|
650
|
+
"updated_at": "2025-12-05T19:36:35.534Z",
|
|
651
|
+
"body": {
|
|
652
|
+
"plain_text": "This looks great!",
|
|
653
|
+
"html": "<div class=\"action-text-content\">This looks great!</div>"
|
|
654
|
+
},
|
|
655
|
+
"creator": {
|
|
656
|
+
"id": "03f5v9zjw7pz8717a4no1h8a7",
|
|
657
|
+
"name": "David Heinemeier Hansson",
|
|
658
|
+
"role": "owner",
|
|
659
|
+
"active": true,
|
|
660
|
+
"email_address": "david@example.com",
|
|
661
|
+
"created_at": "2025-12-05T19:36:35.401Z",
|
|
662
|
+
"url": "http://fizzy.localhost:3006/897362094/users/03f5v9zjw7pz8717a4no1h8a7"
|
|
663
|
+
},
|
|
664
|
+
"reactions_url": "http://fizzy.localhost:3006/897362094/cards/3/comments/03f5v9zo9qlcwwpyc0ascnikz/reactions",
|
|
665
|
+
"url": "http://fizzy.localhost:3006/897362094/cards/3/comments/03f5v9zo9qlcwwpyc0ascnikz"
|
|
666
|
+
}
|
|
667
|
+
]
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
### `GET /:account_slug/cards/:card_number/comments/:comment_id`
|
|
671
|
+
|
|
672
|
+
Returns a specific comment.
|
|
673
|
+
|
|
674
|
+
__Response:__
|
|
675
|
+
|
|
676
|
+
```json
|
|
677
|
+
{
|
|
678
|
+
"id": "03f5v9zo9qlcwwpyc0ascnikz",
|
|
679
|
+
"created_at": "2025-12-05T19:36:35.534Z",
|
|
680
|
+
"updated_at": "2025-12-05T19:36:35.534Z",
|
|
681
|
+
"body": {
|
|
682
|
+
"plain_text": "This looks great!",
|
|
683
|
+
"html": "<div class=\"action-text-content\">This looks great!</div>"
|
|
684
|
+
},
|
|
685
|
+
"creator": {
|
|
686
|
+
"id": "03f5v9zjw7pz8717a4no1h8a7",
|
|
687
|
+
"name": "David Heinemeier Hansson",
|
|
688
|
+
"role": "owner",
|
|
689
|
+
"active": true,
|
|
690
|
+
"email_address": "david@example.com",
|
|
691
|
+
"created_at": "2025-12-05T19:36:35.401Z",
|
|
692
|
+
"url": "http://fizzy.localhost:3006/897362094/users/03f5v9zjw7pz8717a4no1h8a7"
|
|
693
|
+
},
|
|
694
|
+
"reactions_url": "http://fizzy.localhost:3006/897362094/cards/3/comments/03f5v9zo9qlcwwpyc0ascnikz/reactions",
|
|
695
|
+
"url": "http://fizzy.localhost:3006/897362094/cards/3/comments/03f5v9zo9qlcwwpyc0ascnikz"
|
|
696
|
+
}
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
### `POST /:account_slug/cards/:card_number/comments`
|
|
700
|
+
|
|
701
|
+
Creates a new comment on a card.
|
|
702
|
+
|
|
703
|
+
| Parameter | Type | Required | Description |
|
|
704
|
+
|-----------|------|----------|-------------|
|
|
705
|
+
| `body` | string | Yes | The comment body (supports rich text) |
|
|
706
|
+
| `created_at` | datetime | No | Override creation timestamp (ISO 8601 format) |
|
|
707
|
+
|
|
708
|
+
__Request:__
|
|
709
|
+
|
|
710
|
+
```json
|
|
711
|
+
{
|
|
712
|
+
"comment": {
|
|
713
|
+
"body": "This looks great!"
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
__Response:__
|
|
719
|
+
|
|
720
|
+
Returns `201 Created` with a `Location` header pointing to the new comment.
|
|
721
|
+
|
|
722
|
+
### `PUT /:account_slug/cards/:card_number/comments/:comment_id`
|
|
723
|
+
|
|
724
|
+
Updates a comment. Only the comment creator can update their comments.
|
|
725
|
+
|
|
726
|
+
| Parameter | Type | Required | Description |
|
|
727
|
+
|-----------|------|----------|-------------|
|
|
728
|
+
| `body` | string | Yes | The updated comment body |
|
|
729
|
+
|
|
730
|
+
__Request:__
|
|
731
|
+
|
|
732
|
+
```json
|
|
733
|
+
{
|
|
734
|
+
"comment": {
|
|
735
|
+
"body": "This looks even better now!"
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
__Response:__
|
|
741
|
+
|
|
742
|
+
Returns the updated comment.
|
|
743
|
+
|
|
744
|
+
### `DELETE /:account_slug/cards/:card_number/comments/:comment_id`
|
|
745
|
+
|
|
746
|
+
Deletes a comment. Only the comment creator can delete their comments.
|
|
747
|
+
|
|
748
|
+
__Response:__
|
|
749
|
+
|
|
750
|
+
Returns `204 No Content` on success.
|
|
751
|
+
|
|
752
|
+
## Reactions
|
|
753
|
+
|
|
754
|
+
Reactions are short (16-character max) responses to comments.
|
|
755
|
+
|
|
756
|
+
### `GET /:account_slug/cards/:card_number/comments/:comment_id/reactions`
|
|
757
|
+
|
|
758
|
+
Returns a list of reactions on a comment.
|
|
759
|
+
|
|
760
|
+
__Response:__
|
|
761
|
+
|
|
762
|
+
```json
|
|
763
|
+
[
|
|
764
|
+
{
|
|
765
|
+
"id": "03f5v9zo9qlcwwpyc0ascnikz",
|
|
766
|
+
"content": "👍",
|
|
767
|
+
"reacter": {
|
|
768
|
+
"id": "03f5v9zjw7pz8717a4no1h8a7",
|
|
769
|
+
"name": "David Heinemeier Hansson",
|
|
770
|
+
"role": "owner",
|
|
771
|
+
"active": true,
|
|
772
|
+
"email_address": "david@example.com",
|
|
773
|
+
"created_at": "2025-12-05T19:36:35.401Z",
|
|
774
|
+
"url": "http://fizzy.localhost:3006/897362094/users/03f5v9zjw7pz8717a4no1h8a7"
|
|
775
|
+
},
|
|
776
|
+
"url": "http://fizzy.localhost:3006/897362094/cards/3/comments/03f5v9zo9qlcwwpyc0ascnikz/reactions/03f5v9zo9qlcwwpyc0ascnikz"
|
|
777
|
+
}
|
|
778
|
+
]
|
|
779
|
+
```
|
|
780
|
+
|
|
781
|
+
### `POST /:account_slug/cards/:card_number/comments/:comment_id/reactions`
|
|
782
|
+
|
|
783
|
+
Adds a reaction to a comment.
|
|
784
|
+
|
|
785
|
+
| Parameter | Type | Required | Description |
|
|
786
|
+
|-----------|------|----------|-------------|
|
|
787
|
+
| `content` | string | Yes | The reaction text |
|
|
788
|
+
|
|
789
|
+
__Request:__
|
|
790
|
+
|
|
791
|
+
```json
|
|
792
|
+
{
|
|
793
|
+
"reaction": {
|
|
794
|
+
"content": "Great 👍"
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
__Response:__
|
|
800
|
+
|
|
801
|
+
Returns `201 Created` on success.
|
|
802
|
+
|
|
803
|
+
### `DELETE /:account_slug/cards/:card_number/comments/:comment_id/reactions/:reaction_id`
|
|
804
|
+
|
|
805
|
+
Removes your reaction from a comment.
|
|
806
|
+
|
|
807
|
+
__Response:__
|
|
808
|
+
|
|
809
|
+
Returns `204 No Content` on success.
|
|
810
|
+
|
|
811
|
+
## Steps
|
|
812
|
+
|
|
813
|
+
Steps are to-do items on a card.
|
|
814
|
+
|
|
815
|
+
### `GET /:account_slug/cards/:card_number/steps/:step_id`
|
|
816
|
+
|
|
817
|
+
Returns a specific step.
|
|
818
|
+
|
|
819
|
+
__Response:__
|
|
820
|
+
|
|
821
|
+
```json
|
|
822
|
+
{
|
|
823
|
+
"id": "03f5v9zo9qlcwwpyc0ascnikz",
|
|
824
|
+
"content": "Write tests",
|
|
825
|
+
"completed": false
|
|
826
|
+
}
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
### `POST /:account_slug/cards/:card_number/steps`
|
|
830
|
+
|
|
831
|
+
Creates a new step on a card.
|
|
832
|
+
|
|
833
|
+
| Parameter | Type | Required | Description |
|
|
834
|
+
|-----------|------|----------|-------------|
|
|
835
|
+
| `content` | string | Yes | The step text |
|
|
836
|
+
| `completed` | boolean | No | Whether the step is completed (default: `false`) |
|
|
837
|
+
|
|
838
|
+
__Request:__
|
|
839
|
+
|
|
840
|
+
```json
|
|
841
|
+
{
|
|
842
|
+
"step": {
|
|
843
|
+
"content": "Write tests"
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
```
|
|
847
|
+
|
|
848
|
+
__Response:__
|
|
849
|
+
|
|
850
|
+
Returns `201 Created` with a `Location` header pointing to the new step.
|
|
851
|
+
|
|
852
|
+
### `PUT /:account_slug/cards/:card_number/steps/:step_id`
|
|
853
|
+
|
|
854
|
+
Updates a step.
|
|
855
|
+
|
|
856
|
+
| Parameter | Type | Required | Description |
|
|
857
|
+
|-----------|------|----------|-------------|
|
|
858
|
+
| `content` | string | No | The step text |
|
|
859
|
+
| `completed` | boolean | No | Whether the step is completed |
|
|
860
|
+
|
|
861
|
+
__Request:__
|
|
862
|
+
|
|
863
|
+
```json
|
|
864
|
+
{
|
|
865
|
+
"step": {
|
|
866
|
+
"completed": true
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
```
|
|
870
|
+
|
|
871
|
+
__Response:__
|
|
872
|
+
|
|
873
|
+
Returns the updated step.
|
|
874
|
+
|
|
875
|
+
### `DELETE /:account_slug/cards/:card_number/steps/:step_id`
|
|
876
|
+
|
|
877
|
+
Deletes a step.
|
|
878
|
+
|
|
879
|
+
__Response:__
|
|
880
|
+
|
|
881
|
+
Returns `204 No Content` on success.
|
|
882
|
+
|
|
883
|
+
## Tags
|
|
884
|
+
|
|
885
|
+
Tags are labels that can be applied to cards for organization and filtering.
|
|
886
|
+
|
|
887
|
+
### `GET /:account_slug/tags`
|
|
888
|
+
|
|
889
|
+
Returns a list of all tags in the account, sorted alphabetically.
|
|
890
|
+
|
|
891
|
+
__Response:__
|
|
892
|
+
|
|
893
|
+
```json
|
|
894
|
+
[
|
|
895
|
+
{
|
|
896
|
+
"id": "03f5v9zo9qlcwwpyc0ascnikz",
|
|
897
|
+
"title": "bug",
|
|
898
|
+
"created_at": "2025-12-05T19:36:35.534Z",
|
|
899
|
+
"url": "http://fizzy.localhost:3006/897362094/cards?tag_ids[]=03f5v9zo9qlcwwpyc0ascnikz"
|
|
900
|
+
},
|
|
901
|
+
{
|
|
902
|
+
"id": "03f5v9zo9qlcwwpyc0ascnilz",
|
|
903
|
+
"title": "feature",
|
|
904
|
+
"created_at": "2025-12-05T19:36:35.534Z",
|
|
905
|
+
"url": "http://fizzy.localhost:3006/897362094/cards?tag_ids[]=03f5v9zo9qlcwwpyc0ascnilz"
|
|
906
|
+
}
|
|
907
|
+
]
|
|
908
|
+
```
|
|
909
|
+
|
|
910
|
+
## Columns
|
|
911
|
+
|
|
912
|
+
Columns represent stages in a workflow on a board. Cards move through columns as they progress.
|
|
913
|
+
|
|
914
|
+
### `GET /:account_slug/boards/:board_id/columns`
|
|
915
|
+
|
|
916
|
+
Returns a list of columns on a board, sorted by position.
|
|
917
|
+
|
|
918
|
+
__Response:__
|
|
919
|
+
|
|
920
|
+
```json
|
|
921
|
+
[
|
|
922
|
+
{
|
|
923
|
+
"id": "03f5v9zkft4hj9qq0lsn9ohcm",
|
|
924
|
+
"name": "Recording",
|
|
925
|
+
"color": "var(--color-card-default)",
|
|
926
|
+
"created_at": "2025-12-05T19:36:35.534Z"
|
|
927
|
+
},
|
|
928
|
+
{
|
|
929
|
+
"id": "03f5v9zkft4hj9qq0lsn9ohcn",
|
|
930
|
+
"name": "Published",
|
|
931
|
+
"color": "var(--color-card-4)",
|
|
932
|
+
"created_at": "2025-12-05T19:36:35.534Z"
|
|
933
|
+
}
|
|
934
|
+
]
|
|
935
|
+
```
|
|
936
|
+
|
|
937
|
+
### `GET /:account_slug/boards/:board_id/columns/:column_id`
|
|
938
|
+
|
|
939
|
+
Returns the specified column.
|
|
940
|
+
|
|
941
|
+
__Response:__
|
|
942
|
+
|
|
943
|
+
```json
|
|
944
|
+
{
|
|
945
|
+
"id": "03f5v9zkft4hj9qq0lsn9ohcm",
|
|
946
|
+
"name": "In Progress",
|
|
947
|
+
"color": "var(--color-card-default)",
|
|
948
|
+
"created_at": "2025-12-05T19:36:35.534Z"
|
|
949
|
+
}
|
|
950
|
+
```
|
|
951
|
+
|
|
952
|
+
### `POST /:account_slug/boards/:board_id/columns`
|
|
953
|
+
|
|
954
|
+
Creates a new column on the board.
|
|
955
|
+
|
|
956
|
+
| Parameter | Type | Required | Description |
|
|
957
|
+
|-----------|------|----------|-------------|
|
|
958
|
+
| `name` | string | Yes | The name of the column |
|
|
959
|
+
| `color` | string | No | The column color. One of: `var(--color-card-default)` (Blue), `var(--color-card-1)` (Gray), `var(--color-card-2)` (Tan), `var(--color-card-3)` (Yellow), `var(--color-card-4)` (Lime), `var(--color-card-5)` (Aqua), `var(--color-card-6)` (Violet), `var(--color-card-7)` (Purple), `var(--color-card-8)` (Pink) |
|
|
960
|
+
|
|
961
|
+
__Request:__
|
|
962
|
+
|
|
963
|
+
```json
|
|
964
|
+
{
|
|
965
|
+
"column": {
|
|
966
|
+
"name": "In Progress",
|
|
967
|
+
"color": "var(--color-card-4)"
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
```
|
|
971
|
+
|
|
972
|
+
__Response:__
|
|
973
|
+
|
|
974
|
+
Returns `201 Created` with a `Location` header pointing to the new column.
|
|
975
|
+
|
|
976
|
+
### `PUT /:account_slug/boards/:board_id/columns/:column_id`
|
|
977
|
+
|
|
978
|
+
Updates a column.
|
|
979
|
+
|
|
980
|
+
| Parameter | Type | Required | Description |
|
|
981
|
+
|-----------|------|----------|-------------|
|
|
982
|
+
| `name` | string | No | The name of the column |
|
|
983
|
+
| `color` | string | No | The column color |
|
|
984
|
+
|
|
985
|
+
__Request:__
|
|
986
|
+
|
|
987
|
+
```json
|
|
988
|
+
{
|
|
989
|
+
"column": {
|
|
990
|
+
"name": "Done"
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
```
|
|
994
|
+
|
|
995
|
+
__Response:__
|
|
996
|
+
|
|
997
|
+
Returns `204 No Content` on success.
|
|
998
|
+
|
|
999
|
+
### `DELETE /:account_slug/boards/:board_id/columns/:column_id`
|
|
1000
|
+
|
|
1001
|
+
Deletes a column.
|
|
1002
|
+
|
|
1003
|
+
__Response:__
|
|
1004
|
+
|
|
1005
|
+
Returns `204 No Content` on success.
|
|
1006
|
+
|
|
1007
|
+
## Users
|
|
1008
|
+
|
|
1009
|
+
Users represent people who have access to an account.
|
|
1010
|
+
|
|
1011
|
+
### `GET /:account_slug/users`
|
|
1012
|
+
|
|
1013
|
+
Returns a list of active users in the account.
|
|
1014
|
+
|
|
1015
|
+
__Response:__
|
|
1016
|
+
|
|
1017
|
+
```json
|
|
1018
|
+
[
|
|
1019
|
+
{
|
|
1020
|
+
"id": "03f5v9zjw7pz8717a4no1h8a7",
|
|
1021
|
+
"name": "David Heinemeier Hansson",
|
|
1022
|
+
"role": "owner",
|
|
1023
|
+
"active": true,
|
|
1024
|
+
"email_address": "david@example.com",
|
|
1025
|
+
"created_at": "2025-12-05T19:36:35.401Z",
|
|
1026
|
+
"url": "http://fizzy.localhost:3006/897362094/users/03f5v9zjw7pz8717a4no1h8a7"
|
|
1027
|
+
},
|
|
1028
|
+
{
|
|
1029
|
+
"id": "03f5v9zjysoy0fqs9yg0ei3hq",
|
|
1030
|
+
"name": "Jason Fried",
|
|
1031
|
+
"role": "member",
|
|
1032
|
+
"active": true,
|
|
1033
|
+
"email_address": "jason@example.com",
|
|
1034
|
+
"created_at": "2025-12-05T19:36:35.419Z",
|
|
1035
|
+
"url": "http://fizzy.localhost:3006/897362094/users/03f5v9zjysoy0fqs9yg0ei3hq"
|
|
1036
|
+
},
|
|
1037
|
+
{
|
|
1038
|
+
"id": "03f5v9zk1dtqduod5bkhv3k8m",
|
|
1039
|
+
"name": "Jason Zimdars",
|
|
1040
|
+
"role": "member",
|
|
1041
|
+
"active": true,
|
|
1042
|
+
"email_address": "jz@example.com",
|
|
1043
|
+
"created_at": "2025-12-05T19:36:35.435Z",
|
|
1044
|
+
"url": "http://fizzy.localhost:3006/897362094/users/03f5v9zk1dtqduod5bkhv3k8m"
|
|
1045
|
+
},
|
|
1046
|
+
{
|
|
1047
|
+
"id": "03f5v9zk3nw9ja92e7s4h2wbe",
|
|
1048
|
+
"name": "Kevin Mcconnell",
|
|
1049
|
+
"role": "member",
|
|
1050
|
+
"active": true,
|
|
1051
|
+
"email_address": "kevin@example.com",
|
|
1052
|
+
"created_at": "2025-12-05T19:36:35.451Z",
|
|
1053
|
+
"url": "http://fizzy.localhost:3006/897362094/users/03f5v9zk3nw9ja92e7s4h2wbe"
|
|
1054
|
+
}
|
|
1055
|
+
]
|
|
1056
|
+
```
|
|
1057
|
+
|
|
1058
|
+
### `GET /:account_slug/users/:user_id`
|
|
1059
|
+
|
|
1060
|
+
Returns the specified user.
|
|
1061
|
+
|
|
1062
|
+
__Response:__
|
|
1063
|
+
|
|
1064
|
+
```json
|
|
1065
|
+
{
|
|
1066
|
+
"id": "03f5v9zjw7pz8717a4no1h8a7",
|
|
1067
|
+
"name": "David Heinemeier Hansson",
|
|
1068
|
+
"role": "owner",
|
|
1069
|
+
"active": true,
|
|
1070
|
+
"email_address": "david@example.com",
|
|
1071
|
+
"created_at": "2025-12-05T19:36:35.401Z",
|
|
1072
|
+
"url": "http://fizzy.localhost:3006/897362094/users/03f5v9zjw7pz8717a4no1h8a7"
|
|
1073
|
+
}
|
|
1074
|
+
```
|
|
1075
|
+
|
|
1076
|
+
### `PUT /:account_slug/users/:user_id`
|
|
1077
|
+
|
|
1078
|
+
Updates a user. You can only update users you have permission to change.
|
|
1079
|
+
|
|
1080
|
+
| Parameter | Type | Required | Description |
|
|
1081
|
+
|-----------|------|----------|-------------|
|
|
1082
|
+
| `name` | string | No | The user's display name |
|
|
1083
|
+
| `avatar` | file | No | The user's avatar image |
|
|
1084
|
+
|
|
1085
|
+
__Request:__
|
|
1086
|
+
|
|
1087
|
+
```json
|
|
1088
|
+
{
|
|
1089
|
+
"user": {
|
|
1090
|
+
"name": "David H. Hansson"
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
```
|
|
1094
|
+
|
|
1095
|
+
__Response:__
|
|
1096
|
+
|
|
1097
|
+
Returns `204 No Content` on success.
|
|
1098
|
+
|
|
1099
|
+
### `DELETE /:account_slug/users/:user_id`
|
|
1100
|
+
|
|
1101
|
+
Deactivates a user. You can only deactivate users you have permission to change.
|
|
1102
|
+
|
|
1103
|
+
__Response:__
|
|
1104
|
+
|
|
1105
|
+
Returns `204 No Content` on success.
|
|
1106
|
+
|
|
1107
|
+
## Notifications
|
|
1108
|
+
|
|
1109
|
+
Notifications inform users about events that happened in the account, such as comments, assignments, and card updates.
|
|
1110
|
+
|
|
1111
|
+
### `GET /:account_slug/notifications`
|
|
1112
|
+
|
|
1113
|
+
Returns a list of notifications for the current user. Unread notifications are returned first, followed by read notifications.
|
|
1114
|
+
|
|
1115
|
+
__Response:__
|
|
1116
|
+
|
|
1117
|
+
```json
|
|
1118
|
+
[
|
|
1119
|
+
{
|
|
1120
|
+
"id": "03f5va03bpuvkcjemcxl73ho2",
|
|
1121
|
+
"read": false,
|
|
1122
|
+
"read_at": null,
|
|
1123
|
+
"created_at": "2025-11-19T04:03:58.000Z",
|
|
1124
|
+
"title": "Plain text mentions",
|
|
1125
|
+
"body": "Assigned to self",
|
|
1126
|
+
"creator": {
|
|
1127
|
+
"id": "03f5v9zjw7pz8717a4no1h8a7",
|
|
1128
|
+
"name": "David Heinemeier Hansson",
|
|
1129
|
+
"role": "owner",
|
|
1130
|
+
"active": true,
|
|
1131
|
+
"email_address": "david@example.com",
|
|
1132
|
+
"created_at": "2025-12-05T19:36:35.401Z",
|
|
1133
|
+
"url": "http://fizzy.localhost:3006/897362094/users/03f5v9zjw7pz8717a4no1h8a7"
|
|
1134
|
+
},
|
|
1135
|
+
"card": {
|
|
1136
|
+
"id": "03f5v9zo9qlcwwpyc0ascnikz",
|
|
1137
|
+
"title": "Plain text mentions",
|
|
1138
|
+
"status": "published",
|
|
1139
|
+
"url": "http://fizzy.localhost:3006/897362094/cards/3"
|
|
1140
|
+
},
|
|
1141
|
+
"url": "http://fizzy.localhost:3006/897362094/notifications/03f5va03bpuvkcjemcxl73ho2"
|
|
1142
|
+
}
|
|
1143
|
+
]
|
|
1144
|
+
```
|
|
1145
|
+
|
|
1146
|
+
### `POST /:account_slug/notifications/:notification_id/reading`
|
|
1147
|
+
|
|
1148
|
+
Marks a notification as read.
|
|
1149
|
+
|
|
1150
|
+
__Response:__
|
|
1151
|
+
|
|
1152
|
+
Returns `204 No Content` on success.
|
|
1153
|
+
|
|
1154
|
+
### `DELETE /:account_slug/notifications/:notification_id/reading`
|
|
1155
|
+
|
|
1156
|
+
Marks a notification as unread.
|
|
1157
|
+
|
|
1158
|
+
__Response:__
|
|
1159
|
+
|
|
1160
|
+
Returns `204 No Content` on success.
|
|
1161
|
+
|
|
1162
|
+
### `POST /:account_slug/notifications/bulk_reading`
|
|
1163
|
+
|
|
1164
|
+
Marks all unread notifications as read.
|
|
1165
|
+
|
|
1166
|
+
__Response:__
|
|
1167
|
+
|
|
1168
|
+
Returns `204 No Content` on success.
|