Logs
Append, list, and delete activity/comment logs on tracks.
Append a comment or activity log to a task or goal, list logs, and delete individual logs. Anyone who can access the track can also read and append to its logs — logs don't carry a separate ACL.
accountId is resolved from the auth token and is never passed in the request. The active workspace comes from the token or the workspaceId query parameter. Appending and deleting logs are free; listing logs costs 1 credit.
Create a log
POST /v1/logs
Authorization: Bearer <token>
Content-Type: application/json
{
"trackId": "00000000-0000-4000-8000-000000000010",
"kind": "comment",
"content": "Blocked on missing test fixtures.",
"metadata": { "source": "ci", "runId": "build-184" },
"idempotencyKey": "00000000-0000-4000-8000-000000000001"
}trackId is required and must be a task or goal UUID. content is required and is trimmed before validation.
kind is one of:
| Kind | Use for |
|---|---|
comment |
Discussion, questions, notes, or shared context |
update |
Work-state reports: what changed, was found, or next |
review |
Verdicts, QA results, approvals, or review outcomes |
comment is the default. The internal system kind is reserved for platform-generated entries and cannot be written through the public API.
metadata accepts an optional JSON object, capped at 16KB once serialized. Put larger human-readable detail in content instead. idempotencyKey is optional; pass a UUID when retrying a create request safely. Reusing an idempotency key returns the existing log unless that log has been deleted, in which case the API returns 409.
Returns 201:
{
"log": {
"id": "00000000-0000-4000-8000-000000000020",
"entryId": "00000000-0000-4000-8000-000000000010",
"userId": "user_123",
"authorName": "Ada",
"kind": "comment",
"content": "Blocked on missing test fixtures.",
"metadata": { "source": "ci", "runId": "build-184" },
"idempotencyKey": "00000000-0000-4000-8000-000000000001",
"createdAt": "2026-07-07T10:15:00.000Z"
},
"type": "task"
}List logs for one track
GET /v1/logs?trackId=<trackId>&order=desc&cursor=<logId>
Authorization: Bearer <token>trackId scopes the read to one track's logs and always reflects that track's current ACL. Add authorId=<userId> to show only logs by one visible author on that track.
List the activity feed
Omit trackId for an activity feed across every track you can currently access:
GET /v1/logs?authorId=<userId>&order=desc&cursor=<logId>
Authorization: Bearer <token>authorId works with or without trackId. If the requested author is outside what the caller can see, the response is empty instead of leaking whether that author wrote logs.
Results are ordered newest first by default (order=desc). Use order=asc for chronological replay or, with cursor, to fetch logs appended after a known log. Pass the previous response's nextCursor back as cursor with the same order to fetch the next page.
{
"logs": [
{
"id": "00000000-0000-4000-8000-000000000020",
"entryId": "00000000-0000-4000-8000-000000000010",
"userId": "user_123",
"authorName": "Ada",
"kind": "comment",
"content": "Blocked on missing test fixtures.",
"metadata": { "source": "ci", "runId": "build-184" },
"idempotencyKey": "00000000-0000-4000-8000-000000000001",
"createdAt": "2026-07-07T10:15:00.000Z"
}
],
"type": "task",
"total": 1,
"hasNext": false,
"nextCursor": null
}type is included when trackId is set. Cross-track feed responses omit it because results can span tasks and goals.
The cross-track feed (when trackId is omitted) is backed by an ACL snapshot taken when each log was written, not a live re-check of the track's current ACL — if you're later removed from a track, logs you could already see there may still appear in this feed (a request with trackId set always reflects that track's live ACL and is unaffected).
Each log includes userId and authorName resolved for the caller. An author outside what the caller can already see, for example someone who has since left the workspace, is returned as "unknown" for both fields rather than leaking their account id.
Delete a log
DELETE /v1/logs/:logId
Authorization: Bearer <token>Returns 200:
{
"deleted": true,
"type": "task"
}Authors can delete their own logs; a track's creator can delete any log on that track. Deleted logs are omitted from future list responses. Deleting an unknown or already-deleted log returns 404.
Cost
| Operation | Cost |
|---|---|
logs.create |
free |
logs.list |
1 credit |
logs.delete |
free |
See Credits for the full table.
Common mistakes
- Use a track UUID in REST
trackId; CLI and MCP log commands also accept a URL that contains the task or goal UUID. - Keep
orderunchanged when passingnextCursorinto the next list request. - Use
metadatafor compact machine-readable fields only; large explanations belong incontent.