PolderAPI

Backlog API

Incidents

Declare incidents, read and change them, post status updates, write on the timeline and assign roles.

Base URLhttps://backlog.polder.work

Incidents are addressed by their number in the workspace: /incidents/42 is INC-42. Two scopes: incidents:read reads, incidents:write declares and changes.

Scopes only narrow what the token's owner may do. The owner must be a non-guest member of a workspace that has Incidents switched on, otherwise every call answers 403.

Important A private incident is a 404 for a token whose owner is not one of its members, whatever its scopes. It is also missing from the list. Administrators get no special treatment through the API.

The same things exist in the MCP server as polder_* incident tools. See Scopes.

An incident

The list returns the compact form, a single incident returns it plus the detail.

Field Description
id, number, identifier Id, number in the workspace and INC-42.
title, summary Title and description.
private Only members can see it.
source Where it came from; api when declared here.
status { id, name, phase }. Phases: triage, active, post_incident, closed, declined, merged.
severity { id, name, rank, color, description } or null.
type { id, name } or null.
lead { id, name, avatar } of whoever holds the lead role, or null.
declared_at, resolved_at, next_update_at ISO 8601 or null.
duration, url Time open and the link to the incident in Polder.

A single incident also has accepted_at, closed_at, merged_into, channel (the chat channel), roles (every role with its holder), members, following, timestamps, metrics (seconds), timeline, updates (the latest 50), links (only what you may see yourself), tasks, postmortem and more.

List incidents

GET/api/v1/workspaces/{workspace}/incidentsscope incidents:read

Incidents you may see, most recently declared first, paged.

Parameter Description
phase open (everything still running), or one phase: triage, active, post_incident, closed, declined, merged. Anything else is a 422.
page, per_page Paging. per_page defaults to 50, at most 200.
curl "https://backlog.polder.work/api/v1/workspaces/7/incidents?phase=open" \
  -H "Authorization: Bearer $POLDER_TOKEN"
{
  "data": [{
    "id": 90, "identifier": "INC-42", "number": 42, "title": "Checkout is down", "private": false,
    "status": { "id": 2, "name": "Investigating", "phase": "active" },
    "severity": { "id": 1, "name": "SEV1", "rank": 1, "…": "…" },
    "lead": { "id": 3, "name": "Sanne", "avatar": null }, "…": "…"
  }],
  "meta": { "page": 1, "per_page": 50, "total": 1, "last_page": 1 }
}

Get the options

GET/api/v1/workspaces/{workspace}/incidents/optionsscope incidents:read

The workspace's configuration you pick ids from: severities, types (with private_by_default), statuses (with their phase) and roles (id, key, name, description). Fetch it before declaring or changing an incident.

{ "data": { "severities": [{ "id": 1, "name": "SEV1", "…": "…" }], "types": [], "statuses": [], "roles": [] } }

Declare an incident

POST/api/v1/workspaces/{workspace}/incidentsscope incidents:writethrottle 30 per minute

Declares an incident with the next number of the workspace and the source api. It starts straight in the active phase, or in triage when you ask for it. Answers 201 with the full incident.

Body

Field Type Required Description
title string yes At most 255 characters.
summary string no At most 10,000 characters.
severity_id integer no From the options.
type_id integer no From the options.
private boolean no Defaults to the type's private_by_default, otherwise false.
triage boolean no true to report into triage instead of straight in; meant for integrations such as monitors and scripts.
curl https://backlog.polder.work/api/v1/workspaces/7/incidents \
  -H "Authorization: Bearer $POLDER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "Checkout is down", "severity_id": 1}'

Get an incident

GET/api/v1/workspaces/{workspace}/incidents/{number}scope incidents:read

The full incident. 404 when the number does not exist in this workspace or the incident is private and you are not a member.

{ "data": { "identifier": "INC-42", "title": "Checkout is down", "roles": [], "timeline": [], "updates": [], "…": "…" } }

Change an incident

PATCH/api/v1/workspaces/{workspace}/incidents/{number}scope incidents:write

Changes the fields you send. A status change goes through the lifecycle (it can set timestamps, notify people and write to the timeline). Answers 200 with the full incident.

Field Type Description
title string At most 255 characters.
summary string or null At most 10,000 characters.
severity_id integer or null From the options.
type_id integer or null From the options.
status_id integer A status of this workspace; an unknown one is a 404.

To tell people what is going on, use Post a status update instead.

Post a status update

POST/api/v1/workspaces/{workspace}/incidents/{number}/updatesscope incidents:write

Posts an update for the people following the incident, optionally changing status and severity in the same step and scheduling the next update. Answers 201 with the update's id and the incident row.

Field Type Required Description
body string yes At most 10,000 characters.
impact string no At most 5,000 characters.
actions string no What is being done, at most 5,000 characters.
status_id integer no Move the incident to this status.
severity_id integer no Change the severity.
next_update_in integer no Minutes until the next update is due, 1 to 10080 (a week). Only kept while the incident is open.
{ "data": { "id": 311, "incident": { "identifier": "INC-42", "next_update_at": "2026-10-28T10:30:00+00:00", "…": "…" } } }

Get the timeline

GET/api/v1/workspaces/{workspace}/incidents/{number}/timelinescope incidents:read

Everything that happened, oldest first. Each event has id, kind (note, message, role, …), actor, occurred_at, data, edited, hidden and editable. The timeline is not paged.

{ "data": [{ "id": 1, "kind": "note", "actor": { "id": 3, "name": "Sanne", "avatar": null }, "occurred_at": "2026-10-28T09:12:00+00:00", "data": { "text": "Rolled back the release" }, "edited": false, "hidden": false, "editable": true }] }

Add a timeline note

POST/api/v1/workspaces/{workspace}/incidents/{number}/timelinescope incidents:write

Writes a note on the timeline. Answers 201 with the new event's id.

Field Type Required Description
text string yes At most 10,000 characters.
occurred_at date no When it happened, for notes written afterwards. Defaults to now; a moment in the future is a 422.
curl https://backlog.polder.work/api/v1/workspaces/7/incidents/42/timeline \
  -H "Authorization: Bearer $POLDER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"text": "Rolled back the release", "occurred_at": "2026-10-28T09:12:00+00:00"}'

Assign a role

PUT/api/v1/workspaces/{workspace}/incidents/{number}/roles/{role}scope incidents:write

Gives a role (the ids come from the options) to a person, or clears it. role is the role's id, not its number. The new holder becomes a member of the incident and the change is written on the timeline. Setting the same holder again changes nothing. Answers 200 with the incident row.

Field Type Required Description
user_id integer or null no The new holder, who must be able to use Incidents in this workspace. null or absent clears the role.

The lead role cannot be cleared while the incident is open (422 on user_id).

curl -X PUT https://backlog.polder.work/api/v1/workspaces/7/incidents/42/roles/1 \
  -H "Authorization: Bearer $POLDER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"user_id": 3}'