Skip to content
Skip to Content
APIFiltering and counting

Filtering and counting

A workspace with six hundred todos has one useful answer and five hundred and ninety-nine records in the way. Filter on the server, count on the server, and page only what is left.

Narrow first

curl "https://api.usedoozy.com/api/v1/todos?status=active&priority=urgent" \ -H "Authorization: Bearer $DOOZY_API_KEY"

GET /todos accepts:

ParameterWhat it selects
statusready, in_progress, done, or active for the first two together
priorityurgent, high, medium, low, or none for todos with no priority set
typetask or responsibility
todoListIdTodos in one list
captureIdTodos that came out of one capture
assigneeIdTodos assigned to one person or agent
assignedToMeTodos assigned to the owner of the key
unassignedTodos nobody is responsible for
includeArchivedArchived todos instead of active ones
updatedSinceTodos changed at or after an RFC 3339 instant
createdSinceTodos created at or after an RFC 3339 instant
dueBefore, dueAfterTodos with a due date on one side of a YYYY-MM-DD date
queryFree text against the title and body

Booleans take true, 1 or yes, and their opposites. Filters combine, and every one of them narrows.

status=active is the one worth knowing. It covers ready and in_progress, which is the work still outstanding, and it is the same word Doozy’s own agents use for the same set.

query matches the title and the body:

curl "https://api.usedoozy.com/api/v1/todos?query=launch%20note" \ -H "Authorization: Bearer $DOOZY_API_KEY"

Captures search their titles, bodies and summaries the same way, and also take tags, type, createdAfter, createdBefore and updatedSince.

Count without listing

GET /todos/summary takes every filter the list takes and returns counts alone:

curl "https://api.usedoozy.com/api/v1/todos/summary" \ -H "Authorization: Bearer $DOOZY_API_KEY"
{ "object": "todo_summary", "total": 647, "active": 256, "byStatus": { "ready": 250, "in_progress": 6, "done": 391 }, "byPriority": { "urgent": 3, "high": 21, "medium": 58, "low": 9, "none": 556 } }

To count one filtered set instead, pass the filter:

curl "https://api.usedoozy.com/api/v1/todos/summary?priority=urgent&unassigned=true" \ -H "Authorization: Bearer $DOOZY_API_KEY"

When you want a page and its total in one request, ask the list for the count:

curl "https://api.usedoozy.com/api/v1/todos?status=active&limit=25&include=totalCount" \ -H "Authorization: Bearer $DOOZY_API_KEY"

totalCount is how many match the filters, not how many are on the page. It costs a second query, so it is null unless you ask.

Incremental sync

Keep the time of your last sync and ask only for what moved:

const since = lastSyncedAt.toISOString(); const url = new URL('https://api.usedoozy.com/api/v1/todos'); url.searchParams.set('updatedSince', since); url.searchParams.set('limit', '100');

A todo counts as changed when any field on it changes, including its status.

Sorting

sort takes createdAt, updatedAt, dueDate or priority, and order takes asc or desc. The default is createdAt descending, so newest first.

Sorting and paging work together: a cursor is anchored on whatever you sorted by, so keep sort and order the same across the pages of one walk.

Unrecognised parameters are refused

A parameter the endpoint does not accept returns 400 with unknown_parameter, naming it and listing the accepted ones.

{ "error": { "type": "invalid_request_error", "code": "unknown_parameter", "message": "`updated_since` is not a parameter this endpoint accepts, so it was refused rather than ignored. Accepted parameters: assignedToMe, assigneeId, captureId, createdSince, cursor, dueAfter, dueBefore, include, includeArchived, limit, order, priority, query, sort, status, todoListId, type, unassigned, updatedSince.", "param": "updated_since" } }

This is deliberate. A misspelled filter that is quietly dropped comes back 200 with every record in the workspace, and nothing in that response says the filter never applied.

Last updated on