Legal Entities API
Provision, list, authorise, and off-board your customers as Peppol legal entities. The multi-tenant surface for platforms.
legal_entities:* scope. A standard key receives 403. Customers you
don't own return 404, never another platform's data.
Create a customer as a draft Peppol legal entity. getpeppr validates the identifier format
(for example, a Luhn check), then kicks off registry verification asynchronously. Returns
202 on creation, or 200 if the same externalId is
replayed (the call is idempotent).
202 while the identifier later settles as
verification_failed, not_found, or registration_failed
if the identifier is fake, unsupported, already registered elsewhere, or not attachable on
the test network. Poll GET /v1/legal-entities/:id or subscribe to
legal_entity.* webhooks before treating the customer as send-ready.
Body parameters
| Name | Type | Required | Description |
|---|---|---|---|
externalId | string | Required | Your stable reference for this customer (1–64 chars). Echoed on every response and webhook. |
companyName | string | Required | Legal company name (2–64 chars). Matched against the business registry. |
country | string | Required | ISO 3166-1 alpha-2 country code (e.g. GB). |
address.line1 | string | Required | Street address (2–192 chars). |
address.city | string | Required | City (2–64 chars). |
address.zip | string | Required | Postal / ZIP code (2–32 chars). |
identifier.scheme | string | Required | Peppol identifier scheme (1–16 chars, e.g. GB:CRN, 0208). |
identifier.value | string | Required | The identifier value (1–64 chars). Format-checked (e.g. Luhn) before verification. |
import { Peppol } from "@getpeppr/sdk";
const peppol = new Peppol({ apiKey: "sk_live_your_master_key" });
const customer = await peppol.legalEntities.create({
externalId: "customer_8412",
companyName: "Bright Health Ltd",
country: "GB",
address: { line1: "10 King Street", city: "London", zip: "EC2V 8EA" },
identifier: { scheme: "GB:CRN", value: "12345678" },
});
console.log(customer.id, customer.status); // "7c9a1b34-…", "pending"// 202 Accepted — verification runs asynchronously
{
"id": "7c9a1b34-2d5e-4f60-8a1b-9c2d3e4f5a6b",
"externalId": "customer_8412",
"companyName": "Bright Health Ltd",
"country": "GB",
"identifier": { "scheme": "GB:CRN", "value": "12345678" },
"status": "pending",
"environment": "production",
"createdAt": "2026-06-01T10:00:00.000Z"
}Belgian customers
For Belgian Legal Entities, use scheme 0208 with the 10-digit BCE/KBO
enterprise number. If you start from a VAT number such as BE0685660237, drop
the BE prefix and send 0208:0685660237. The
companyName should be the exact registered legal name for that number. Avoid
9925 for this API flow unless getpeppr support explicitly instructs you to use it.
When VAT registration is confirmed during verification, getpeppr also registers the derived
BE:VAT identifier on the network automatically — required for sending invoices
that carry VAT (see Network identifiers and VAT).
curl https://api.getpeppr.dev/v1/legal-entities \
-H "Authorization: Bearer sk_sandbox_your_master_key" \
-H "Content-Type: application/json" \
-d '{
"externalId": "customer_be_001",
"companyName": "Exact Registered Legal Name",
"country": "BE",
"address": { "line1": "Rue de la Loi 16", "city": "Brussels", "zip": "1000" },
"identifier": { "scheme": "0208", "value": "0685660237" }
}'Swedish customers
For Swedish Legal Entities, use scheme 0007 with the 10-digit organisation
number (organisationsnummer). If you start from a VAT number such as
SE556036079301, drop the SE prefix and the trailing
01 and send 0007:5560360793. When the derived VAT number is
confirmed against VIES, getpeppr also registers the SE:VAT identifier on the
network automatically (see Network identifiers and VAT).
List the customers you manage, newest first. Results are isolated to your platform account.
When offset exceeds the total, data is empty and has_more is false.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
limit | number | Optional | Max results (default 50, max 100). |
offset | number | Optional | Pagination offset (default 0, max 100000). |
import { Peppol } from "@getpeppr/sdk";
const peppol = new Peppol({ apiKey: "sk_live_your_master_key" });
// One page
const page = await peppol.legalEntities.list({ limit: 20, offset: 0 });
console.log(page.data, page.meta.hasMore);
// …or iterate every customer — pagination handled for you
for await (const customer of peppol.legalEntities.listAll()) {
console.log(customer.externalId, customer.status);
}{
"data": [
{
"id": "7c9a1b34-2d5e-4f60-8a1b-9c2d3e4f5a6b",
"externalId": "customer_8412",
"companyName": "Bright Health Ltd",
"country": "GB",
"identifier": { "scheme": "GB:CRN", "value": "12345678" },
"status": "active",
"environment": "production",
"createdAt": "2026-06-01T10:00:00.000Z"
}
],
"pagination": { "total_count": 42, "offset": 0, "limit": 20, "has_more": true }
}
Retrieve a single customer by their getpeppr id. On production this surfaces the
full attestation lifecycle status (see the
status reference);
in sandbox it returns the verification status. Unknown or unowned ids return 404.
import { Peppol } from "@getpeppr/sdk";
const peppol = new Peppol({ apiKey: "sk_live_your_master_key" });
const customer = await peppol.legalEntities.get(
"7c9a1b34-2d5e-4f60-8a1b-9c2d3e4f5a6b",
);
console.log(customer.status); // production: full attestation lifecycle status
Off-board a customer. The legal entity is archived: the customer drops out of active lists
and can no longer send, while audit records, attestations, and history are retained for
compliance. Returns 200 with the archived entity. You can also archive a
customer from the console (Legal Entities → the row's
Archive action), which applies the same retention rules — production
archives require typing the customer reference to confirm.
import { Peppol } from "@getpeppr/sdk";
const peppol = new Peppol({ apiKey: "sk_live_your_master_key" });
const result = await peppol.legalEntities.archive(
"7c9a1b34-2d5e-4f60-8a1b-9c2d3e4f5a6b",
);
console.log(result.status); // "archived"{
"id": "7c9a1b34-2d5e-4f60-8a1b-9c2d3e4f5a6b",
"externalId": "customer_8412",
"status": "archived"
}
Request (or resend) the customer's authorisation. getpeppr emails a co-branded, getpeppr-signed
attestation link to the contact; once they confirm, the customer advances toward
active. Production only — calling this with a sandbox key returns
400.
Body parameters
| Name | Type | Required | Description |
|---|---|---|---|
contactEmail | string | Required | Email of the person who will authorise invoicing for this customer (max 254 chars). |
contactName | string | Optional | Display name shown in the authorisation email (max 128 chars). |
409 if the customer isn't verified yet or has already attested, and
502 if the email couldn't be sent (retry to mint a fresh link). Issuing an
attestation emits a legal_entity.awaiting_authz webhook.
import { Peppol } from "@getpeppr/sdk";
const peppol = new Peppol({ apiKey: "sk_live_your_master_key" });
const attestation = await peppol.legalEntities.requestAttestation(
"7c9a1b34-2d5e-4f60-8a1b-9c2d3e4f5a6b",
{ contactEmail: "owner@brighthealth.co.uk", contactName: "Dr Jane Okafor" },
);
console.log(attestation.status, attestation.expiresAt); // "awaiting_authz", "…"// 202 Accepted — co-branded email sent to the customer
{
"id": "7c9a1b34-2d5e-4f60-8a1b-9c2d3e4f5a6b",
"externalId": "customer_8412",
"status": "awaiting_authz",
"expiresAt": "2026-06-08T10:00:00.000Z"
}