Skip to content

Quick add syntax

Every place you can type a task name, Conatus parses tokens out of it. Type the whole task in one line and the fields fill themselves in:

Renew passport tomorrow at 9am for 45m {friday} p1 #Admin @errand

That creates a P1 task called “Renew passport” in the project Admin, labelled errand, due tomorrow at 09:00, estimated at 45 minutes, with a deadline of this coming Friday.

Recognised tokens are removed from the name. Anything left over is the task name.

Token Sets Examples
#name Project #Admin, #Work
@name Label @errand, @deep-work
p1–p4 Priority p1, P3
a date phrase Due date see below
at <time> Due time at 9am, at 17:30, at 9:05pm
for <duration> Duration for 90m, for 2h, for 1h30m
{date phrase} Deadline {friday}, {next week}, {2026-03-01}
every … Repeat rule every day, every 2 weeks, every monday
due, by Due date due friday, due by friday, by friday
deadline … Deadline, without braces deadline friday, deadline by september 15
remind me … Reminder remind me tomorrow to call mum
a part of day Due time tomorrow morning, this afternoon, tonight

The same vocabulary is used for due dates, for deadlines inside { } and for due before: / due after: in the filter language.

Phrase Resolves to
today, tod Today
tomorrow, tmr Tomorrow
monday … sunday (or mon, tue, …) The next such weekday, never today
next week The coming Monday
next friday That weekday in the coming week
in 3 days Today plus three days
2026-03-01 That ISO date
1/3, 1.3 Day/month. Rolls to next year if it has already passed
september 15, sep 15, 15 sep, 15th september That calendar date
the 15th, on the 1st That day of the month, next one that exists
in two days, in a week Number words work wherever digits do, up to ninety-nine

Numeric dates are always day-first, whatever your display format. Month names and ISO dates avoid the ambiguity entirely.

“Today” is your day. The composer uses your device’s timezone; the /api/v1/tasks/quick-add endpoint uses the timezone on the account, set in Settings → Preferences.

at is optional, but only in front of a time that cannot be mistaken for anything else. 5pm, 17:30, noon and midnight parse on their own. A bare 9 does not, because there is no way to tell it from a quantity, so it stays in the task name unless you write at 9.

Accepted forms: 9, 09, 9am, 9pm, 9:30, 09:30, 9:05pm, 17:30, 5 p.m., noon, midnight. Twelve-hour forms need am or pm; without a suffix the number is read as a 24-hour clock.

A time with no date implies today.

morning, afternoon, evening and tonight set a time without you naming one: 09:00, 15:00, 18:00 and 18:00. An explicit clock time always wins, so tomorrow morning at 11 is 11:00.

During a daylight-saving transition, a time that does not exist is rejected rather than quietly moved.

for is required. Unlike a time, a bare number can never be read as a duration. Everything after it is one token:

for 90m for 2h for 1h30m for 45min for 2hours

Hours accept h, hr, hrs, hour, hours; minutes accept m, min, mins, minute, minutes. Words and decimals work too: for an hour, for half an hour, for 1.5 hours, for 90 minutes. A duration has to come out as a whole number of minutes between 1 and 1440.

Braces mark a deadline rather than a due date:

File tax return {2026-04-30}
Ship the release {next friday}

The braces must hug the phrase exactly. { friday } will not parse and stays in the task name. An unparseable or unterminated brace is left alone, so a task called Fix the {weird} bug keeps its name intact.

The word deadline does the same job without braces, optionally followed by on or by:

File tax return deadline 2026-04-30
Ship the release deadline by next friday

A deadline holds a date and nothing else. {noon} stays in the task name.

remind me creates a reminder on the task:

Remind me tomorrow to call mum
Remind me at noon to call mum
Remind me to call mum tomorrow at 5pm

A reminder does not set a due date. The two are separate fields, so a task can have either, both or neither. A reminder with a date but no time fires at 09:00.

every … sets a repeat rule and picks the first occurrence:

  • interval rules (every day, every 3 weeks, every month) start today;
  • weekday rules (every monday) start on the next such weekday.

The full grammar is on Recurring tasks.

  • First wins for dates. The first recognisable date phrase becomes the due date; later ones stay in the name.
  • Last wins for projects. #a #b puts the task in b.
  • Labels accumulate, and duplicates are ignored.
  • A repeat rule blocks a separate date. every monday tomorrow takes the repeat rule and leaves tomorrow in the name.
  • Unknown names are dropped, not invented. #Nothing where no project called “Nothing” exists falls back to the current project (or Inbox); a @label that does not exist is not applied. Conatus never creates a project or label from a quick-add token.
  • Explicit form fields win. Whatever you pick in the priority, date or time controls overrides the parsed token.
  • A task always keeps a name. If the tokens would consume the entire line, the whole line is used as the name and nothing is parsed.
  • Ambiguous phrasing stays literal. around 3, at 3ish, biweekly and twice a week are left in the name on purpose, because none of them names one unambiguous time or schedule. An incomplete phrase is never rounded down to a shorter one: every 6th friday does not become a monthly task on the 6th.

POST /api/v1/tasks/quick-add runs the same parser server-side:

curl -X POST https://tasks.example.com/api/v1/tasks/quick-add \
-H "Authorization: Bearer tdm_..." \
-H "Content-Type: application/json" \
-d '{"text":"Renew passport tomorrow at 9am p1 #Admin @errand"}'

The response carries the created task, the parsed breakdown so a client can show what it understood and warnings naming any @label that did not match. See REST API.

The endpoint needs tasks:write. If the text contains a remind me phrase it also needs reminders:write, and a token without it gets a 403 rather than a task with the reminder silently dropped.