Platform
Every invoice, validated end to end.
Every submission runs through the same six stages, in order, with no silent drops and no bypass path.
01
Ingest
Any JSON your system already produces
02
Normalize
Alias-mapped to the PINT-AE canonical shape
03
Validate
Every check group, no short-circuit
04
Ledger
Tenant-isolated, RLS-enforced persistence
05
Route
To your ASP, with circuit breakers and retry
06
Webhook
Status back to you at every terminal state
Validation sandbox
Every check runs. Nothing short-circuits.
POST /api/v1/compliance/validate runs the exact same normalize-and-check pipeline as /submit, with zero persistence. Every failed check returns a ValidationIssue (field, code, message, severity), never a generic failure.
MISSING_MANDATORYerrorA field PINT-AE requires unconditionally could not be mapped from your payload.
LINE_MATHerrornet_amount + vat_amount != gross_amount on a line item (2dp, ROUND_HALF_UP).
VAT_RATE_MISMATCHerrorThe vat_rate on a line isn't one of the rates allowed for that VAT category.
TIN_TRN_MISMATCHerrorThe Peppol TIN doesn't match the corresponding TRN field.
MISSING_CONDITIONALwarningA conditionally-mandatory field is missing given the rest of the document.
Ledger & audit
Every invoice reaches a terminal state.
Every transition flows through a single choke point that also writes an append-only audit event. There is no code path that updates status without recording why.
The three non-happy-path states are reachable from any stage: each is a persisted status, a failure_detail, an audit row, and a webhook back to your system.
Security layer
Isolation enforced by the database.
- Postgres Row-Level Security, FORCE-enabled: even the table owner is policy-bound.
- AES-256-GCM envelope encryption for BYOK ASP credentials: the key-encryption key lives outside the database.
- HMAC-SHA256-signed webhooks in both directions, with freshness windows and replay protection.
- TLS-only ingress; deployed in-country on Microsoft Azure, UAE North region.
ALTER TABLE ae_compliance.invoice_ledger FORCE ROW LEVEL SECURITY; CREATE POLICY tenant_isolation_ledger ON ae_compliance.invoice_ledger USING (tenant_id = current_setting('app.current_tenant_id')::uuid);ASP routing
Retries, circuit breakers, and honest failure.
Transient errors (timeouts, 5xx, 429) retry with exponential backoff and jitter, up to 8 attempts, gated by a circuit breaker per (tenant, ASP) pair. A permanent error moves straight to FAILED with a failure webhook, never a silent stall.
Receiving (buyer flow)
Every invoice you receive gets checked too.
Your counterparty’s Accredited Service Provider delivers their invoice to your Access Point, and the same validation pipeline that checks your outbound submissions runs against it. If something doesn’t reconcile, it is flagged for review, never rejected, because the document already cleared the FTA network before it reached you.
ACKNOWLEDGED is an internal bookkeeping mark: it records that the document was checked and filed, not a business response sent back over the network to the sender.
Oversight
One snapshot of the business. Alerts that don’t wait for you.
Every customer gets one Executive Snapshot of where things stand this period: gross AED invoiced and the VAT on it, rejection rate, how many invoices have been stuck for 3 or more days, an estimated penalty exposure, and how concentrated your invoicing is across your top 5 buyers.
It is built from invoices issued, not invoices paid. There is no cash flow, collections, or accounts-payable visibility here, because that data doesn’t exist in the product yet.
The same page surfaces an alert the moment something needs attention: a penalty-risk flag, an identity-mismatch flag, a rejection-rate spike, or an ASP outage, so you hear it from the dashboard first, not from a downstream problem.
PENALTY_RISKwarningOne or more invoices failed to transmit this month, building toward the per-document FTA penalty.
IDENTITY_MISMATCHerrorA supplier or buyer identity mismatch in the last 30 days that can block clearance, the only one of these treated as critical.
REJECTION_SPIKEwarningThis week's rejection-and-failure rate has moved well above what's normal for this account.
ASP_BREAKER_OPENwarningTransmissions to your Accredited Service Provider are temporarily paused after repeated failures, and retry automatically once the connection recovers.