| Tool | What it does | Kind |
|---|---|---|
get_current_session | Get the running session | Read · idempotent · no outside service |
get_day_plan | Read the day’s plan | Read · idempotent · no outside service |
get_journal | Read the journal window | Read · idempotent · no outside service |
list_due_habits | What is due on a day | Read · idempotent · no outside service |
list_habit_completions | What was done, over a window | Read · idempotent · no outside service |
list_habits | List your habits | Read · idempotent · no outside service |
list_rounds | The rounds of a day | Read · idempotent · no outside service |
list_today_sessions | List the day’s sessions | Read · idempotent · no outside service |
suggest_day_plan | Propose a plan for the day | Read · idempotent · no outside service |
archive_habit | Archive a habit | Write · destructive · no outside service |
close_round | Close a round | Write · idempotent · no outside service |
complete_habit | Complete a habit for a day | Write · idempotent · no outside service |
create_habit | Create a habit | Write · no outside service |
mark_round_engaged | Record that a round was actually worked | Write · idempotent · no outside service |
plan_round | Fill an ADHD-mode round | Write · idempotent · no outside service |
plan_today | Save the day’s plan | Write · idempotent · no outside service |
set_round_plan | Plan a round | Write · idempotent · no outside service |
share_session | Share a finished session to Activity, or take it back | Write · idempotent · no outside service |
start_session | Start a session | Write · no outside service |
stop_session | Stop the running session | Write · idempotent · no outside service |
uncomplete_habit | Undo a day’s completion | Write · destructive · idempotent · no outside service |
update_habit | Update a habit | Write · idempotent · no outside service |
upsert_journal_entry | Write the day’s mood and note | Write · idempotent · no outside service |
get_current_session
Get the running session. Returns the session still running, ornull when the timer is stopped.
| Kind | Read · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | GET https://api.doers.sh/v2/sessions/current |
| CLI | doers sessions get-current |
| Touches | workSessions |
| Operation | getCurrentSession |
Input
This tool takes no arguments.Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
session | object | null | ||
session.id | string | ||
session.taskId | string | null | ||
session.title | string | ||
session.startedAt | number | Epoch milliseconds. | |
session.endedAt | number | null | null while the session is still running. | |
session.visibility | string | public, anonymized, private | What the activity feed may show of it. Private until shared at the session’s end. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_current_session",
"arguments": {}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "Running: “Prepare the Acme quarterly review” since 2026-09-22T09:30:00.000Z."
}
],
"structuredContent": {
"session": {
"id": "3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb",
"taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
"title": "Prepare the Acme quarterly review",
"startedAt": 1790069400000,
"endedAt": 1790069400000,
"visibility": "public"
}
}
}
}
doers sessions get-current
get_day_plan
Read the day’s plan. Returns the saved plan for the day (3 to 5 tasks, one focus task, a note) and the state of the ADHD-mode rounds.| Kind | Read · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | GET https://api.doers.sh/v2/plan |
| CLI | doers plan get |
| Touches | coachPlanTasks, coachPlans, roundTasks, rounds, tasks |
| Operation | getDayPlan |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
day (query) | string | no | YYYY-MM-DD | Local day key, YYYY-MM-DD. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
day | string | ||
plan | object | null | ||
plan.taskIds | string[] | ||
plan.focusTaskId | string | null | ||
plan.note | string | ||
plan.tasks | object[] | ||
plan.tasks[].id | string | ||
plan.tasks[].title | string | ||
plan.tasks[].priority | integer | -9007199254740991 to 9007199254740991 | |
plan.tasks[].score | number (optional) | ||
plan.tasks[].reasons | string[] (optional) | ||
rounds | object[] | ||
rounds[].index | integer | -9007199254740991 to 9007199254740991 | |
rounds[].label | string | ||
rounds[].taskIds | string[] | ||
rounds[].engaged | boolean | ||
rounds[].closedAt | number | null |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_day_plan",
"arguments": {
"day": "2026-09-22"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "Plan for 2026-09-22: Prepare the Acme quarterly review."
}
],
"structuredContent": {
"day": "2026-09-22",
"plan": {
"taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"],
"focusTaskId": "330571bf-d351-4dd2-8723-26c22871d591",
"note": "Notes for the Acme launch.",
"tasks": [
{
"id": "0ebb429f-a86d-481c-8630-fac53db1c91c",
"title": "Prepare the Acme quarterly review",
"priority": 2,
"score": 3,
"reasons": ["Notes for the Acme launch."]
}
]
},
"rounds": [
{
"index": 0,
"label": "Acme",
"taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"],
"engaged": true,
"closedAt": 1790069400000
}
]
}
}
}
doers plan get --day 2026-09-22
get_journal
Read the journal window. The raw material of the journal: tasks completed, sessions worked, and the entries written. Nothing is bucketed by day: the caller’s timezone decides where a day starts, and only the caller knows it.since bounds the first two; sinceDay bounds the entries, which are already keyed by local day.
| Kind | Read · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | GET https://api.doers.sh/v2/journal |
| CLI | doers journal get |
| Touches | journalEntries |
| Operation | getJournal |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
since (query) | number | yes | Epoch milliseconds. | ||
sinceDay (query) | string | yes | YYYY-MM-DD | Local day key, YYYY-MM-DD. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
completions | object[] | ||
completions[].id | string | ||
completions[].title | string | ||
completions[].completedAt | number | Epoch milliseconds. | |
completions[].projectId | string | null | ||
completions[].areaId | string | null | ||
sessions | object[] | ||
sessions[].id | string | ||
sessions[].taskId | string | null | ||
sessions[].title | string | ||
sessions[].startedAt | number | Epoch milliseconds. | |
sessions[].endedAt | number | null | null while the session is still running. | |
sessions[].visibility | string | public, anonymized, private | What the activity feed may show of it. Private until shared at the session’s end. |
entries | object[] | ||
entries[].day | string | YYYY-MM-DD | Local day key, YYYY-MM-DD. |
entries[].mood | integer | null | -9007199254740991 to 9007199254740991 | 1 worst: 5 best, or null for a day left unrated. |
entries[].note | string |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_journal",
"arguments": {
"since": 3,
"sinceDay": "2026-09-22"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "1 completed · 1 session(s) · 1 entr(y/ies)."
}
],
"structuredContent": {
"completions": [
{
"id": "21606b58-37ee-4917-8e56-cff2afe21083",
"title": "Prepare the Acme quarterly review",
"completedAt": 1790069400000,
"projectId": "244210e4-8437-4655-8980-a70249a99369",
"areaId": "4a91ee5f-0106-42b3-8c11-c168352f0abf"
}
],
"sessions": [
{
"id": "3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb",
"taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
"title": "Prepare the Acme quarterly review",
"startedAt": 1790069400000,
"endedAt": 1790069400000,
"visibility": "public"
}
],
"entries": [
{
"day": "2026-09-22",
"mood": 3,
"note": "Notes for the Acme launch."
}
]
}
}
}
doers journal get --since 3 --since-day 2026-09-22
list_due_habits
What is due on a day. The habits whose rule fires on that day, each with its completion for the day if any. Archived habits are never due.| Kind | Read · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | GET https://api.doers.sh/v2/habits/due/{day} |
| CLI | doers habits list-due |
| Touches | habitCompletions, habits |
| Operation | listDueHabits |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
day (path) | string | yes | YYYY-MM-DD | Local day key, YYYY-MM-DD. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
habits | object[] | ||
habits[].habit | object | ||
habits[].habit.id | string | ||
habits[].habit.name | string | ||
habits[].habit.startsOn | string | YYYY-MM-DD | The anchor every occurrence is expanded from. |
habits[].habit.rule | object | A habit’s rule: the task’s repeat grammar without a mode, phased on startsOn. | |
habits[].habit.rule.every | integer | 1 to 365 | The multiplier: 2 × week. |
habits[].habit.rule.unit | string | day, week, month, year | |
habits[].habit.rule.weekdays | integer[] (optional) | at most 7 items, each: 1 to 7 | ISO weekdays (1 = Monday … 7 = Sunday) the weekly rule fires on. Only valid with unit “week”. |
habits[].habit.target | object | What one occurrence asks for: a tick, a quantity in a unit, or minutes. | |
habits[].habit.target.kind | string | check, quantity, minutes | |
habits[].habit.target.amount | integer (optional) | 1 to 100000 | |
habits[].habit.target.unit | string (optional) | 1 to 40 characters | |
habits[].habit.target.minutes | integer (optional) | 1 to 1440 | |
habits[].habit.createdAt | number | Epoch milliseconds. | |
habits[].habit.archivedAt | number | null | ||
habits[].completion | object | null | ||
habits[].completion.id | string | ||
habits[].completion.habitId | string | ||
habits[].completion.day | string | YYYY-MM-DD | Local day key, YYYY-MM-DD. |
habits[].completion.amount | integer | null | 0 to 9007199254740991 | What was done, for a quantity target. |
habits[].completion.minutes | integer | null | 0 to 9007199254740991 | What was done, for a minutes target. |
habits[].completion.completedAt | number | Epoch milliseconds. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_due_habits",
"arguments": {
"day": "2026-09-22"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "- [09aee23b-1fd4-4638-818d-2c392100518a] Acme ✓"
}
],
"structuredContent": {
"habits": [
{
"habit": {
"id": "09aee23b-1fd4-4638-818d-2c392100518a",
"name": "Acme",
"startsOn": "2026-09-22",
"rule": {
"every": 3,
"unit": "day"
},
"target": {
"kind": "check"
},
"createdAt": 1790069400000,
"archivedAt": 1790069400000
},
"completion": {
"id": "21606b58-37ee-4917-8e56-cff2afe21083",
"habitId": "09aee23b-1fd4-4638-818d-2c392100518a",
"day": "2026-09-22",
"amount": 3,
"minutes": 30,
"completedAt": 1790069400000
}
}
]
}
}
}
doers habits list-due --day 2026-09-22
list_habit_completions
What was done, over a window. Every completion between two days inclusive, oldest first, archived habits included: the ledger the Logbook and the Stats read.| Kind | Read · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | GET https://api.doers.sh/v2/habits/completions |
| CLI | doers habits list-habit-completions |
| Touches | habitCompletions, habits |
| Operation | listHabitCompletions |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
since (query) | string | yes | YYYY-MM-DD | Local day key, YYYY-MM-DD. | |
until (query) | string | yes | YYYY-MM-DD | Local day key, YYYY-MM-DD. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
completions | object[] | ||
completions[].id | string | ||
completions[].habitId | string | ||
completions[].day | string | YYYY-MM-DD | Local day key, YYYY-MM-DD. |
completions[].amount | integer | null | 0 to 9007199254740991 | What was done, for a quantity target. |
completions[].minutes | integer | null | 0 to 9007199254740991 | What was done, for a minutes target. |
completions[].completedAt | number | Epoch milliseconds. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_habit_completions",
"arguments": {
"since": "2026-09-22",
"until": "2026-09-22"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "1 completion(s)."
}
],
"structuredContent": {
"completions": [
{
"id": "21606b58-37ee-4917-8e56-cff2afe21083",
"habitId": "09aee23b-1fd4-4638-818d-2c392100518a",
"day": "2026-09-22",
"amount": 3,
"minutes": 30,
"completedAt": 1790069400000
}
]
}
}
}
doers habits list-habit-completions --since 2026-09-22 --until 2026-09-22
list_habits
List your habits. Every habit, oldest first. Archived ones only when asked for.| Kind | Read · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | GET https://api.doers.sh/v2/habits |
| CLI | doers habits list |
| Touches | habitCompletions, habits |
| Operation | listHabits |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
includeArchived (query) | boolean | no | No description in the registry. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
habits | object[] | ||
habits[].id | string | ||
habits[].name | string | ||
habits[].startsOn | string | YYYY-MM-DD | The anchor every occurrence is expanded from. |
habits[].rule | object | A habit’s rule: the task’s repeat grammar without a mode, phased on startsOn. | |
habits[].rule.every | integer | 1 to 365 | The multiplier: 2 × week. |
habits[].rule.unit | string | day, week, month, year | |
habits[].rule.weekdays | integer[] (optional) | at most 7 items, each: 1 to 7 | ISO weekdays (1 = Monday … 7 = Sunday) the weekly rule fires on. Only valid with unit “week”. |
habits[].target | object | What one occurrence asks for: a tick, a quantity in a unit, or minutes. | |
habits[].target.kind | string | check, quantity, minutes | |
habits[].target.amount | integer (optional) | 1 to 100000 | |
habits[].target.unit | string (optional) | 1 to 40 characters | |
habits[].target.minutes | integer (optional) | 1 to 1440 | |
habits[].createdAt | number | Epoch milliseconds. | |
habits[].archivedAt | number | null |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_habits",
"arguments": {
"includeArchived": true
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "- [09aee23b-1fd4-4638-818d-2c392100518a] Acme"
}
],
"structuredContent": {
"habits": [
{
"id": "09aee23b-1fd4-4638-818d-2c392100518a",
"name": "Acme",
"startsOn": "2026-09-22",
"rule": {
"every": 3,
"unit": "day"
},
"target": {
"kind": "check"
},
"createdAt": 1790069400000,
"archivedAt": 1790069400000
}
]
}
}
}
doers habits list --include-archived true
list_rounds
The rounds of a day. Returns every round already planned, engaged or closed for that day, in order. A day with nothing on it returns an empty list rather than inventing rounds: a round exists once something has been said about it.| Kind | Read · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | GET https://api.doers.sh/v2/rounds |
| CLI | doers rounds list |
| Touches | rounds |
| Operation | listRounds |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
day (query) | string | yes | YYYY-MM-DD | Local day key, YYYY-MM-DD. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
rounds | object[] | ||
rounds[].day | string | YYYY-MM-DD | Local day key, YYYY-MM-DD. |
rounds[].index | integer | -9007199254740991 to 9007199254740991 | Which round of the day, counting from zero. |
rounds[].taskIds | string[] | The mini-plan, in display order. | |
rounds[].engaged | boolean | A session was started, or a planned task ticked. | |
rounds[].closedAt | number | null | When it was closed. The first close wins. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_rounds",
"arguments": {
"day": "2026-09-22"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "- round 0: 1 task(s), engaged, closed"
}
],
"structuredContent": {
"rounds": [
{
"day": "2026-09-22",
"index": 0,
"taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"],
"engaged": true,
"closedAt": 1790069400000
}
]
}
}
}
doers rounds list 2026-09-22
list_today_sessions
List the day’s sessions. Sessions started at or aftersince, newest first. since is the start of the day in the caller’s timezone, which only the caller knows: the server does not guess it. At most 100 are returned.
| Kind | Read · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | GET https://api.doers.sh/v2/sessions |
| CLI | doers sessions list-today |
| Touches | workSessions |
| Operation | listTodaySessions |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
since (query) | number | yes | Epoch milliseconds. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
sessions | object[] | ||
sessions[].id | string | ||
sessions[].taskId | string | null | ||
sessions[].title | string | ||
sessions[].startedAt | number | Epoch milliseconds. | |
sessions[].endedAt | number | null | null while the session is still running. | |
sessions[].visibility | string | public, anonymized, private | What the activity feed may show of it. Private until shared at the session’s end. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_today_sessions",
"arguments": {
"since": 3
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "- [3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb] Prepare the Acme quarterly review"
}
],
"structuredContent": {
"sessions": [
{
"id": "3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb",
"taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
"title": "Prepare the Acme quarterly review",
"startedAt": 1790069400000,
"endedAt": 1790069400000,
"visibility": "public"
}
]
}
}
}
doers sessions list-today --since 3
suggest_day_plan
Propose a plan for the day. Computes a proposed plan from the prioritisation engine and splits the day into rounds. Writes nothing: it is a draft to put to the user, then commit withPUT /v2/plan.
Each round gets at most 3 tasks, the heaviest first.
| Kind | Read · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | GET https://api.doers.sh/v2/plan/suggestion |
| CLI | doers plan suggest |
| Touches | coachPlanTasks, coachPlans, roundTasks, rounds, tasks |
| Operation | suggestDayPlan |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
day (query) | string | no | YYYY-MM-DD | Local day key, YYYY-MM-DD. | |
workStart (query) | string | no | "09:00" | HH:MM | Time HH:MM: only meaningful alongside a date. |
workEnd (query) | string | no | "18:00" | HH:MM | Time HH:MM: only meaningful alongside a date. |
roundMin (query) | integer | no | 120 | 30 to 240 | No description in the registry. |
maxTasks (query) | integer | no | 5 | 1 to 6 | No description in the registry. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
day | string | ||
suggestion | object[] | ||
suggestion[].id | string | ||
suggestion[].title | string | ||
suggestion[].priority | integer | -9007199254740991 to 9007199254740991 | |
suggestion[].score | number (optional) | ||
suggestion[].reasons | string[] (optional) | ||
focusTaskId | string | null | ||
rounds | object[] | ||
rounds[].index | integer | -9007199254740991 to 9007199254740991 | |
rounds[].label | string | ||
rounds[].taskIds | string[] |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "suggest_day_plan",
"arguments": {
"day": "2026-09-22",
"workStart": "09:00"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "Proposal for 2026-09-22:\n- [650ffa82-126b-44c5-83df-581cbc078399] Prepare the Acme quarterly review"
}
],
"structuredContent": {
"day": "2026-09-22",
"suggestion": [
{
"id": "650ffa82-126b-44c5-83df-581cbc078399",
"title": "Prepare the Acme quarterly review",
"priority": 2,
"score": 3,
"reasons": ["Notes for the Acme launch."]
}
],
"focusTaskId": "330571bf-d351-4dd2-8723-26c22871d591",
"rounds": [
{
"index": 0,
"label": "Acme",
"taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"]
}
]
}
}
}
doers plan suggest --day 2026-09-22 --work-start 09:00
archive_habit
Archive a habit. Takes it out of the list and out of what is due. Its completions stay, so what was done can still be counted. Archiving twice is a no-op.| Kind | Write · destructive · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | POST https://api.doers.sh/v2/habits/{habitId}/archive |
| CLI | doers habits archive |
| Touches | habitCompletions, habits |
| Operation | archiveHabit |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
habitId (path) | string | yes | No description in the registry. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
habit | object | ||
habit.id | string | ||
habit.name | string | ||
habit.startsOn | string | YYYY-MM-DD | The anchor every occurrence is expanded from. |
habit.rule | object | A habit’s rule: the task’s repeat grammar without a mode, phased on startsOn. | |
habit.rule.every | integer | 1 to 365 | The multiplier: 2 × week. |
habit.rule.unit | string | day, week, month, year | |
habit.rule.weekdays | integer[] (optional) | at most 7 items, each: 1 to 7 | ISO weekdays (1 = Monday … 7 = Sunday) the weekly rule fires on. Only valid with unit “week”. |
habit.target | object | What one occurrence asks for: a tick, a quantity in a unit, or minutes. | |
habit.target.kind | string | check, quantity, minutes | |
habit.target.amount | integer (optional) | 1 to 100000 | |
habit.target.unit | string (optional) | 1 to 40 characters | |
habit.target.minutes | integer (optional) | 1 to 1440 | |
habit.createdAt | number | Epoch milliseconds. | |
habit.archivedAt | number | null |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "archive_habit",
"arguments": {
"habitId": "09aee23b-1fd4-4638-818d-2c392100518a"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: habit archived [09aee23b-1fd4-4638-818d-2c392100518a]"
}
],
"structuredContent": {
"habit": {
"id": "09aee23b-1fd4-4638-818d-2c392100518a",
"name": "Acme",
"startsOn": "2026-09-22",
"rule": {
"every": 3,
"unit": "day"
},
"target": {
"kind": "check"
},
"createdAt": 1790069400000,
"archivedAt": 1790069400000
}
}
}
}
doers habits archive --habit-id 09aee23b-1fd4-4638-818d-2c392100518a
close_round
Close a round. Marks the round finished, stamping the moment. The first close wins: calling it again leaves the original timestamp alone, because when the work stopped is the fact worth keeping. A round that was never planned or engaged has nothing to close and answers 404.| Kind | Write · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | POST https://api.doers.sh/v2/rounds/{day}/{index}/close |
| CLI | doers rounds close |
| Touches | rounds |
| Operation | closeRound |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
day (path) | string | yes | YYYY-MM-DD | Local day key, YYYY-MM-DD. | |
index (path) | integer | yes | 0 to 5 | Which round of the day, counting from zero. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
round | object | ||
round.day | string | YYYY-MM-DD | Local day key, YYYY-MM-DD. |
round.index | integer | -9007199254740991 to 9007199254740991 | Which round of the day, counting from zero. |
round.taskIds | string[] | The mini-plan, in display order. | |
round.engaged | boolean | A session was started, or a planned task ticked. | |
round.closedAt | number | null | When it was closed. The first close wins. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "close_round",
"arguments": {
"day": "2026-09-22",
"index": 0
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: round 0 closed."
}
],
"structuredContent": {
"round": {
"day": "2026-09-22",
"index": 0,
"taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"],
"engaged": true,
"closedAt": 1790069400000
}
}
}
}
doers rounds close 2026-09-22 0
complete_habit
Complete a habit for a day. Records the occurrence, with what was done for a measured target. Doing it again for the same day updates the one record rather than adding a second. Refused on a day the habit is not due, and on an archived habit.| Kind | Write · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | PUT https://api.doers.sh/v2/habits/{habitId}/completions/{day} |
| CLI | doers habits complete |
| Touches | habitCompletions, habits |
| Operation | completeHabit |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
habitId (path) | string | yes | No description in the registry. | ||
day (path) | string | yes | YYYY-MM-DD | Local day key, YYYY-MM-DD. | |
amount | integer | no | 0 to 100000 | No description in the registry. | |
minutes | integer | no | 0 to 1440 | No description in the registry. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
completion | object | ||
completion.id | string | ||
completion.habitId | string | ||
completion.day | string | YYYY-MM-DD | Local day key, YYYY-MM-DD. |
completion.amount | integer | null | 0 to 9007199254740991 | What was done, for a quantity target. |
completion.minutes | integer | null | 0 to 9007199254740991 | What was done, for a minutes target. |
completion.completedAt | number | Epoch milliseconds. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "complete_habit",
"arguments": {
"habitId": "09aee23b-1fd4-4638-818d-2c392100518a",
"day": "2026-09-22",
"amount": 3,
"minutes": 30
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: done for 2026-09-22"
}
],
"structuredContent": {
"completion": {
"id": "21606b58-37ee-4917-8e56-cff2afe21083",
"habitId": "09aee23b-1fd4-4638-818d-2c392100518a",
"day": "2026-09-22",
"amount": 3,
"minutes": 30,
"completedAt": 1790069400000
}
}
}
}
doers habits complete --habit-id 09aee23b-1fd4-4638-818d-2c392100518a --day 2026-09-22 --amount 3 --minutes 30
create_habit
Create a habit. A name, the day it starts, a rule, and a target. The rule is the task’s repeat grammar without a mode: a habit is always phased on the day it starts.| Kind | Write · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | POST https://api.doers.sh/v2/habits |
| CLI | doers habits create |
| Touches | habitCompletions, habits |
| Operation | createHabit |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
name | string | yes | 1 to 200 characters | No description in the registry. | |
startsOn | string | yes | YYYY-MM-DD | Local day key, YYYY-MM-DD. | |
rule | object | yes | A habit’s rule: the task’s repeat grammar without a mode, phased on startsOn. | ||
rule.every | integer | yes | 1 to 365 | The multiplier: 2 × week. | |
rule.unit | string | yes | day, week, month, year | No description in the registry. | |
rule.weekdays | integer[] | no | at most 7 items, each: 1 to 7 | ISO weekdays (1 = Monday … 7 = Sunday) the weekly rule fires on. Only valid with unit “week”. | |
target | object | yes | What one occurrence asks for: a tick, a quantity in a unit, or minutes. | ||
target.kind | string | yes | check, quantity, minutes | No description in the registry. | |
target.amount | integer | no | 1 to 100000 | No description in the registry. | |
target.unit | string | no | 1 to 40 characters | No description in the registry. | |
target.minutes | integer | no | 1 to 1440 | No description in the registry. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
habit | object | ||
habit.id | string | ||
habit.name | string | ||
habit.startsOn | string | YYYY-MM-DD | The anchor every occurrence is expanded from. |
habit.rule | object | A habit’s rule: the task’s repeat grammar without a mode, phased on startsOn. | |
habit.rule.every | integer | 1 to 365 | The multiplier: 2 × week. |
habit.rule.unit | string | day, week, month, year | |
habit.rule.weekdays | integer[] (optional) | at most 7 items, each: 1 to 7 | ISO weekdays (1 = Monday … 7 = Sunday) the weekly rule fires on. Only valid with unit “week”. |
habit.target | object | What one occurrence asks for: a tick, a quantity in a unit, or minutes. | |
habit.target.kind | string | check, quantity, minutes | |
habit.target.amount | integer (optional) | 1 to 100000 | |
habit.target.unit | string (optional) | 1 to 40 characters | |
habit.target.minutes | integer (optional) | 1 to 1440 | |
habit.createdAt | number | Epoch milliseconds. | |
habit.archivedAt | number | null |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_habit",
"arguments": {
"name": "Acme",
"startsOn": "2026-09-22",
"rule": {
"every": 3,
"unit": "day"
},
"target": {
"kind": "check"
}
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: habit created [09aee23b-1fd4-4638-818d-2c392100518a] Acme"
}
],
"structuredContent": {
"habit": {
"id": "09aee23b-1fd4-4638-818d-2c392100518a",
"name": "Acme",
"startsOn": "2026-09-22",
"rule": {
"every": 3,
"unit": "day"
},
"target": {
"kind": "check"
},
"createdAt": 1790069400000,
"archivedAt": 1790069400000
}
}
}
}
doers habits create Acme --starts-on 2026-09-22
# rule, target: structured argument(s) the CLI cannot pass as flags.
mark_round_engaged
Record that a round was actually worked. Engaged means a session was started or a planned task ticked during the round: the difference between a day that was planned and a day that happened. Idempotent, and it creates the round if nothing was planned for it: working an unplanned block still counts.| Kind | Write · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | POST https://api.doers.sh/v2/rounds/{day}/{index}/engage |
| CLI | doers rounds engage |
| Touches | rounds |
| Operation | markRoundEngaged |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
day (path) | string | yes | YYYY-MM-DD | Local day key, YYYY-MM-DD. | |
index (path) | integer | yes | 0 to 5 | Which round of the day, counting from zero. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
round | object | ||
round.day | string | YYYY-MM-DD | Local day key, YYYY-MM-DD. |
round.index | integer | -9007199254740991 to 9007199254740991 | Which round of the day, counting from zero. |
round.taskIds | string[] | The mini-plan, in display order. | |
round.engaged | boolean | A session was started, or a planned task ticked. | |
round.closedAt | number | null | When it was closed. The first close wins. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "mark_round_engaged",
"arguments": {
"day": "2026-09-22",
"index": 0
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: round 0 engaged."
}
],
"structuredContent": {
"round": {
"day": "2026-09-22",
"index": 0,
"taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"],
"engaged": true,
"closedAt": 1790069400000
}
}
}
}
doers rounds engage 2026-09-22 0
plan_round
Fill an ADHD-mode round. Replaces a round’s mini-plan: 3 tasks maximum, the heaviest first. A task lives in one round only: it is removed from the day’s other rounds.| Kind | Write · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | PUT https://api.doers.sh/v2/plan/rounds/{index} |
| CLI | doers plan round |
| Touches | coachPlanTasks, coachPlans, roundTasks, rounds, tasks |
| Operation | planRound |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
index (path) | integer | yes | 0 to 5 | No description in the registry. | |
taskIds | string[] | yes | at most 3 items, each: UUID | Identifier of a row. | |
day | string | no | YYYY-MM-DD | Local day key, YYYY-MM-DD. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
day | string | ||
index | integer | -9007199254740991 to 9007199254740991 | |
taskIds | string[] |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "plan_round",
"arguments": {
"index": 0,
"taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"],
"day": "2026-09-22"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: round 1 planned (1 task(s))."
}
],
"structuredContent": {
"day": "2026-09-22",
"index": 0,
"taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"]
}
}
}
doers plan round 0 --task-ids 0ebb429f-a86d-481c-8630-fac53db1c91c --day 2026-09-22
plan_today
Save the day’s plan. Replaces the day’s plan.focusTaskId names THE priority: if it is not in taskIds, the first task is used instead. The note is a short encouragement shown at the top of Today.
| Kind | Write · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | PUT https://api.doers.sh/v2/plan |
| CLI | doers plan set |
| Touches | coachPlanTasks, coachPlans, roundTasks, rounds, tasks |
| Operation | planToday |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
taskIds | string[] | yes | at most 6 items, each: UUID | Identifier of a row. | |
focusTaskId | string | no | UUID | Identifier of a row. | |
note | string | no | "" | 0 to 300 characters | No description in the registry. |
day | string | no | YYYY-MM-DD | Local day key, YYYY-MM-DD. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
day | string | ||
taskIds | string[] | ||
focusTaskId | string | null | ||
note | string |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "plan_today",
"arguments": {
"taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"],
"focusTaskId": "330571bf-d351-4dd2-8723-26c22871d591",
"note": ""
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: plan for 2026-09-22 saved (1 task(s))."
}
],
"structuredContent": {
"day": "2026-09-22",
"taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"],
"focusTaskId": "330571bf-d351-4dd2-8723-26c22871d591",
"note": "Notes for the Acme launch."
}
}
}
doers plan set --task-ids 0ebb429f-a86d-481c-8630-fac53db1c91c --focus-task-id 330571bf-d351-4dd2-8723-26c22871d591 --note ""
set_round_plan
Plan a round. Replaces the round’s mini-plan. At most 3 tasks: one substantial and two small is the shape it was built for; a longer list is not a plan. A task belongs to one round of the day. Planning it here removes it from any other round of the same day, so it cannot appear twice. An empty list clears the plan. The round itself is created if it does not exist yet. When movedTaskIds and both interval bounds are supplied, those tasks are also softly scheduled onto the target day without changing deadlines or completion state.| Kind | Write · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | PUT https://api.doers.sh/v2/rounds/{day}/{index}/plan |
| CLI | doers rounds plan |
| Touches | roundTasks, rounds, tasks |
| Operation | setRoundPlan |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
day (path) | string | yes | YYYY-MM-DD | Local day key, YYYY-MM-DD. | |
index (path) | integer | yes | 0 to 5 | Which round of the day, counting from zero. | |
taskIds | string[] | yes | at most 3 items, each: UUID | In display order. Pass an empty array to clear the plan. | |
movedTaskIds | string[] | no | at most 3 items, each: UUID | The subset moved by this request and softly scheduled into the interval. | |
roundStartMin | integer | no | 0 to 1439 | Inclusive target interval start, in minutes after midnight. | |
roundEndMin | integer | no | 1 to 1440 | Exclusive target interval end, in minutes after midnight. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
round | object | ||
round.day | string | YYYY-MM-DD | Local day key, YYYY-MM-DD. |
round.index | integer | -9007199254740991 to 9007199254740991 | Which round of the day, counting from zero. |
round.taskIds | string[] | The mini-plan, in display order. | |
round.engaged | boolean | A session was started, or a planned task ticked. | |
round.closedAt | number | null | When it was closed. The first close wins. | |
removedFromOtherRounds | integer | -9007199254740991 to 9007199254740991 |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "set_round_plan",
"arguments": {
"day": "2026-09-22",
"index": 0,
"taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"]
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: round 0 planned with 1 task(s)."
}
],
"structuredContent": {
"round": {
"day": "2026-09-22",
"index": 0,
"taskIds": ["0ebb429f-a86d-481c-8630-fac53db1c91c"],
"engaged": true,
"closedAt": 1790069400000
},
"removedFromOtherRounds": 3
}
}
}
doers rounds plan 2026-09-22 0 --task-ids 0ebb429f-a86d-481c-8630-fac53db1c91c
share_session
Share a finished session to Activity, or take it back. Public shows the effort and the task’s title; anonymized shows the effort and only where the task lived; private, the default, shows nothing. Only a finished session of your own; a running one is refused.| Kind | Write · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | PUT https://api.doers.sh/v2/sessions/{sessionId}/visibility |
| CLI | doers sessions share |
| Touches | areas, follows, projects, sessionFlames, tasks, user, workSessions |
| Operation | shareSession |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
sessionId (path) | string | yes | No description in the registry. | ||
visibility | string | yes | public, anonymized, private | Who sees this task on shared and social surfaces: public shows title and project, anonymized shows only the area, private shows nothing. New tasks default to private. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
session | object | ||
session.id | string | ||
session.taskId | string | null | ||
session.title | string | ||
session.startedAt | number | Epoch milliseconds. | |
session.endedAt | number | null | null while the session is still running. | |
session.visibility | string | public, anonymized, private | What the activity feed may show of it. Private until shared at the session’s end. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "share_session",
"arguments": {
"sessionId": "3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb",
"visibility": "public"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: session is public"
}
],
"structuredContent": {
"session": {
"id": "3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb",
"taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
"title": "Prepare the Acme quarterly review",
"startedAt": 1790069400000,
"endedAt": 1790069400000,
"visibility": "public"
}
}
}
}
doers sessions share --session-id 3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb --visibility public
start_session
Start a session. Starts the timer. Any session still running is stopped first, so this is safe to call without checking the current state.| Kind | Write · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | POST https://api.doers.sh/v2/sessions |
| CLI | doers sessions start |
| Touches | workSessions |
| Operation | startSession |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
taskId | string | null | no | UUID | No description in the registry. | |
title | string | no | 0 to 500 characters | No description in the registry. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
session | object | ||
session.id | string | ||
session.taskId | string | null | ||
session.title | string | ||
session.startedAt | number | Epoch milliseconds. | |
session.endedAt | number | null | null while the session is still running. | |
session.visibility | string | public, anonymized, private | What the activity feed may show of it. Private until shared at the session’s end. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "start_session",
"arguments": {
"taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
"title": "Prepare the Acme quarterly review"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: session “Prepare the Acme quarterly review” started [3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb]."
}
],
"structuredContent": {
"session": {
"id": "3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb",
"taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
"title": "Prepare the Acme quarterly review",
"startedAt": 1790069400000,
"endedAt": 1790069400000,
"visibility": "public"
}
}
}
}
doers sessions start --task-id 0ebb429f-a86d-481c-8630-fac53db1c91c --title "Prepare the Acme quarterly review"
stop_session
Stop the running session. Stops the timer and returns the session it closed. Returnsnull when nothing was running: stopping a stopped timer is not an error.
| Kind | Write · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | POST https://api.doers.sh/v2/sessions/stop |
| CLI | doers sessions stop |
| Touches | workSessions |
| Operation | stopSession |
Input
This tool takes no arguments.Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
session | object | null | ||
session.id | string | ||
session.taskId | string | null | ||
session.title | string | ||
session.startedAt | number | Epoch milliseconds. | |
session.endedAt | number | null | null while the session is still running. | |
session.visibility | string | public, anonymized, private | What the activity feed may show of it. Private until shared at the session’s end. |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "stop_session",
"arguments": {}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: session “Prepare the Acme quarterly review” stopped."
}
],
"structuredContent": {
"session": {
"id": "3f3af1ec-ebbd-4410-8b41-7ec0d27bbfcb",
"taskId": "0ebb429f-a86d-481c-8630-fac53db1c91c",
"title": "Prepare the Acme quarterly review",
"startedAt": 1790069400000,
"endedAt": 1790069400000,
"visibility": "public"
}
}
}
}
doers sessions stop
uncomplete_habit
Undo a day’s completion. Removes the occurrence’s record. Not found when there was none.| Kind | Write · destructive · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | DELETE https://api.doers.sh/v2/habits/{habitId}/completions/{day} |
| CLI | doers habits uncomplete |
| Touches | habitCompletions, habits |
| Operation | uncompleteHabit |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
habitId (path) | string | yes | No description in the registry. | ||
day (path) | string | yes | YYYY-MM-DD | Local day key, YYYY-MM-DD. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
ok | boolean | true |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "uncomplete_habit",
"arguments": {
"habitId": "09aee23b-1fd4-4638-818d-2c392100518a",
"day": "2026-09-22"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: completion removed"
}
],
"structuredContent": {
"ok": true
}
}
}
doers habits uncomplete --habit-id 09aee23b-1fd4-4638-818d-2c392100518a --day 2026-09-22
update_habit
Update a habit. Any of the name, the start day, the rule or the target. History is untouched.| Kind | Write · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | PATCH https://api.doers.sh/v2/habits/{habitId} |
| CLI | doers habits update |
| Touches | habitCompletions, habits |
| Operation | updateHabit |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
habitId (path) | string | yes | No description in the registry. | ||
name | string | no | 1 to 200 characters | No description in the registry. | |
startsOn | string | no | YYYY-MM-DD | Local day key, YYYY-MM-DD. | |
rule | object | no | A habit’s rule: the task’s repeat grammar without a mode, phased on startsOn. | ||
rule.every | integer | yes | 1 to 365 | The multiplier: 2 × week. | |
rule.unit | string | yes | day, week, month, year | No description in the registry. | |
rule.weekdays | integer[] | no | at most 7 items, each: 1 to 7 | ISO weekdays (1 = Monday … 7 = Sunday) the weekly rule fires on. Only valid with unit “week”. | |
target | object | no | What one occurrence asks for: a tick, a quantity in a unit, or minutes. | ||
target.kind | string | yes | check, quantity, minutes | No description in the registry. | |
target.amount | integer | no | 1 to 100000 | No description in the registry. | |
target.unit | string | no | 1 to 40 characters | No description in the registry. | |
target.minutes | integer | no | 1 to 1440 | No description in the registry. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
habit | object | ||
habit.id | string | ||
habit.name | string | ||
habit.startsOn | string | YYYY-MM-DD | The anchor every occurrence is expanded from. |
habit.rule | object | A habit’s rule: the task’s repeat grammar without a mode, phased on startsOn. | |
habit.rule.every | integer | 1 to 365 | The multiplier: 2 × week. |
habit.rule.unit | string | day, week, month, year | |
habit.rule.weekdays | integer[] (optional) | at most 7 items, each: 1 to 7 | ISO weekdays (1 = Monday … 7 = Sunday) the weekly rule fires on. Only valid with unit “week”. |
habit.target | object | What one occurrence asks for: a tick, a quantity in a unit, or minutes. | |
habit.target.kind | string | check, quantity, minutes | |
habit.target.amount | integer (optional) | 1 to 100000 | |
habit.target.unit | string (optional) | 1 to 40 characters | |
habit.target.minutes | integer (optional) | 1 to 1440 | |
habit.createdAt | number | Epoch milliseconds. | |
habit.archivedAt | number | null |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "update_habit",
"arguments": {
"habitId": "09aee23b-1fd4-4638-818d-2c392100518a",
"name": "Acme",
"startsOn": "2026-09-22"
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: habit updated [09aee23b-1fd4-4638-818d-2c392100518a] Acme"
}
],
"structuredContent": {
"habit": {
"id": "09aee23b-1fd4-4638-818d-2c392100518a",
"name": "Acme",
"startsOn": "2026-09-22",
"rule": {
"every": 3,
"unit": "day"
},
"target": {
"kind": "check"
},
"createdAt": 1790069400000,
"archivedAt": 1790069400000
}
}
}
}
doers habits update --habit-id 09aee23b-1fd4-4638-818d-2c392100518a --name Acme --starts-on 2026-09-22
upsert_journal_entry
Write the day’s mood and note. Creates the day’s entry or patches it. An omitted field is left alone; an explicitnull mood clears the rating, which is how the app toggles a face off.
| Kind | Write · idempotent · no outside service |
| Auth | Bearer token: a personal API token (pc_…) or an OAuth access token (pcat_…) |
| REST | PUT https://api.doers.sh/v2/journal/{day} |
| CLI | doers journal upsert-journal-entry |
| Touches | journalEntries |
| Operation | upsertJournalEntry |
Input
| Field | Type | Required | Default | Allowed values | Description |
|---|---|---|---|---|---|
day (path) | string | yes | YYYY-MM-DD | Local day key, YYYY-MM-DD. | |
mood | integer | null | no | 1 to 5 | No description in the registry. | |
note | string | no | 0 to 10000 characters | No description in the registry. |
Output
Output fields
Output fields
| Field | Type | Allowed values | Description |
|---|---|---|---|
entry | object | ||
entry.day | string | YYYY-MM-DD | Local day key, YYYY-MM-DD. |
entry.mood | integer | null | -9007199254740991 to 9007199254740991 | 1 worst: 5 best, or null for a day left unrated. |
entry.note | string |
Example
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "upsert_journal_entry",
"arguments": {
"day": "2026-09-22",
"mood": 3,
"note": "Notes for the Acme launch."
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "OK: journal entry for 2026-09-22 saved."
}
],
"structuredContent": {
"entry": {
"day": "2026-09-22",
"mood": 3,
"note": "Notes for the Acme launch."
}
}
}
}
doers journal upsert-journal-entry 2026-09-22 --mood 3 --note "Notes for the Acme launch."