init.Tasks openapi.json inittasks.com

what is recoverable, what is not, and what a container takes with it

Trash and deletion

Two operations, and only one of them is reversible.

reversible confirm needed
trash yes, until it purges no
permanent delete no yes

Trash is the safety net, so trashing takes no confirmation. Permanent delete is the cascade, so it does.

Trashing

POST /v1/todos/{id}/trash and POST /v1/containers/{id}/trash stamp the row.

For a container, only the root row is stamped. Its subtree is hidden by exclusion rather than marked, which is what lets a restore bring the whole thing back untouched.

POST /v1/todos/{id}/restore and POST /v1/containers/{id}/restore clear the stamp. A restored container brings its subtree with it.

Reading the trash

GET /v1/trash lists trashed roots only, newest first: the order is (trashedAt desc, id desc), and it is what the cursor resumes in.

A row trashed on its own inside a container that was later trashed does not appear here. It is inside the container's subtree, and it still purges on its own stamp. So the list is what a user can act on, not everything that carries a stamp.

/v1/trash needs todos:read, and DELETE /v1/trash needs todos:write, whatever kind of row is involved.

Seeing trashed to-dos in a list

GET /v1/todos?include_trashed=true puts trashed to-dos back into an ordinary list. The parameter is the string "true" or "false", not a boolean.

Every other list route excludes trashed rows and has no equivalent switch.

The purge

A trashed row is purged automatically 30 days after it was stamped.

The purge runs on its own stamp, so a to-do trashed three weeks before its parent container outlives the container's own window by a week.

Do not treat the trash as storage you can read back later. If your integration needs a copy, take one before you trash.

Permanent delete

DELETE /v1/todos/{id} and DELETE /v1/containers/{id} delete a trashed row for good. Pass an id you got from GET /v1/trash.

For a container this is a cascade: the row, its child containers, their to-dos, and every attachment on any of them. There is no partial form and nothing is recoverable afterwards.

DELETE /v1/trash does the same for everything in the trash at once, and answers with a count.

json
{ "deleted": 12 }

What deletion looks like to a reader

A permanently deleted row answers not_found on every route. A trashed row is still readable at its own URL and through /v1/trash.

There is no tombstone and no deleted-since feed. If you keep a copy, reconcile by walking the list rather than by asking what went away. See keeping a copy in sync.

The inbox has no delete

A capture row cannot be deleted, on either surface. Archiving is how the product deletes one, and an archived row stays readable through GET /v1/inbox?status=archived. See the data model.

Next