POST /v1/validate — exemples par langage

Requête : le document XML/PDF brut en corps. Réponse : JSON (rapport de conformité).

curl

curl -X POST "https://api.example/v1/validate" \
  -H "Authorization: Bearer $FACTURX_API_KEY" \
  --data-binary @document.xml

PHP

<?php
$ch = curl_init('https://api.example/v1/validate');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('FACTURX_API_KEY')],
    CURLOPT_POSTFIELDS => file_get_contents('document.xml'),
    CURLOPT_RETURNTRANSFER => true,
]);
$report = json_decode(curl_exec($ch), true);
if (!$report['conforme']) {
    foreach ($report['violations'] as $v) echo $v['message'] . "\n";
}

Python

import requests, os

with open("document.xml", "rb") as f:
    resp = requests.post(
        "https://api.example/v1/validate",
        headers={"Authorization": f"Bearer {os.environ['FACTURX_API_KEY']}"},
        data=f,
    )
report = resp.json()
print("conforme:", report["conforme"], "— rule pack:", report["rulepack"]["id"])

JavaScript (Node.js)

import { readFile } from "node:fs/promises";

const doc = await readFile("document.xml");
const resp = await fetch("https://api.example/v1/validate", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.FACTURX_API_KEY}` },
  body: doc,
});
const report = await resp.json();
console.log("conforme:", report.conforme);

Go

package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
)

func main() {
	f, _ := os.Open("document.xml")
	defer f.Close()

	req, _ := http.NewRequest(http.MethodPost, "https://api.example/v1/validate", f)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("FACTURX_API_KEY"))

	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()

	var report struct {
		Conforme bool `json:"conforme"`
		Rulepack struct{ ID string `json:"id"` } `json:"rulepack"`
	}
	json.NewDecoder(resp.Body).Decode(&report)
	fmt.Println("conforme:", report.Conforme, "rule pack:", report.Rulepack.ID)
}

Ce que schematronChecked signifie

Depuis Story 3.7, ?profile=EN16931 et ?profile=EXTENDED-CTC-FR (le défaut si omis) exécutent réellement le schematron officiel FNFE-MPE (schematronChecked: true) — le rapport vérifie XSD et les règles métier BR-* (référentiel fnfempe/France_RFE, release v1.4.0.02), avec le code BR-* officiel, le chemin XPath et le message dans chaque violation.

Depuis Story 13.1, ?profile=PEPPOL-BIS exécute de même le schematron officiel OpenPEPPOL (rule pack ubl-peppol-bis-3.0.20) — codes de règle BR-* (socle CEN/EN16931) ou PEPPOL-EN16931-R* (règles propres au réseau Peppol). Ce profil est aussi retenu automatiquement sur un document UBL dont cbc:CustomizationID déclare viser Peppol BIS Billing 3.0, sans paramètre explicite — voir réglementation Peppol/Belgique.

⚠️ Limites qui subsistent, honnêtement documentées :

  • Aucun corpus de non-régression automatisé en CI (seuls quelques exemples officiels ont été vérifiés ponctuellement — voir rulepacks/README.md).
  • conforme: true reste relatif au rule pack appliqué, jamais une garantie absolue de conformité réglementaire (le référentiel lui-même peut évoluer, ou un cas non couvert par les exemples testés peut échapper à cette vérification) — voir la page réglementation.