This reference documents the command-line interface, Python API, REST microservice, and validation pipeline for pain001 v0.0.56. Every flag, endpoint, and behaviour listed here is taken from the shipped code, not from aspiration.
Pain001 supports 11 ISO 20022 message definitions: pain.001.001.03 through pain.001.001.12 (Customer Credit Transfer Initiation, ten versions) and pain.008.001.02 (Customer Direct Debit Initiation).
1. Command-Line Interface#
The pain001 executable groups its functionality into subcommands. Running it with only generation flags invokes generate implicitly, so existing automation keeps working.
| Subcommand | Purpose |
|---|---|
generate |
Convert a data file into schema-validated ISO 20022 XML (default command). |
validate |
Validate input data without writing XML. |
versions [--json] |
List all 11 supported message definitions. |
inspect |
Show the required and optional fields for a message type. |
init |
Scaffold a starter CSV template for a message type. |
serve [--host] [--port] [--reload] |
Launch the FastAPI REST microservice (requires the api extra). |
mcp |
Launch the in-tree Model Context Protocol server (5 tools; the full 17-tool server ships as pain001-mcp). |
plugins list / show / disable |
Inspect and manage discovered loader, validator, scheme, and writer plugins. |
generate options
| Flag | Description |
|---|---|
-t, --xml-message-type |
Message definition, e.g. pain.001.001.09. |
-d, --data |
Input data: .csv, .json, .jsonl, .db / .sqlite, .parquet, or PGP-encrypted .gpg / .asc. |
-o, --output-dir |
Directory that receives the generated XML. |
-m, --template / -s, --schema |
Override the bundled Jinja2 template or XSD schema. |
-c, --config |
Load defaults from a configuration profile (--profile, --show-config). |
--dry-run (alias --validate-only) |
Validate input against the JSON Schema, XSD, and scheme rulebook without writing output. |
--scheme |
Enforce a scheme rulebook: sepa-sct, sepa-inst, sepa-sdd, sepa-b2b, or xborder-ct. |
--explain --scheme-format {text,json} |
Report each scheme rule that passed or failed, human- or machine-readable. |
--streaming / --chunk-size |
Memory-bounded chunked processing for large batches (default 1,000 transactions per chunk; each chunk becomes its own XML file with recomputed NbOfTxs and CtrlSum). |
--emit-metrics |
Emit machine-readable run metrics for observability pipelines. |
Exit codes are CI-friendly: 0 success, 1 validation failure, 2 usage error.
2. Python API#
from pain001.core.core import process_files
# Generate a validated pain.001.001.09 file from CSV
process_files(
xml_message_type="pain.001.001.09",
xml_template_file_path="template.xml",
xsd_schema_file_path="schema.xsd",
data_file_path="payments.csv",
output_dir="out",
)
Every generated document passes three layers before it is written:
- Input validation — each record is checked against the message type's JSON Schema, with field-alias normalisation and IBAN/BIC syntax checks.
- Scheme rulebook (optional) — SEPA SCT, SEPA Instant, SEPA SDD Core, SEPA B2B, or cross-border credit transfer rules.
- XSD validation — the rendered XML is validated against the official ISO 20022 schema via
xmlschemabefore a single byte is written to disk.
Monetary amounts are handled as decimal.Decimal during XML generation and scheme validation — never IEEE 754 floats — and NbOfTxs / CtrlSum control totals are recomputed from the validated records rather than trusted from input.
Beyond pain.001 generation, the core library also ships a pain.002 status-report parser and generator (so you can read the bank's accept/reject response) and a camt.053 statement parser and generator for end-of-day reconciliation, plus a VersionMapper that migrates records between message versions.
3. REST Microservice#
pip install "pain001[api]"
pain001 serve --host 0.0.0.0 --port 8000
All endpoints are mounted under /api/v1 (with an unversioned /api alias):
| Method & Path | Purpose |
|---|---|
GET /api/v1/health |
Liveness probe. |
POST /api/v1/validate |
Validate records; returns field-level errors. |
POST /api/v1/generate |
Synchronous XML generation. |
POST /api/v1/generate/async |
Queue a large batch for background generation. |
GET /api/v1/status/{job_id} |
Poll an async job. |
GET /api/v1/download/{job_id} |
Download the finished XML. |
DELETE /api/v1/jobs/{job_id} |
Clean up a completed job. |
GET /metrics |
Prometheus metrics. |
Interactive documentation is served at /api/docs (Swagger UI), /api/redoc, and /api/reference (Scalar), with the OpenAPI document at /openapi.json.
4. Input Normalisation#
Pain001 coerces real-world exports into valid records before validation:
- Field aliases — common ERP column names map onto canonical fields (for example
amount→payment_amount). - IBAN / BIC normalisation — whitespace stripped, case folded, then checked (ISO 13616 mod-97 for IBANs, ISO 9362 structure for BICs).
- Dates — ISO 8601
YYYY-MM-DDparsing for execution dates. - Amounts — routed through
decimal.Decimal; malformed amounts fail validation instead of silently rounding. - Character set — transliteration helpers reduce content to the ISO 20022 Latin character set accepted by SWIFT and SEPA.
5. Plugin Architecture#
The suite is extensible through four entry-point groups: pain001.loaders, pain001.validators, pain001.schemes, and pain001.writers. pain001-loader-xlsx registers through this mechanism and is auto-discovered on install; pain001-loader-mt101 is a standalone parsing library consumed directly (and by the MCP server's convert_mt101 tool). A kill switch — PAIN001_DISABLE_PLUGINS=1 — disables third-party plugin discovery entirely in locked-down environments.
6. Quality Gates#
The core library is developed against strict, verifiable gates: 100% line and branch coverage enforced in CI (--cov-fail-under=100), strict mypy typing, 100% docstring coverage, and security linting (Bandit, pip-audit). A CycloneDX SBOM is generated for every release build.
Continue with the Installation Guide, the MCP server for AI agents, or the payments glossary.