What is checked, in order
- The gateway — the credential (
x-api-keyorx-project-id, one of them), the page’s origin for a project id, whether the route is open to that credential, the body’s size (64 KiB) and the gateway’s rate limits. Its refusals carry anEPXcode and a real HTTP status: see Errors — gateway codes (not restated here). - Body decode — malformed JSON never reaches the hub’s routes: its framework refuses it,
EMC0028referenceBody. Well-formed JSON the form can’t take (a wrong JSON type such as1.5for an integer field) isEIN0001referencebody, and so is a body the framework never read (no JSONContent-Type) on a route that reads one. - Form fields — validated in struct order; only the first failing field is reported.
error_referenceis the field’s JSON wire name (amount,sourceAsset, …), not an internal field name. - Route-specific resolution — corridor/asset resolution and so on. The worked example is
POST /quote’s own resolution order: see Request — not restated here. - The rate-limit charge — validation passing is what triggers the hub’s own charge, before the quote pipeline or the order service does any work, so the quote, preparation and order lookups come after it. See Handling rate limits.
What you can verify before calling
What the hub does not check
Bodies are decoded leniently: unknown JSON fields are ignored, not refused. Malformed JSON is the framework’sEMC0028 reference Body; well-formed JSON of a wrong type is EIN0001 reference
body; and only the first failing field is reported. What that implies for client-side validation:
- EVM addresses are not format-checked at quote time. A non-EVM
recipient/sourceAccountthat doesn’t decode isEIN0001on that field, but a malformed EVM address is admitted and fails later, not asEIN0001(Get quote — Request). - On-chain id spelling is not validated. Uppercase hex or a missing
0xisn’t an error — it simply finds nothing, and on/fillthat reads like “not filled yet” (known issue). See Get on-chain fill — Behavior. chainDomainon fill-by-tx is not validated. An unknown or miscased domain finds no watermark and answersEIN0051, notEIN0001.
Framework refusals before the hub runs
These happen in the hub’s framework, before any route code:- Malformed JSON —
EMC0028referenceBody. - A GET that carries a body with a JSON
Content-Type—EMC0005. Without a JSONContent-Typethe body is not read, and the GET is served. - A POST with an empty body and a
Content-Typeof exactlyapplication/json—EMC0005. A body over the hub’s size limit reads as empty, so it is refused the same way. With a parameter (application/json; charset=utf-8) or noContent-Type, the empty body reaches the route, which answersEIN0001referencebody.
Validating against the catalog
Build pickers fromGET /catalog rather than a hand-kept table — a page can
read it with your project id, so pickers render before your user signs in to anything, and it’s
rebuilt only on restart. What native, nativeKey, swapRouter and wrappedKey mean for what a
chain accepts as a source is Get catalog — Response — not restated here.