Skip to content

Contacts & Directory

Manage your contact list, search the Peppol Directory to find participants, and import them with automatic Peppol registration verification.

GET /v1/contacts #

List all contacts for your account with optional filtering and pagination.

Query parameters

NameTypeRequiredDescription
namestringOptionalFilter by name (partial match)
isClientbooleanOptionalFilter clients only
isProviderbooleanOptionalFilter providers only
limitnumberOptionalMax results (default: 20)
offsetnumberOptionalPagination offset (default: 0)
import { Peppol } from "@getpeppr/sdk";

const peppol = new Peppol({ apiKey: "sk_sandbox_..." });

// List contacts with optional filters
const { contacts, meta } = await peppol.contacts.list({
  name: "Acme",        // filter by name (partial match)
  isClient: true,      // only clients
  limit: 10,
  offset: 0,
});

for (const contact of contacts) {
  console.log(`${contact.name} — ${contact.peppolId ?? "no Peppol ID"}`);
}

console.log(`Showing ${contacts.length} of ${meta.total_count}`);
GET /v1/contacts/:id #

Retrieve a single contact by ID. Returns the full contact object including directoryVerified and directoryLastChecked fields.

Terminal
curl https://api.getpeppr.dev/v1/contacts/cnt_abc123 \
  -H "Authorization: Bearer sk_sandbox_..."
POST /v1/contacts #

Create a new contact. If a peppolId is provided, getpeppr automatically verifies the participant against the Peppol Directory and populates enrichment fields.

Body parameters

NameTypeRequiredDescription
namestringRequiredContact name
peppolIdstringOptionalPeppol ID (e.g. 0208:BE0456789012) — triggers auto-enrichment
vatNumberstringOptionalVAT registration number
companyIdstringOptionalCompany registration number
streetstringOptionalStreet address
citystringOptionalCity
postalCodestringOptionalPostal / ZIP code
countrystringOptionalISO 3166-1 alpha-2 country code
emailstringOptionalContact email
phonestringOptionalPhone number
isClientbooleanOptionalMark as client (default: true)
isProviderbooleanOptionalMark as provider (default: false)
Include an Idempotency-Key header to safely retry requests without creating duplicate contacts.
import { Peppol } from "@getpeppr/sdk";

const peppol = new Peppol({ apiKey: "sk_sandbox_..." });

// Create a contact — if peppolId is provided, auto-enrichment kicks in
const contact = await peppol.contacts.create({
  name: "Wayne Enterprises NV",
  peppolId: "0208:BE0123456789",
  vatNumber: "BE0123456789",
  street: "Avenue Louise 54",
  city: "Brussels",
  postalCode: "1050",
  country: "BE",
  email: "invoices@wayne.be",
  isClient: true,
});

console.log(`Created: ${contact.id}`);
// directoryVerified + directoryLastChecked auto-populated
PUT /v1/contacts/:id #

Update an existing contact. This is a partial update — only the fields you include in the request body are modified. Omitted fields remain unchanged.

import { Peppol } from "@getpeppr/sdk";

const peppol = new Peppol({ apiKey: "sk_sandbox_..." });

// Partial update — only provided fields are changed
const updated = await peppol.contacts.update("cnt_abc123", {
  email: "new-invoices@wayne.be",
  isProvider: true,
});

console.log(`Updated: ${updated.name}`);
DELETE /v1/contacts/:id #

Permanently delete a contact. Returns 204 No Content on success.

import { Peppol } from "@getpeppr/sdk";

const peppol = new Peppol({ apiKey: "sk_sandbox_..." });

await peppol.contacts.delete("cnt_abc123");
// Returns 204 No Content

Peppol Directory

The Peppol Directory is a public registry of all participants on the Peppol network. Use it to find recipients before sending invoices.

Search the Peppol Directory by name, country, or VAT number. At least one search criterion is required.

Query parameters

NameTypeRequiredDescription
namestringOptionalSearch by name (min 3 characters)
countrystringOptionalISO 3166-1 alpha-2 country code
vatNumberstringOptionalVAT registration number
limitnumberOptionalMax results (default: 20)
offsetnumberOptionalPagination offset (default: 0)
The name parameter requires a minimum of 3 characters. Directory search has a stricter rate limit than other API endpoints to respect the public directory's usage policy.
import { Peppol } from "@getpeppr/sdk";

const peppol = new Peppol({ apiKey: "sk_sandbox_..." });

// Search the Peppol Directory by name, country, or VAT
const results = await peppol.directory.search({
  name: "Wayne",       // min 3 characters
  country: "BE",       // ISO 3166-1 alpha-2
  limit: 5,
});

for (const entry of results.data) {
  console.log(`${entry.name} — ${entry.scheme}:${entry.id}`);
  console.log(`  Country: ${entry.country}, Registered: ${entry.registrationDate}`);
}
GET /v1/directory/:scheme/:id #

Look up a specific participant by their EAS scheme and identifier. Returns registration status, capabilities, and metadata.

Use this to verify whether a specific Peppol ID is active before sending an invoice.

import { Peppol } from "@getpeppr/sdk";

const peppol = new Peppol({ apiKey: "sk_sandbox_..." });

// Look up a specific participant by scheme + ID
const result = await peppol.directory.lookup("0208", "BE0123456789");

if (result.participant.registered) {
  console.log(`Found: ${result.participant.name}`);
  console.log(`Capabilities: ${result.participant.capabilities.join(", ")}`);
} else {
  console.log("Participant not found on Peppol network");
}

Workflows

Import from Directory

A common workflow is to search the Peppol Directory, then import a participant as a contact. When you create a contact with a peppolId, auto-enrichment fills in any missing details from the directory.

Auto-enrichment only fills in fields you didn't provide. Your data always takes priority over directory data.
import { Peppol } from "@getpeppr/sdk";

const peppol = new Peppol({ apiKey: "sk_sandbox_..." });

// 1. Search the directory
const results = await peppol.directory.search({ name: "Wayne", country: "BE" });
const match = results.data[0];

// 2. Import as a contact — auto-enrichment fills in the details
const contact = await peppol.contacts.create({
  name: match.name,
  peppolId: `${match.scheme}:${match.id}`,
  country: match.country,
  isClient: true,
});

console.log(`Imported: ${contact.name} (${contact.peppolId})`);

Auto-Enrichment

When you create a contact with a peppolId, getpeppr automatically queries the Peppol Directory in the background and updates the contact with:

  • directoryVerifiedtrue if the participant is registered on Peppol
  • directoryLastChecked — timestamp of the last verification
  • Missing fields like name, country, and vatNumber (if not provided by you)
Enrichment is fire-and-forget — the contact is created immediately, and directory data is populated asynchronously. It never overwrites fields you explicitly provided.

Re-verify a Contact

To check if a contact is still registered on the Peppol network, use the directory lookup endpoint with their Peppol ID. This is useful for periodic validation of your contact list.

import { Peppol } from "@getpeppr/sdk";

const peppol = new Peppol({ apiKey: "sk_sandbox_..." });

// Check if a contact is still registered on Peppol
const contact = await peppol.contacts.get("cnt_abc123");
const [scheme, id] = contact.peppolId!.split(":");

const result = await peppol.directory.lookup(scheme, id);

if (result.participant.registered) {
  console.log(`${contact.name} is still active on Peppol`);
} else {
  console.warn(`${contact.name} is no longer registered!`);
}