Delivery API
TBoard API reference
TBoard is the delivery source of truth. A project can hold multiple boards (e.g. Development, Bugs, Business requirements), each with its own configurable columns and its own work-item key prefix. Agents should load the work item before acting, record material progress, attach verifiable evidence, and move it between columns only when the workflow permits it.
/api/boardAll project, board, column, and work-item identifiers are UUIDs. Work-item keys such as DB-0049 are per-board display references, not route identifiers.
Each work item has a boardId and a columnId; columnId is the authoritative board position. The legacy phase enum (inbox…done) is kept as a derived compatibility value. Move an item with /column (authoritative) or the legacy /phase. A board or doc space can be private (visible to admins/owners and its creator only). Creating boards or doc spaces requires an org admin; the default board is auto-provisioned.
All Board calls
| Method | Path | Purpose |
|---|---|---|
| GET | /api/board/health | Delivery Board service status. |
| GET | /api/board/auth/check?projectId=:projectId | Verify Board authority for a project.Board read |
| GET | /api/board/projects | List Board projects visible to the credential.Board read |
| GET | /api/board/projects/:projectId | Read one project.Board read |
| GET | /api/board/projects/:projectId/boards | List the project's boards (visible to the caller).Board read |
| POST | /api/board/projects/:projectId/boards | Create a board.Board write · admin |
| GET | /api/board/projects/:projectId/boards/:boardId | Read a board with its columns.Board read |
| PATCH | /api/board/projects/:projectId/boards/:boardId | Update a board (name, kind, visibility, sortOrder, archived).Board write · admin |
| GET | /api/board/projects/:projectId/boards/:boardId/columns | List a board's columns.Board read |
| POST | /api/board/projects/:projectId/boards/:boardId/columns | Add a column.Board write |
| PATCH | /api/board/projects/:projectId/boards/:boardId/columns/:columnId | Rename / recategorise / reorder a column.Board write |
| DELETE | /api/board/projects/:projectId/boards/:boardId/columns/:columnId | Delete a column (its items move to a surviving column).Board write |
| PATCH | /api/board/projects/:projectId/boards/:boardId/column-order | Reorder columns.Board write |
| GET | /api/board/projects/:projectId/work-items | List/filter work items (boardId, columnId, phase, type…) with cursor pagination.Board read |
| POST | /api/board/projects/:projectId/work-items | Create a work item (on boardId, else the default board).Board write |
| PATCH | /api/board/projects/:projectId/work-items/:workItemId | Update editable work-item fields.Board write |
| PATCH | /api/board/projects/:projectId/work-items/:workItemId/column | Move to a column (authoritative).Board write |
| PATCH | /api/board/projects/:projectId/work-items/:workItemId/phase | Move the legacy phase with a reason.Board write |
| PATCH | /api/board/projects/:projectId/work-items/:workItemId/claim | Claim or release execution ownership.Board write |
| PATCH | /api/board/projects/:projectId/work-items/:workItemId/assignment | Change the assigned user.Board write |
| GET | /api/board/projects/:projectId/work-items/:workItemId/comments | List comments.Board read |
| POST | /api/board/projects/:projectId/work-items/:workItemId/comments | Add a human, agent, or system comment.Board write |
| GET | /api/board/projects/:projectId/work-items/:workItemId/handoffs | List handoffs.Board read |
| POST | /api/board/projects/:projectId/work-items/:workItemId/handoffs | Hand work to another member.Board write |
| PATCH | /api/board/projects/:projectId/work-items/:workItemId/handoffs/:handoffId/accept | Accept a handoff.Board write |
| GET | /api/board/projects/:projectId/work-items/:workItemId/runs | List agent runs and usage.Board read |
| POST | /api/board/projects/:projectId/work-items/:workItemId/runs | Create an execution run.Board write |
| PATCH | /api/board/projects/:projectId/work-items/:workItemId/runs/:runId | Update run state/outcome.Board write |
| POST | /api/board/projects/:projectId/work-items/:workItemId/runs/:runId/usage | Record token/cost usage idempotently.Board write |
| GET | /api/board/projects/:projectId/work-items/:workItemId/review-findings | List structured review findings.Board read |
| POST | /api/board/projects/:projectId/work-items/:workItemId/review-findings | Create a finding.Board write |
| PATCH | /api/board/projects/:projectId/work-items/:workItemId/review-findings/:findingId | Resolve, dismiss, or update a finding.Board write |
| GET | /api/board/projects/:projectId/work-items/:workItemId/evidence | List evidence, optionally filtered by run/finding.Board read |
| POST | /api/board/projects/:projectId/work-items/:workItemId/evidence | Attach evidence.Board write |
| GET | /api/board/events | List audit events by project/work item.Board read |
| POST | /api/board/events | Ingest an additional idempotent audit fact.Board write |
| GET | /api/board/events/stream | Stream Board events.Board read |
| GET | /api/board/projects/:projectId/members/usage | Report member/project agent usage.Board read |
Create a work item
curl -X POST "$TWINDEM_API_BASE/board/projects/$TWINDEM_PROJECT_ID/work-items" \
-H "Authorization: Bearer $TWINDEM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "feature",
"title": "Document payment callback",
"description": "Add contract, examples, and integration notes.",
"priority": "P1",
"labels": ["docs", "api"],
"component": "payments"
}'
Types: epic, story, architecture, feature, bug, task. Priorities: P0–P4. Add "boardId" to target a specific board; omit it to use the project's default board. The key (e.g. BUG-0007) is assigned from that board's prefix.
Boards and columns
List a project's boards, then read one to get its ordered columns. Each column has a key, a label, and a category (todo · in_progress · done). Creating a board (admin) seeds the six default columns; new boards get their own keyPrefix.
GET /api/board/projects/<projectId>/boards
GET /api/board/projects/<projectId>/boards/<boardId> # includes columns
# admin only
POST /api/board/projects/<projectId>/boards
{ "name": "Bug Tracker", "kind": "bugs", "keyPrefix": "BUG", "visibility": "project" }
POST /api/board/projects/<projectId>/boards/<boardId>/columns
{ "label": "Blocked", "category": "todo" }
Board kinds: development, bugs, requirements, custom. Visibility: project (all members) or private (admins/owners + creator).
List and expand work
GET /api/board/projects/<projectId>/work-items
?boardId=<board-id>
&columnId=<column-id>
&phase=in_progress
&type=feature
&include=comments,runs,usage,evidence,findings,events,handoffs
&limit=50
&cursor=<last-work-item-id>
Each work item carries boardId and columnId. Filter by board and/or column; the legacy phase filter still works (inbox, refinement, in_progress, review, uat, done). The response contains workItems and nullable nextCursor. Work items on a private board are hidden from members who cannot see it.
Move a work item
Prefer moving by column — it is authoritative and works with custom columns. The legacy phase endpoint remains for compatibility.
PATCH /api/board/projects/<projectId>/work-items/<workItemId>/column
{ "columnId": "<target-column-id>", "reason": "Implementation and tests complete." }
# legacy, still supported
PATCH /api/board/projects/<projectId>/work-items/<workItemId>/phase
{ "phase": "review", "reason": "Requesting independent review." }
Record an agent run
POST /api/board/projects/<projectId>/work-items/<workItemId>/runs
{
"idempotencyKey": "terminal:<device-id>:<local-run-id>:create",
"executionClient": "headless",
"runRole": "implementation",
"provider": "openai",
"modelLabel": "Codex",
"status": "running",
"summary": "Implementing the approved scope."
}
Run roles include planning, implementation, review, fix, verification, release, answer, and manual. Terminal states include completed, failed, blocked, and cancelled.
Attach evidence
POST /api/board/projects/<projectId>/work-items/<workItemId>/evidence
{
"idempotencyKey": "terminal:<device-id>:<run-id>:tests",
"runId": "<run-id>",
"kind": "test_output",
"health": "healthy",
"title": "API tests passed",
"contentText": "124 passed, 0 failed",
"metadata": { "command": "npm test", "commit": "abc123" }
}
Use review findings for actionable defects; use comments for narrative context; use evidence for proof. Avoid hiding all three inside one unstructured comment.