SUMU

Best practices

The pieces that turn a working integration into a production-grade one.

Everything below is documented in full elsewhere in this reference — this page is the checklist that ties it together. If you only read one section, read Check the receiver first and Always send an idempotency key; they're the two mistakes that are expensive to make in production and free to avoid.

Check the receiver first

Before calling Create an invoice, call Participant lookup on the buyer's identifier. A business that isn't registered on Peppol yet — or hasn't published the capability you need — will fail delivery after you've already committed an invoice number, which is harder to unwind than a lookup that returns registered: false. Lookups are cheap and cached briefly on SUMU's side; there's no penalty for checking routinely rather than only when a send fails.

Always send an idempotency key

Every POST that creates something accepts an Idempotency-Key header — see Idempotency. An invoice number, once issued, is permanently claimed. Without a key, retrying a request whose response you never saw either double-sends or fails with a 409 CONFLICT_ERROR on the duplicate invoice number, and neither is cleanly recoverable after the fact. Generate the key once per logical send (e.g. from your own order/invoice reference), not once per HTTP attempt.

Validate before you build the real thing

Validate runs the full Oman rule set against a UBL document without sending anything, doesn't count against your send quota, and is safe to call as often as you like. Wire it into CI or a pre-flight check in your own pipeline rather than discovering schematron failures in production — they come back as a plain 400 VALIDATION_ERROR, same as a missing field, so catching them early is on you, not on a distinct error code.

Handle errors by code, and back off correctly

Work from the full error table rather than branching on HTTP status alone — the API returns a small set of generic codes, and message is where the specific reason lives. A 409 CONFLICT_ERROR on registering a taxpayer needs a completely different response (go finish the Fawtara association) than a 409 CONFLICT_ERROR on creating one with a vat_id you already have (go retrieve the existing record) — read the message to tell them apart. On 429, respect the Retry-After header and back off exponentially rather than retrying immediately — see Rate limits. On 502 UPSTREAM_ERROR, retry later; it means Peppol or the Tax Authority is unreachable, not that your request was wrong.

Track delivery deliberately

Every send gives you a transaction_id immediately, before delivery or tax reporting have happened — see why there are two separate outcomes. Don't poll Get a transaction in a tight loop; either register a webhook (see below) or poll on a sane interval. If you do both, treat the webhook as authoritative and use polling only as a reconciliation fallback, not as your primary signal.

Verify webhook signatures

Every webhook delivery carries an X-Sumu-Signature header — an HMAC-SHA256 of the timestamp and raw body, keyed with the secret shown once at registration. Webhooks has the full verification code. Treat an unverified webhook body as untrusted input; don't act on it without checking the signature first.

Respect rate limits, and plan bulk sends around the reporting window

Limits apply per API key, shared across every taxpayer on the Platform track — see Rate limits for the actual numbers. There's no batch-send endpoint today, so a month-end run is many individual calls: spread it over the hour rather than bursting it, since Oman requires tax reporting within 15 minutes of issuing a B2B invoice. Talk to SUMU before a run above 10,000 documents.

Keep credentials out of source control

Load your API key from an environment variable or a secrets manager, never a committed file. Rotate by creating a new key and deploying it before revoking the old one — see Authentication for the multi-key rotation model. If you're on the Platform track, also read that page's callout on the current access-control gap: one key today has full access to every taxpayer under it.

Test against sandbox before going live

sumu_test_ keys run the same schematron/UBL pipeline as production, just against a non-production host and a lower rate limit — see Sandbox for the full breakdown. Point your integration tests at sandbox rather than mocking SUMU's API yourself where possible; it's more likely to catch a real Oman validation rule than a hand-written stub is — but don't treat it as consequence-free by default.

SUMU

Sumu — an e-invoicing platform owned and operated by OceanGate for Smart Technologies LLC, a FinTech and SaaS solutions company. All rights reserved © 2026.

joinsumu.com ↗

On this page