Docs
Getting started with the extension, and adding tasks to your TODO list from your own scripts and apps.
Get started
- Install the extension. Add to Chrome. Chrome Web Store listing coming soon. Until then, install it from GitHub.
- 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.
- 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
| Field | What it does |
|---|---|
instructions | Required. What to do, in plain words, up to 8,000 characters. |
account | The account to do it as, such as an X handle (@studio). It switches to that account first. |
notBefore | The earliest time to run, in ISO 8601 with an offset (2026-10-01T09:00:00-07:00). Without it, the task is due now. |
priority | From -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. |
tz | The time zone of repeat, such as America/New_York. Default UTC. |
mediaIds | Up 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:
pending: waiting until it's due, or for a retry.running: your Chrome is working on it.paused: it needs you, for example to sign in or enter a code.pauseReasonsays why.done:resultSummarysays what happened, andresultUrllinks to the result, such as the post.failed:failReasonsays why.cancelled.
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
- 60 requests a minute per key.
- 10,000 new tasks a day per account, across all its keys (the day is UTC).
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.
| Status | Meaning |
|---|---|
400 | The body isn't valid. details lists what's wrong. |
401 | The 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. |
404 | No such task or file in your account. |
409 | The task can't change right now, for example deleting one that's running. |
429 | Over a limit. Wait Retry-After seconds. |
Keep your key safe
- Call the API from a server, not a web page. Browsers block requests to the API from other sites, and a key in a page's code is a key anyone can copy.
- A key can add and manage your tasks and files, nothing else. It can't see your billing or change your account.
- Revoke a key on the dashboard's API keys page. It stops working at once.
The full reference, in OpenAPI format: https://app.browsertodo.com/openapi.json.