# API overview

> Falak's REST API — base URL, bearer token auth, abilities, response envelope, pagination, errors and rate limits — plus the list of every endpoint.

Source: https://falak.sh/docs/api/overview/

Falak has a public REST API for automation: the `falak` CLI, CI pipelines, scripts and AI agents use it. This page covers what applies to every endpoint.

## Surfaces

| Surface | Base | Auth | For |
|---|---|---|---|
| **Public REST API v1** | `https://<panel>/api/v1` | Bearer token | You, the CLI, CI |
| **Deploy hooks** | `https://<panel>/api/deploy/{token}` | The secret token in the URL | CI, chat ops, git servers |
| Internal builder API | `https://<panel>/api/internal` | Builder token or signed URLs | `falak-builder` only |
| Agent protocol | `https://agents.<panel>/agent/v1` | Mutual TLS | `falak-agent` only |

## Authentication

1. Create a token under **Settings → API tokens**: a name, an optional expiry in days (1–3650), and abilities.
2. Send it on every request:

   ```bash
   curl https://falak.example.com/api/v1/me \
     -H "Authorization: Bearer $FALAK_TOKEN" \
     -H "Accept: application/json"
   ```

![Settings → API tokens: a form with name, expiry and a checklist of abilities grouped by module, and the list of active tokens.](./_images/settings-api-tokens.png)

- A token is pinned to **one organization**: the one you were in when you created it.
- **Abilities** are permission names (`deployments.create`, …) or `*` (**All abilities**: everything your role allows, now and later).
- A request is allowed only when the token has the ability **and** the token owner's role grants the permission. A token never exceeds its owner's role.
- Revoke tokens on the same page.

For bootstrapping, the first admin's token can be created on the control plane host: `falak-ctl admin create you@example.com --token=cli` (prints the token).

## Conventions

| Topic | Rule |
|---|---|
| Headers | Always send `Accept: application/json`; send `Content-Type: application/json` with a body |
| Envelope | Payloads are wrapped in `{"data": …}` |
| Pagination | Paginated lists add `links` and `meta` (`current_page`, `per_page`, `total`, `last_page`); use `?page=` and `?per_page=` (up to 100) |
| Ids | Lowercase ULIDs; uppercase is accepted anywhere |
| Sites | Addressed by id **or slug** everywhere (`{site}`) |
| Environments | Addressed by slug or id |
| Timestamps | ISO-8601 |

## Errors

| Status | Body | Meaning |
|---|---|---|
| `401` | | Missing or invalid token |
| `403` | `{"message": "…"}` | Ability or role missing |
| `404` | `{"message": "…"}` | Not found, **or** belongs to another organization |
| `409` | `{"message": "…"}` | The action cannot run now (for example agent upgrades) |
| `422` | `{"message": "…", "errors": {"field": ["…"]}}` | Validation failed |
| `429` | | Rate limited |
| `503` | | A backend (Loki) is not available |

## Rate limits

| Endpoints | Limit |
|---|---|
| Deploy, rollback, cancel, agent upgrade, template deploy | 30 / minute |
| Env read/write, Laravel toggles | 60 / minute |
| DNS check | 60 / minute |
| Site logs, access logs | 120 / minute |
| Deploy hooks | 30 / minute |

## Endpoints

| Method | Path | Permission | Page |
|---|---|---|---|
| GET | `/api/v1/me` | (any token) | [Identity](/docs/api/identity/) |
| GET | `/api/v1/organizations` | (any token) | [Identity](/docs/api/identity/) |
| GET | `/api/v1/servers` | `servers.view` | [Servers](/docs/api/servers/) |
| POST | `/api/v1/servers` | `servers.create` | [Servers](/docs/api/servers/) |
| GET | `/api/v1/servers/{server}` | `servers.view` | [Servers](/docs/api/servers/) |
| DELETE | `/api/v1/servers/{server}` | `servers.delete` | [Servers](/docs/api/servers/) |
| POST | `/api/v1/servers/{server}/agent/upgrade` | `fleet.agents.manage` | [Servers](/docs/api/servers/) |
| GET | `/api/v1/sites` | `sites.view` | [Sites](/docs/api/sites/) |
| POST | `/api/v1/sites` | `sites.create` | [Sites](/docs/api/sites/) |
| GET | `/api/v1/sites/{site}` | `sites.view` | [Sites](/docs/api/sites/) |
| GET / PUT | `/api/v1/sites/{site}/env` | `sites.env.view` / `sites.env.manage` | [Sites](/docs/api/sites/) |
| PUT | `/api/v1/sites/{site}/laravel` | `sites.manage` | [Sites](/docs/api/sites/) |
| GET | `/api/v1/sites/{site}/logs` | `telemetry.view` | [Logs](/docs/api/logs/) |
| GET | `/api/v1/sites/{site}/access-logs` | `telemetry.view` | [Logs](/docs/api/logs/) |
| GET / POST | `/api/v1/sites/{site}/deployments` | `deployments.view` / `deployments.create` | [Deployments](/docs/api/deployments/) |
| GET | `/api/v1/deployments/{deployment}` | `deployments.view` | [Deployments](/docs/api/deployments/) |
| GET | `/api/v1/deployments/{deployment}/output` | `deployments.view` | [Deployments](/docs/api/deployments/) |
| POST | `/api/v1/deployments/{deployment}/cancel` | `deployments.create` | [Deployments](/docs/api/deployments/) |
| POST | `/api/v1/sites/{site}/rollback` | `deployments.rollback` | [Deployments](/docs/api/deployments/) |
| GET | `/api/v1/sites/{site}/releases` | `deployments.view` | [Deployments](/docs/api/deployments/) |
| GET | `/api/v1/domains/options` | `edge.view` | [Domains and DNS](/docs/api/domains-and-dns/) |
| GET | `/api/v1/dns/check` | `edge.view` | [Domains and DNS](/docs/api/domains-and-dns/) |
| GET / POST | `/api/v1/projects` | `projects.view` / `projects.manage` | [Projects](/docs/api/projects/) |
| GET / PATCH / DELETE | `/api/v1/projects/{project}` | `projects.view` / `projects.manage` | [Projects](/docs/api/projects/) |
| GET / POST | `/api/v1/projects/{project}/environments` | `projects.view` / `projects.manage` | [Projects](/docs/api/projects/) |
| PATCH / DELETE | `/api/v1/projects/{project}/environments/{environment}` | `projects.manage` | [Projects](/docs/api/projects/) |
| POST | `/api/v1/projects/{project}/{environment}/templates/{slug}/deploy` | `templates.view` + `projects.manage` + `sites.create` | [Templates](/docs/api/templates/) |
| GET / POST | `/api/v1/source-control/connections` | `source_control.view` / `source_control.manage` | [Source control](/docs/api/source-control/) |
| GET / POST | `/api/deploy/{token}` | (token in URL) | [Deploy hooks](/docs/api/deploy-hooks/) |

Databases, processes, firewall rules, domains management, alerts, templates management and the terminal are not in the public API yet. They are available in the UI.

## Next steps
