Twindem DocumentationProjects · People · AI--:-- UTC

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.

Namespace/api/board

All project, board, column, and work-item identifiers are UUIDs. Work-item keys such as DB-0049 are per-board display references, not route identifiers.

Boards, columns & the legacy phase

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

MethodPathPurpose
GET/api/board/healthDelivery Board service status.
GET/api/board/auth/check?projectId=:projectIdVerify Board authority for a project.Board read
GET/api/board/projectsList Board projects visible to the credential.Board read
GET/api/board/projects/:projectIdRead one project.Board read
GET/api/board/projects/:projectId/boardsList the project's boards (visible to the caller).Board read
POST/api/board/projects/:projectId/boardsCreate a board.Board write · admin
GET/api/board/projects/:projectId/boards/:boardIdRead a board with its columns.Board read
PATCH/api/board/projects/:projectId/boards/:boardIdUpdate a board (name, kind, visibility, sortOrder, archived).Board write · admin
GET/api/board/projects/:projectId/boards/:boardId/columnsList a board's columns.Board read
POST/api/board/projects/:projectId/boards/:boardId/columnsAdd a column.Board write
PATCH/api/board/projects/:projectId/boards/:boardId/columns/:columnIdRename / recategorise / reorder a column.Board write
DELETE/api/board/projects/:projectId/boards/:boardId/columns/:columnIdDelete a column (its items move to a surviving column).Board write
PATCH/api/board/projects/:projectId/boards/:boardId/column-orderReorder columns.Board write
GET/api/board/projects/:projectId/work-itemsList/filter work items (boardId, columnId, phase, type…) with cursor pagination.Board read
POST/api/board/projects/:projectId/work-itemsCreate a work item (on boardId, else the default board).Board write
PATCH/api/board/projects/:projectId/work-items/:workItemIdUpdate editable work-item fields.Board write
PATCH/api/board/projects/:projectId/work-items/:workItemId/columnMove to a column (authoritative).Board write
PATCH/api/board/projects/:projectId/work-items/:workItemId/phaseMove the legacy phase with a reason.Board write
PATCH/api/board/projects/:projectId/work-items/:workItemId/claimClaim or release execution ownership.Board write
PATCH/api/board/projects/:projectId/work-items/:workItemId/assignmentChange the assigned user.Board write
GET/api/board/projects/:projectId/work-items/:workItemId/commentsList comments.Board read
POST/api/board/projects/:projectId/work-items/:workItemId/commentsAdd a human, agent, or system comment.Board write
GET/api/board/projects/:projectId/work-items/:workItemId/handoffsList handoffs.Board read
POST/api/board/projects/:projectId/work-items/:workItemId/handoffsHand work to another member.Board write
PATCH/api/board/projects/:projectId/work-items/:workItemId/handoffs/:handoffId/acceptAccept a handoff.Board write
GET/api/board/projects/:projectId/work-items/:workItemId/runsList agent runs and usage.Board read
POST/api/board/projects/:projectId/work-items/:workItemId/runsCreate an execution run.Board write
PATCH/api/board/projects/:projectId/work-items/:workItemId/runs/:runIdUpdate run state/outcome.Board write
POST/api/board/projects/:projectId/work-items/:workItemId/runs/:runId/usageRecord token/cost usage idempotently.Board write
GET/api/board/projects/:projectId/work-items/:workItemId/review-findingsList structured review findings.Board read
POST/api/board/projects/:projectId/work-items/:workItemId/review-findingsCreate a finding.Board write
PATCH/api/board/projects/:projectId/work-items/:workItemId/review-findings/:findingIdResolve, dismiss, or update a finding.Board write
GET/api/board/projects/:projectId/work-items/:workItemId/evidenceList evidence, optionally filtered by run/finding.Board read
POST/api/board/projects/:projectId/work-items/:workItemId/evidenceAttach evidence.Board write
GET/api/board/eventsList audit events by project/work item.Board read
POST/api/board/eventsIngest an additional idempotent audit fact.Board write
GET/api/board/events/streamStream Board events.Board read
GET/api/board/projects/:projectId/members/usageReport 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: P0P4. 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.