Skip to main content
Tasks follow the JMAP Tasks draft (urn:oximail:params:jmap:tasks alongside the standard shape), with tasks as JSTask objects (RFC 8984 family). The same items are served as VTODOs over CalDAV.

Objects and methods

Behaviours worth knowing

  • Create without taskListIds files the task into the account’s default list — resolved before the write transaction, so it is fast even under load.
  • Recurrence and progress follow JSTask: recurring tasks expand through the same occurrence authority as calendar events; per-occurrence completion is representable. A task carries one recurrence rule, under the same closed profile and stored normalised like an event’s (recurrence): a second rule, or a bound outside the profile, is refused invalidProperties on Task/set (it used to be serverFail) and 403 over CalDAV, including a VTODO with two RRULE lines.
  • Alerts support offset and absolute triggers; an absolute alert does not require a due date. Firing is server-side with per-occurrence deduplication. An alert keeps acknowledged and relatedTo (both used to be dropped on write), Task/set validates acknowledged at create, and the task scheduler honours it like the calendar one.
  • “Later” is Task/snoozeAlert {accountId, id, alertId, until}. The server writes the RFC 8984 §4.5.2 snooze through Task/set: the fired alert acknowledged, a child absolute alert at until (a future UTCDateTime, at most 7 days ahead) that rings once and replaces any earlier snooze of the same alert. Errors and rules are those of Event/snoozeAlert.
  • null patches erase. A JMAP update patch setting a property to null clears it (RFC 8620 §5.3) — description and priority included.
  • Dependencies and time tracking (dependsOn, time fields) are modelled on the task object.
  • A task carries its timeZone (RFC 8984 §4.7.1). A DUE:…Z written by CalDAV anchors in Etc/UTC rather than floating, a TZID is normalised to IANA and the anchor of DUE wins; the alert scheduler honours the task’s own anchor before the principal → organization chain, so a reminder fires at the task’s instant, not the principal’s wall clock. A row from before the column stays floating, its historical meaning; a template instantiation too.
  • Sharing is one rule. TaskListRights is mayReadItems, mayWriteOwn, mayWriteAll (requires mayWriteOwn), mayShare, mayDelete. TaskList/get filters the lists a cross-account reader may read and computes their myRights through the same calculation as mailboxes and calendars; Task/get and Task/query are scoped to readable lists, Task/set consults the rights per list, and a grant or a revocation notifies the grantee (sharing).
  • The trash is two-stage (ADR-035): isTrashed: true on an update trashes, false restores, trashedAt is server-set. The trash sweep destroys what has been trashed longer than the tenant’s horizon, its tasks.trash_retention_days override or else [tasks] trash_retention_days (30 by default, floor 1; an override of 0 purges nothing), through the Drive’s exit: legal holds respected, the Destroyed change announced (per-tenant horizons).
  • A note can point at a task. A Note.links entry of type task keeps the page a task came from; the link is a reference, not a constraint (notes).
  • VTODO round-trip: CalDAV clients see task lists as collections; VTODO VALARMs (including absolute TRIGGER;VALUE=DATE-TIME) import into alerts and re-emit on GET; ETags are content hashes, so concurrent edits from two protocols conflict loudly (412) instead of overwriting silently. Duplicate rows from repeated imports are repaired with oximail account dedupe-tasks (migration).
Task-to-content links (tasklinks) and templates are advertised as OxiMail capability objects, so a generic JMAP client can feature-detect them. Strictness rules are identical to the mail surface.