AperioFlow Start free

Docs API reference

API: projects, phases and tasks

53 endpoints. Send your API key as Authorization: Bearer <key> on each request; see The API and AI assistants for keys, errors, idempotency and the conventions every endpoint shares.

GET /api/projects

List projects with progress and summary counts

Parameters:

NameInTypeRequiredDescription
statusqueryStatusNoOnly projects with this status.
qquerystringNoCase-insensitive search across name, description and owner.
includequerystringNoSet to tree to include each project's full phases tree. One of: tree.

Responses:

StatusMeaning
200Projects, ordered by position then id (array of ProjectListItem)
401Missing or invalid API key (Error)

POST /api/projects

Create a project, optionally with a nested plan

Nested phases[].tasks[].subtasks[] are created in one transaction. If any item is invalid, nothing is created.

Parameters:

NameInTypeRequiredDescription
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Request body (application/json, required): ProjectCreate.

FieldTypeRequiredDescription
nameNameYesTrimmed; must not be blank. At least 1 character. Up to 300 characters.
descriptionDescriptionNoUp to 20000 characters.
statusStatusNoOne of: todo, in_progress, blocked, done, cancelled. Default "todo".
priorityPriorityNoOne of: low, medium, high, critical. Default "medium".
ownerOwnerNoUp to 200 characters.
owner_user_idOwnerUserIdNoThe owner as a member of the organisation. Setting it fills owner with their name unless owner is sent too.
start_dateDateOrNullNo
due_dateDateOrNullNo
positionPositionNoSort order among siblings. New items are added at the end by default.
repo_urlRepoUrlNoUp to 2000 characters.
task_keyTaskKeyNoThe start of every task key in the project (a task is AF-12). Unique in the organisation; a clash is a 400 on task_key. Made from the name's initials when not given on create.
phasesarray of PhaseCreateNo

Example:

{
  "name": "Website relaunch",
  "status": "in_progress",
  "owner": "Dana",
  "due_date": "2026-12-01",
  "phases": [
    {
      "name": "Foundations",
      "tasks": [
        {
          "name": "Repo & CI",
          "status": "done"
        },
        {
          "name": "Design system",
          "subtasks": [
            {
              "name": "Colour tokens"
            },
            {
              "name": "Typography"
            }
          ]
        }
      ]
    },
    {
      "name": "Build",
      "tasks": [
        {
          "name": "Home page",
          "priority": "high"
        }
      ]
    }
  ]
}

Responses:

StatusMeaning
201Created project with its full tree (Project)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
413Request body larger than 2 MB (Error)

GET /api/projects/{id}

Get a project with its full tree

With view=summary the phases, tasks and subtasks come without their descriptions (the project keeps its own), which for a large project is less than half the size. A task's description is in GET /api/tasks/{id}. With view=list the phases keep their descriptions and only the tasks and subtasks leave theirs out (what the website's project page shows before a task is opened).

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
viewquerystringNosummary leaves out the descriptions of the phases, tasks and subtasks; list leaves out only those of the tasks and subtasks. Any other value is refused (400). One of: summary, list.

Responses:

StatusMeaning
200Project (Project)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

PATCH /api/projects/{id}

Update a project

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Request body (application/json, required): ProjectUpdate.

FieldTypeRequiredDescription
nameNameNoTrimmed; must not be blank. At least 1 character. Up to 300 characters.
descriptionDescriptionNoUp to 20000 characters.
statusStatusNoOne of: todo, in_progress, blocked, done, cancelled. Default "todo".
priorityPriorityNoOne of: low, medium, high, critical. Default "medium".
ownerOwnerNoUp to 200 characters.
owner_user_idOwnerUserIdNoThe owner as a member of the organisation. Setting it fills owner with their name unless owner is sent too.
start_dateDateOrNullNo
due_dateDateOrNullNo
positionPositionNoSort order among siblings. New items are added at the end by default.
repo_urlRepoUrlNoUp to 2000 characters.
task_keyTaskKeyNoThe start of every task key in the project (a task is AF-12). Unique in the organisation; a clash is a 400 on task_key. Made from the name's initials when not given on create.

Example:

{
  "status": "done"
}

Responses:

StatusMeaning
200Updated project with its full tree (Project)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

DELETE /api/projects/{id}

Delete a project and everything under it

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Responses:

StatusMeaning
204Deleted
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

GET /api/projects/{id}/phases

List a project's phases (with tasks and subtasks)

With view=summary each phase comes with its progress but without its tasks or description, for a phase picker.

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
viewquerystringNosummary leaves out descriptions (and, on a phase list, the tasks). Any other value is refused (400). One of: summary.

Responses:

StatusMeaning
200Phases, ordered by position then id (array of Phase)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

POST /api/projects/{id}/phases

Add a phase to a project, optionally with nested tasks

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Request body (application/json, required): PhaseCreate.

FieldTypeRequiredDescription
project_idParentIdNoFrom 1 to 2147483647.
nameNameYesTrimmed; must not be blank. At least 1 character. Up to 300 characters.
descriptionDescriptionNoUp to 20000 characters.
statusStatusNoOne of: todo, in_progress, blocked, done, cancelled. Default "todo".
priorityPriorityNoOne of: low, medium, high, critical. Default "medium".
ownerOwnerNoUp to 200 characters.
owner_user_idOwnerUserIdNoThe owner as a member of the organisation. Setting it fills owner with their name unless owner is sent too.
start_dateDateOrNullNo
due_dateDateOrNullNo
positionPositionNoSort order among siblings. New items are added at the end by default.
kindstringNoOnly build is accepted. Sections are created by moving a task into one, or by creating a task with section. One of: build.
tasksarray of TaskCreateNo

Responses:

StatusMeaning
201Created phase (Phase)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

GET /api/projects/{id}/activity

Change history for one project, newest first

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
limitqueryintegerNoDefault 50. From 1 to 500.
beforequeryintegerNoReturn entries with an id lower than this (for paging). From 1 to ....

Responses:

StatusMeaning
200Activity entries (array of Activity)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

POST /api/phases

Create a phase (parent given in the body)

Parameters:

NameInTypeRequiredDescription
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Request body (application/json, required).

FieldTypeRequiredDescription
project_idParentIdNoFrom 1 to 2147483647.
nameNameYesTrimmed; must not be blank. At least 1 character. Up to 300 characters.
descriptionDescriptionNoUp to 20000 characters.
statusStatusNoOne of: todo, in_progress, blocked, done, cancelled. Default "todo".
priorityPriorityNoOne of: low, medium, high, critical. Default "medium".
ownerOwnerNoUp to 200 characters.
owner_user_idOwnerUserIdNoThe owner as a member of the organisation. Setting it fills owner with their name unless owner is sent too.
start_dateDateOrNullNo
due_dateDateOrNullNo
positionPositionNoSort order among siblings. New items are added at the end by default.
kindstringNoOnly build is accepted. Sections are created by moving a task into one, or by creating a task with section. One of: build.
tasksarray of TaskCreateNo

Responses:

StatusMeaning
201Created phase (Phase)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

GET /api/phases/{id}

Get a phase with its tasks and subtasks

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.

Responses:

StatusMeaning
200Phase (Phase)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

PATCH /api/phases/{id}

Update a phase (set project_id to move it)

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Request body (application/json, required): PhaseUpdate.

FieldTypeRequiredDescription
project_idParentIdNoFrom 1 to 2147483647.
nameNameNoTrimmed; must not be blank. At least 1 character. Up to 300 characters.
descriptionDescriptionNoUp to 20000 characters.
statusStatusNoOne of: todo, in_progress, blocked, done, cancelled. Default "todo".
priorityPriorityNoOne of: low, medium, high, critical. Default "medium".
ownerOwnerNoUp to 200 characters.
owner_user_idOwnerUserIdNoThe owner as a member of the organisation. Setting it fills owner with their name unless owner is sent too.
start_dateDateOrNullNo
due_dateDateOrNullNo
positionPositionNoSort order among siblings. New items are added at the end by default.
kindPhaseKindNobuild for a build phase, otherwise the section kind. One of: build, regular, awaiting_owner, awaiting_response. Default "build".

Responses:

StatusMeaning
200Updated phase (Phase)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

DELETE /api/phases/{id}

Delete a phase and everything under it

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Responses:

StatusMeaning
204Deleted
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

GET /api/phases/{id}/tasks

List a phase's tasks (with subtasks)

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.

Responses:

StatusMeaning
200Tasks, ordered by position then id (array of Task)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

POST /api/phases/{id}/tasks

Add a task to a phase, optionally with nested subtasks

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Request body (application/json, required): TaskCreate.

FieldTypeRequiredDescription
phase_idParentIdNoFrom 1 to 2147483647.
nameNameYesTrimmed; must not be blank. At least 1 character. Up to 300 characters.
descriptionDescriptionNoUp to 20000 characters.
statusStatusNoOne of: todo, in_progress, blocked, done, cancelled. Default "todo".
priorityPriorityNoOne of: low, medium, high, critical. Default "medium".
ownerOwnerNoUp to 200 characters.
owner_user_idOwnerUserIdNoThe owner as a member of the organisation. Setting it fills owner with their name unless owner is sent too.
start_dateDateOrNullNo
due_dateDateOrNullNo
positionPositionNoSort order among siblings. New items are added at the end by default.
subtasksarray of SubtaskCreateNo

Responses:

StatusMeaning
201Created task (Task)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

POST /api/tasks

Create a task (parent given in the body)

Give either phase_id, or project_id and section to create the task in one of the project's sections (created if needed).

Parameters:

NameInTypeRequiredDescription
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Request body (application/json, required)

Example:

{
  "phase_id": 3,
  "name": "Home page"
}

Responses:

StatusMeaning
201Created task (Task)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

GET /api/tasks/{id}

Get a task with its subtasks

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.

Responses:

StatusMeaning
200Task (Task)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

PATCH /api/tasks/{id}

Update a task (set phase_id to move it)

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Request body (application/json, required): TaskUpdate.

FieldTypeRequiredDescription
phase_idParentIdNoFrom 1 to 2147483647.
nameNameNoTrimmed; must not be blank. At least 1 character. Up to 300 characters.
descriptionDescriptionNoUp to 20000 characters.
statusStatusNoOne of: todo, in_progress, blocked, done, cancelled. Default "todo".
priorityPriorityNoOne of: low, medium, high, critical. Default "medium".
ownerOwnerNoUp to 200 characters.
owner_user_idOwnerUserIdNoThe owner as a member of the organisation. Setting it fills owner with their name unless owner is sent too.
start_dateDateOrNullNo
due_dateDateOrNullNo
positionPositionNoSort order among siblings. New items are added at the end by default.

Example:

{
  "status": "done"
}

Responses:

StatusMeaning
200Updated task (Task)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

DELETE /api/tasks/{id}

Delete a task and its subtasks

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Responses:

StatusMeaning
204Deleted
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

GET /api/tasks/by-key/{key}

Get a task by its short key

Finds the task with this key in the caller's organisation, for links from branch names and commit messages. A task moved to another project has that project's key and number, so its old key finds nothing.

Parameters:

NameInTypeRequiredDescription
keypathstringYesA project's task key, a hyphen and the task's number, for example AF-12. Case does not matter.

Responses:

StatusMeaning
200Task (Task)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

POST /api/tasks/{id}/move

Move a task into a section, or to a phase

Send section to move the task into that section of its own project (created the first time), or phase_id to move it to a phase (a section must belong to the task's project). The task keeps its status, subtasks and history; the move is logged like a PATCH of phase_id. Going into a section from a build phase records that phase in origin_phase_id; moving between sections keeps it; going to a build phase clears it. Moving a task to where it already is changes nothing.

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Request body (application/json, required): TaskMove.

FieldTypeRequiredDescription
sectionSectionKindNoregular (Regular tasks), awaiting_owner (Awaiting owner) or awaiting_response (Awaiting response). One of: regular, awaiting_owner, awaiting_response.
phase_idParentIdNoFrom 1 to 2147483647.

Example:

{
  "section": "awaiting_owner"
}

Responses:

StatusMeaning
200The moved task (Task)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

POST /api/tasks/{id}/return

Return a task to its build phase

Moves the task back to the build phase it came from (origin_phase_id), or to the build phase given as phase_id, which must be in the same project. A 400 names phase_id when the task has no origin (it was created in the section, or its phase was deleted) and none was given.

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Request body (application/json).

FieldTypeRequiredDescription
phase_idParentIdNoFrom 1 to 2147483647.

Responses:

StatusMeaning
200The returned task (Task)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

GET /api/tasks/{id}/comments

Comments on a task (also /api/subtasks/{id}/comments and /api/issues/{id}/comments)

Only when the server has COMMENTS=on; otherwise this route does not exist. Oldest first. body_html is rendered on the server from body: raw HTML is shown as text and only web, mail and same-site links are links.

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.

Responses:

StatusMeaning
200The comments (array of Comment)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

POST /api/tasks/{id}/comments

Add a comment

Written by a signed-in member. A key that is not tied to a person gets a 400. The activity log records that a comment was added, never its text.

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.

Request body (application/json, required).

FieldTypeRequiredDescription
bodystringYesMarkdown. At least 1 character. Up to 10000 characters.
mention_user_idsarray of integerNoCurrent members of the organisation to mention (anyone else is a 400 and nothing is saved). Each gets an email only when the server has WORK_EMAILS=on and they have not switched these emails off: fixed subject, who mentioned them and a link to the task, never the comment's text. The author is never emailed. Up to 20 items.

Responses:

StatusMeaning
201The comment (Comment)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

PATCH /api/comments/{id}

Edit a comment (its author only)

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.

Request body (application/json, required).

FieldTypeRequiredDescription
bodystringYesAt least 1 character. Up to 10000 characters.

Responses:

StatusMeaning
200The comment, with edited_at set (Comment)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
403Only the author can edit a comment
404Item (or its parent) does not exist (Error)

DELETE /api/comments/{id}

Delete a comment (its author, or an admin)

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.

Responses:

StatusMeaning
204Deleted
401Missing or invalid API key (Error)
403Only the author or an admin can delete a comment
404Item (or its parent) does not exist (Error)

Search projects, phases, tasks and subtasks

Items of the caller's organisation whose name or description contains the text, any case (% and _ are plain characters). Name matches come first, then projects before phases before tasks before subtasks.

A query can also name an item by its ID, and that item comes first with matched id: id:123 (or #123) is anything with that ID and project:123, phase:123, task:123 or subtask:123 one kind, each returning only the exact match; P123, T123 and S123 (the badges the app shows for phases, tasks and subtasks) and a task key such as AF-12 return the exact match followed by any text matches.

Parameters:

NameInTypeRequiredDescription
qquerystringYes2 to 100 characters. At least 2 characters. Up to 100 characters.
limitqueryintegerNoDefault 50. From 1 to 100.

Responses:

StatusMeaning
200The matches

GET /api/labels

The organisation's labels

Responses:

StatusMeaning
200Labels by name, with how many tasks carry each (array of Label)
401Missing or invalid API key (Error)

POST /api/labels

Add a label

Request body (application/json, required): LabelInput.

FieldTypeRequiredDescription
namestringNoUnique in the organisation. At least 1 character. Up to 40 characters.
colorLabelColorNoOne of: gray, red, orange, yellow, green, teal, blue, purple, pink.

Example:

{
  "name": "Bug",
  "color": "red"
}

Responses:

StatusMeaning
201The new label (Label)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)

PATCH /api/labels/{id}

Rename or recolour a label

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.

Request body (application/json, required): LabelInput.

FieldTypeRequiredDescription
namestringNoUnique in the organisation. At least 1 character. Up to 40 characters.
colorLabelColorNoOne of: gray, red, orange, yellow, green, teal, blue, purple, pink.

Responses:

StatusMeaning
200The label (Label)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

DELETE /api/labels/{id}

Delete a label (admins); it comes off every task

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.

Responses:

StatusMeaning
204Deleted
401Missing or invalid API key (Error)
403Admins only
404Item (or its parent) does not exist (Error)

PUT /api/tasks/{id}/labels

Replace the labels on a task

The task ends up with exactly these labels (an empty list clears them). The change is logged in the activity. A PATCH of the task ignores labels.

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Request body (application/json, required).

FieldTypeRequiredDescription
label_idsarray of integerYesUp to 50 items.

Example:

{
  "label_ids": [
    3,
    5
  ]
}

Responses:

StatusMeaning
200The task with its labels (Task)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

PUT /api/tasks/{id}/repeat

Make a task repeat, or change how it repeats

The task needs a due date: the pattern counts from it. When the task is marked done, by any route (a PATCH, a bulk change, the connector), the next one is made in the same transaction: a copy with the same name, description, priority, owner, labels and subtasks (set back to to do), due on the first date of the pattern after both the finished task's due date and today (so finishing late never makes a heap of missed ones), with the start date moved by the same distance. Cancelling a task makes no next one and does not stop the series. No email is ever sent. The date a task is made for is claimed in the database first, so the same date is never made twice. Dates are the UTC date. At most 200 repeating tasks per organisation.

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Request body (application/json, required).

FieldTypeRequiredDescription
freqstringYesOne of: daily, weekly, monthly.
every_nintegerNoDefault 1. From 1 to 52.
weekdaysarray of integerNoWeekly only: 1 Monday to 7 Sunday. Defaults to the weekday of the due date.
month_dayintegerNoMonthly only: a shorter month takes its last day. Defaults to the day of the due date. From 1 to 31.
ends_onstring or null (date)NoNo new task is made for a date after this.

Example:

{
  "freq": "weekly",
  "weekdays": [
    1,
    4
  ],
  "ends_on": "2027-01-01"
}

Responses:

StatusMeaning
200The task with its repeat (Task)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

DELETE /api/tasks/{id}/repeat

Stop a task repeating

The tasks already made stay; no new one is made. Nothing happens if the task did not repeat.

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Responses:

StatusMeaning
200The task, with repeat null (Task)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

GET /api/projects/{id}/export.csv

The project's tasks and subtasks as a CSV file

UTF-8 with a byte order mark, CRLF line ends. Columns Key, Type (task or subtask), Phase, Section, Name, Status, Priority, Owner, Start, Due, Labels, Description. A cell starting with = + - @ tab or carriage return gets a single quote in front. At most 50,000 rows.

Parameters:

NameInTypeRequiredDescription
idpathintegerYes

Responses:

StatusMeaning
200The file
404Item (or its parent) does not exist (Error)
413More than 50

POST /api/projects/{id}/import/preview

Check a CSV file of tasks for import (admins and up); writes nothing

Parameters:

NameInTypeRequiredDescription
idpathintegerYes
phase_idqueryintegerYesA build phase of the project.

Request body (text/csv, required)

Responses:

StatusMeaning
200ok, rows, skipped_subtasks, errors (row, column, message; never cell content), total_errors, sample (the first 20 tasks)
400The request body is invalid or is not valid JSON (Error)
404Item (or its parent) does not exist (Error)
413The file is over 1 MB

POST /api/projects/{id}/import

Import the tasks of a CSV file, all or none (admins and up)

The file is read and checked again here. Up to 2,000 rows. One import at a time per organisation and 10 an hour. No email; one activity line; the file is not kept.

Parameters:

NameInTypeRequiredDescription
idpathintegerYes
phase_idqueryintegerYes

Request body (text/csv, required)

Responses:

StatusMeaning
201Imported: { imported: n }
400The request body is invalid or is not valid JSON (Error)
404Item (or its parent) does not exist (Error)
409Another import is running for this organisation
413The file is over 1 MB
429More than 10 imports in the last hour

PUT /api/tasks/{id}/blocked-by

Replace the tasks this task waits on

The task ends up waiting on exactly these tasks (an empty list clears them), up to 20, all in the same project. A task cannot wait on itself, and a loop (it would wait on a task that already waits on it, directly or through others) is refused with a 400. The change is logged in the activity. Nothing is blocked by the server: a task that waits on another can still be changed; the web app shows a "Blocked by" tag while any of them is not done or cancelled.

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Request body (application/json, required).

FieldTypeRequiredDescription
task_idsarray of integerYesUp to 20 items.

Example:

{
  "task_ids": [
    12,
    15
  ]
}

Responses:

StatusMeaning
200The task with its blocked_by (Task)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

GET /api/my-work

The signed-in member's own tasks in every project

Open tasks whose owner_user_id is the caller, in build phases and sections alike, soonest due first (tasks with no due date last). section is build for a task in a build phase, otherwise its section. Needs a person: an environment key or the shared password is not one and gets a 400.

Parameters:

NameInTypeRequiredDescription
include_closedquerybooleanNoAlso return done and cancelled tasks. Default false.
label_idqueryintegerNoOnly tasks carrying this label. From 1 to ....

Responses:

StatusMeaning
200Tasks with their phase or section and project
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)

POST /api/phases/{id}/reorder-tasks

Put a phase's tasks in a new order

task_ids must be exactly the phase's tasks, each once. Their position becomes 0, 1, 2 ... in that order, in one transaction, and the change is logged once on the phase (nothing is logged when the order is the same). Works on sections too. The web board's drag and drop uses it.

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Request body (application/json, required).

FieldTypeRequiredDescription
task_idsarray of integerYes

Example:

{
  "task_ids": [
    5,
    3,
    4
  ]
}

Responses:

StatusMeaning
200The phase with its tasks in the new order (Phase)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

POST /api/tasks/bulk

One change to many tasks at once

Up to 100 distinct tasks, all or nothing in one transaction: each is changed (and logged) exactly as a PATCH of that task would be, and a label can be added or taken off without touching the task's other labels. set takes status, priority and due_date (null clears it); the owner is not part of it, so no assignment email is ever sent from here. An unknown task, a task of another organisation, a project that is switched off or any bad value stops the whole request with nothing changed. The web app's table uses it.

Parameters:

NameInTypeRequiredDescription
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Request body (application/json, required).

FieldTypeRequiredDescription
task_idsarray of integerYesUp to 100 items.
setobjectNo
add_label_idintegerNoFrom 1 to ....
remove_label_idintegerNoFrom 1 to ....

Example:

{
  "task_ids": [
    5,
    3,
    4
  ],
  "set": {
    "status": "done"
  }
}

Responses:

StatusMeaning
200How many tasks changed
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

GET /api/projects/{id}/views

The caller's own saved table views of a project

Private to the signed-in member. A key that is not tied to a person (an environment key or the shared password) gets a 400.

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.

Responses:

StatusMeaning
200The views by name (array of SavedView)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

POST /api/projects/{id}/views

Save a table view

Names are unique per person and project ignoring case; at most 30 per project. A missing config field takes its default; an unknown field or value is a 400 naming it.

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.

Request body (application/json, required).

FieldTypeRequiredDescription
namestringYesAt least 1 character. Up to 60 characters.
configSavedViewConfigYes

Example:

{
  "name": "Blocked things",
  "config": {
    "status": "blocked",
    "sort": "due",
    "dir": "asc",
    "group": "phase"
  }
}

Responses:

StatusMeaning
201The saved view (SavedView)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

PATCH /api/views/{id}

Rename a saved view and/or replace its settings

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.

Request body (application/json, required).

FieldTypeRequiredDescription
namestringNoAt least 1 character. Up to 60 characters.
configSavedViewConfigNo

Responses:

StatusMeaning
200The saved view (SavedView)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

DELETE /api/views/{id}

Delete a saved view

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.

Responses:

StatusMeaning
204Deleted
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

GET /api/sections

Tasks in every project's sections

Tasks in the sections of every project (or one), ordered awaiting owner, awaiting response, regular, then by project and position. Build phases are never included. Open tasks only unless include_closed.

Parameters:

NameInTypeRequiredDescription
kindquerystringNoOne section kind, or several separated by commas.
project_idqueryintegerNoFrom 1 to ....
label_idqueryintegerNoOnly tasks carrying this label. From 1 to ....
include_closedquerybooleanNoAlso return done and cancelled tasks. Default false.

Responses:

StatusMeaning
200Tasks with their section, project and origin phase (array of SectionTask)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)

GET /api/tasks/{id}/subtasks

List a task's subtasks

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.

Responses:

StatusMeaning
200Subtasks, ordered by position then id (array of Subtask)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

POST /api/tasks/{id}/subtasks

Add a subtask to a task

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Request body (application/json, required): SubtaskCreate.

FieldTypeRequiredDescription
task_idParentIdNoFrom 1 to 2147483647.
nameNameYesTrimmed; must not be blank. At least 1 character. Up to 300 characters.
descriptionDescriptionNoUp to 20000 characters.
statusStatusNoOne of: todo, in_progress, blocked, done, cancelled. Default "todo".
priorityPriorityNoOne of: low, medium, high, critical. Default "medium".
ownerOwnerNoUp to 200 characters.
owner_user_idOwnerUserIdNoThe owner as a member of the organisation. Setting it fills owner with their name unless owner is sent too.
start_dateDateOrNullNo
due_dateDateOrNullNo
positionPositionNoSort order among siblings. New items are added at the end by default.

Responses:

StatusMeaning
201Created subtask (Subtask)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

POST /api/subtasks

Create a subtask (parent given in the body)

Parameters:

NameInTypeRequiredDescription
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Request body (application/json, required).

FieldTypeRequiredDescription
task_idParentIdNoFrom 1 to 2147483647.
nameNameYesTrimmed; must not be blank. At least 1 character. Up to 300 characters.
descriptionDescriptionNoUp to 20000 characters.
statusStatusNoOne of: todo, in_progress, blocked, done, cancelled. Default "todo".
priorityPriorityNoOne of: low, medium, high, critical. Default "medium".
ownerOwnerNoUp to 200 characters.
owner_user_idOwnerUserIdNoThe owner as a member of the organisation. Setting it fills owner with their name unless owner is sent too.
start_dateDateOrNullNo
due_dateDateOrNullNo
positionPositionNoSort order among siblings. New items are added at the end by default.

Responses:

StatusMeaning
201Created subtask (Subtask)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

GET /api/subtasks/{id}

Get a subtask

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.

Responses:

StatusMeaning
200Subtask (Subtask)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

PATCH /api/subtasks/{id}

Update a subtask (set task_id to move it)

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Request body (application/json, required): SubtaskUpdate.

FieldTypeRequiredDescription
task_idParentIdNoFrom 1 to 2147483647.
nameNameNoTrimmed; must not be blank. At least 1 character. Up to 300 characters.
descriptionDescriptionNoUp to 20000 characters.
statusStatusNoOne of: todo, in_progress, blocked, done, cancelled. Default "todo".
priorityPriorityNoOne of: low, medium, high, critical. Default "medium".
ownerOwnerNoUp to 200 characters.
owner_user_idOwnerUserIdNoThe owner as a member of the organisation. Setting it fills owner with their name unless owner is sent too.
start_dateDateOrNullNo
due_dateDateOrNullNo
positionPositionNoSort order among siblings. New items are added at the end by default.

Responses:

StatusMeaning
200Updated subtask (Subtask)
400The request body is invalid or is not valid JSON (Error)
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

DELETE /api/subtasks/{id}

Delete a subtask

Parameters:

NameInTypeRequiredDescription
idpathintegerYesFrom 1 to 2147483647.
X-ActorheaderstringNoName recorded in the activity log (up to 200 characters, URI-encoded if not ASCII).

Responses:

StatusMeaning
204Deleted
401Missing or invalid API key (Error)
404Item (or its parent) does not exist (Error)

GET /api/dashboard

Open, overdue and due-soon task counts for each project

Counts only, for tasks in build phases that are not done or cancelled. Projects with no open task are left out. Overdue means due before today; due soon means due today up to 6 days ahead.

Parameters:

NameInTypeRequiredDescription
todayquerystring (date)NoThe caller's own date, YYYY-MM-DD. Defaults to the server's UTC date.

Responses:

StatusMeaning
200Counts per project
400today is not a date written YYYY-MM-DD
401Missing or invalid API key (Error)

GET /api/activity

Change history across all projects, newest first

Parameters:

NameInTypeRequiredDescription
limitqueryintegerNoDefault 50. From 1 to 500.
beforequeryintegerNoReturn entries with an id lower than this (for paging). From 1 to ....
project_idqueryintegerNoOnly entries for this project. From 1 to ....

Responses:

StatusMeaning
200Activity entries (array of Activity)
401Missing or invalid API key (Error)

Start free All the docs Video guides

Built for the people who write the code and answer the phone when it breaks.

Run from the UK. Hosted in France.

UK time --:--

Already in?Open the app Start free today
View our policies