Skip to main content

Country Invoice Requirements

One call tells you which fields of a canonical invoice a country's rules need before GoRoute will send it:

GET /api/v1/jurisdictions/{code}/requirements

{code} is the country as an ISO 3166-1 alpha-2 code, such as BE or NO (UK answers for GB). Paths are relative to https://app.goroute.ai/peppol-api. It needs a valid API key and no special permission. It reads nothing about your organisation and changes nothing.

The answer comes from the country's pack, GoRoute's implementation of that country's rules. It lists what GoRoute's code enforces on that country's documents, and nothing from anywhere else: the pack's own checks, and the checks GoRoute's core platform runs on the country's documents. Each entry says which of the two enforces it (enforced_by). A country without a pack answers the Peppol BIS Billing 3.0 baseline: what GoRoute refuses a BIS invoice for on its way out. The answer describes the country's rules, whether or not the pack is switched on for your service; whether it runs there is a separate question (see Jurisdiction Settings).

curl -H "X-API-Key: YOUR_API_KEY" \
"https://app.goroute.ai/peppol-api/api/v1/jurisdictions/BE/requirements"

The answerโ€‹

{
"country": "BE",
"pack": "BE",
"requirements": {
"version": 2,
"profile": "peppol-bis-3.0-be",
"extends": "peppol-bis-3.0",
"customization_ids": [],
"summary": "Belgium's pack checks a Belgian seller's BIS invoice or credit note before it is sent ...",
"documents": [
{
"document_type": "invoice",
"fields": [
{
"field": "order_reference",
"requirement": "conditional",
"condition": "when the receiver is addressed under scheme 0208 (a Belgian enterprise number)",
"severity": "warning",
"pattern": null,
"detail": "The purchase-order number most Belgian public bodies (Mercurius) expect.",
"rule": "BE_B2G_ORDER_REFERENCE",
"enforced_by": {
"layer": "pack",
"module": "app/jurisdictions/be/checks.py",
"rule": "BE_B2G_ORDER_REFERENCE",
"switch": null,
"note": null
}
}
],
"identifier_schemes": [
{
"key": "be_vat_core",
"eas": null,
"fields": ["buyer.vat_number"],
"pattern": "^BE\\d{10}$",
"normalise": "Spaces and dots removed and upper-cased.",
"check": null,
"condition": "when the buyer's country is BE (its address, else its peppol_id scheme, else its VAT prefix)",
"severity": "warning",
"rule": "COUNTRY_BE_002",
"enforced_by": {
"layer": "core",
"module": "app/services/country_validation.py",
"rule": "BE_002",
"switch": null,
"note": null
}
}
],
"code_lists": [
{
"key": "attachment_mime",
"fields": ["attachments[].mime_type"],
"values": [
"application/pdf",
"application/vnd.oasis.opendocument.spreadsheet",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"image/jpeg",
"image/png",
"text/csv"
],
"values_file": null,
"detail": null,
"condition": "when the attachment is embedded (content_base64); a link (external_url) is not checked",
"severity": "error",
"rule": "BE_ATTACHMENT_MIME",
"source": "app/services/writer_rules.py BE_ATTACHMENT_MIME_CODES, read by app/jurisdictions/be/checks.py (EN 16931 BR-CL-24)",
"enforced_by": {
"layer": "pack",
"module": "app/jurisdictions/be/checks.py",
"rule": "BE_ATTACHMENT_MIME",
"switch": null,
"note": null
}
}
],
"checks": []
}
],
"check_rules": {
"be_mod97": "10 digits (those after the country prefix when the pattern has one) whose last two are 97 minus the first eight mod 97."
}
},
"baseline": { "profile": "peppol-bis-3.0", "...": "the BIS baseline, in the same shape" }
}

The example is shortened; a real answer lists every entry.

FieldMeaning
countryThe country asked about, as its ISO code
packThe pack that carries the country's rules, or null for a country with none
requirementsThe country's requirements (below)
baselineThe BIS baseline, when requirements.extends is peppol-bis-3.0; otherwise null

requirements:

FieldMeaning
versionThe version of this shape, 2. A change that is not purely additive raises it
profileThe rule set: peppol-bis-3.0, pint-a-nz, pint-om, pint-ae, nrs, verifactu ...
extendspeppol-bis-3.0 when these rules come on top of the BIS baseline, else null
customization_idsThe CustomizationID values the rules apply to, when the pack claims documents by one
summaryWhat is checked, and what is not, in a sentence or two
documentsOne entry per canonical document_type the rules cover
check_rulesWhat each check-digit rule named in identifier_schemes computes

Each document lists four things:

  • fields: canonical fields by their path (seller.vat_number, lines[].hs_code). requirement is required (always), conditional (only under condition) or forbidden (must be empty). pattern, when set, is the format the value must have; detail says what it must be when a pattern cannot.
  • identifier_schemes: the identifiers the checks accept on a party, the canonical fields they read, the Peppol scheme (eas) when the identifier is also an electronic address, the pattern after the clean-up normalise describes, and the check digit (check).
  • code_lists: closed lists of values the checks accept in some fields, with where the list is defined (source). A list too long to carry inline, such as Oman's HS codes, has empty values and names the file that holds them (values_file).
  • checks: checks on the rendered document that name no single field, such as an official PINT Schematron sheet GoRoute runs in full (rule_ids lists every assert in it) or Oman's check of a UBL document's own UUID.

severity is error when the check refuses the send, or warning when it only records a warning and the document still goes. rule is the code you would see in a refusal.

enforced_by says where the entry is enforced:

FieldMeaning
layerpack, the country pack's own check, or core, a check GoRoute's core platform runs on that country's documents
moduleThe file in GoRoute's code that enforces it
ruleThe rule's id as that file writes it
switchThe setting under which the check refuses (or runs at all), when one does, such as SEND_RULES_MODE=enforce
noteWhat you should know about the check as it stands, when there is something

Where a core check and the pack's check disagree, both entries are listed as they stand. GoRoute is moving the core's country checks into the packs; an entry's layer and module change when its check moves, and its rule stays the same.

What is not listed: the canonical schema's own required fields (number, issue_date, seller.name ...), which the request schema already marks; and the official BIS 3.0 Schematron, which refuses only where your service is set to enforce it. An empty list means nothing is checked of that kind on that document type.

Refusalsโ€‹

Statuserror_codeWhen
401โ€”No API key, or one that is not valid
404COUNTRY_INVALID{code} is not an ISO 3166-1 alpha-2 country
503JURISDICTION_REQUIREMENTS_UNAVAILABLEThe country's pack publishes no requirements on this service