browsertodo

Docs

Getting started with the extension, and adding tasks to your TODO list from your own scripts and apps.

Get started

  1. Install the extension. Add to Chrome. Chrome Web Store listing coming soon. Until then, install it from GitHub.
  2. Choose what runs it. Your own Claude Code (through a local helper, Windows 10 or 11), your own Claude API key pasted in settings, or browsertodo AI after signing in with Google. The helper's setup is in the README on GitHub; the costs are on the pricing page.
  3. Give it something to do. Press Ctrl+Shift+K on any page and say what you want done.

Add tasks from your code

Your scripts and other apps can add tasks to your TODO list through the browsertodo API: a scheduler that queues the day's posts, a form that turns a request into a task, a cron job. The tasks run in your Chrome like the ones you add yourself. When one is due, the extension, signed in to the same account, picks it up; it checks for due tasks every 15 minutes by default (Settings, in the extension).

API keys come with the Starter, Plus and Pro plans.

1. Create an API key

In the dashboard, open API keys, then Create a key. Name it after the app that will use it and choose Add tasks. Copy the key when it's shown: it starts with bt_ and is shown only once. We keep only a hash of it.

Give each app its own key, so you can revoke one without touching the others.

2. Add a task

Send the key as a bearer token:

curl -X POST https://app.browsertodo.com/v1/tasks \
  -H "Authorization: Bearer $BROWSERTODO_KEY" \
  -H "Content-Type: application/json" \
  -d '{"instructions": "Post the launch news on X", "account": "@studio"}'

The same from JavaScript (Node 18 or later, or any server runtime with fetch):

const res = await fetch("https://app.browsertodo.com/v1/tasks", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BROWSERTODO_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    instructions: "Post the launch news on X",
    account: "@studio",
    notBefore: "2026-10-01T09:00:00-07:00",
  }),
});
const task = await res.json(); // 201: the new task, "status": "pending"

Task fields

FieldWhat it does
instructionsRequired. What to do, in plain words, up to 8,000 characters.
accountThe account to do it as, such as an X handle (@studio). It switches to that account first.
notBeforeThe earliest time to run, in ISO 8601 with an offset (2026-10-01T09:00:00-07:00). Without it, the task is due now.
priorityFrom -1000 to 1000, default 0. Among due tasks, higher runs first.
repeat{"dailyAt": ["09:00", "18:00"]}: run every day at these times, up to 24 a day. When a run ends, the next one is added.
tzThe time zone of repeat, such as America/New_York. Default UTC.
mediaIdsUp to 10 files to use, from uploads.

Several tasks at once

Send up to 100 tasks in one request. Either all of them are added or, if one is invalid, none are.

curl -X POST https://app.browsertodo.com/v1/tasks/batch \
  -H "Authorization: Bearer $BROWSERTODO_KEY" \
  -H "Content-Type: application/json" \
  -d '{"tasks": [
        {"instructions": "Post on X: Good morning", "account": "@alpha", "notBefore": "2026-10-01T09:00:00-07:00"},
        {"instructions": "Post on X: Good morning", "account": "@beta",  "notBefore": "2026-10-01T09:20:00-07:00"}
      ]}'

Attach files

Upload a file (an image for a post, a document to fill in a form) as the multipart field file, up to 100 MB, then put its id in a task's mediaIds:

curl -X POST https://app.browsertodo.com/v1/media \
  -H "Authorization: Bearer $BROWSERTODO_KEY" \
  -F "file=@./photo.jpg"
# {"id": "01K...", "filename": "photo.jpg", "contentType": "image/jpeg", "size": 123456}

Follow a task

GET /v1/tasks/<id> returns { task, events }. The task's status is one of:

Also: GET /v1/tasks?status=pending lists tasks, newest first. PATCH /v1/tasks/<id> changes a pending or paused task, POST /v1/tasks/<id>/cancel cancels it, POST /v1/tasks/<id>/retry runs a failed or paused task again, and DELETE /v1/tasks/<id> deletes one that isn't running.

Limits

Over a limit, the API answers 429 with a Retry-After header: wait that many seconds and try again.

Errors

Errors come back as JSON with an error field.

StatusMeaning
400The body isn't valid. details lists what's wrong.
401The key is missing, mistyped or revoked.
403"error": "plan_required": the account has no plan with API keys, or its plan ended. The key works again after subscribing. Other 403s: the key can't call that endpoint.
404No such task or file in your account.
409The task can't change right now, for example deleting one that's running.
429Over a limit. Wait Retry-After seconds.

Keep your key safe

The full reference, in OpenAPI format: https://app.browsertodo.com/openapi.json.