# Octany > Octany is a Swedish billing engine for subscriptions, one-off orders, and > hosted checkout. This file follows the [llms.txt](https://llmstxt.org/) > convention so coding agents can map the integration surface in one fetch. The public API is REST/JSON over HTTPS. Every request is **scoped to an account** by including the account UUID in the URL path (`/api/{account}/…`). Authentication is a per-account API key sent as the `X-API-KEY` header. Webhooks are signed with HMAC-SHA256 of the JSON body, keyed by the endpoint's secret, in the `Octany-Signature` header. ## Docs - [Integration guide](docs/integration.md): auth, base URL, errors, pagination, locale, end-to-end subscription example. - [Frontend guide](docs/frontend.md): Fundraising embeds, Checkout URL + query params, embeddable cart (`window.Octany`), and Classic widget. - [API reference](../website/api.html): human-readable endpoint groups, request bodies, response examples, and resource payload shapes. - [OpenAPI 3.1 spec](docs/openapi.yaml): machine-readable contract for every documented endpoint. - [Webhooks](docs/webhooks.md): full event catalog (`subscription.*`, `order.*`, `product.*`), example payloads, signature verification in PHP/Node/Python. - [Migration from Stripe Cashier](docs/migrating-from-cashier.md): concept mapping and gaps. - [Docs index](docs/README.md): table of contents and known-gaps list. ## Resources at a glance - `GET /api/{account}/subscriptions` — list with `filter[reference_id]`, paginated 20. - `GET /api/{account}/subscription/{id}` — retrieve. - `POST /api/{account}/subscription/{id}/cancel` — cancel. - `POST /api/{account}/subscription/{id}/product` — swap product on a subscription. - `GET /api/{account}/subscription/{id}/orders` — list orders for a subscription, `per_page` configurable. - `POST /api/{account}/subscription/{id}/order` — charge a one-off product on a subscription. - `GET /api/{account}/products` — list (paginated 100). - `GET /api/{account}/product/{id}` — retrieve. Also `POST` (update) and `DELETE`. - `GET /api/{account}/order/{id}` — retrieve. - `POST /api/{account}/webhooks/endpoints` — register a webhook URL. ## Subscription status values `active`, `trialing`, `pending`, `future_start`, `delayed`, `unpaid`, `cancelled`, `expired`. See [docs/integration.md#subscription-status](docs/integration.md#subscription-status) for definitions. ## Webhook event names `subscription.created`, `subscription.updated`, `subscription.cancelled`, `subscription.renewed`, `order.confirmed`, `order.paid`, `product.updated`, `product.deleted`, `product-group.updated`, `product-group.deleted`, `test.hook`. Full payloads in [docs/webhooks.md](docs/webhooks.md). ## Resource IDs Subscription, order, and webhook-delivery `id` values are integers today (e.g. `76963688`) but should be treated as **opaque** — store them in a wide column (`bigint` or string) and don't gate on `is_int` / `typeof === 'number'`. Product IDs are integers and stable. Account is a UUID in the URL path. ## "Is this user paying?" ``` status in ('active', 'trialing') AND (ends_at is null OR ends_at > now) ``` `delayed` is transient (Octany retrying the renewal); `unpaid` is terminal. `cancelled` does **not** mean revoke access — check `ends_at`. ## Post-checkout reconciliation To land the user back in your app the moment payment settles, poll `GET /subscriptions?filter[reference_id]=` from the success page (every 2-3s) rather than waiting on a webhook. The same syncer should run from both the poll and the webhook handler so either path is sufficient. See [checkout-v2.html#reconciliation](../checkout-v2.html#reconciliation). ## Optional - [Hosted checkout](docs/integration.md#hosted-checkout): how to construct a checkout URL today (no API session helper yet). - [Idempotency](docs/migrating-from-cashier.md#idempotency): no `Idempotency-Key` header today; reconcile via list-after-write. - [Known gaps](docs/README.md#known-gaps-filed-for-upcoming-work): things that are explicitly missing so you don't go looking.