# About the API (/reference)



The pages in this section are generated directly from the MolnPay OpenAPI document, so they describe
exactly what each endpoint accepts and returns. The document itself is published at
[/openapi.json](/openapi.json) if you want to generate a client, a mock server or types from it — and its
`info.description` inlines the same quickstart these guides are built from, so an agent reading only the
document gets every rule.

## Base URL [#base-url]

```text
https://api.molnpay.com
```

Every endpoint sits under `/v1`. There is one host; a project is either live (`mp…` keys, mainnet) or test
(`mptest…` keys, the chain simulated through `/v1/test/*`), and the key decides which.

## Authentication [#authentication]

One header on every request:

```text
Authorization: Bearer mp<64 hex>
```

`mptest<64 hex>` for a test project. Keys are minted in the [console](https://app.molnpay.com/api-keys)
and shown once. A missing, malformed, expired or revoked key answers `401 invalid_api_key`; a key of the
wrong **kind** for a route answers `403 wrong_key_kind`, because you are authenticated and "use your other
key" is something you can act on. [Authentication](/concepts/authentication) has the whole scheme.

## Conventions [#conventions]

Requests and responses are JSON; send `Content-Type: application/json` on anything with a body.

**Amounts are decimal strings, never JSON numbers.** Atomic amounts (`"1500000000000000000"`) come with a
`*_decimal` twin and the asset's `decimals`; fiat amounts (`price_amount`, every `*_cents`) are integer
minor units, also as strings. [Money representation](/concepts/money).

**Timestamps are RFC 3339, UTC.**

**Lists are cursor-paginated, newest first.** `limit` 1–100 (default 25), an opaque `cursor`, and
`next_cursor` until it comes back `null`. [Pagination](/concepts/pagination).

**`Idempotency-Key` is honoured on every POST and required on payouts.** [Idempotency](/concepts/idempotency).

**A not-found and a not-yours answer identically.** Another project's customer, endpoint or delivery is a
`404`, never a `403`, so nothing confirms that an id exists.

**Every failure uses one envelope:** `{ error, code, type, message, param?, request_id }`. Branch on
`code`; quote `request_id` when you write to support. [Errors](/concepts/errors).

## Stability [#stability]

The API is versioned in the path at `/v1`, and webhook envelopes carry `api_version`. Within a version,
changes are additive: new endpoints, new optional request fields, new response properties, new event types
and new error codes can appear without notice; existing fields do not change meaning or disappear.

<Callout type="warn" title="Do not use strict object mappers">
  Because new response properties can appear at any time, a deserializer configured to throw on unknown
  keys will break on a routine, backwards-compatible change. Configure yours to ignore what it does not
  recognise, and keep a default branch on every enumerated value.
</Callout>

## Where to start [#where-to-start]

[Customers](/reference/customers) and [Wallets](/reference/wallets) are what every wallet-service
integration needs; `GET /v1/ping` ([Meta](/reference/meta)) is the first call worth making, because it
tells you what your key may do.
