---
title: "API overview"
description: "Authenticate with the Firefight REST API, understand the two key kinds, and make your first request."
canonical: https://firefight.app/docs/api/overview/
---

# 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

All endpoints live under a versioned path.

```
https://app.firefight.app/api/v1
```

The version is part of the URL. Breaking changes ship as a new version, so `v1` responses stay stable.

## Creating API keys

Create and manage keys under **Settings → 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 keeps only a hash.

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 can write nothing. Use it for your own scripts and agent sessions. |

Personal tokens are deliberately read-only. If your automation needs to create or update anything, mint a service key with exactly the permissions it needs.

You can rename a key, edit a service key's permissions, deactivate it temporarily, or delete it at any time from the same settings page.

## Authentication

Pass your token in the `Authorization` header on every request.

```
Authorization: Bearer ff_4kWm2xPqR8vNcT6yBhJd3fLzGaU9sEnQoXwA
```

Requests without a valid token get a `401` response. Requests with a valid token that lacks the needed permission get a `403`.

## 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` | List, fetch, declare, and update incidents |
| `severities` | `read` | List your workspace's severity levels |
| `statuses` | `read` | List your workspace's incident statuses |
| `incident_types` | `read` | List your workspace's incident types |
| `custom_fields` | `read` | List your workspace's custom field definitions |
| `catalog` | `read`, `create`, `update`, `delete` | Read catalog types, and manage catalog entries |
| `alerts` | `read` | Search ingested alerts through the [MCP server](https://firefight.app/docs/api/mcp-server.md) |
| `policies` | `read` | Dry-run alert routing through the [MCP server](https://firefight.app/docs/api/mcp-server.md) |

The `alerts` and `policies` resources currently apply only to MCP tools. There are no REST endpoints for them yet.

:::tip
Grant the narrowest set that works. A key that only declares incidents from your alerting pipeline needs `incidents:create` and nothing else.
:::

## 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](https://firefight.app/docs/api/using-the-api.md) for the error format.

## Your first request

List the most recent incidents in your workspace.

```bash
curl https://app.firefight.app/api/v1/incidents \
  -H "Authorization: Bearer ff_4kWm2xPqR8vNcT6yBhJd3fLzGaU9sEnQoXwA"
```

```json
{
  "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",
        "lifecycle_stage": "active"
      },
      "severity": {
        "id": "c7e2f9a1-3b4d-4c6e-8f0a-5d6b7c8e9f01",
        "name": "SEV2",
        "rank": 2
      },
      "type": null,
      "lead": {
        "id": "e4a8b2c6-1d3f-4e5a-b7c9-0f1a2b3c4d5e",
        "type": "user",
        "name": "Maja Kovac",
        "email": "maja@example.com"
      },
      "source": "datadog",
      "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](https://firefight.app/docs/api/using-the-api.md) for idempotent incident creation, error handling, and pagination, or set up [outbound webhooks](https://firefight.app/docs/api/webhooks.md) to push events to your systems instead of polling.
