Skip to content
Back to News
Changelog

SDK 5.1.0 and CLI 0.11.0 — payload joins DocumentFormat, invoiceTypeCode follows the network's two vocabularies

sdkclipeppol

Two things ship in 5.1.0, and both were measured against the published 5.0.0, not against our working tree.

getAs(id, "payload") now compiles

GET /v1/invoices/{id}/as/payload has served since August — it returns the business document with the Peppol SBDH envelope stripped, for callers who supplied their own UBL and want to inspect what was transmitted. The OpenAPI contract declared it. The SDK's DocumentFormat type had four members and did not know it, so a TypeScript integrator needed a cast to reach a published format.

On 5.1.0 the union has five members and the cast is gone. The same caveat the contract carries applies: payload is the document as transmitted, not your own bytes — the network re-serialises in transit, so seal a canonical form (C14N) if you need to compare across the boundary.

A parity lock in the console now asserts that the route's accepted formats, the published OpenAPI enum and the built SDK union stay identical — this exact gap could not reopen silently.

invoiceTypeCode follows the rulebook, not a list of seven

BR-CL-01 is fatal on the network and defines two disjoint vocabularies: 50 codes are legal as <cbc:InvoiceTypeCode>, a different set of 13 as <cbc:CreditNoteTypeCode> — only 81 belongs to both. Until now the SDK validated the field against a hand-written list of seven codes, applied regardless of document kind. Both directions were wrong:

  • On a credit note, six of the seven advertised codes were illegal. A credit note carrying 383, 384, 386, 389 or 751 now raises a validation error locally, citing BR-CL-01 and suggesting the codes legal for a credit note. On 5.0.0 every one of them passed local validation — and every one is fatal on the network.
  • On an invoice, 44 legal codes were refused. 382, 326 (partial invoice — named by the German national rule DE-R-017) and 42 others now pass. The default behaviour is unchanged: omit the field and the document kind decides (380 invoice, 381 credit note).

The public InvoiceTypeCode type is now the exact union of both vocabularies (62 values) — a widening, so existing code keeps compiling. The type cannot express the context; runtime validation does. Two new exports, getInvoiceTypeCodes() and getCreditNoteTypeCodes(), return each vocabulary.

Also in this release

  • PaginationMeta.truncated is documented as always false today. No gateway list route emits the field (every list endpoint returns exactly total_count, offset, limit and has_more), so the previous doc promised a state that cannot occur. The field is kept, not removed: the client derives it from the wire, and a future gateway that starts emitting it will surface without a breaking release.
  • The package now ships its LICENSE file. The 5.0.0 tarball did not contain one; the corrected README from the documentation audit travels with it.

CLI 0.11.0

@getpeppr/cli bundles its own copy of the SDK, so these verdicts only reach CLI users when the CLI is rebundled — 0.11.0, released alongside, does that.

Measured against the published 0.10.0 (which bundles SDK 5.0.0): a partial invoice carrying 326 used to exit 1 on getpeppr validate — a false refusal — and now passes. In the other direction, a credit note carrying 383, 384, 386, 389 or 751 used to pass local validation and fail on the network; it now exits 1 locally with a BR-CL-01 error naming the codes legal for a credit note. The CLI tarball also ships its LICENSE file for the first time.

Upgrading

npm install @getpeppr/sdk@5.1.0

Nothing breaks. If you send credit notes with an explicit invoiceTypeCode other than 381, local validation now refuses what the network already refused — switch to a code in getCreditNoteTypeCodes().