# API Overview

The Monetarie API lets you integrate PIX payments into your system. All operations require API Key and IP Whitelist; `POST` endpoints additionally require HMAC-SHA512 over the body.

## Base URL

| Environment | URL |
|-------------|-----|
| Production | `https://api.monetarie.com` |
| Homologation | `https://api-h.monetarie.com` |

## Authentication

Security layers (per request type):

1. **IP Whitelist** (all) -- Source IP must be in the whitelist configured on the API Key
2. **API Key** (all) -- Header `Authorization: ApiKey {client_id}:{client_secret}` on every request
3. **HMAC-SHA512** (only `POST`) -- Request body signature; required on `POST /pix/cash-in`, `POST /pix/cash-out`, `POST /cpf/validate`, `POST /webhooks`, `POST /pix/refund`. `GET` and `DELETE` requests **do not** carry HMAC (they have no body to sign).

:::warning Mandatory alphabetical order in HMAC body
POST requests that require HMAC must sign the body with **keys in alphabetical order**. The backend runs `Jason.decode + Jason.encode!` on the body for validation, which reorders the keys. If your client does not alphabetize before signing, the locally computed HMAC will not match the server → HTTP 401.

Full details: [HMAC-SHA512](/en/hmac).
:::

See [Authentication](/en/auth-token) and [HMAC-SHA512](/en/hmac) for details.

## Format

| Field | Format |
|-------|--------|
| Content-Type | `application/json` |
| Request values | Integers in **centavos** (R$ 1.00 = `100`) |
| Response values | Integers in **subcentavos** (base units; R$ 1.00 = `10000`, ÷ 10,000 for BRL) |
| Dates | ISO 8601 in UTC with `Z` suffix (`2026-03-09T15:30:00Z`) |
| IDs | UUID v4 or alphanumeric string |
| E2E ID | `^E\d{8}[a-zA-Z0-9]{22,26}$` (BACEN standard, 31-35 chars, suffix may contain letters) |

::: tip Terminology
In this documentation, **subcentavos** and **base units** refer to the same unit (10,000 = R$ 1.00). The term "base units" appears in some inherited examples; consider it synonymous with subcentavos. Always divide the response value by 10,000 to get BRL.
:::

::: warning E2E may contain letters
The suffix after `E + ISPB + timestamp` is **alphanumeric, 9 to 13 characters long** (not only digits). Banks like Nubank emit E2Es with letters at the end. Always validate with the full regex. Details in [PIX Cash-In by E2E ID](/en/pix-cashin-e2e).
:::

::: danger Value conversion
**To send**: multiply BRL by 100. R$ 1.00 = `100`.
**To read responses**: divide by 10,000. `10000` ÷ 10,000 = R$ 1.00.
**Never use floating point** -- always integers.
:::

## Key case (optional camelCase)

JSON responses use `snake_case` by default (e.g., `transaction_id`, `end_to_end_id`). If your client prefers `camelCase`, send the header:

```
X-Key-Case: camelCase
```

The backend converts **all keys of the JSON response** (including nested objects) automatically. Example: `transaction_id` → `transactionId`, `pix_key_type` → `pixKeyType`. The header does not affect the input body - always send it in `snake_case` on `POST`.

## Response Pattern

### Success

```json
{
  "worked": true,
  "transaction_id": "PIXOUT20260309abcdef123456",
  "status": "processing"
}
```

### Error

The error shape varies by the layer that rejected the request:

```json
// HMAC plug (401 invalid signature)
{ "worked": false, "detail": "Invalid HMAC signature" }

// ApiKeyAuth (401 / 403)
{ "error": { "status": 401, "message": "Invalid API key" } }

// API error responses (404 / 400 / 409 / 422 / 500)
{ "errors": { "not_found": "transaction not found" } }
```

See the full table at [Authentication -- Error Responses](/en/auth-token#error-responses).

## HTTP Codes

| Code | Meaning |
|------|---------|
| 200 | Success |
| 201 | Resource created (webhook) |
| 400 | Invalid parameters |
| 401 | Missing or invalid API Key / Invalid HMAC |
| 403 | IP not authorized in whitelist |
| 404 | Resource not found |
| 422 | Validation failed (insufficient balance, invalid key) |
| 429 | Rate limit exceeded |
| 500 | Internal error |

## Rate Limiting

| Type | Limit |
|------|-------|
| Per IP (authenticated) | 90,000 requests/minute (1,500 req/s) |
| Per IP (authentication / login) | 5 requests/minute |
| `GET /balance` | **no rate limit** (high-frequency polling allowed) |

Response headers:

```
X-RateLimit-Remaining: 59997
Retry-After: 3  (only when 429)
```

## Idempotency

POST requests accept the `Idempotency-Key` header (max **256 characters**) to prevent duplicate processing. Only **2xx (success)** responses are cached for 24 hours. If the same key is resent for the same method and endpoint, the API returns the original response with the header `X-Idempotent-Replay: true`.

```
Idempotency-Key: unique-request-id-123
```

::: tip Key scope
The key is bound to `method + path + Idempotency-Key`. The same key can be reused in different endpoints without collision. Error responses (4xx/5xx) are **not** cached -- the client can retry after fixing the failure.
:::

::: info GET/DELETE and Idempotency-Key
`GET` and `DELETE` requests **silently ignore** the `Idempotency-Key` header -- the plug only acts on `POST`. Sending the key on these methods does not cause an error, but generates no cache or replay.
:::

## Retry and quarantine policies

- **Quarantine (stage=5)**: A PIX Cash-Out stuck in `status: "processing"` for more than 30 minutes is moved to quarantine, where it stays awaiting manual resolution by the Monetarie team. The status remains `"processing"` from the client's perspective until finalization. Details in the flow: [PIX Lifecycle](/en/pix-lifecycle).
- **Automatic webhook retry**: failed deliveries (timeout, 5xx, closed connection) are rescheduled for up to 7 attempts (intervals `[0, 30s, 2min, 10min, 30min, 1h, 2h, 4h]`). See [Webhooks](/en/webhooks).
- **Client retry**: upon receiving `429`, honor `Retry-After`. Upon receiving `500` or timeout, use exponential backoff + `Idempotency-Key` to avoid duplication. See [Authentication](/en/auth-token) for details.
- **Webhook anti-replay window**: the `X-Monetarie-Timestamp` header is Unix time in seconds. The server **does not** reject old webhooks; it is up to your endpoint to discard deliveries with `|now - timestamp| > 300s` (± 5 minutes) as defense-in-depth against replay. See [Webhooks -- Signature Validation](/en/webhooks#signature-validation).

## External ID

Optional `external_id` field (max 128 chars, alphanumeric + `._:-`) accepted in cash-in and cash-out. Returned in responses and webhooks. Allows lookup by reference:

```
GET /api/external/transactions/ref/{external_id}
```

## Endpoints

### PIX Cash Out (Send)

| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/external/pix/cash-out` | Send PIX by key or copy-and-paste |

### PIX Cash In (Receive)

| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/external/pix/cash-in` | Generate QR Code for receiving |

### Queries

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/external/transactions` | List transactions |
| GET | `/api/external/transactions/:id` | Query transaction by ID |
| GET | `/api/external/transactions/e2e/:e2e_id` | Query by E2E ID |
| GET | `/api/external/transactions/tag/:tag` | Query by tag (prefix) |
| GET | `/api/external/transactions/ref/:external_id` | Query by external_id |
| GET | `/api/external/transactions/:id/receipt` | Receipt |

### Account

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/external/balance` | Account balance |
| GET | `/api/external/statement` | Statement |

### PIX Keys

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/external/pix/keys` | List account PIX keys |

### Refund

| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/external/pix/refund` | PIX refund (total or partial) |

### MED

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/external/med` | List MEDs |
| GET | `/api/external/med/:id` | MED details |
| POST | `/api/external/med/:id/defense` | Submit MED defense with explanation and evidence |

### Validation

| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/external/cpf/validate` | Validate CPF |

### Webhooks

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/external/webhooks` | List webhooks |
| POST | `/api/external/webhooks` | Register webhook |
| DELETE | `/api/external/webhooks/:id` | Remove webhook |
