pacs008 API reference
pacs008 offers a REST API, CLI, and Python library for payment validation, XML generation, and repeatable release workflows. Teams can use the same rules in local tests and live services.
Implementation notes
Start with the smallest path that fits the workflow.
Use one path for local checks, one for service runs, and one for embedded code.
- Use sync generation for quick checks.
- Use async generation for large files.
- Keep the input payload and validation report together.
Installation
Install the package from PyPI. Requires Python 3.10 or later.
python -m pip install pacs008
REST API
Start the FastAPI server to validate payment data and generate XML.
Start the server
uvicorn pacs008.api.app:app --reload --host 0.0.0.0 --port 8000
Endpoints
| Endpoint | Description |
|---|---|
GET /api/health | Health check that returns service status |
POST /api/validate | Validate payment data without generating XML |
POST /api/generate | Generate XML now and return the file |
POST /api/generate/async | Submit an async generation job |
GET /api/status/{job_id} | Check job status by ID |
GET /api/download/{job_id} | Download XML after the job completes |
DELETE /api/jobs/{job_id} | Cancel a pending or running job |
GET /api/docs | Swagger UI for testing all endpoints |
See Message Types for the full list of supported message pages.
Validation example
Validate payment data before generating XML.
curl -X POST http://localhost:8000/api/validate \
-H "Content-Type: application/json" \
-d '{
"message_type": "pacs.008.001.13",
"data": [{
"msg_id": "MSG-2026-001",
"creation_date_time": "2026-01-15T10:30:00",
"nb_of_txs": "1",
"settlement_method": "CLRG",
"interbank_settlement_date": "2026-01-15",
"end_to_end_id": "E2E-INV-2026-001",
"interbank_settlement_amount": "25000.00",
"interbank_settlement_currency": "EUR",
"charge_bearer": "SHAR",
"debtor_name": "Acme Corp GmbH",
"debtor_agent_bic": "DEUTDEFF",
"creditor_agent_bic": "COBADEFF",
"creditor_name": "Widget Industries SA"
}]
}'
{
"valid": true,
"message_type": "pacs.008.001.13",
"errors": [],
"warnings": []
}
Synchronous generation example
Generate a pacs.008.001.13 XML file from JSON data.
curl -X POST http://localhost:8000/api/generate \
-H "Content-Type: application/json" \
-d '{
"message_type": "pacs.008.001.13",
"template": "pacs008/templates/pacs.008.001.13/template.xml",
"schema": "pacs008/templates/pacs.008.001.13/pacs.008.001.13.xsd",
"data": [{
"msg_id": "MSG-2026-001",
"creation_date_time": "2026-01-15T10:30:00",
"nb_of_txs": "1",
"settlement_method": "CLRG",
"interbank_settlement_date": "2026-01-15",
"end_to_end_id": "E2E-INV-2026-001",
"tx_id": "TX-001",
"interbank_settlement_amount": "25000.00",
"interbank_settlement_currency": "EUR",
"charge_bearer": "SHAR",
"debtor_name": "Acme Corp GmbH",
"debtor_agent_bic": "DEUTDEFF",
"creditor_agent_bic": "COBADEFF",
"creditor_name": "Widget Industries SA"
}]
}' --output pacs008_output.xml
Asynchronous generation
For large files, submit an async job and poll until it finishes.
# Submit the job
JOB=$(curl -s -X POST http://localhost:8000/api/generate/async \
-H "Content-Type: application/json" \
-d '{"message_type":"pacs.008.001.13","data":[...]}')
JOB_ID=$(echo $JOB | jq -r '.job_id')
# Poll for completion
curl http://localhost:8000/api/status/$JOB_ID
# Download the result
curl http://localhost:8000/api/download/$JOB_ID --output result.xml
{
"job_id": "8f7f0d4b-7df9-4d1a-8d47-19f4f28b6d38",
"status": "completed",
"message_type": "pacs.008.001.13",
"download_url": "/api/download/8f7f0d4b-7df9-4d1a-8d47-19f4f28b6d38"
}
CLI
The CLI takes a data file, message version, template, and schema. It validates the input and writes XML to the output directory.
Basic usage
pacs008 -t \
-m \
-s \
-d
Example
pacs008 -t pacs.008.001.13 \
-m pacs008/templates/pacs.008.001.13/template.xml \
-s pacs008/templates/pacs.008.001.13/pacs.008.001.13.xsd \
-d payments.csv
Dry-run mode
Use --dry-run to validate input data without generating XML. The exit code shows whether validation passed (0) or failed (1).
pacs008 -t pacs.008.001.13 \
-m pacs008/templates/pacs.008.001.13/template.xml \
-s pacs008/templates/pacs.008.001.13/pacs.008.001.13.xsd \
-d payments.csv \
--dry-run
Add --verbose for detailed output during generation.
Python API
Use the library directly in Python scripts or services.
Generate XML from payment records
from pacs008 import generate_xml_string
payments = [{
"msg_id": "MSG-2026-001",
"creation_date_time": "2026-01-15T10:30:00",
"nb_of_txs": "1",
"settlement_method": "CLRG",
"interbank_settlement_date": "2026-01-15",
"end_to_end_id": "E2E-INV-2026-001",
"tx_id": "TX-001",
"interbank_settlement_amount": "25000.00",
"interbank_settlement_currency": "EUR",
"charge_bearer": "SHAR",
"debtor_name": "Acme Corp GmbH",
"debtor_agent_bic": "DEUTDEFF",
"creditor_agent_bic": "COBADEFF",
"creditor_name": "Widget Industries SA",
}]
xml = generate_xml_string(
payments,
"pacs.008.001.13",
"pacs008/templates/pacs.008.001.13/template.xml",
"pacs008/templates/pacs.008.001.13/pacs.008.001.13.xsd",
)
print(xml)
SWIFT compliance check
Check and clean data against SWIFT character and field-length rules before generation.
from pacs008.compliance import cleanse_data_with_report
raw = [{"debtor_name": "Müller & Söhne™", "msg_id": "X" * 50}]
clean, report = cleanse_data_with_report(raw)
print(report.summary())
Docker
Run the API in a container using the bundled Dockerfile.
docker build -t pacs008:latest .
docker run -p 8000:8000 pacs008:latest
docker run --rm -e PACS008_LOG_LEVEL=INFO -v $PWD/examples:/data -p 8000:8000 pacs008:latest
IBAN and BIC validation
Validate financial identifiers independently of XML generation.
from pacs008.validation import validate_iban, validate_bic
is_valid, error = validate_iban("DE89370400440532013000", strict=False)
is_valid, error = validate_bic("DEUTDEFF", strict=False)
Streaming
Load large datasets in configurable chunks to limit memory usage.
from pacs008.data.loader import load_payment_data_streaming
for chunk in load_payment_data_streaming("large_payments.csv", chunk_size=500):
print(f"Processing {len(chunk)} records")
from pacs008.validation import validate_batch
for chunk in load_payment_data_streaming("large_payments.csv", chunk_size=500):
report = validate_batch(chunk, "pacs.008.001.13")
print(report.summary())
Validation service
Run the full pre-generation validation pipeline programmatically.
from pacs008.validation import ValidationService, ValidationConfig
service = ValidationService()
report = service.validate_all(ValidationConfig(
xml_message_type="pacs.008.001.13",
xml_template_file_path="pacs008/templates/pacs.008.001.13/template.xml",
xsd_schema_file_path="pacs008/templates/pacs.008.001.13/pacs.008.001.13.xsd",
data_file_path="payments.csv",
))
print(report.is_valid, report.errors)
Required data fields
Each payment record must include these fields. Version-specific fields are listed below.
| Field | Description | Constraint |
|---|---|---|
msg_id | Message identifier | Max 35 characters |
creation_date_time | Creation timestamp | ISO 8601 format |
nb_of_txs | Number of transactions | Positive integer |
settlement_method | Settlement method | CLRG, INDA, COVE, or INGA |
end_to_end_id | End-to-end identifier | Max 35 characters |
interbank_settlement_amount | Interbank settlement amount | Decimal, e.g. `25000.00` |
interbank_settlement_currency | Settlement currency | ISO 4217 code |
charge_bearer | Charge bearer | DEBT, CRED, SHAR, or SLEV |
debtor_name | Debtor name | Max 140 characters |
debtor_agent_bic | Debtor agent BIC | 8 or 11 characters |
creditor_agent_bic | Creditor agent BIC | 8 or 11 characters |
creditor_name | Creditor name | Max 140 characters |
Version-specific fields
| Field | Description | Constraint |
|---|---|---|
uetr | Unique end-to-end transaction reference | UUID format — available from v08 |
mandate_id | Mandate identifier | Available from v10 |
expiry_date_time | Message expiry timestamp | Available in v13 |