Country Profiles
thelawin.dev's Peppol generator selects an appropriate PINT (Peppol International) profile based on the seller country, or you can pick one explicitly.
Why country profiles?
Peppol BIS 3.0 was originally an EU standard. To work across non-EU jurisdictions — Singapore, Australia, New Zealand, Malaysia, UAE, Japan — Peppol introduced PINT (Peppol International) variants. Each country has its own tax taxonomy (GST vs VAT vs consumption tax), a specific CustomizationID, and country-specific Schematron rules.
The country_profile field controls which CustomizationID and which tax scheme the generator emits. Without it, the API defaults to standard_eu, so existing EU and UK callers are not affected.
Supported profiles
| Profile | Description | TaxScheme | Status |
|---|---|---|---|
standard_eu | Peppol BIS 3.0 (EU, UK) | VAT | Stable |
pint_international | PINT base, no country extensions | VAT | Stable |
pint_sg | Singapore PINT (UBL 1.4.0) | GST | Stable (passes Peppol Schematron) |
pint_eu | International EU PINT (2025-11) | VAT | Stable (passes Peppol Schematron) |
pint_au | Australia PINT | GST | Preview — requires ABN business identifier (see Known Gaps) |
pint_nz | New Zealand PINT | GST | Preview — requires NZBN business identifier |
pint_my | Malaysia PINT | VAT | Preview — requires BRN + InvoicePeriod |
pint_ae | UAE PINT | VAT | Preview — multiple country-specific structural extensions pending |
pint_jp | Japan PINT | VAT (= Consumption Tax) | Preview — requires InvoicePeriod |
Automatic detection
If you don't pass country_profile, the API maps from seller.country:
seller.country | Resolved profile |
|---|---|
| Any EU member state, GB | standard_eu |
| SG | pint_sg |
| AU | pint_au |
| NZ | pint_nz |
| MY | pint_my |
| AE | pint_ae |
| JP | pint_jp |
| Anything else | standard_eu (fallback) |
AU vs NZ disambiguation
Both pint_au and pint_nz resolve from their respective country code. If you need to force one regardless of the seller address, pass country_profile explicitly.
Explicit override
Pass country_profile at the top level of the request body:
curl -X POST https://api.thelawin.dev/v1/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"format": "peppol",
"country_profile": "pint_sg",
"invoice": {
"number": "INV-2026-001",
"date": "2026-01-15",
"buyer_reference": "PO-SG-9876",
"seller": {
"name": "Singapore Trading Pte Ltd",
"country": "SG",
"peppol_id": "0195:201234567A"
},
"buyer": {
"name": "Enterprise Customer Pte Ltd",
"country": "SG",
"peppol_id": "0195:202345678B"
},
"items": [{
"description": "Consulting Services",
"quantity": 10,
"unit": "HUR",
"unit_price": 150,
"vat_rate": 9.0,
"tax_category": "SR"
}]
}
}'Tax scheme override
Each profile sets a TaxScheme automatically. To override (rare), set invoice.tax_scheme:
{
"format": "peppol",
"country_profile": "pint_jp",
"invoice": {
"tax_scheme": "VAT"
}
}For Japan, the Schematron uses VAT as the scheme identifier — this is its notation for Japanese Consumption Tax. The auto-derived value already handles this; the override exists for edge cases.
Tax category override per line
Each profile sets a default tax category code for line items. To override (for example, zero-rated or exempt lines), set items[].tax_category:
{
"invoice": {
"items": [
{ "description": "Consulting", "vat_rate": 9.0, "tax_category": "SR" },
{ "description": "Export sale", "vat_rate": 0.0, "tax_category": "ZR" },
{ "description": "Exempt service", "vat_rate": 0.0, "tax_category": "ES" }
]
}
}Tax category codes by profile
| Profile | Codes | Notes |
|---|---|---|
standard_eu, pint_eu, pint_international | S, Z, E, AE, K, G, O | Standard EN 16931 codes |
pint_sg | SR, ZR, ES | Standard-Rated, Zero-Rated, Exempt |
pint_au, pint_nz | S, Z, E | GST-equivalent mapping |
pint_my | SA, SE | Standard, Exempt |
pint_ae | S, Z, E | UAE VAT standard codes |
pint_jp | S, Z, E | Consumption Tax codes |
CustomizationID values
The CustomizationID element identifies the profile in the XML. For reference:
| Profile | CustomizationID |
|---|---|
standard_eu | urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0 |
pint_international | urn:peppol:pint:billing-1 |
pint_sg | urn:peppol:pint:billing-1@sg-1 |
pint_eu | urn:peppol:pint:billing-1@eu-1 |
pint_au | urn:peppol:pint:billing-1@au-1 |
pint_nz | urn:peppol:pint:billing-1@nz-1 |
pint_my | urn:peppol:pint:billing-1@my-1 |
pint_ae | urn:peppol:pint:billing-1@ae-1 |
pint_jp | urn:peppol:pint:billing-1@jp-1 |
Known gaps
Preview-status profiles (AU, NZ, MY, JP, AE) produce structurally valid XML but may not pass every Schematron rule in the respective phive rule-sets without additional country-specific extensions. The current conformance status from our phive-rules test suite:
| Profile | Schematron result | Blocking issues |
|---|---|---|
pint_sg | Passes | None |
pint_eu | Passes (4 warnings) | None blocking |
pint_my | 3 errors | PartyLegalEntity BRN scheme, InvoicePeriod |
pint_jp | 1 error | InvoicePeriod (BG-14) |
pint_au | 4 errors | ABN in PartyLegalEntity/CompanyID |
pint_nz | 4 errors | NZBN scheme in PartyLegalEntity/CompanyID |
pint_ae | 9 errors | UAE structural extensions (ProfileExecutionID, line UUIDs, CountrySubentity) |
Planned additions per profile:
- PINT-AU/NZ —
PartyLegalEntity/CompanyIDwithschemeID="0151"(ABN) /"0088"(NZBN) - PINT-MY —
PartyLegalEntity/CompanyIDwith BRN scheme + optionalInvoicePeriodelement - PINT-JP —
InvoicePeriodfor full BG-14 coverage - PINT-AE —
ProfileExecutionID, per-line UUIDs,CountrySubentityfrom the emirates list (AUH/DXB/SHJ/UAQ/FUJ/AJM/RAK)
country_profile already selects the correct CustomizationID and TaxScheme for all profiles. The listed items are about stricter Schematron conformance, not structural validity.
Further reading
- Invoice Formats — all nine supported formats
- Generate API — full field reference including
country_profileandtax_category - Validation — pre-validate your payload before PDF generation