> ## Documentation Index
> Fetch the complete documentation index at: https://docs.meum.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

> Create, list, retrieve, poll status, and cancel invoices via Public Merchant API v1.

All invoice IDs use opaque `inv_` tokens. Internal UUIDs are never returned.

## Authentication

```
Authorization: Bearer sk_live_...
```

## Create invoice

`POST /v1/invoices`

|                 |                             |
| --------------- | --------------------------- |
| **Scope**       | `invoices:write`            |
| **Idempotency** | Not supported on this route |
| **Rate limit**  | Write bucket (`enforce`)    |

### Request body

| Field               | Required | Validation                                        |
| ------------------- | -------- | ------------------------------------------------- |
| `amount`            | Yes      | Decimal string, settlement amount                 |
| `currency`          | Yes      | ISO currency code                                 |
| `external_order_id` | No       | Merchant reference                                |
| `callback_url`      | No       | HTTPS webhook target (developer keys)             |
| `return_url`        | No       | Buyer redirect after payment                      |
| `metadata`          | No       | JSON object; sensitive keys stripped in responses |

### Response `201`

Returns `id` (`inv_...`), `status`, `checkout_url`, `amount`, `currency`, `output_asset`, `expires_at`.

### Errors

| Code                           | HTTP | When                          |
| ------------------------------ | ---- | ----------------------------- |
| `INSUFFICIENT_SCOPE`           | 403  | Missing `invoices:write`      |
| `payout_wallet_not_configured` | 400  | Store payout not set          |
| `store_mismatch`               | 403  | `store_id` does not match key |

### Webhooks

`invoice.created` when the invoice is persisted.

### Examples

```bash theme={null}
curl -X POST https://api.meum.io/v1/invoices \
  -H "Authorization: Bearer sk_live_EXAMPLE" \
  -H "Content-Type: application/json" \
  -d '{"amount":"99.00","currency":"USD","external_order_id":"order-1001"}'
```

```javascript theme={null}
const res = await fetch("https://api.meum.io/v1/invoices", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${apiKey}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ amount: "99.00", currency: "USD" }),
});
```

```php theme={null}
$ch = curl_init("https://api.meum.io/v1/invoices");
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer sk_live_EXAMPLE",
    "Content-Type: application/json",
  ],
  CURLOPT_POSTFIELDS => json_encode(["amount" => "99.00", "currency" => "USD"]),
  CURLOPT_RETURNTRANSFER => true,
]);
```

### Security

Never log full API keys. `checkout_url` is buyer-facing; do not embed secrets in metadata.

***

## List invoices

`GET /v1/invoices`

|                |                                                     |
| -------------- | --------------------------------------------------- |
| **Scope**      | `invoices:read`                                     |
| **Pagination** | Cursor (`limit`, `starting_after`, `ending_before`) |
| **Rate limit** | Read bucket (`observe`)                             |

Query: `status`, `external_order_id`, `payment_link_id` (`plink_...`).

***

## Retrieve invoice

`GET /v1/invoices/{id}`

|               |                        |
| ------------- | ---------------------- |
| **Scope**     | `invoices:read`        |
| **Path `id`** | `inv_...` public token |

Response uses snake\_case. Money fields are strings.

***

## Poll status

`GET /v1/invoices/{id}/status`

Lightweight status for hosted checkout polling. May include `deposit_address`, `swap_status`, and `return_url` when applicable.

***

## Cancel invoice

`POST /v1/invoices/{id}/cancel`

|           |                  |
| --------- | ---------------- |
| **Scope** | `invoices:write` |

Only open invoices (`awaiting_payment`, `quoted`, etc.) can be cancelled. Emits `invoice.cancelled` webhook.
