Skip to main content
Every item has state, one of three values: Lifecycle is universal for user content — the same three states apply to every core.*, app.*, user.*, and <publisher>.* type. Types don’t declare their own states or transitions. system.* items are the exception. Their lifecycle is bounded to active and revoked — different shape because they’re operational items, not user content. The universal three-state model doesn’t apply.

Transitions

Invalid transitions return 400 invalid_transition. You cannot go directly from trashed to archived — restore to active first.

API

Transitions happen through four routes:
POST /items/{id}/transition is the universal entry point — pass the target state in the body:
The dedicated restore and delete routes are sugar for the common cases. Transitions are logged in the audit trail.

Triage vs lifecycle

Triage workflows — a read-later app’s Inbox / Later / Shortlist, a clipboard’s pinned vs. unpinned — are app concerns, not core state. Apps model triage in their own type’s properties (e.g. location: "shortlist" on a custom bookmark type) or in extensions. Lifecycle and triage are separate axes. An item can be triaged to “Shortlist” (app concept) while its state is active (core concept).

Hard deletion

DELETE /items/{id}/purge is irreversible. Admin-scoped, logged, no soft-delete safety net. The normal DELETE is soft — items transition to trashed and auto-purge after the retention window.
Purge removes:
  • The item row.
  • All edges with this item as source or target.
  • The metadata row.
  • All extensions scoped to this item.
  • Attachment references (blobs themselves are content-addressed and may be retained if referenced by other items).