ePostman docs
PortálConsole

Predbežná validáciaPre-flight validation

Overte faktúru a dosiahnuteľnosť príjemcu ešte pred odoslaním.Check an invoice and the receiver's reachability before you send it.

3 min čítania3 min read
  • #validácia
  • #pre-flight
  • #documents/validate
  • #reachability
  • #smp
  • #schematron
  • #validation
  • #pre-flight
  • #documents/validate
  • #reachability
  • #smp
  • #schematron

Pred odoslaním dokumentu si ho môžete dať overiť. Endpoint prejde rovnakým päťúrovňovým validačným reťazcom, aký beží po odoslaní — takže čo prejde tu, prejde aj tam. Nevytvára faktúru, nič neukladá a nespotrebúva kredit.

Overenie dokumentu

POST /api/v1/documents/validate
X-Api-Key:
Content-Type: application/json
Accept-Language: sk
{
  "xml_content": "<Invoice xmlns=…>…</Invoice>",
  "receiver_peppol_id": "0245:2120984085"
}

Povinné je jediné pole — xml_content. Prítomnosť receiver_peppol_id zapína aj overenie príjemcu cez Peppol SMP; bez neho sa overuje len samotný dokument.

Odpoveď má vždy stav 200, aj keď je dokument neplatný. Neplatná faktúra nie je chyba volania — verdikt je súčasťou dát.

{
  "valid": false,
  "network_ready": false,
  "overall_severity": "FATAL",
  "validation_levels": {
    "L1_xml": "OK", "L2_xsd": "OK", "L3_en16931": "OK",
    "L4_peppol": "FATAL", "L5_sk": "WARNING"
  },
  "errors": [{
    "rule_id": "PEPPOL-EN16931-R001",
    "level": 4,
    "severity": "FATAL",
    "raw_message": "Business process MUST be provided.",
    "raw_location": "/Invoice[1]/cbc:ProfileID",
    "title": "Chýba identifikátor obchodného procesu",
    "explanation": "Peppol vyžaduje, aby faktúra deklarovala…",
    "fix": "Doplňte element cbc:ProfileID s hodnotou…",
    "location": "Hlavička faktúry → Profil",
    "localized": true
  }],
  "warnings": [],
  "truncated": false,
  "total_findings": 1,
  "document": { "document_type": "INVOICE", "invoice_number": "FA-2026-001", "…": "…" },
  "receiver": {
    "peppol_id": "0245:2120984085",
    "registered": true,
    "supports_document_type": false,
    "reason": "NOT_SERVICED",
    "checked_at": "2026-08-05T10:00:00Z"
  },
  "duration_ms": 1840
}

Nálezy sú lokalizované, originál zostáva

title, explanation, fix a location sa prekladajú podľa hlavičky Accept-Language (podporujeme sk a en; bez hlavičky sa použije en). Použitý jazyk vraciame v Content-Language.

raw_message a raw_location sa neprekladajú nikdy — sú to originálny text Schematronu a XPath. Práve ich potrebujete, keď riešite problém s dodávateľom svojho ERP.

Ak pravidlo v katalógu ešte nemáme, localized je false a title obsahuje originálnu anglickú správu. Nález sa nikdy nestratí.

Päť úrovní validácie

ÚroveňČo overuje
L1_xmlsprávnosť XML
L2_xsdschéma UBL 2.1
L3_en16931pravidlá EN 16931
L4_peppolpravidlá Peppol BIS 3.0
L5_skslovenské národné pravidlá

Hodnoty sú OK, WARNING, FATAL alebo SKIPPED. SKIPPED znamená, že úroveň nebežala — typicky preto, že skončila skôr: zlyhanie na L1 zastaví všetko ostatné.

Pravidlá EN 16931 a Peppol BIS bežia v jednom reťazci, takže sa nikdy nespúšťajú dvakrát; každá úroveň napriek tomu hlási vlastný výsledok.

Úroveň L5_sk môže navyše vrátiť ERROR — slovenskú sadu pravidiel sa nepodarilo spustiť. Dokument to nezhodí, ale medzi upozorneniami nájdete nález s rule_id SK_ENGINE, aby bolo zrejmé, že slovenské pravidlá overené neboli.

Overenie príjemcu

network_ready je true, len keď je dokument platný a príjemca je v sieti a podporuje daný typ dokumentu. Obe polia — network_ready aj receiver — sú v odpovedi len vtedy, keď ste o overenie požiadali.

Pole reason rozlišuje tri situácie, ktoré sa nesmú zamieňať:

reasonVýznamČo s tým
NOT_REGISTEREDpríjemca nie je v Peppol sietioverte jeho Peppol ID
NOT_SERVICEDpríjemca je v sieti, ale nepodporuje tento typ dokumentuoverte typ dokumentu
LOOKUP_UNAVAILABLEverdikt sa nezistil — SMP neodpovedaloskúste o chvíľu znova

Pri LOOKUP_UNAVAILABLEregistered aj supports_document_type null, nie false — neoverili sme, že príjemca neexistuje, len sme sa to nedozvedeli.

Overenie príjemcu bez dokumentu

Ak potrebujete len zistiť, či je zákazník dosiahnuteľný, dokument posielať nemusíte:

GET /api/v1/participants/0245:2120984085/reachability?document_type=INVOICE

Odpoveď má rovnaký tvar ako blok receiver vyššie.

Limity

  • dokument najviac 10 MB, rovnako ako pri odoslaní; väčší vráti 413
  • najviac 500 nálezov v odpovedi; pri skrátení je truncated: true a total_findings nesie skutočný počet
  • ak je validačná služba dočasne nedostupná, vrátime 503 a hlavičku Retry-After; odosielanie faktúr to neovplyvňuje
  • 10 validácií za minútu na organizáciu a 30 dopytov na dostupnosť za minútu. Obe cesty majú vlastné počítadlo — validovanie v cykle vám nevyčerpá kvótu na odosielanie faktúr. Ak vám limit nestačí, ozvite sa — je konfigurovateľný. Zostatok nesú hlavičky X-RateLimit-Limit, X-RateLimit-Remaining a X-RateLimit-Reset, pri prekročení príde 429 s Retry-After

You can have a document checked before you send it. The endpoint runs the same five-level validation chain that runs after submission — so whatever passes here will pass there. It creates no invoice, stores nothing and consumes no credit.

Validating a document

POST /api/v1/documents/validate
X-Api-Key:
Content-Type: application/json
Accept-Language: en
{
  "xml_content": "<Invoice xmlns=…>…</Invoice>",
  "receiver_peppol_id": "0245:2120984085"
}

Only xml_content is required. Including receiver_peppol_id also turns on the receiver check via the Peppol SMP; without it only the document itself is validated.

The response is always 200, even for an invalid document. An invalid invoice is not a call failure — the verdict is part of the data.

{
  "valid": false,
  "network_ready": false,
  "overall_severity": "FATAL",
  "validation_levels": {
    "L1_xml": "OK", "L2_xsd": "OK", "L3_en16931": "OK",
    "L4_peppol": "FATAL", "L5_sk": "WARNING"
  },
  "errors": [{
    "rule_id": "PEPPOL-EN16931-R001",
    "level": 4,
    "severity": "FATAL",
    "raw_message": "Business process MUST be provided.",
    "raw_location": "/Invoice[1]/cbc:ProfileID",
    "title": "Business process identifier is missing",
    "explanation": "Peppol requires the invoice to state…",
    "fix": "Add the cbc:ProfileID element with the value…",
    "location": "Invoice header → Profile",
    "localized": true
  }],
  "warnings": [],
  "truncated": false,
  "total_findings": 1,
  "document": { "document_type": "INVOICE", "invoice_number": "FA-2026-001", "…": "…" },
  "receiver": {
    "peppol_id": "0245:2120984085",
    "registered": true,
    "supports_document_type": false,
    "reason": "NOT_SERVICED",
    "checked_at": "2026-08-05T10:00:00Z"
  },
  "duration_ms": 1840
}

Findings are localized, the original stays

title, explanation, fix and location are translated according to the Accept-Language header (sk and en are supported; without the header we use en). The language actually applied comes back in Content-Language.

raw_message and raw_location are never translated — they are the original Schematron text and XPath. Those are exactly what you need when working the problem with your ERP vendor.

If a rule is not in our catalogue yet, localized is false and title carries the original English message. A finding is never lost.

The five validation levels

LevelWhat it checks
L1_xmlXML well-formedness
L2_xsdUBL 2.1 schema
L3_en16931EN 16931 rules
L4_peppolPeppol BIS 3.0 rules
L5_skSlovak national rules

Values are OK, WARNING, FATAL or SKIPPED. SKIPPED means the level did not run — typically because validation stopped earlier: a failure at L1 halts everything after it.

The EN 16931 and Peppol BIS rules run in a single chain, so they are never executed twice; each level still reports its own result.

Level L5_sk can additionally return ERROR — the Slovak rule set failed to execute. It does not fail the document, but you will find a finding with rule_id SK_ENGINE among the warnings, so it is clear the Slovak rules were not verified.

The receiver check

network_ready is true only when the document is valid and the receiver is in the network and supports the document type. Both network_ready and receiver appear in the response only when you asked for the check.

The reason field distinguishes three situations that must not be conflated:

reasonMeaningWhat to do
NOT_REGISTEREDthe receiver is not in the Peppol networkverify their Peppol ID
NOT_SERVICEDthe receiver is in the network but does not support this document typeverify the document type
LOOKUP_UNAVAILABLEno verdict was reached — the SMP did not answerretry shortly

With LOOKUP_UNAVAILABLE both registered and supports_document_type are null, not false — we did not establish that the receiver is missing, we simply did not find out.

Checking a receiver without a document

If you only need to know whether a customer is reachable, you do not have to send a document:

GET /api/v1/participants/0245:2120984085/reachability?document_type=INVOICE

The response has the same shape as the receiver block above.

Limits

  • documents up to 10 MB, the same as for sending; larger ones return 413
  • at most 500 findings per response; when truncated, truncated is true and total_findings carries the real count
  • if the validation service is temporarily unavailable we return 503 with a Retry-After header; sending invoices is unaffected
  • 10 validations per minute per organisation and 30 reachability lookups per minute. Both paths have their own counter — validating in a loop will not exhaust your invoice-sending quota. Get in touch if the limit is too tight; it is configurable. The remaining allowance is carried by the X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers; exceeding it returns 429 with Retry-After