API and API keys

A small REST API for scripts, automations and anything else that needs to read or write tasks without a browser.

Base URL: https://todome.hobbytime.tech/api/v1. A machine-readable description lives at /api/v1/openapi.json if your tooling can consume one.

Note: If your goal is “let Claude or ChatGPT manage my tasks”, you probably do not want this page. Claude and ChatGPT connect without any key handling at all.

Keys

Create one at Settings → API. Keys start with tdm_ and are shown once — Todome stores only a hash, so a lost key cannot be recovered, only revoked and replaced.

Choose a scope when you create it. Read can list and fetch; read-write can also create, update, complete and delete. Anything that only needs to display your tasks should get a read key.

  • A key is tied to one workspace and acts as the person who created it.
  • Revoke a key from the same screen; it stops working immediately.
  • Keys can be given an expiry date. An expired key behaves exactly like a revoked one.

Authenticating

curl https://todome.hobbytime.tech/api/v1/tasks \
  -H "Authorization: Bearer tdm_your_key_here"

Session cookies deliberately do not work here. The API is for machines, and accepting cookies would make every endpoint reachable from any web page you happened to be visiting.

Endpoints

Method and pathDoesNeeds
GET /tasksList tasks in the workspaceread
POST /tasksCreate a taskwrite
GET /tasks/:idFetch one taskread
PATCH /tasks/:idUpdate, including completing itwrite
DELETE /tasks/:idDelete a taskwrite
GET /projectsList projectsread

Listing

GET /tasks accepts completed=true|false, projectId, dueBefore=YYYY-MM-DD and limit (up to 200, default 50).

Creating

curl -X POST https://todome.hobbytime.tech/api/v1/tasks \
  -H "Authorization: Bearer tdm_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Send the quarterly report",
    "dueDate": "2026-08-14",
    "dueTime": "17:00",
    "priority": 1
  }'

Only title is required. dueDate is YYYY-MM-DD, dueTime is HH:MM, priority is 1 to 4. To file it in a project, pass a projectId from GET /projects — names are not accepted, because a name is not unique enough to write against.

Note: This endpoint takes structured fields, not a sentence. The natural-language parsing described in Quick Add happens in the app, before it reaches here.

Completing

curl -X PATCH https://todome.hobbytime.tech/api/v1/tasks/TASK_ID \
  -H "Authorization: Bearer tdm_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"isCompleted": true}'

Completing through the API behaves exactly like ticking the box in the app: a repeating task spawns its next occurrence, karma is recorded, and the calendar event is removed. There is no second-class path for automations.

Errors

Every failure returns the same envelope, so you can branch on the code rather than the prose:

{ "error": { "code": "insufficient_scope", "message": "..." } }
StatusCodeMeans
400invalid_body / invalid_queryThe request did not validate
401unauthorizedKey missing, malformed, revoked or expired
403insufficient_scopeA read-only key tried to write
404not_foundNo such task or project in this workspace
429rate_limitedOver the rate limit
500internal_errorOur fault

A 404 is also what you get for a resource that exists but belongs to someone else. That is intentional: the alternative tells a stranger which ids are real.

Rate limit

120 requests per minute per key. Counted per key rather than per IP, since automations legitimately share addresses and a per-key budget is what actually protects a workspace. Over the limit you get a 429 — back off and retry rather than looping.

Keeping keys safe

  • Never put a key in browser-side code or a public repository. Anyone holding it can do whatever its scope allows to your workspace.
  • Use environment variables, and a separate key per integration so one can be revoked alone.
  • Set an expiry on anything experimental. A key you forget about is the one that leaks.
  • If a key is ever exposed, revoke it first and investigate afterwards.