# Requests

> The anatomy of a Merchant API request and the exact order in which the server checks it, which determines the status returned and whether a rate-limit token is consumed.

A Merchant API request is an HTTPS request to the configured base URL, authenticated by a key, with a JSON body for the two `POST` routes.

```http
POST /merchant/v1/enrichments HTTP/1.1
Host: api.noryo.app
Authorization: Bearer nry_mer_sbx_<key_id>.<secret>
Content-Type: application/json
Idempotency-Key: 0b6f2c1e-6f1d-4a43-9d7e-2b9e6f5c8a10

{"descriptor":"CB MCDONALDS PARIS 4519","external_transaction_id":"tx_8f21c0"}
```

## The order of checks

The server checks a request in a fixed order and stops at the first refusal. This order explains which status you receive when several things are wrong at once, and which refusals consume a rate-limit token.

| Step | Check | Refusal |
|---|---|---|
| 1 | Host declared for the API | `400 invalid_request` |
| 2 | `Content-Type: application/json` (`POST` routes) | `415 unsupported_media_type` |
| 3 | Body of 16 KiB at most (`POST` routes) | `413 request_entity_too_large` |
| 4 | Readable JSON body (`POST` routes) | `400 invalid_json` |
| 5 | `Authorization` header, known key, consistent prefix | `401 invalid_api_key` |
| 6 | Shape of the `Idempotency-Key`, when the header is present | `400 invalid_idempotency_key` |
| 7 | Key not revoked, organisation and workspace active | `401 invalid_api_key`, `403 account_inactive` |
| 8 | **Rate limit** | `429 rate_limited` |
| 9 | Route-specific checks (body schema, scope, identifiers, path identifier) | `400`, `403`, `404`, `409` |
| 10 | Computation and settlement (idempotency, deduplication, allowance, commercial access) | `402`, `403`, `409`, `410`, `503` |

Steps 9 and 10 are detailed for each route in [Create](https://developer.noryo.app/en-GB/merchant/enrichments/create), [Read](https://developer.noryo.app/en-GB/merchant/enrichments/read) and [Refresh](https://developer.noryo.app/en-GB/merchant/refresh).

## What consumes a rate-limit token

Every request that reaches step 8 consumes **one** token, whatever the final response: a `200`, an idempotent replay, a validation `400`, a `403 insufficient_scope`, a `404`, a `409`. A request refused at steps 1 to 7 consumes nothing: an unknown or revoked key has no bucket to wear down. A `GET` read costs one token, like a create call. See [Rate limits](https://developer.noryo.app/en-GB/merchant/rate-limits).

## What enters no computation

The host, the `Idempotency-Key`, the `Noryo-Request-Id` and the API key do not enter a transaction's economic identity. The same body sent by two keys of the same workspace and environment designates the same transaction. See [The two identifiers](https://developer.noryo.app/en-GB/merchant/identifiers).

## In this section

- [Headers](https://developer.noryo.app/en-GB/merchant/requests/headers): request and response headers, and when they are present.
- [The two identifiers](https://developer.noryo.app/en-GB/merchant/identifiers): `Idempotency-Key` and `external_transaction_id`, and why you want both.
- [Idempotency](https://developer.noryo.app/en-GB/merchant/requests/idempotency): the window, the scope, replays, concurrency.
- [Formats](https://developer.noryo.app/en-GB/merchant/requests/formats): JSON, encoding, size, field and identifier formats.
- [Validation](https://developer.noryo.app/en-GB/merchant/requests/validation): the closed schema and every error message.

---

Canonical page: https://developer.noryo.app/en-GB/merchant/requests
