SDKs

Validate XML and e-invoices from your own code in a few lines, with the official clients for PHP, Laravel, Symfony, Python and JavaScript / TypeScript.

The SDKs call the xmlvalid API with a key from Dashboard → API keys. Each document is one API validation: 100 a month on Free, 10,000 to 100,000 on Pro. They are open source, under the MIT license.

Packages

Each guide covers catalog schemas, your own schemas and schemas made of several files, Schematron business rules, e-invoices and Factur-X PDFs, large files, webhooks and testing.

PHP

Any PHP 8.2+ project, with any PSR-18 HTTP client.

composer require xmlvalid/xmlvalid-php
Laravel

A validation rule for uploads, a facade, webhook events and Artisan commands. Laravel 12 and 13.

composer require xmlvalid/xmlvalid-laravel
Symfony

A validator constraint, the client as a service, webhook events and console commands. Symfony 6.4, 7.4 and 8.

composer require xmlvalid/xmlvalid-symfony
Python

A sync and an async client on httpx, fully typed. Python 3.10+.

pip install xmlvalid
JavaScript and TypeScript

No dependencies, with types. Node 20+, Bun, Deno and Cloudflare Workers.

npm install @xmlvalid/sdk

Which one to use

Users upload invoices in a Laravel app
The Laravel package: ValidXml::schema('peppol-bis-3-invoice') in the request's rules, and the field fails with the line and the broken rule.
The same in Symfony
The Symfony bundle: #[ValidXml(schema: 'peppol-bis-3-invoice')] on the property.
Any other PHP
The PHP SDK, which the two above are built on.
Scripts, data pipelines, Django or FastAPI
The Python SDK, with AsyncClient for asyncio.
Node, serverless and edge functions
The JavaScript SDK. Keep the key on the server: from a browser, call your own backend.

What they all do

Send the document
A file is streamed as it is read, so a large document is never loaded into memory. Your own schema file and Schematron rules (with the files they include) go along with it; a schema made of several files is saved once and used by its id.
Wait for the result
validate waits up to 15 minutes, polling less often as it goes. submit answers at once, for queues and webhooks; results are kept for 24 hours.
Retry when rate limited
A request refused for too many requests a minute is sent again after the time the API asks for. A used up monthly quota is not retried.
Typed results and errors
Each finding has its line, column, level, type, the business rule that failed (BR-CO-16) with a link to its page, and a link to the explanation of the message. Each kind of refusal (a wrong key, an unknown schema, a document over the plan's size) is an exception of its own.
Webhooks
On Pro, they check the signature of the events xmlvalid sends when a validation finishes or a URL monitor changes state; the Laravel package and the Symfony bundle turn them into events.
Reports and the account
The HTML report of a validation, a public link to it for 30 days (Pro), this month's usage and the list of schemas you can use.

Other languages

The API is plain HTTP and JSON, described in the API reference and as OpenAPI 3.1, from which a client for any language can be generated. The Postman collection generates code snippets too. For scripts and CI there is the command-line client, and for no-code workflows the integrations.