# Use the Lampwick API

> Everything the dashboard shows or does is in the JSON API under https://app.lampwick.dev/api/v1, described by an OpenAPI 3.1 document.

The JSON API under `https://app.lampwick.dev/api/v1` does everything the dashboard does, for scripts, a CLI or your own integrations. The dashboard's <kbd>⌘</kbd> <kbd>K</kbd> palette runs on the same API.

## Requirements

- A personal API token, created under **API tokens** on **Account & security**. It sees what your account sees: your teams and their projects.

## Make your first request

```bash
export LAMPWICK_TOKEN=YOUR_LAMPWICK_TOKEN
curl -H "Authorization: Bearer $LAMPWICK_TOKEN" https://app.lampwick.dev/api/v1/projects
```

`YOUR_LAMPWICK_TOKEN` is your personal token, which starts with `lwp_`.

## Check that it works

The answer is a JSON object with your projects, each with its `team`. A `401` means the token is wrong, expired or revoked.

## The OpenAPI document

- `GET https://app.lampwick.dev/api/v1/openapi.json` (no token needed) is an OpenAPI 3.1 document of the whole API, to generate a client or CLI from.
- Every operation has an `operationId` (`listIssues`, `getIssue`, `updateIssue`, …). Response schemas are complete: all keys are required, and what can be empty is nullable.
- `GET https://app.lampwick.dev/api/v1` lists all endpoints and conventions in compact form.

## Tokens

- Lampwick stores only a hash, so you see a token once. Up to 50 tokens per account, with an optional expiry.
- A token gives the same access as your signed-in session.
- Resetting your password or turning on [two-factor authentication](/docs/teams/#turn-on-two-factor-authentication) revokes all your tokens.

## Conventions

| Topic | Rule |
|---|---|
| Times | RFC 3339, in UTC. |
| Durations | `duration`, `avg`, `p95` and the like are in microseconds. |
| `range` | `1h`, `24h` (the default), `7d` or `14d`. |
| `q` and `limit` | Search term (case-insensitive substring) and number of results, with a maximum per endpoint. |
| Unknown parameters | Unknown query parameters or body fields, and invalid values, give `400`. |
| Bodies | JSON, with `Content-Type: application/json`. |

## Errors

Errors look like `{"error": {"code": "…", "message": "…"}}`.

| Status | Meaning |
|---|---|
| `400 bad_request` | A parameter or body field is unknown or invalid. |
| `401 unauthorized` | No token, or a wrong one. |
| `403 forbidden` | Not allowed, for example an action for team owners done by a member. |
| `404 not_found` | It doesn't exist, or it belongs to a team you are not in. Lampwick doesn't tell the two apart. |
| `409 conflict` | The change breaks a rule, such as removing the last owner of a team. |
| `429 rate_limited` | Too many requests of one kind. |

## Examples

```bash
api() { curl -fsS -H "Authorization: Bearer $LAMPWICK_TOKEN" -H 'content-type: application/json' "https://app.lampwick.dev/api/v1$@"; }

api /projects | jq '.projects[] | {id, name, open_issues}'
api '/projects/1/issues?status=open&range=7d' | jq '.issues[] | {id, ref, class, message, recent}'
api /projects/1/issues/42 -X PATCH -d '{"status":"resolved"}'
api '/projects/1/groups/requests?sort=p95&limit=10' | jq '.groups[] | {label, p95_ms: (.p95/1000)}'
api '/projects/1/logs?level=error&q=timeout'
```

Replace `1` with your project's `id` and `42` with an issue's `id` from the lists.

To give an AI agent the same access, [connect it to the MCP server](/docs/mcp/).
