| name | fizzy |
| description | Interact with the Fizzy kanban tool via its REST API. Use this skill whenever the user wants to read or modify anything in Fizzy — listing boards, finding or creating cards, moving cards between columns, closing cards, adding comments, checking activity, managing tags, or any other Fizzy operation. Trigger on requests like "show me my Fizzy boards", "create a card for X", "what's in the backlog?", "move card |
Fizzy API Skill
Fizzy is a kanban-style project management tool. This skill covers everything needed to interact with it programmatically.
Configuration
Two environment variables must be present:
| Variable | Example |
|---|
FIZZY_BASE_URL | https://fizzy.example.com |
FIZZY_API_KEY | Personal access token with Read+Write permission |
All requests need these headers:
Authorization: Bearer $FIZZY_API_KEY
Accept: application/json
Content-Type: application/json (for POST/PUT/PATCH)
Critical: Accept: application/json is required on every request — including write operations with no response body (taggings, closure, triage). Fizzy's bearer token authentication is gated on request.format.json?. Without this header, the token is silently rejected with a 401 even with valid credentials.
Account slug
Every resource URL is scoped to an account slug — a path segment like /897362094 that identifies the account. Resolve it once per session:
curl -s -H "Authorization: Bearer $FIZZY_API_KEY" -H "Accept: application/json" \
"$FIZZY_BASE_URL/my/identity" | jq -r '.accounts[0].slug'
Cache the result as ACCOUNT_SLUG and reuse it — don't re-fetch it on every call. For self-hosted single-account instances, the slug is stable and rarely changes.
If you're using a dedicated bot/agent token (rather than a personal one), comments and actions made with it will show up as that bot user in Fizzy's activity feed — useful for keeping agent activity visibly distinct from human activity.
Fizzy workflow model
Cards flow through columns on a board. Fizzy also has three built-in states outside of columns:
- Triage: unprocessed inbox — cards land here before being placed in a column
- Not Now: explicitly deprioritized — Fizzy's entropy system will resurface these periodically
- Done: closed cards — immune to entropy, stay put permanently
Use columns for active workflow stages (e.g. "In Research", "In Development"). Use tags to add metadata or mark terminal states (e.g. active, retired on closed cards).
Common workflows
List all boards
curl -s -H "Authorization: Bearer $FIZZY_API_KEY" -H "Accept: application/json" \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/boards" | jq .
Get columns for a board
curl -s -H "Authorization: Bearer $FIZZY_API_KEY" -H "Accept: application/json" \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/boards/$BOARD_ID/columns" | jq .
List cards (with filters)
curl -s -H "Authorization: Bearer $FIZZY_API_KEY" -H "Accept: application/json" \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/cards" | jq .
curl -s ... "$FIZZY_BASE_URL$ACCOUNT_SLUG/cards?board_ids[]=$BOARD_ID" | jq .
curl -s ... "$FIZZY_BASE_URL$ACCOUNT_SLUG/cards?assignment_status=unassigned" | jq .
curl -s ... "$FIZZY_BASE_URL$ACCOUNT_SLUG/cards?terms[]=dark+mode" | jq .
curl -s ... "$FIZZY_BASE_URL$ACCOUNT_SLUG/cards?indexed_by=maybe" | jq .
Get a specific card
curl -s -H "Authorization: Bearer $FIZZY_API_KEY" -H "Accept: application/json" \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/cards/$CARD_NUMBER" | jq .
Cards are referenced by their human-readable number (e.g. 42), not their internal ID.
Create a card
curl -s -X POST \
-H "Authorization: Bearer $FIZZY_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"card": {"title": "My new card", "description": "<p>Details here</p>"}}' \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/boards/$BOARD_ID/cards"
Returns 201 Created with a Location header pointing to the new card.
Update a card
curl -s -X PUT \
-H "Authorization: Bearer $FIZZY_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"card": {"title": "Updated title"}}' \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/cards/$CARD_NUMBER"
Delete a card
curl -s -X DELETE -H "Authorization: Bearer $FIZZY_API_KEY" \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/cards/$CARD_NUMBER"
Returns 204 No Content. Permanent — use with care.
Move a card into a column (triage)
curl -s -X POST \
-H "Authorization: Bearer $FIZZY_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"column_id": "$COLUMN_ID"}' \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/cards/$CARD_NUMBER/triage"
Returns 204 No Content on success.
Send a card back to triage (remove from column)
curl -s -X DELETE \
-H "Authorization: Bearer $FIZZY_API_KEY" \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/cards/$CARD_NUMBER/triage"
Close / reopen a card
curl -s -X POST -H "Authorization: Bearer $FIZZY_API_KEY" \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/cards/$CARD_NUMBER/closure"
curl -s -X DELETE -H "Authorization: Bearer $FIZZY_API_KEY" \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/cards/$CARD_NUMBER/closure"
Move a card to "Not Now"
curl -s -X POST -H "Authorization: Bearer $FIZZY_API_KEY" \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/cards/$CARD_NUMBER/not_now"
Move a card to a different board
curl -s -X PUT \
-H "Authorization: Bearer $FIZZY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"board_id": "$TARGET_BOARD_ID"}' \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/cards/$CARD_NUMBER/board"
Assign / unassign a user (toggle)
curl -s -X POST \
-H "Authorization: Bearer $FIZZY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"assignee_id": "$USER_ID"}' \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/cards/$CARD_NUMBER/assignments"
This is a toggle — calling it on an already-assigned user unassigns them.
Add a comment
curl -s -X POST \
-H "Authorization: Bearer $FIZZY_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"comment": {"body": "This looks great!"}}' \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/cards/$CARD_NUMBER/comments"
Toggle a tag on a card
curl -s -X POST \
-H "Authorization: Bearer $FIZZY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"tag_title": "bug"}' \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/cards/$CARD_NUMBER/taggings"
Caution: this is a toggle, not an add. Calling it twice removes the tag. Before applying a tag, check the card's existing tags array and skip the call if the tag is already present.
List all tags
curl -s -H "Authorization: Bearer $FIZZY_API_KEY" -H "Accept: application/json" \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/tags" | jq .
List users
curl -s -H "Authorization: Bearer $FIZZY_API_KEY" -H "Accept: application/json" \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/users" | jq .
Activity feed
curl -s -H "Authorization: Bearer $FIZZY_API_KEY" -H "Accept: application/json" \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/activities" | jq .
curl -s ... "$FIZZY_BASE_URL$ACCOUNT_SLUG/activities?board_ids[]=$BOARD_ID" | jq .
curl -s ... "$FIZZY_BASE_URL$ACCOUNT_SLUG/activities?creator_ids[]=$USER_ID" | jq .
My pinned cards
curl -s -H "Authorization: Bearer $FIZZY_API_KEY" -H "Accept: application/json" \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/my/pins" | jq .
Pin / unpin a card
curl -s -X POST -H "Authorization: Bearer $FIZZY_API_KEY" \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/cards/$CARD_NUMBER/pin"
curl -s -X DELETE -H "Authorization: Bearer $FIZZY_API_KEY" \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/cards/$CARD_NUMBER/pin"
Steps (to-do items on a card)
curl -s -X POST \
-H "Authorization: Bearer $FIZZY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"step": {"content": "Write tests"}}' \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/cards/$CARD_NUMBER/steps"
curl -s -X PUT \
-H "Authorization: Bearer $FIZZY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"step": {"completed": true}}' \
"$FIZZY_BASE_URL$ACCOUNT_SLUG/cards/$CARD_NUMBER/steps/$STEP_ID"
Pagination
All list endpoints are paginated. If there are more results, the response includes a Link header:
link: <https://fizzy.example.com/.../cards?page=2>; rel="next"
To fetch all pages, follow the next link until it disappears. Example:
page="$FIZZY_BASE_URL$ACCOUNT_SLUG/cards"
while [ -n "$page" ]; do
response=$(curl -sI -H "Authorization: Bearer $FIZZY_API_KEY" \
-H "Accept: application/json" -w "\n%{stdout}" "$page")
page=$(echo "$response" | grep -i 'link:' | grep -o '<[^>]*>; rel="next"' | grep -o 'https://[^>]*')
done
For most interactive tasks, a single page is enough. Only paginate when the user needs a complete list.
List parameters
When filtering by multiple IDs, repeat the parameter:
?board_ids[]=ID1&board_ids[]=ID2
Error handling
| Status | Meaning |
|---|
| 401 | Bad or missing API key — or database lock contention on write (see below) |
| 403 | Insufficient permissions |
| 404 | Resource not found (or no access) |
| 422 | Validation failed — response body has error details |
| 500 | Bad input (e.g. wrong type for a field) — validate before sending |
Write contention on SQLite-backed instances
Self-hosted Fizzy instances commonly use SQLite. Background job workers (e.g. Turbo Stream broadcasts) can compete with API write requests for the database write lock. Under concurrent load, write requests can fail with a misleading 401 response — the actual cause is a database-busy/locked error, not bad auth. If you hit a 401 on a write that looks like it should have valid auth, retry once before assuming it's a real auth failure.
Rich text fields
description (cards) and body (comments) accept HTML. Keep it simple:
<p>Plain paragraph</p>
<p>With <strong>bold</strong> and <em>italic</em></p>
<ul><li>Item one</li><li>Item two</li></ul>
Tips
- Always resolve the account slug first via
/my/identity if you don't have it, then cache it for the session.
- Cards are addressed by number in URLs (e.g.
/cards/42), not by their internal id.
- The
column field on a card is only present when the card has been triaged into a column; cards in Triage/Not Now/Done have no column.
closed: true means the card is Done.
- When closing a card and then tagging it (e.g., a terminal status tag), do the operations sequentially — the card must be closed before applying the tag.
- Check a card's existing
tags array before calling /taggings to avoid accidentally toggling a tag off.
- When you need a board ID or column ID, list them first — they are opaque strings, not human-readable names.
- Fizzy's
steps endpoint (POST/PUT .../cards/{number}/steps) gives cards a real to-do checklist — use it for multi-stage work instead of just narrating steps in the description or a comment. Anyone opening the card can see progress at a glance.