Quickstart
- Sign in and open Account settings → API keys.
- Choose Create an API key, give it a name, pick Read only or Read and write and when it expires. Copy the key: it is shown once.
- Send your first request:
curl https://allscrum.com/api/v1/me \
-H "Authorization: Bearer allscrum_your_key_here"
You get your account back:
{
"data": {
"id": "Xk29fQ7a",
"name": "Ann Owner",
"email": "[email protected]",
"timezone": "Europe/Amsterdam",
"api_key": {"id": "pL3m9QzR", "name": "My script", "scope": "write", "expires_at": "2026-11-19T10:00:00Z", "allowed_ips": []}
}
}
From here, GET /projects lists your projects and GET /tasks?assignee_id=me your tasks.
Authentication
Every request (except GET / and GET /openapi.json) needs an API key in the Authorization header:
Authorization: Bearer allscrum_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Tools that can't set that header can send X-API-Key: allscrum_… instead. Keys always start with allscrum_, which makes them easy to spot if one ends up somewhere it shouldn't, like a public repository.
Keys in the URL (not recommended)
For tools that can't send headers at all, like a spreadsheet formula, a read-only key also works in the URL of GET requests:
curl "https://allscrum.com/api/v1/tasks?assignee_id=me&api_key=allscrum_your_read_only_key"
We advise against this. URLs are stored in server and proxy logs, browser history and bookmarks, and travel along when a link is shared or a page links elsewhere. Anyone who sees such a URL can read everything you can. Use the Authorization header whenever you can. If you must use the URL, give it a separate read-only key with a short expiry and allowed IP addresses. Responses then carry an X-API-Key-Warning header, and keys that can make changes are always refused in the URL (403 api_key_in_url_not_allowed).
A key acts as you
A key belongs to the person who created it and has exactly their access. When you lose access to a project, so do your keys. Everything a key changes shows up in the history under your name, marked via API.
Access
- Read only keys can call
GETendpoints. Anything else returns403 insufficient_scope. - Read and write keys can call every endpoint, including deleting things you are allowed to delete.
Give each integration its own key with the least access it needs. That way you can revoke one without touching the others.
Expiry
When you create a key, choose when it expires: after 1 hour, 3 hours, 1 day, 1 week, 1 month, 3 months, 6 months, 1 year, 2 years, or never. After that, requests with it return 401 api_key_expired. A key's expiry can't be extended: create a new key and revoke the old one.
Allowed IP addresses
You can limit a key to IP addresses and CIDR ranges, IPv4 or IPv6, for example 203.0.113.7 or 198.51.100.0/24. Requests from anywhere else return 403 ip_not_allowed. You can change the list at any time without replacing the key.
Keep keys secret. Store them in environment variables or a secrets manager, never in code or in a web page. You get an email whenever a key is created on your account. If a key may have leaked, revoke it in your settings: it stops working immediately.
Requests
The base URL is https://allscrum.com/api/v1. Use HTTPS. Send request bodies as JSON with Content-Type: application/json.
curl -X POST https://allscrum.com/api/v1/tasks \
-H "Authorization: Bearer $ALLSCRUM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"project_id": "AbC1234", "title": "Fix the login page", "type": "bug", "priority": "high"}'
Only GET and POST?
Some clients, proxies and firewalls only let GET and POST through. Send a POST with an X-HTTP-Method-Override header instead, and it is handled exactly like a PATCH or DELETE, permissions and idempotency keys included:
curl -X POST https://allscrum.com/api/v1/tasks/CAR-12 \
-H "Authorization: Bearer $ALLSCRUM_API_KEY" \
-H "X-HTTP-Method-Override: PATCH" \
-H "Content-Type: application/json" \
-d '{"priority": "high"}'
IDs
Every object has an 8-character id, like a1B2c3D4. A few objects can also be addressed the way you see them in the app:
- Projects by the code in their URL:
allscrum.com/p/AbC1234→GET /projects/AbC1234. - Tasks by their key:
GET /tasks/CAR-12. If two of your projects use the same key, you get409 ambiguous_task_keywith both candidates; use the ID then. - Teams by the code in their URL.
Fields
PATCHchanges only the fields you send. Sendnullto clear a field, like"assignee_id": null.- Unknown fields and query parameters are refused (
422 unknown_field,400 invalid_parameter). A typo never silently changes what a request does. - Types are strict:
"points": 5works,"points": "5"doesn't. - Times are ISO 8601 in UTC, like
2026-10-18T09:30:00Z. Dates areYYYY-MM-DD. - Task descriptions and notes are HTML with simple formatting (paragraphs, lists, bold, links, code). Plain text works too; line breaks are kept. Responses include a plain-text version as well.
Responses and errors
Successful responses put the result in data. Creating something returns 201 Created with a Location header; deleting returns 204 No Content.
{"data": {"id": "a1B2c3D4", "key": "CAR-12", "title": "Fix the login page", "status": "open", "...": "..."}}
Errors have a status code, a stable code for your program, and a message for people. details.field names the field at fault when there is one.
HTTP/1.1 422 Unprocessable Content
{"error": {"code": "validation_failed", "message": "Pick a priority from the list.", "details": {"field": "priority"}, "request_id": "5f2c9a1be04d7c31"}}
| Status | Codes | What to do |
|---|---|---|
| 400 | invalid_parameter, invalid_json, invalid_idempotency_key, invalid_method_override | Fix the request. |
| 401 | unauthorized, invalid_api_key, api_key_expired | Send a valid key, or create a new one. |
| 403 | insufficient_scope, ip_not_allowed, account_disabled, api_key_in_url_not_allowed, forbidden | The key or its owner may not do this, for example a member changing project settings. |
| 404 | not_found, route_not_found | It doesn't exist, or you don't have access to it. |
| 405 | method_not_allowed | Use a method from the Allow header. |
| 409 | conflict, ambiguous_task_key, version_conflict, backlog_disabled, idempotency_conflict | The current state doesn't allow it, like starting a sprint while another runs. Fetch fresh data and decide. |
| 413, 415 | payload_too_large, unsupported_media_type | Send JSON, up to 1 MB. |
| 422 | validation_failed, missing_field, unknown_field, idempotency_key_reused | Fix the field named in details.field. |
| 429 | rate_limited | Wait Retry-After seconds. |
| 500 | internal_error | Retry with an idempotency key. If it keeps happening, contact us with the request_id. |
| 503 | project_busy, service_unavailable | Retry after Retry-After seconds. |
Every response has an X-Request-Id header. Mention it when you contact us about a request.
Pagination
Task lists (GET /tasks and GET /projects/{project}/tasks) come in pages. Use page (from 1) and per_page (default 50, at most 100):
GET /tasks?assignee_id=me&status=open&per_page=100&page=2
{"data": [ ... ], "meta": {"page": 2, "per_page": 100, "total": 243, "total_pages": 3}}
The Link header holds ready-made URLs for the first, prev, next and last pages. Other lists (projects, lanes, comments, sprints…) come complete.
History endpoints return 50 entries at a time, newest first. For older entries, pass meta.next_before as before until meta.has_more is false.
Keeping a copy in sync
Every task has updated_at, which changes when any of its fields, its lane or its place changes. Ask for what changed since your last sync with GET /tasks?updated_after=2026-10-18T09:30:00Z&archived=all.
Rate limits
Each key can make 120 requests per minute. Every response tells you where you stand:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117
X-RateLimit-Reset: 1792367400
Over the limit you get 429 rate_limited with a Retry-After header in seconds. Repeated requests with invalid keys from one address are limited as well.
Safe retries
Networks fail. If a POST times out, did the task get created or not? Send an Idempotency-Key header with any unique value, a UUID for example, and retry with the same key:
curl -X POST https://allscrum.com/api/v1/tasks \
-H "Authorization: Bearer $ALLSCRUM_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c8e52-3f0b-4d1e-9a4b-2f6b7c1d0e9a" \
-d '{"project_id": "AbC1234", "title": "Invoice March"}'
The first request does the work. Repeats with the same key and the same request, for 24 hours, return the stored response with Idempotent-Replayed: true, without creating anything twice. The same key with a different request returns 422 idempotency_key_reused. Idempotency keys work for POST, PATCH and DELETE.
Permissions
The API follows the same rules as the app:
- Any project member can work with tasks, comments, checklists, blockers, epics, notes, planned sprints and the backlog.
- Project admins and the owner can also change settings, lanes and members, and start or complete sprints.
- Only the owner can delete a project or change its team. Deleting a project needs
?confirm=with its exact name. - Comments can be edited by their author, and deleted by their author or an admin.
Something you can't open returns 404, never 403, so the API never reveals what exists in other people's projects.
Examples
Your open tasks, most urgent first
curl "https://allscrum.com/api/v1/tasks?assignee_id=me&status=open&sort=-priority" \
-H "Authorization: Bearer $ALLSCRUM_API_KEY"
Move a task to Done
Find the lane with GET /projects/{project}/lanes (the done lane has "is_done": true), then:
curl -X PATCH https://allscrum.com/api/v1/tasks/CAR-12 \
-H "Authorization: Bearer $ALLSCRUM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"lane_id": "Lp9x2KqA"}'
Plan and start a sprint
# 1. Plan a sprint
curl -X POST https://allscrum.com/api/v1/projects/AbC1234/sprints -H "Authorization: Bearer $ALLSCRUM_API_KEY" \
-H "Content-Type: application/json" -d '{"name": "Sprint 8", "goal": "Checkout flow"}'
# 2. Put backlog items in it
curl -X POST https://allscrum.com/api/v1/projects/AbC1234/backlog/plan -H "Authorization: Bearer $ALLSCRUM_API_KEY" \
-H "Content-Type: application/json" -d '{"task_ids": ["a1B2c3D4", "e5F6g7H8"], "sprint_id": "S8x9y0Zq"}'
# 3. Start it (project admins)
curl -X POST https://allscrum.com/api/v1/sprints/S8x9y0Zq/start -H "Authorization: Bearer $ALLSCRUM_API_KEY" \
-H "Content-Type: application/json" -d '{"end_date": "2026-11-02"}'
JavaScript
const response = await fetch('https://allscrum.com/api/v1/tasks', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ALLSCRUM_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({project_id: 'AbC1234', title: 'Deploy failed on main', type: 'bug', priority: 'highest'}),
});
const body = await response.json();
if (!response.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
console.log(`Created ${body.data.key}: ${body.data.url}`);
Python
import os, requests
api = requests.Session()
api.headers["Authorization"] = f"Bearer {os.environ['ALLSCRUM_API_KEY']}"
page = 1
while True:
r = api.get("https://allscrum.com/api/v1/tasks", params={"assignee_id": "me", "status": "open", "per_page": 100, "page": page})
r.raise_for_status()
body = r.json()
for task in body["data"]:
print(task["key"], task["title"])
if page >= body["meta"]["total_pages"]:
break
page += 1
AI agents (MCP)
AllScrum has an MCP server, so AI assistants and agents like Claude, ChatGPT, Claude Code, Cursor and GitHub Copilot can work with your board directly: "what's on my plate today?", "create a bug for this stack trace", "move CAR-12 to Done". There is nothing to install. The server is at:
https://allscrum.com/mcp
There are two ways to connect:
- Sign in (OAuth): add the URL and the app opens an AllScrum page where you sign in and click Allow. That's how Claude, ChatGPT, Claude Code and most current tools connect. Step by step for everyone: Use AllScrum in Claude and ChatGPT.
- An API key, for tools that can only send a header, or for agents running unattended: send it as
Authorization: Bearer allscrum_….
Claude Code
# Sign in: add the server, then type /mcp in Claude Code and choose Authenticate
claude mcp add --transport http allscrum https://allscrum.com/mcp
# Or with an API key
claude mcp add --transport http allscrum https://allscrum.com/mcp \
--header "Authorization: Bearer allscrum_your_key_here"
Cursor
In ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project). Leave out headers to sign in instead:
{
"mcpServers": {
"allscrum": {
"url": "https://allscrum.com/mcp",
"headers": {"Authorization": "Bearer allscrum_your_key_here"}
}
}
}
VS Code (GitHub Copilot)
In .vscode/mcp.json. Without headers, VS Code asks you to sign in; with them, it asks for the key once and stores it securely:
{
"inputs": [{"type": "promptString", "id": "allscrum-key", "description": "AllScrum API key", "password": true}],
"servers": {
"allscrum": {
"type": "http",
"url": "https://allscrum.com/mcp",
"headers": {"Authorization": "Bearer ${input:allscrum-key}"}
}
}
}
Claude and ChatGPT
Add AllScrum as a custom connector with the URL above; they sign in with OAuth. See the step-by-step guide. A read-only key in the URL (/mcp?api_key=…) also works there, but isn't recommended: the URL, key included, is stored by the app and ends up in logs.
What agents can do
The server offers 47 tools: search, read projects, boards, tasks, comments, sprints, the backlog, notes and history, and create and change tasks, comments, checklists, blockers, lanes, epics, sprints and notes. Each tool is an API endpoint, with the same permissions, limits and validation. Deleting projects and inviting people are left out on purpose.
- Read-only access (a read-only key, or "Read only" when signing in) only gets the tools that read. Start there, with a short expiry while you try things out.
- Agents can use the task keys people mention, like
CAR-12, directly. - Mistakes come back as clear messages the agent can correct, not silent surprises.
- Everything an agent changes shows in the project history, marked via API with the key's or app's name, and most changes can be undone there.
Building your own agent instead? Give it the OpenAPI document, or call the API directly.
OAuth for MCP clients
For developers of MCP clients: AllScrum follows the MCP authorization specification (OAuth 2.1). Clients that implement it, like the official MCP SDKs, need no AllScrum-specific code.
- A request to
/mcpwithout a token returns401withWWW-Authenticate: Bearer resource_metadata="https://allscrum.com/.well-known/oauth-protected-resource/mcp". - That document (RFC 9728) names
https://allscrum.comas the authorization server, whose metadata is at/.well-known/oauth-authorization-server(RFC 8414). - Register with
POST /oauth/register(Dynamic Client Registration, RFC 7591). No account or approval needed. - Send the person to
/oauth/authorizewith PKCE andresource=https://allscrum.com/mcp(RFC 8707), and exchange the code atPOST /oauth/token. - Call
/mcpwithAuthorization: Bearer <access token>; refresh with the refresh token when it expires.
| Rule | Details |
|---|---|
| Grant types | authorization_code with refresh_token. No implicit, password or client credentials grants. |
| PKCE | Required on every request, S256 only. |
| Clients | Public (token_endpoint_auth_method: none) or with a secret (client_secret_basic or client_secret_post). Registration is limited per IP address; apps that never connect anyone are removed after 7 days. |
| Redirect URIs | Matched exactly. https, http only for localhost / 127.0.0.1 / [::1], or an app's own scheme. Never fragments. |
| Scopes | read or write (includes read). Without a scope, the person chooses. The granted scope is in the token response. |
| Access tokens | Opaque, valid for 1 hour, accepted only by /mcp (the REST API takes API keys). |
| Refresh tokens | Valid for 90 days, renewed with each use. Each works once: you get a new one with every refresh. Using one twice ends the connection. |
| Codes | Valid for 10 minutes, once. Using one twice ends the connection. |
| Signing out | POST /oauth/revoke (RFC 7009) with either token ends the connection. |
| Errors | As in RFC 6749: {"error": "invalid_grant", "error_description": "…"}. The authorization response includes iss (RFC 9207). |
Versioning
This is version 1 of the API, under /api/v1. Within version 1 we only make changes that don't break working code:
- New endpoints, new optional parameters and fields, and new fields in responses can be added at any time. Ignore fields you don't know.
- New values can be added to lists like task types and error codes. Handle unknown values gracefully.
- Anything that would break working code (removing or renaming fields, changing types or meaning) gets a new version, with time to move.
Reference
The API reference lists every endpoint with its parameters, request and response fields and errors. It is generated from the OpenAPI 3.1 document, which you can import into Postman, Insomnia or a client generator.
Endpoints by area:
| Area | Endpoints |
|---|---|
| Account | GET /me, GET /search |
| Workspaces | /workspaces, /workspaces/{workspace} |
| Projects | /projects, /projects/{project}, …/members, …/activity |
| Board | GET /projects/{project}/board, /projects/{project}/lanes, /lanes/{lane} |
| Tasks | /tasks, /tasks/{task}, …/move, …/archive, …/comments, …/checklist, …/blockers, …/activity |
| Planning | …/epics, …/sprints, /sprints/{sprint}/start, …/complete, …/backlog |
| Notes | /projects|workspaces|teams/{id}/notes, /notes/{note} |
| Teams | /teams, /teams/{team}, …/members |