<!--
  SINGLE-SOURCE SYNC (ADR-0021): canonical prose for /docs/api-reference, mirrored 1:1 by
  resources/js/pages/public/docs/api-reference.tsx — edit BOTH in the same change (engineering-rules P4).
  The endpoint table is HAND-SYNCED from openapi/payxiro.v1.yaml (the source of truth) and the live
  /api/v1 route table; a Pest drift test keeps the spec and routes identical. When the spec adds an
  endpoint, update this table, the .md, and the .tsx together.
-->

# API reference

The machine-readable contract is the OpenAPI 3.1 document — the source of truth for the API.

- **[Download the OpenAPI 3.1 document → /docs/openapi.yaml](/docs/openapi.yaml)**

A rendered, interactive reference is coming with the developer portal (Phase 3). Until then, this is
the endpoint overview and the raw spec above.

## Phase 1 endpoints

Base URL `https://payxiro.com/api/v1`. All endpoints authenticate with a bearer secret key; the
`sk_test_` / `sk_live_` prefix selects the environment.

| Method | Path                         | Description                                                   |
| ------ | ---------------------------- | ------------------------------------------------------------- |
| GET    | `/ping`                      | Liveness / auth check                                         |
| POST   | `/customers`                 | Create a Customer (dedupes on `external_ref`)                 |
| GET    | `/customers`                 | List Customers (cursor pagination)                            |
| GET    | `/customers/{id}`            | Retrieve a Customer                                           |
| POST   | `/payments`                  | Create a Payment (requires `Idempotency-Key`)                 |
| GET    | `/payments`                  | List Payments                                                 |
| GET    | `/payments/{id}`             | Retrieve a Payment                                            |
| POST   | `/payments/{id}/submit-form` | Submit manual-method dynamic-form values                      |
| POST   | `/checkout_sessions`         | Create a hosted Checkout Session (requires `Idempotency-Key`) |
| GET    | `/checkout_sessions/{id}`    | Retrieve a Checkout Session                                   |
| POST   | `/webhook_endpoints`         | Register a Webhook Endpoint (secret shown once)               |
| GET    | `/webhook_endpoints`         | List Webhook Endpoints                                        |
| GET    | `/webhook_endpoints/{id}`    | Retrieve a Webhook Endpoint                                   |
| PATCH  | `/webhook_endpoints/{id}`    | Update a Webhook Endpoint                                     |
| DELETE | `/webhook_endpoints/{id}`    | Delete a Webhook Endpoint                                     |

## Conventions recap

- Amounts are decimal strings; asset codes are `CODE` or `CODE.NETWORK`; timestamps are ISO-8601 UTC.
- List endpoints use cursor pagination: `limit` (default 20, max 100) and `starting_after`; responses
  carry `has_more` and `next_cursor`. No page numbers, no total counts.
- Filter on the standard indexed columns: `status` (comma-separated), `asset_code`, `country`,
  `customer`, `provider_account`, `created_after` / `created_before`.
- Errors use the `{ "error": { type, code, message, param, request_id } }` envelope.
- v1 evolves additively only — tolerate unknown fields and enum values on read.

## Not yet live

Payouts, Refunds, Wallets, and the Events log are specified in the API design but are **not exposed in
Phase 1** (crypto-first, deposits-only — ADR-0012). They ship additively when built: Payouts in Phase
2+, Refunds later. The OpenAPI document describes only what the running server exposes today, so the
spec never drifts from reality.

See [Getting started](/docs/getting-started) for auth, idempotency, and the error envelope in full.
