API reference

REST API

Stateless Express API backed by Postgres. All /api/v1 routes require a user identity header until full auth ships.

Authentication

Pass X-Briefs-User-Id on every request. In development the API falls back to DEFAULT_USER_ID from .env when the header is omitted.

Header
X-Briefs-User-Id: demo

Endpoints

MethodPathDescription
GET/healthService health — no auth
GET/api/v1/itemsList items for the authenticated user
GET/api/v1/items/:idFetch a single item
POST/api/v1/itemsCreate an item (writes Create activity)
PATCH/api/v1/items/:idUpdate an item (writes Update activity)
GET/api/v1/items/:id/activitiesAppend-only activity log for an item
GET/api/v1/actors/meEnsure and return the person actor for the user
GET/api/v1/actors/:idFetch an actor by id

Items

List
curl -H "X-Briefs-User-Id: demo" \
  http://localhost:8001/api/v1/items
Create
curl -H "X-Briefs-User-Id: demo" \
  -H "Content-Type: application/json" \
  -d '{"name":"Ship items UI","kind":"task"}' \
  http://localhost:8001/api/v1/items

Optional ingest dedupe on create: pass "source": { "system": "github", "externalId": "issue-18" }. The database enforces uniqueness per user on (userId, source.system, source.externalId).

Activities

List for item
curl -H "X-Briefs-User-Id: demo" \
  http://localhost:8001/api/v1/items/<item-id>/activities

Activities are read-only via the API. They are written by the domain service on every item create or update.

Update body

PATCH accepts partial updates — status, name, description, tags, lifecycle, and more. Validated with itemUpdateInputSchema from @briefs/shared.

Example
curl -H "X-Briefs-User-Id: demo" \
  -H "Content-Type: application/json" \
  -d '{"status":"in_progress"}' \
  <api>/api/v1/items/<item-id>