# API reference

Manage routes and TLS certificates with a JSON API over HTTP. Changes apply to live traffic without reloading.

The Ceryx API is a small JSON API over HTTP. Use it to add, change and remove [routes](/docs/api/routes), and to store your own [TLS certificates](/docs/api/certificates). Every change applies to new requests right away, without restarting or reloading Ceryx.

This reference is generated from the [OpenAPI spec](/docs/api/openapi.yaml) for Ceryx 1.0.0. You can use the spec to generate API clients, or give it to an agent as a tool definition.

## Reaching the API

The API listens on port `8080` inside the Ceryx container. Services on the `ceryx` Docker network reach it at:

```text
http://ceryx:8080
```

From the server running Ceryx, you can call it through the container:

```bash
docker compose -p ceryx exec ceryx curl localhost:8080/api/routes
```

> [!WARNING] The API has no authentication
> Anyone who can reach port `8080` can change your routes. Keep it on a private network and never publish it to the internet. See [Exposing the API safely](#exposing-the-api-safely).

## Requests and responses

- Request and response bodies are JSON. Send `Content-Type: application/json` with every request that has a body.
- Every path also accepts a trailing slash, so `/api/routes` and `/api/routes/` are the same.
- Creating something returns `201`, deleting returns `204` with no body. Deleting something that doesn't exist also returns `204`, so deletes are safe to retry.

## Errors

Errors return a JSON body with a `detail` message:

```json
{
  "detail": "No route found for app.example.com"
}
```

| Status | Meaning |
| --- | --- |
| `400` | The request body is missing, isn't valid JSON, or has an invalid field. |
| `404` | The route or certificate doesn't exist, or the path isn't part of the API. |
| `405` | The path doesn't support the method. The `Allow` header lists the methods it does support. |
| `500` | Storage failed, or a Ceryx setting the request needs has an unusable value. `detail` names the setting. |

## Endpoints

### Routes

| Endpoint | Description |
| --- | --- |
| `GET /api/routes` | [List routes](/docs/api/routes#list-routes) |
| `POST /api/routes` | [Create or replace a route](/docs/api/routes#create-or-replace-a-route) |
| `GET /api/routes/{host}` | [Get a route](/docs/api/routes#get-a-route) |
| `PUT /api/routes/{host}` | [Update a route](/docs/api/routes#update-a-route) |
| `DELETE /api/routes/{host}` | [Delete a route](/docs/api/routes#delete-a-route) |

### Certificates

| Endpoint | Description |
| --- | --- |
| `GET /api/certificates` | [List stored certificates](/docs/api/certificates#list-stored-certificates) |
| `POST /api/certificates` | [Create or replace a certificate](/docs/api/certificates#create-or-replace-a-certificate) |
| `GET /api/certificates/{domain}` | [Get the certificate served for a domain](/docs/api/certificates#get-the-certificate-served-for-a-domain) |
| `PUT /api/certificates/{domain}` | [Update a stored certificate](/docs/api/certificates#update-a-stored-certificate) |
| `DELETE /api/certificates/{domain}` | [Delete a stored certificate](/docs/api/certificates#delete-a-stored-certificate) |

## Exposing the API safely

Keep the API reachable only by the services that manage routes:

- Leave port `8080` unpublished, as the [production Compose file](/docs/deploy) does. Services that need the API join the `ceryx` network instead.
- If a service on another machine needs the API, put it behind something that authenticates requests, such as a VPN or an authenticating proxy.
- Give agents and CI jobs access through a small service of your own that checks which hostnames they may change. See [Agent environments](/docs/use-cases/agent-environments).
