API Documentation

Integrate your tools with FlowBoard using our REST API.

Quick Start

  1. Sign in to FlowBoard and go to Settings → Integrations
  2. Generate an API key with the permissions you need
  3. Include the key in every request as a Bearer token

Authentication

All API requests require a valid API key passed via the Authorization header:

Authorization: Bearer YOUR_API_KEY

Rate limit: 100 requests per minute per API key. Exceeding this returns HTTP 429.

Optional Headers

Header Required Description
X-User-EmailNo Your email in the workspace. Enables mine=true filter and proper comment attribution.

Base URL

https://europe-west3-flowwboard.cloudfunctions.net

Endpoints

POST/submitTask

Permission: Submit Ideas or Submit Bugs

Request Body

{
  "title": "Task title (3-200 characters)",
  "description": "Task description (0-5000 characters)",
  "type": "idea" | "bug" | "feature" | "improvement" | "fix" | "chore",
  "projectId": "optional, required for feature/improvement/fix/chore",
  "tags": ["optional", "array", "of", "tags"],
  "metadata": { "custom": "data" },
  "impact": 7,
  "clients": 4,
  "techEase": 6,
  "estimate": 4.5,
  "customFields": { "risk": "low" }
}

The last five fields are optional scoring inputs. priorityScore is computed from them using the workspace's priority formula — it is no longer a flat default, so a task submitted with real impact and client counts now sorts where it belongs. customFields keys must match a field configured in the workspace (by id or display name); an unknown key returns a 400 naming the valid ones. Call /getWorkspaceSchema to discover them.

Response (201 Created)

{
  "id": "task-id",
  "taskNumber": 123,
  "message": "Idea submitted successfully"
}

Example

curl -X POST https://europe-west3-flowwboard.cloudfunctions.net/submitTask \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Add dark mode support",
    "description": "Users want a dark mode option.",
    "type": "idea",
    "tags": ["ui", "feature-request"]
  }'
GET/getTasks

Permission: Search Tasks

Query Parameters

Parameter Type Description
qstring Free-text search across title and description. Omit for the previous match-everything behaviour
sortBystring "priority" (default), "votes", or "created". Anything else is a 400
boardstring"bugs", "ideas", or "flows"
projectIdstringFilter by project ID
projectNamestring Filter by project name (case-sensitive)
tagsstringComma-separated tags (AND logic)
statusstring open, in_progress, blocked, ready, done, paused
statusesstring Comma-separated statuses (OR logic)
assigneestringFilter by assignee user ID
mineboolean If true, filter tasks assigned to the user identified by X-User-Email header
typestring feature, improvement, fix, chore, bug
typesstringComma-separated types
limitnumber Max results (default: 100, max: 500)
excludeReleasedboolean Exclude released tasks (default: true)
excludeArchivedboolean Exclude archived tasks (default: true)
includeDeletedboolean Include deleted tasks (default: false)

Response (200 OK)

{
  "tasks": [
    {
      "id": "task-id",
      "taskNumber": "123",
      "title": "Task title",
      "status": "open",
      "type": "feature",
      "tags": ["client-acme"],
      "projectId": "proj123",
      "assignee": "user123",
      "createdAt": "2024-01-01T00:00:00.000Z"
    }
  ],
  "count": 1,
  "filters": { ... }
}
GET/getTask?taskId={taskId}

Permission: Search Tasks

Also accepts taskNumber as an alternative to taskId (e.g. /getTask?taskNumber=42)

Response (200 OK)

{
  "task": {
    "id": "task-id",
    "title": "Task title",
    "description": "Task description",
    "status": "open",
    "type": "feature",
    "tags": ["ui"],
    "taskNumber": "123"
  },
  "comments": [
    {
      "id": "comment-id",
      "text": "Comment text",
      "createdBy": "user123",
      "createdAt": "2024-01-01T00:00:00.000Z"
    }
  ]
}
PATCH/updateTask?taskId={taskId}

Permission: Update Tasks

Also accepts taskNumber as an alternative to taskId. Include X-User-Email header for proper comment attribution.

Request Body (all optional, at least one required)

{
  "status": "open" | "in_progress" | "blocked" | "ready" | "done" | "paused",
  "comment": "Add a comment (1-5000 characters)",
  "assignee": "userId or empty string to clear",
  "branchName": "feature/my-branch (0-200 characters)",
  "externalReference": {
    "type": "github_pr",
    "url": "https://github.com/...",
    "id": "optional",
    "title": "optional"
  }
}

Response (200 OK)

{
  "success": true,
  "taskId": "task-id",
  "message": "Task updated successfully"
}
DELETE/deleteTask?taskId={taskId}

Permission: Update Tasks

Also accepts taskNumber as an alternative to taskId

Soft-deletes a task. The task can be restored from the Trash.

GET/listProjects

Permission: View Projects

Returns all projects in the workspace with their IDs, names, and descriptions.

GET/getComments?taskId={taskId}

Permission: Manage Comments

Also accepts taskNumber as an alternative to taskId

Returns all comments for a given task, ordered by creation date.

POST/addComment?taskId={taskId}

Permission: Manage Comments

Also accepts taskNumber as an alternative to taskId. Include X-User-Email header for proper comment attribution.

Request Body

{
  "taskId": "task-id",
  "text": "Comment text (1-5000 characters)"
}
GET/listReleases

Permission: Search Tasks

Returns all releases in the workspace with version, date, and included tasks.

GET/getRelease?releaseId={releaseId}

Permission: Search Tasks

Returns a single release with full details including all associated tasks.

GET/getReleaseDraft

Permission: Manage Releases

Returns the current release draft state: tasks staged for release and hotfix, version string, and deploy notes.

Response

{
  "draft": {
    "version": "2.1.0",
    "releaseItems": [{ "id": "...", "title": "...", "status": "done", "type": "feature", "taskNumber": 42 }],
    "hotfixItems": [],
    "deployNotes": "",
    "updatedAt": "2026-04-14T10:00:00.000Z"
  }
}
PATCH/updateReleaseDraft

Permission: Manage Releases

Add or remove tasks from the release/hotfix draft, or set version/deploy notes.

Request Body

Field Type Description
actionstringRequired. One of: add, remove, set_version, set_deploy_notes
liststring"release" (default) or "hotfix"
taskIdsstring Comma-separated task IDs (for add/remove)
taskNumbersstring Comma-separated task numbers (alternative to taskIds)
versionstringVersion string (for set_version)
deployNotesstring Deploy notes HTML (for set_deploy_notes)
POST/confirmRelease

Permission: Manage Releases

Confirm and publish a release from the current draft. Creates the release document, archives all included tasks, and clears the draft.

Request Body

Field Type Description
versionstring Release version (overrides draft version)
namestring Release name (defaults to "Release {version}")
liststring"release" (default) or "hotfix"
isPublicbooleanMake release publicly visible
environmentsstring[] Environment tags (e.g. ["Staging", "Production"])

Response

{
  "success": true,
  "releaseId": "abc123",
  "name": "Release 2.1.0",
  "version": "2.1.0",
  "taskCount": 5,
  "isHotfix": false,
  "message": "Release \"Release 2.1.0\" confirmed with 5 task(s)."
}
POST/voteIdea?taskId={taskId}

Permission: Submit Ideas

Also accepts taskNumber as an alternative to taskId

Request Body

{
  "ideaId": "idea-id"
}
POST/bulkUpdateTasks

Permission: Update Tasks

Apply the same change to up to 50 tasks in one call. Identify targets with either taskIds or taskNumbers (comma-separated or an array). A task that can't be updated is skipped with a reason rather than failing the whole batch.

Request Body

{
  "taskNumbers": "42,43,44",
  "status": "done",
  "assignee": "user-id",
  "projectId": "proj_abc123",
  "addTags": "q3,billing",
  "removeTags": "triage",
  "dueDate": "2026-10-01",
  "comment": "Closed out after the billing release"
}

Response

{
  "requested": 3,
  "updated": 2,
  "skipped": 1,
  "results": [
    { "taskId": "abc", "taskNumber": 42, "updated": true },
    { "taskId": "def", "taskNumber": 43, "updated": true },
    { "taskId": "ghi", "taskNumber": 44, "updated": false, "reason": "..." }
  ],
  "message": "2 of 3 task(s) updated"
}
POST/scoreTask?taskId={taskId}

Permission: Update Tasks

Set scoring inputs on any task and recompute priorityScore from the workspace formula. Works on ideas, bugs and flow items alike. Also accepts taskNumber. At least one field must be present. Every write appends a before/after audit comment.

Request Body

{
  "impact": 8,
  "clients": 3,
  "techEase": 6,
  "estimate": 4.5,
  "customFields": { "risk": "low" }
}

Response

{
  "success": true,
  "taskId": "task_xyz789",
  "priorityScore": 17,
  "changes": [
    { "field": "techEase", "before": 4, "after": 6 }
  ],
  "message": "Scoring updated"
}

If every submitted value already matches the task, nothing is written and changes comes back empty. customFields keys are matched by field id or display name — an unknown key is a 400 listing the valid fields.

POST/reviewIdea?taskId={taskId}

Permission: Review Ideas

Accept, reject, send for rework, or place an idea — the same four actions available on the Ideas page. Only operates on tasks sitting on the workspace's ideas board; use /updateTask for anything else.

Request Body

{
  "action": "reject",
  "reason": "Already covered by the export settings page.",
  "projectId": "proj_abc123"
}

reason is required for reject and rework and is posted as a comment the submitter can see. projectId is required for place. Resulting status: accept → ready, reject → blocked, rework → rework, place → open.

The Review Ideas scope is off on every key created before it existed, and cannot be added in place — mint a new key with it checked.

GET/getWorkspaceSchema

Permission: View Projects

Discover the workspace's scoring configuration before writing to it — valid custom field keys, the priority formula, the project list, and the ideas and bugs board ids. No parameters.

Response

{
  "priorityFormula": "impact + clients + techEase",
  "customFields": [
    { "id": "field_1735987654321", "name": "risk", "type": "select", "options": ["low", "high"] }
  ],
  "projects": [
    { "id": "proj_abc123", "name": "Backend" }
  ],
  "ideasBoardId": "ideas_board_id",
  "bugsBoardId": "bugs_board_id"
}
GET/listMembers

Permission: View Projects

List workspace members and their roles, so you can resolve a person to the user id that assignee expects. No parameters.

Response

{
  "members": [
    { "userId": "abc123", "email": "dev@example.com", "displayName": "Sam", "role": "admin" }
  ]
}

A member whose auth record was deleted still appears, with email and displayName null — a stale membership stays visible rather than vanishing.

POST/addTasksToRelease

Permission: Manage Releases

Attach tasks to a release that already exists. Identify the release by releaseId or version, and the tasks by taskIds or taskNumbers.

Request Body

{
  "version": "2.4.0",
  "taskNumbers": "42,43,44"
}

If a version string matches more than one release the call fails and asks for a releaseId instead.

POST/removeTasksFromRelease

Permission: Manage Releases

Detach tasks from a release. Same identification rules as /addTasksToRelease.

Request Body

{
  "releaseId": "rel_abc123",
  "taskNumbers": "44"
}

MCP Server (AI Tools)

Connect AI tools like Claude Code, Cursor, and Windsurf to FlowBoard via our MCP server. Add this to your tool's MCP configuration:

macOS / Linux:

{
  "mcpServers": {
    "flowboard": {
      "command": "npx",
      "args": ["-y", "@flowboardlabs/mcp-server"],
      "env": {
        "FLOWBOARD_API_KEY": "YOUR_API_KEY",
        "FLOWBOARD_USER_EMAIL": "you@example.com"
      }
    }
  }
}

Windows:

{
  "mcpServers": {
    "flowboard": {
      "command": "cmd",
      "args": ["/c", "npx", "-y", "@flowboardlabs/mcp-server"],
      "env": {
        "FLOWBOARD_API_KEY": "YOUR_API_KEY",
        "FLOWBOARD_USER_EMAIL": "you@example.com"
      }
    }
  }
}

FLOWBOARD_USER_EMAIL is optional but recommended — it enables "list my tasks" and attributes comments to your account.

Error Codes

Code Description
400 Bad Request — Missing or invalid parameters
401 Unauthorized — Missing or invalid API key
403 Forbidden — API key lacks the required permission
404 Not Found — Task or resource not found
429 Too Many Requests — Rate limit exceeded (100 req/min)
500Internal Server Error

Need Help?

Check out the MCP Server guide for AI tool integration, or the GitHub/GitLab integration guide for webhook setup. For questions, contact support@flowboard.dev.