# Compatibility

> What a client can rely on, what may change without a version change, and the rules for writing an integration that does not break.

This page says what your code can rely on, and what it must not assume.

## What to rely on

| Item | Why |
|---|---|
| The `code` field of errors | It is the machine contract of the error body, and the only stability promise Noryo makes about that body. Moving from one domain to another changes no code. |
| The HTTP status | It accompanies every code |
| The key format | `nry_mer_sbx_` or `nry_mer_live_`, a 10-character `key_id`, a dot, the secret: a frozen public format |
| The `enr_` and `req_` prefixes | They tell enrichment identifiers and request identifiers apart |
| The version carried by the path | `/merchant/v1`; a future `v2` would live beside it |

## What may change without a version change

| Item | Consequence for your code |
|---|---|
| `title` and `detail` of errors | Written for humans, in English; may be reworded at any time. Do not parse them. |
| The domain of the base URL and of `type` links | The host is not part of the contract: keep the base URL in configuration |
| The resolution policy (threshold, required fields) | It decides `resolved` or `partial`; its threshold is not a contract value. Decide on `enrichment.status`, not on a copied `confidence` threshold. |
| Rate limits | Operational settings; read `Noryo-RateLimit-Limit` rather than a constant |
| Catalogue coverage | A transaction that is `not_found` today may be resolved by a refresh tomorrow |

## The rules of a client that does not break

1. **Decide on `code`**, never on an error's text.
2. **Handle an unknown value with care.** An unknown `enrichment.reason` reads as `unspecified`; an unexpected status is treated as an unusable result; an unknown error code is handled according to its HTTP status.
3. **Read responses tolerantly.** Ignore fields you do not know, and accept that an optional field (`category`, `logo_url`) may be absent.
4. **Send strict requests.** The request schema is closed: add no field outside the contract, it would be refused. Omit an optional field rather than sending it as `null`.
5. **Treat identifiers as opaque.** Store `enrichment_id` and `Noryo-Request-Id` as they are, without drawing business meaning from them: an `enrichment_id` is random and tells neither an order nor a volume.
6. **Resolve `Location` against your base URL**, since it is relative.
7. **Read header names case-insensitively**, as HTTP requires.

## Official names

The product is called **Noryo Merchant API**. Field, status and code names stay in English in every language of the documentation, exactly as the API returns them.

---

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