Skip to content

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

ProfileDescriptionTaxSchemeStatus
standard_euPeppol BIS 3.0 (EU, UK)VATStable
pint_internationalPINT base, no country extensionsVATStable
pint_sgSingapore PINT (UBL 1.4.0)GSTStable (passes Peppol Schematron)
pint_euInternational EU PINT (2025-11)VATStable (passes Peppol Schematron)
pint_auAustralia PINTGSTPreview — requires ABN business identifier (see Known Gaps)
pint_nzNew Zealand PINTGSTPreview — requires NZBN business identifier
pint_myMalaysia PINTVATPreview — requires BRN + InvoicePeriod
pint_aeUAE PINTVATPreview — multiple country-specific structural extensions pending
pint_jpJapan PINTVAT (= Consumption Tax)Preview — requires InvoicePeriod

Automatic detection

If you don't pass country_profile, the API maps from seller.country:

seller.countryResolved profile
Any EU member state, GBstandard_eu
SGpint_sg
AUpint_au
NZpint_nz
MYpint_my
AEpint_ae
JPpint_jp
Anything elsestandard_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:

bash
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:

json
{
  "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:

json
{
  "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

ProfileCodesNotes
standard_eu, pint_eu, pint_internationalS, Z, E, AE, K, G, OStandard EN 16931 codes
pint_sgSR, ZR, ESStandard-Rated, Zero-Rated, Exempt
pint_au, pint_nzS, Z, EGST-equivalent mapping
pint_mySA, SEStandard, Exempt
pint_aeS, Z, EUAE VAT standard codes
pint_jpS, Z, EConsumption Tax codes

CustomizationID values

The CustomizationID element identifies the profile in the XML. For reference:

ProfileCustomizationID
standard_euurn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0
pint_internationalurn:peppol:pint:billing-1
pint_sgurn:peppol:pint:billing-1@sg-1
pint_euurn:peppol:pint:billing-1@eu-1
pint_auurn:peppol:pint:billing-1@au-1
pint_nzurn:peppol:pint:billing-1@nz-1
pint_myurn:peppol:pint:billing-1@my-1
pint_aeurn:peppol:pint:billing-1@ae-1
pint_jpurn: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:

ProfileSchematron resultBlocking issues
pint_sgPassesNone
pint_euPasses (4 warnings)None blocking
pint_my3 errorsPartyLegalEntity BRN scheme, InvoicePeriod
pint_jp1 errorInvoicePeriod (BG-14)
pint_au4 errorsABN in PartyLegalEntity/CompanyID
pint_nz4 errorsNZBN scheme in PartyLegalEntity/CompanyID
pint_ae9 errorsUAE structural extensions (ProfileExecutionID, line UUIDs, CountrySubentity)

Planned additions per profile:

  • PINT-AU/NZPartyLegalEntity/CompanyID with schemeID="0151" (ABN) / "0088" (NZBN)
  • PINT-MYPartyLegalEntity/CompanyID with BRN scheme + optional InvoicePeriod element
  • PINT-JPInvoicePeriod for full BG-14 coverage
  • PINT-AEProfileExecutionID, per-line UUIDs, CountrySubentity from 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_profile and tax_category
  • Validation — pre-validate your payload before PDF generation

ZUGFeRD 2.4 & Factur-X 1.0.8 compliant