The API
ogma has a JSON API under /api/v1 for automating projects and boards.
Building an integration with an LLM or agent? Two options:
- MCP (the easy way): the workspace portal serves this whole API as
ready-made tools (
projects_board,projects_card_create, …) at its/mcpendpoint — one line to connect Claude Code or any MCP client, authenticated with the same API tokens. See the portal's/llms.txt. - Raw HTTP: point the model at
/llms.txt— a single plain-Markdown page with this whole reference in a machine-friendly form.
Authenticating
Create a token on the account service (see Your account), then send it as a bearer token:
TOKEN=gbn_...
A token acts as you and carries your permissions. Requests that change data
must send Content-Type: application/json.
What you can do
- You —
GET /me - Projects —
GET|POST /projects,GET|PATCH|DELETE /projects/{id} - Board —
GET /projects/{id}/columns(columns with their cards in one call),POST /projects/{id}/columns,PATCH|DELETE /columns/{id} - Cards —
POST /columns/{id}/cards,GET|PATCH|DELETE /cards/{id},POST /cards/{id}/move,POST /cards/{id}/archive|unarchive(file a card away without destroying it — prefer this to DELETE). PATCH acceptstitle,body,assignee_id,due_at,priority_id,owner_type(humanoragent),shepherds, andwork_phase(empty string clears the optional ones — exceptshepherds, which is a list and clears with[]). Every card payload carriesnumber— the per-board handle the UI shows as#12(server-assigned, never reused); routes always take theid. - Comments —
GET|POST /cards/{id}/comments,DELETE /comments/{id} - Checklist —
GET|POST /cards/{id}/checklist(POST:{"text": …}),PATCH|DELETE /checklist/{id}(PATCH:{"text": …, "done": …, "position": …}, every field optional;position= new 0-based index in the card's checklist order). Cards report the tally aschecklist_done/checklist_total. - Labels —
GET|POST /projects/{id}/labels,PATCH|DELETE /labels/{id}(PATCH renames/recolors:{"name": …, "color": …}, either field optional),GET|POST /cards/{id}/labels,DELETE /cards/{id}/labels/{label_id} - Priorities —
GET|POST /projects/{id}/priorities(the ordered ladder, most urgent first; POST appends at the bottom),PATCH|DELETE /priorities/{id}(PATCH:{"name": …, "color": …, "position": …}, every field optional;position= new 0-based rung, 0 = most urgent, and responses report the same rung unit; DELETE drops cards carrying it back to no priority) - Attachments —
GET|POST /cards/{id}/attachments,GET|POST /comments/{id}/attachments,GET|DELETE /attachments/{id} - Members —
GET|POST /projects/{id}/members,DELETE /projects/{id}/members/{user_id} - For agents — claim and release a card with
POST|DELETE /cards/{id}/claim, or take the next unclaimed agent card withPOST /projects/{id}/claim-next; publish a plan, split a card, or hand it on withPOST /cards/{id}/plan,/decompose,/handoff; entry gates viaGET /cards/{id}/gate,POST /cards/{id}/gate/acks,DELETE /cards/{id}/gate/acks/{criterion_id}andGET|POST /projects/{id}/gate-criteria,PATCH|DELETE /gate-criteria/{id}; the stale-work report atGET /projects/{id}/rot; live attention withPOST /cards/{id}/attention,DELETE /attention,GET /projects/{id}/attention; and findings atGET|POST /cards/{id}/findings. Bodies, responses and the rules behind them are spelled out in/llms.txt.
Your token's project roles apply exactly as they do in the app.
A couple of limits worth knowing: cards and comments created through the API
don't run @mention parsing, so they generate no mentions, notifications, or
activity-history entries (those come from the web app).
Examples
# Create a project
# Add a card, then move it
# Attach a file, then download it
AID=
Upload an attachment as multipart/form-data with a single file field (up
to 10 MB). Downloads always come back as an attachment (never inline).
Errors
Errors have a consistent shape:
Codes include unauthenticated, forbidden, not_found, conflict,
validation_failed, rate_limited, and internal.