Request body or query parameter?
One rule holds across the whole API:- the body of a request describes the resource itself — the data that will be stored (the fields of an invoice, a relation, a journal…);
- query parameters configure the call — options that change its behavior
without being stored, such as
?ignore_duplicate=truewhen creating a relation,?type=purchaseon a file import, or?send_peppol=trueto send an invoice right at creation.
422 naming the offending field.
Reading responses
Responses follow the same reading rules everywhere:- Amounts are JSON numbers — never strings.
- A missing value is
null— never an empty string:"phone": nullmeans no phone is recorded. - A field that does not exist for the type is absent, not
null: acompanyrelation carriesvat,identifier,electronic_address,is_customer,is_supplier; acontactcarriesfirst_name,last_name— each without the other’s fields. - An enumeration can read
unknown— a historical value the API cannot classify comes out that way; handle it in your mappings.
null to mean “no value”, and for the absence of the key to mean “not
applicable to this type”.
Tracing a request
Every response carries anX-Request-ID header — an opaque identifier for that
exact call on our side:
500 internal_error.
Creating and updating
Three rules hold for everyPOST and PATCH:
- All or nothing — a request that violates any rule is refused as a whole: an object is never created or updated halfway.
- A
PATCHapplies only the fields present — omitting a field leaves it unchanged; there is no need to send the full object back. - An unknown or read-only field is an error — the request is refused with a
422naming it, never silently ignored: a typo does not go unnoticed.