# StellarFirm API endpoints

> Every public StellarFirm API route with its method, what it needs, and what it answers. The same list is in the OpenAPI 3.1 file at /openapi.json.

The routes below are the whole public StellarFirm API. Each one is also in the [OpenAPI file](https://stellarfirm.ai/openapi.json), with its parameters and answer schemas. A route answers `405` with an `Allow` header for any method not listed here.

## At a glance

| Method and path | Sign-in | What it does |
| --- | --- | --- |
| `GET /api/health` | None | Says the web app is up. |
| `GET /api/site-banner` | None | Reads the notice at the top of the site. |
| `GET /api/entitlement` | Session | Says whether the account may run. |
| `GET /api/credits/balance` | Session | Reads the account's credits. |
| `POST /api/email/unsubscribe` | Signed token | Stops the later onboarding emails. |

## GET /api/health

Answers `200` with `ok: true` while the web app is running. Use it for an uptime check.

```json
{ "ok": true, "service": "...", "surface": "ui", "agent": "not-hosted-here" }
```

## GET /api/site-banner

The notice shown at the top of the site, or `null` when there is none. It is the same for everyone and may be cached for half a minute.

| Field | Type | Meaning |
| --- | --- | --- |
| `banner` | object or null | The notice, or `null`. |
| `banner.kind` | `promo` or `warning` | A `promo` shows on the public site only. A `warning` shows everywhere. |
| `banner.message` | string | The notice text. |

## GET /api/entitlement

Says whether the signed-in account has an active trial or licence. Only a `200` with `ok: true` means the account may run. It is never cached.

| Status | `status` field | Meaning |
| --- | --- | --- |
| 200 | `licensed` or `trial` | The account may run. Ask again within `recheckAfterSeconds`. |
| 401 | `signed-out` | No signed-in session. |
| 403 | `trial-ended` or `invalid` | The account may not run. |
| 503 | `unconfigured` or `unavailable` | The account could not be checked. Try again shortly. |

Every answer except `200` also carries the standard `error` object. See [Errors](/docs/api/errors).

## GET /api/credits/balance

The account's balance as a number of StellarFirm credits, never money. Answers `{ "credits": 120 }` for example. It answers `503` with the code `balance_unavailable` when the balance cannot be read.

## POST /api/email/unsubscribe

One-click unsubscribe from the later onboarding emails. Send the `token` from the link in the email as the query parameter. It answers `200` with a plain text line, `400` with `invalid_token` for a token that is not valid, and `502` with `upstream_failed` when the later emails are still scheduled and you should try again.

## Unknown routes

Any other address under `/api` answers `404` with the error code `not_found`, in JSON, never an HTML page.

## Related

- [Authentication](/docs/api/authentication)
- [Example requests](/docs/api/examples)
- [Errors](/docs/api/errors)

---

Source: https://stellarfirm.ai/docs/api/endpoints
