init.Tasks openapi.json inittasks.com

8 routes

/filters

8 routes.

Saved queries over to-dos. criteria is a JSON string using tag NAMES. It is parsed on create and on patch, and a document the grammar does not accept is validation_failed; only a STORED filter from a newer or older grammar can be inert (it matches nothing).

GET /v1/filters

List filters

The live filters. A filter in the trash is left out unless include_trashed=true (then it carries its trashedAt).

Scopes: filters:read

Query

parameter type notes
limit integer optional min 1, max 200
cursor string optional max 4096 chars
updated_since string (RFC 3339) optional max 24 chars. An RFC 3339 instant, e.g. 2026-09-16T08:30:00.000Z.
include_trashed true, false optional

Response

Errors: grant_expired * grant_revoked * unauthorized * forbidden_scope * account_too_large * validation_failed * rate_limited * internal

POST /v1/filters

Create a filter (criteria uses tag names)

criteria is PARSED. A document that does not match the grammar (a v1 one, an unknown kind or operator, a missing match, an empty set, a fractional within) is validation_failed at /criteria with the grammar in the message, instead of being stored as a filter that silently matches nothing. What is stored is the engine’s own canonical serialisation, so two filters that mean the same thing are the same bytes.

Scopes: filters:write Idempotent. Send Idempotency-Key and a retry replays the first answer instead of writing twice.

Request body

field type notes
name string required max 256 chars, min 1
criteria string required max 10000 chars, min 1
symbol string optional or null, max 64 chars
id string (UPPERCASE UUID) optional max 64 chars. An uppercase UUID, all 36 characters, hex digits in capitals: 8E4F2A1B-7C3D-4E5F-9A0B-1C2D3E4F5A6B. Supplying one is how a create is made idempotent; a repeat is 409 duplicate_id. Lower case is refused, and so is a short id.

Response

Errors: grant_expired * grant_revoked * unauthorized * forbidden_scope * conflict * duplicate_id * payload_too_large * unsupported_media_type * account_too_large * validation_failed * rate_limited * internal

GET /v1/filters/{id}

One filter

Scopes: filters:read

Response

Errors: grant_expired * grant_revoked * unauthorized * forbidden_scope * not_found * account_too_large * rate_limited * internal

GET /v1/filters/{id}/todos

Evaluate a filter with the engine

Evaluated by the same engine the apps run. ⚠ An unparseable or unknown criterion makes a filter INERT: it matches nothing rather than erroring, so an empty page can mean "no matches" or "this filter is broken"; read the filter’s criteria to tell.

Scopes: filters:read, todos:read

Query

parameter type notes
limit integer optional min 1, max 200
cursor string optional max 4096 chars

Response

Errors: grant_expired * grant_revoked * unauthorized * forbidden_scope * not_found * account_too_large * validation_failed * rate_limited * internal

PATCH /v1/filters/{id}

Change a filter

Sending criteria REPLACES the whole set and is parsed exactly as on POST. after (a filter id, or null for first) or before reorders the filter list.

Scopes: filters:write

Request body

field type notes
name string optional max 256 chars, min 1
criteria string optional max 10000 chars, min 1
symbol string optional or null, which clears it, max 64 chars
after string optional or null, which clears it, max 64 chars. Reorder the filter list: right after this filter, or null for first.
before string optional max 64 chars. Reorder the filter list: right before this filter.

Response

Errors: grant_expired * grant_revoked * unauthorized * forbidden_scope * not_found * payload_too_large * unsupported_media_type * account_too_large * validation_failed * rate_limited * internal

POST /v1/filters/{id}/trash

Move a filter to the trash

One write: the filter is stamped trashedAt. It matches nothing and GET /filters leaves it out until /restore; the trash deletes it for good after 30 days (or DELETE /trash). Its to-dos are never touched.

Scopes: filters:write

Response

Errors: grant_expired * grant_revoked * unauthorized * forbidden_scope * not_found * payload_too_large * unsupported_media_type * account_too_large * rate_limited * internal

POST /v1/filters/{id}/restore

Restore a filter from the trash

Scopes: filters:write

Response

Errors: grant_expired * grant_revoked * unauthorized * forbidden_scope * not_found * payload_too_large * unsupported_media_type * account_too_large * rate_limited * internal

DELETE /v1/filters/{id}

Delete a filter

Irreversible, live or in the trash (the apps’ delete moves a filter to the trash: POST /filters/{id}/trash). The to-dos it matched are untouched.

Scopes: filters:write

Response

Errors: grant_expired * grant_revoked * unauthorized * forbidden_scope * not_found * account_too_large * rate_limited * internal