The Bluefie API
Read and change your Projects boards from your own code. Everything below works with one workspace key and a single header, so a useful integration is about ten lines long.
Get a key
An owner or an admin mints keys in Settings, Integrations. A key looks like blf_live_ followed by 40 characters, and it is shown exactly once, when it is created. We keep only a fingerprint of it, so nobody at Bluefie can read it back to you: if it is lost, revoke it and mint another.
A key belongs to one workspace and can never see another. Revoking one takes effect on the very next request.
Authenticate
Send the key as a bearer token on every request.
Authorization: Bearer blf_live_EXAMPLE00000000000000000000000000000000
Keys carry scopes. projects:read covers every GET below and projects:write covers every POST and PATCH. A key that is missing, malformed, unknown or revoked always gets the same answer, so nothing here can be used to work out whether a key ever existed.
Every answer has the same shape
Success:
{ "data": ..., "meta": { "nextCursor": "..." } }Failure, with a code your code can switch on and a message a person can read:
{ "error": { "code": "not_found", "message": "There is no card with that id on this workspace." } }meta appears on lists only. When nextCursor is not null, pass it back as ?cursor= for the next page. Lists come back newest first, hold up to 100 rows (?limit=, 50 by default), and the last page has a null cursor.
Rate limits
120 requests a minute per key, counted in a fixed window. Going over answers 429 with a Retry-After header in seconds and the same error envelope as everything else. If you need more than that, tell us what you are building and we will talk about it rather than let you guess.
You never have to guess how close you are. Every answer after your key is checked carries RateLimit-Policy (the limit and its window) and RateLimit (how many requests are left and how many seconds until the window resets), in the standard form, and a 429 adds Retry-After:
RateLimit-Policy: "key";q=120;w=60 RateLimit: "key";r=87;t=41 Retry-After: 41 (on a 429 only)
Endpoints
Everything lives under https://bluefie.com/api/public/v1. All ids are UUIDs.
GET/boardsneeds projects:read
Every board on your workspace, newest first. Archived boards are left out unless you ask for them with ?includeArchived=1.
curl https://bluefie.com/api/public/v1/boards?limit=2 \ -H "Authorization: Bearer blf_live_EXAMPLE00000000000000000000000000000000"
{
"data": [
{
"id": "6f1c0f2a-1c62-4e33-9b8a-0f2a1c624e33",
"name": "Client work",
"description": "Everything we owe a customer",
"color": "#1f48ff",
"archived_at": null,
"created_at": "2026-08-19T09:14:02.113Z"
}
],
"meta": { "nextCursor": "eyJ0IjoiMjAyNi0wOC0xOVQwOToxNDowMi4xMTNaIiwiaSI6ImQwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDA0MiJ9" }
}POST/boardsneeds projects:write
A new board, with the four default stages (To do, In progress, Review, Done) already on it, so you can create a card straight away.
curl -X POST https://bluefie.com/api/public/v1/boards \
-H "Authorization: Bearer blf_live_EXAMPLE00000000000000000000000000000000" \
-H "Content-Type: application/json" \
-d '{"name":"Onboarding","description":"New customers"}'{
"data": {
"id": "b21d9d2e-2f4b-4a77-9c31-2f4b4a779c31",
"name": "Onboarding",
"description": "New customers",
"color": "#1f48ff",
"archived_at": null,
"created_at": "2026-08-21T10:02:44.001Z",
"columns": [
{ "id": "0a5b...", "name": "To do", "position": 1 },
{ "id": "1b6c...", "name": "In progress", "position": 2 },
{ "id": "2c7d...", "name": "Review", "position": 3 },
{ "id": "3d8e...", "name": "Done", "position": 4 }
]
}
}GET/boards/{id}needs projects:read
One board and its stages, in order. The stage ids are what you need to place a card.
curl https://bluefie.com/api/public/v1/boards/6f1c0f2a-1c62-4e33-9b8a-0f2a1c624e33 \ -H "Authorization: Bearer blf_live_EXAMPLE00000000000000000000000000000000"
{
"data": {
"id": "6f1c0f2a-1c62-4e33-9b8a-0f2a1c624e33",
"name": "Client work",
"description": null,
"color": "#1f48ff",
"archived_at": null,
"created_at": "2026-08-19T09:14:02.113Z",
"columns": [
{ "id": "0a5b...", "name": "To do", "position": 1 }
]
}
}GET/boards/{id}/cardsneeds projects:read
The cards on a board. Narrow it with ?columnId= and ?status= (open, in_progress, done, archived), and page with ?cursor=.
curl "https://bluefie.com/api/public/v1/boards/6f1c0f2a-1c62-4e33-9b8a-0f2a1c624e33/cards?status=open&limit=50" \ -H "Authorization: Bearer blf_live_EXAMPLE00000000000000000000000000000000"
{
"data": [
{
"id": "9e4a77bd-3c18-4f0a-8d55-3c184f0a8d55",
"board_id": "6f1c0f2a-1c62-4e33-9b8a-0f2a1c624e33",
"column_id": "0a5b...",
"position": 3,
"title": "Draft the launch email",
"description": null,
"status": "open",
"priority": "high",
"due_date": "2026-08-30",
"due_at": "2026-08-30T14:00:00.000Z",
"due_tz": "Europe/London",
"labels": ["launch"],
"assignee_user_id": null,
"delegated_agent_role": null,
"created_at": "2026-08-20T11:00:00.000Z",
"updated_at": "2026-08-20T11:00:00.000Z",
"completed_at": null
}
],
"meta": { "nextCursor": null }
}POST/cardsneeds projects:write
A new card, at the end of the stage you name. The stage has to be on the board you name.
curl -X POST https://bluefie.com/api/public/v1/cards \
-H "Authorization: Bearer blf_live_EXAMPLE00000000000000000000000000000000" \
-H "Content-Type: application/json" \
-d '{
"boardId": "6f1c0f2a-1c62-4e33-9b8a-0f2a1c624e33",
"columnId": "0a5b0000-0000-4000-8000-000000000001",
"title": "Build failed on main",
"description": "The 10:04 run went red.",
"priority": "urgent",
"dueDate": "2026-08-22",
"dueTime": "15:00",
"dueTz": "Europe/London",
"labels": ["ci"]
}'{
"data": {
"id": "44b1c8e0-90f2-4c1e-9a3d-90f24c1e9a3d",
"board_id": "6f1c0f2a-1c62-4e33-9b8a-0f2a1c624e33",
"column_id": "0a5b0000-0000-4000-8000-000000000001",
"position": 4,
"title": "Build failed on main",
"status": "open",
"priority": "urgent",
"due_date": "2026-08-22",
"due_at": "2026-08-22T14:00:00.000Z",
"due_tz": "Europe/London",
"labels": ["ci"],
"assignee_user_id": null,
"created_at": "2026-08-21T10:04:19.220Z"
}
}GET/cards/{id}needs projects:read
One card and its whole conversation. Comment authors come back as display names, never as email addresses.
curl https://bluefie.com/api/public/v1/cards/44b1c8e0-90f2-4c1e-9a3d-90f24c1e9a3d \ -H "Authorization: Bearer blf_live_EXAMPLE00000000000000000000000000000000"
{
"data": {
"id": "44b1c8e0-90f2-4c1e-9a3d-90f24c1e9a3d",
"title": "Build failed on main",
"status": "open",
"comments": [
{
"id": "c0ffee00-0000-4000-8000-000000000001",
"body": "Looking at it now.",
"author_name": "Dana Reyes",
"created_at": "2026-08-21T10:09:00.000Z"
}
]
}
}PATCH/cards/{id}needs projects:write
Change a card: title, description, status, priority, dueDate, labels, or columnId to move it to another stage on the same board. A move puts the card at the end of the new stage. Give it a time of day with dueTime (HH:mm) and dueTz (an IANA name like Europe/London): a time needs a date, and sending dueTime as null takes the time off and leaves the date. Cards read back due_at, an absolute instant, and due_tz, the zone to show it in, so everyone on the team sees the same clock face.
curl -X PATCH https://bluefie.com/api/public/v1/cards/44b1c8e0-90f2-4c1e-9a3d-90f24c1e9a3d \
-H "Authorization: Bearer blf_live_EXAMPLE00000000000000000000000000000000" \
-H "Content-Type: application/json" \
-d '{"status":"done","columnId":"3d8e0000-0000-4000-8000-000000000004"}'{
"data": {
"id": "44b1c8e0-90f2-4c1e-9a3d-90f24c1e9a3d",
"column_id": "3d8e0000-0000-4000-8000-000000000004",
"position": 9,
"status": "done",
"completed_at": "2026-08-21T10:31:02.880Z"
}
}POST/cards/{id}/commentsneeds projects:write
Say something on a card. It appears in the thread signed as the API, and the card's history records which key said it.
curl -X POST https://bluefie.com/api/public/v1/cards/44b1c8e0-90f2-4c1e-9a3d-90f24c1e9a3d/comments \
-H "Authorization: Bearer blf_live_EXAMPLE00000000000000000000000000000000" \
-H "Content-Type: application/json" \
-d '{"body":"Deploy 481 is live."}'{
"data": {
"id": "c0ffee00-0000-4000-8000-000000000002",
"body": "Deploy 481 is live.",
"author_name": "API",
"created_at": "2026-08-21T10:33:40.512Z"
}
}When something goes wrong
| code | HTTP | when |
|---|---|---|
| unauthorized | 401 | The key is missing, malformed, unknown or revoked. Every one of those answers the same, on purpose. |
| forbidden | 403 | A real key without the scope this endpoint needs. |
| rate_limited | 429 | More than 120 requests in a minute on one key. Retry-After says how long to wait. |
| invalid_request | 400 | Something in the body or the query string is not right. The message says which part. |
| not_found | 404 | No board or card with that id on this workspace. |
| unavailable | 503 | Projects are not set up on this workspace yet. |
| server_error | 500 | Our fault. Nothing was changed. |
For agents and API tools
The OpenAPI document describes every endpoint on this page, and the booking API on the websites Bluefie hosts, for code generators and agents. agents.md is the short version written for an agent. An agent that speaks MCP connects to https://bluefie.com/api/mcp instead: a person signs in and approves it once, or an admin issues it a key in Settings, Connections.
What this version does not do
Said plainly, so you do not spend an afternoon looking for it:
- It does not assign cards to people or delegate them to agents.
- It does not move a card from one board to another.
- It does not read or change private boards.
- It does not send notifications when it writes. The card carries the record.
- There are no webhooks yet. Poll a board, or tell us what you would listen for.
Questions
Write to info@bluefie.com and tell us what you are building. What we add next comes from those messages.