API overview
Firefight exposes a JSON REST API for reading and writing incidents, reading your workspace’s configuration, and managing service catalog entries. Anything you can automate around your incident response, from declaring incidents out of your monitoring pipeline to syncing the catalog from your infrastructure, goes through this API.
Base URL and versioning
Section titled “Base URL and versioning”All endpoints live under a versioned path.
https://app.firefight.app/api/v1The version is part of the URL. Breaking changes ship as a new version, so v1 responses stay stable.
Machine-readable description
Section titled “Machine-readable description”Everything on this page and the next is also published as an OpenAPI document, so you can generate a client, load the API into an explorer, or hand it to an AI agent as a tool list.
https://firefight.app/openapi.jsonhttps://firefight.app/openapi.yamlEvery operation in it carries a unique ID, a description, typed parameters, and a response schema. The permission an operation checks is on the operation itself as x-firefight-permission, so you can tell before calling it which grant a service key needs.
Creating API keys
Section titled “Creating API keys”Create and manage keys under Developer → API Keys in the Firefight web app. Every key belongs to your workspace and can optionally carry an expiry date. The token itself starts with ff_ and is shown once, at creation time. Store it somewhere safe, because Firefight cannot show it again.
There are two kinds of key.
| Kind | Who can create it | What it can do |
|---|---|---|
| Service key | Workspace admins | A standalone integration identity with granular permissions you pick per resource and action. Use it for monitoring pipelines, CI, and other headless automation. |
| Personal token | Any member, for themselves | Acts as you. It reads everything you can see, and writes only what your own role lets you change. Use it for your own scripts and agent sessions. |
A personal token carries your own authority and nothing more. A member’s token reads, and declares and updates incidents the way the member can in Slack, and an admin’s token can also change workspace configuration. For headless automation, mint a service key with exactly the permissions it needs rather than lending it yours.
You can rename a key, edit a service key’s permissions, deactivate it temporarily, or delete it at any time from the same page. Deleting asks you to confirm first, since anything using the key stops working at once and the key cannot be brought back. Under Connected agents, Revoke also asks first, then disconnects that client straight away.
Authentication
Section titled “Authentication”Pass your token in the Authorization header on every request. The one exception is sending an alert in, which authenticates with the alert source’s own token rather than an API key.
Authorization: Bearer ff_4kWm2xPqR8vNcT6yBhJd3fLzGaU9sEnQoXwARequests without a valid token get a 401 response. Requests with a valid token that lacks the needed permission get a 403.
Resources and permissions
Section titled “Resources and permissions”Service key permissions are a matrix of resources and actions. A key only holds the permissions you grant it, and each endpoint checks one specific pair.
| Resource | Actions with effect | What they unlock |
|---|---|---|
incidents | read, create, update | Read, declare and update incidents, read a timeline and dismiss a note, assign incident roles, take part (raise and pick up work, claim a runbook step, escalate, invite, link, and give a shoutout), and read and write the postmortem |
incident_transcripts | read | Read what people said in an incident channel, once the workspace has turned transcript access on |
severities | read, create, update, delete | List your severity levels, and manage them |
statuses | read, create, update, delete | List your incident statuses, and manage them |
incident_types | read, create, update, delete | List your incident types, and manage them |
custom_fields | read, create, update, delete | List your custom field definitions, and manage them |
forms | read, update | Read a lifecycle form, and change which fields it asks for |
catalog | read, create, update, delete | Read and manage catalog types and entries, and suggest links on the resource map |
runbooks | read, create, update, delete | List and fetch runbooks, and manage them |
handbook | read, create, update, delete | Read the handbook’s pages, and add, change or delete one |
alerts | read, create, update, delete | Search ingested alerts, and manage alert sources |
policies | read, create, update, delete | Dry-run alert routing, and manage routing rules |
approvals | read, update | List approval requests, and approve or deny one |
permissions | admins only | Abilities, principals, permission sets, grants, what members can do in each connected tool, approval rules, the changes Halon may make on its own, and the activity log. Cannot be granted to a key, so use a personal token |
incident_roles | read, create, update, delete | List your incident roles, and manage them |
webhooks | read, create, update, delete | List outbound webhooks, and manage them |
api_keys | admins only | Service keys. Cannot be granted to a key, so use a personal token |
map | read | Read the resource map over MCP |
investigations | read, create | Read Halon’s investigations and how it has done, start one, and ask Halon a question over MCP |
skills | read, create, update, delete | List and read your workspace’s skills, and manage them |
workflows | read, create, update | Change a workflow’s settings, and list, make and run workflows over MCP |
monitoring | read | List the problems Halon raised on its own over MCP |
channel_posts | create | Post a message as Firefight in any channel over MCP |
Most pairs have a REST endpoint behind them. Searching alerts, reading the resource map, working with Halon, listing, making and running workflows, Halon’s notices and posting in a channel are reachable over MCP rather than REST. Everything else on this table is reachable over REST, over MCP, and on the dashboard. The same resources are what you grant a person under Permissions.
Which surface a request came through makes no difference to what it is allowed to do, because the permission is checked the same way in all three. A key that can change severities on the dashboard can change them over the API and over MCP, and one that cannot change them anywhere cannot change them here. See Configuring your workspace.
custom_fields and forms are deliberately separate. custom_fields covers what a field is, such as adding an Affected region dropdown. forms covers which fields responders are asked for and when, so a key that lets an agent define a field does not also let it make Name required on every declaration. See Incident forms.
Rate limits
Section titled “Rate limits”Each key may make up to 1,000 requests per minute. Beyond that, requests get a 429 response until the window resets. See Using the API for the error format.
Your first request
Section titled “Your first request”List the most recent incidents in your workspace.
curl https://app.firefight.app/api/v1/incidents \ -H "Authorization: Bearer ff_4kWm2xPqR8vNcT6yBhJd3fLzGaU9sEnQoXwA"{ "incidents": [ { "id": "0d9b2c1e-7f3a-4b8e-9c5d-2a6e8f1b4d70", "identifier": "INC-42", "name": "Checkout latency spike in eu-west", "summary": "p99 latency on the checkout service exceeded 4s.", "status": { "id": "b1f6a2d4-8c3e-4f5a-9b7d-1e2c3a4b5d6f", "name": "Investigating", "slug": "investigating", "lifecycle_stage": "active" }, "severity": { "id": "c7e2f9a1-3b4d-4c6e-8f0a-5d6b7c8e9f01", "name": "SEV2", "slug": "sev2", "rank": 2 }, "type": null, "lead": { "id": "e4a8b2c6-1d3f-4e5a-b7c9-0f1a2b3c4d5e", "type": "user", "name": "Maja Kovac", "email": "maja@example.com" }, "source": "datadog", "test": false, "declared_by": null, "declared_at": "2026-07-18T09:12:44Z", "detected_at": null, "resolved_at": null, "created_at": "2026-07-18T09:12:44Z", "updated_at": "2026-07-18T09:40:02Z", "custom_fields": {}, "visibility": "public" } ], "pagination": { "page": 1, "per_page": 25, "total": 1, "total_pages": 1 }}From here, read Using the API for idempotent incident creation, error handling, and pagination, or set up outbound webhooks to push events to your systems instead of polling.