Managing Companies
Create, update, list, and delete company profiles in Recommand for Peppol document exchange. Includes Peppol registration and field reference.
This guide explains how to create, update, and manage company profiles in Recommand for Peppol document exchange using the Recommand API.
Overview
A company in Recommand represents a business entity that can send or receive Peppol documents. Each company must be registered before it can participate in document exchange.
Only add companies you operate
Only add companies that you are responsible for, typically your own organization or entities you manage. Do not add companies that you send documents to (customers) or receive documents from (suppliers). Those companies manage their own Peppol registration independently. Trying to add them to your account will cause registration conflicts.
Prerequisites
- A Recommand account with API access
- Your API key and secret
- Your team ID
Retrieving Your Team ID
Your team ID is required for most company management operations. You can find it in the Recommand dashboard under Account > API Keys.
Strict Identifier Validation
Recommand enforces strict format validation on Peppol identifiers and company VAT and enterprise numbers. Numbers that do not pass national validation rules (such as the Belgian modulo-97 check digit) are rejected at creation and update time. Ensure the values you submit are correctly formatted.
Listing Companies
To retrieve all companies associated with your team using the list companies endpoint:
async function listCompanies() {
const response = await fetch(
`https://app.recommand.eu/api/v1/companies`,
{
headers: {
Authorization:
"Basic " +
Buffer.from("your_api_key:your_api_secret").toString("base64"),
},
}
);
const result = await response.json();
return result.companies;
}
// Example usage
const companies = await listCompanies("your_team_id");
companies.forEach((company) => {
console.log(`${company.name} (${company.id})`);
});Creating a Company
Create a company using the create company endpoint. This creates its profile in Recommand and, unless skipDefaultCompanySetup is set, its default identifiers and document types. The company must complete verification before it can send or receive documents.
isSmpRecipient defaults to true: after successful verification, Recommand registers the company on Peppol to receive documents. Set it to false for sending only; verification is still required, but Recommand does not register the company for receiving.
If the company is not yet registered on Peppol, no migration key is needed. You can also create a company that is already registered with another provider. When onboarding such a company for receiving, we recommend submitting its migration keys before completing verification, so Recommand can take over the identifiers when registering them. You can also migrate identifiers after verification; see below.
async function createCompany(companyData) {
const response = await fetch(
`https://app.recommand.eu/api/v1/companies`,
{
method: "POST",
headers: {
Authorization:
"Basic " +
Buffer.from("your_api_key:your_api_secret").toString("base64"),
"Content-Type": "application/json",
},
body: JSON.stringify(companyData),
}
);
return response.json();
}
// Example usage
const newCompany = await createCompany("your_team_id", {
name: "ACME Corporation",
address: "123 Main Street",
postalCode: "1000",
city: "Brussels",
country: "BE",
enterpriseNumber: "0123456789",
vatNumber: "BE0123456789",
});
if (newCompany.success) {
console.log(`Company created with ID: ${newCompany.company.id}`);
console.log(`Verification URL: ${newCompany.verificationUrl}`);
// Present this URL to your user — they can complete or forward the identity check from there
} else {
console.error("Failed to create company:", newCompany.errors);
}The same request with curl
curl -X POST https://app.recommand.eu/api/v1/companies \
-u key_xxx:secret_xxx \
-H "Content-Type: application/json" \
-d @company.json
The company.json body is the JSON object shown above; the
country-specific guides give the exact identifier fields per
country.
Company Fields
| Field | Description | Required | Example |
|---|---|---|---|
name | Company name | Yes | "ACME Corporation" |
address | Street address | Yes | "123 Main Street" |
postalCode | Postal/zip code | Yes | "1000" |
city | City | Yes | "Brussels" |
country | Country code (2-letter ISO code) | Yes | "BE" |
enterpriseNumber | Enterprise number | No | "0123456789" |
enterpriseNumberScheme | Scheme of the enterprise number, written into the documents the company sends | No | "0208" |
vatNumber | VAT registration number | No | "BE0123456789" |
email | Contact email | No | "billing@acme.be" |
phone | Contact phone number | No | "+32 3 123 45 67" |
isSmpRecipient | Register the company to receive documents after verification (defaults to true) | No | true |
skipDefaultCompanySetup | Skip the automatic identifiers and document types, and create them yourself | No | false |
isVerified | Whether the company has been verified (read-only) | n/a | false |
Which identifiers a company needs, and which Peppol identifiers and document types are registered from them, depends on its country. The country-specific getting started guides list the exact fields per country: Belgium, France, the Netherlands and every other supported country.
Moving from another provider with a migration key
Deregistering at the previous provider and registering with Recommand leaves a gap during which nobody can deliver to the company. The Peppol network has a way around that: the current provider asks the network to prepare the move and receives a one-time migration key, which the company passes on to its new provider. The new provider claims the registration with that key, and the network switches the company over in one step.
First create the company with receiving enabled (isSmpRecipient: true, the default), even if it is still registered with the previous provider. Use the returned company.id to list its identifiers and find each identifierId.
Ask the previous provider for a migration key for the exact identifier that is
registered with them, for example 0208:1012081766. Submit it with the
migrate company identifier endpoint:
POST /api/v1/companies/{companyId}/identifiers/{identifierId}/migration
{
"migrationKey": "Ab12$#xyZ9!kLm"
}If the identifier does not exist on the company yet, add it with the
create company identifier endpoint
and pass the migrationKey in the same request.
For a company that has not yet been verified, we recommend submitting all required keys before completing verification using the verificationUrl returned when creating the company. This avoids trying to register identifiers that are still held by the previous provider. For an already verified company with receiving enabled, you can submit a key at any time; the migration is attempted immediately.
If the previous provider cannot supply migration keys, ask them to fully deregister the identifiers before registering them with Recommand. For an unverified company, do this before completing verification. Recommand can then register them normally, but there will be a gap in receiving between deregistration and the new registration.
What happens next depends on whether the company can be published already:
- A company that is verified is taken over immediately. The response has
status
completed, and the network routes to Recommand within minutes. - A company whose identity check is still open keeps the key with status
pending. The moment the company is verified and registered, the key is used. Check the outcome with the list company identifier migrations endpoint. - A key the network refuses ends in status
failedwith the reason. The usual causes are a key issued for a different identifier, a copy error, or a previous provider that cancelled the migration. Ask them for a fresh key and submit it again; a newer key replaces a pending one.
A key covers one identifier. A company that was published under two identifiers at the previous provider, for example both its enterprise number and its VAT number, needs a key for each. After the move the company receives the document types Recommand registers for it, not the ones the previous provider had published.
Retrieving a Company
To get details about a specific company using the get company endpoint:
async function getCompany(companyId) {
const response = await fetch(
`https://app.recommand.eu/api/v1/companies/${companyId}`,
{
headers: {
Authorization:
"Basic " +
Buffer.from("your_api_key:your_api_secret").toString("base64"),
},
}
);
return response.json();
}
// Example usage
const companyDetails = await getCompany("your_team_id", "company_id");
if (companyDetails.success) {
console.log(companyDetails.company);
} else {
console.error("Failed to retrieve company:", companyDetails.errors);
}Updating a Company
To update an existing company using the update company endpoint:
async function updateCompany(companyId, updatedData) {
const response = await fetch(
`https://app.recommand.eu/api/v1/companies/${companyId}`,
{
method: "PUT",
headers: {
Authorization:
"Basic " +
Buffer.from("your_api_key:your_api_secret").toString("base64"),
"Content-Type": "application/json",
},
body: JSON.stringify(updatedData),
}
);
return response.json();
}
// Example usage
const updateResult = await updateCompany("company_id", {
name: "ACME Corporation Updated",
address: "456 New Street",
postalCode: "1000",
city: "Brussels",
country: "BE",
enterpriseNumber: "0123456789",
vatNumber: "BE0123456789",
});
if (updateResult.success) {
console.log("Company updated successfully");
// If vatNumber or enterpriseNumber changed, isVerified is reset to false — reverification required
} else {
console.error("Failed to update company:", updateResult.errors);
}Updating identifiers resets verification
If you update a company's vatNumber or enterpriseNumber, isVerified is automatically reset to false and the company must be verified again before it can participate on the Peppol network.
Deleting a Company
To delete a company using the delete company endpoint:
async function deleteCompany(companyId) {
const response = await fetch(
`https://app.recommand.eu/api/v1/companies/${companyId}`,
{
method: "DELETE",
headers: {
Authorization:
"Basic " +
Buffer.from("your_api_key:your_api_secret").toString("base64"),
},
}
);
return response.json();
}
// Example usage
const deleteResult = await deleteCompany("company_id");
if (deleteResult.success) {
console.log("Company deleted successfully");
} else {
console.error("Failed to delete company:", deleteResult.errors);
}Verifying a Company
After creating a company, an authorised representative must complete an identity check before the company can send or receive documents on the Peppol network. The isVerified field on a company object reflects whether this step has been completed.
The create company response already includes a verificationUrl. Present it to your user straight away. The verification page lets them forward the link to the right person within their organisation. If you need a fresh URL later (e.g. the link was lost or you want to verify an existing company), call the verify company endpoint:
const result = await fetch(
`https://app.recommand.eu/api/v1/companies/${companyId}/verify`,
{
method: "POST",
headers: {
Authorization:
"Basic " +
Buffer.from("your_api_key:your_api_secret").toString("base64"),
},
}
).then((r) => r.json());
if (result.success) {
console.log("Verification URL:", result.verificationUrl);
// Present this URL to your user — they can complete or forward the identity check from there
}Verification can also be completed directly from the Recommand dashboard without using the API. For the full flow, see the Company Verification guide.
Complete Example: Company Management
Here's a full example of creating, updating, and managing companies:
// Setup authentication
const API_KEY = "your_api_key";
const API_SECRET = "your_api_secret";
const TEAM_ID = "your_team_id";
const auth =
"Basic " + Buffer.from(`${API_KEY}:${API_SECRET}`).toString("base64");
const baseUrl = "https://app.recommand.eu/api/v1";
// Create a new company
async function createCompany() {
const response = await fetch(`${baseUrl}/companies`, {
method: "POST",
headers: {
Authorization: auth,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Test Company",
address: "123 Test Street",
postalCode: "1000",
city: "Brussels",
country: "BE",
enterpriseNumber: "0123456789",
vatNumber: "BE0123456789",
}),
});
const result = await response.json();
if (result.success) {
console.log(`Company created with ID: ${result.company.id}`);
return result.company.id;
} else {
console.error("Failed to create company:", result.errors);
return null;
}
}
// List all companies
async function listCompanies() {
const response = await fetch(`${baseUrl}/companies`, {
headers: { Authorization: auth },
});
const result = await response.json();
if (result.success) {
console.log("Companies:");
result.companies.forEach((company) => {
console.log(`- ${company.name} (${company.id})`);
});
return result.companies;
} else {
console.error("Failed to list companies:", result.errors);
return [];
}
}
// Update a company
async function updateCompany(companyId) {
const response = await fetch(`${baseUrl}/companies/${companyId}`, {
method: "PUT",
headers: {
Authorization: auth,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Updated Test Company",
address: "456 Updated Street",
postalCode: "1000",
city: "Brussels",
country: "BE",
enterpriseNumber: "0123456789",
vatNumber: "BE0123456789",
}),
});
const result = await response.json();
if (result.success) {
console.log("Company updated successfully");
return true;
} else {
console.error("Failed to update company:", result.errors);
return false;
}
}
// Delete a company
async function deleteCompany(companyId) {
const response = await fetch(`${baseUrl}/companies/${companyId}`, {
method: "DELETE",
headers: { Authorization: auth },
});
const result = await response.json();
if (result.success) {
console.log("Company deleted successfully");
return true;
} else {
console.error("Failed to delete company:", result.errors);
return false;
}
}
// Example workflow
async function manageCompanies() {
// List existing companies
console.log("Existing companies:");
await listCompanies();
// Create a new company
console.log("\nCreating a new company...");
const companyId = await createCompany();
if (!companyId) return;
// List companies again to see the new one
console.log("\nUpdated company list:");
await listCompanies();
// Update the company
console.log("\nUpdating the company...");
await updateCompany(companyId);
// List companies again to see the update
console.log("\nAfter update:");
await listCompanies();
// Delete the company
console.log("\nDeleting the company...");
await deleteCompany(companyId);
// Final company list
console.log("\nFinal company list:");
await listCompanies();
}
// Run the workflow
manageCompanies().catch((error) => {
console.error("Error in company management workflow:", error);
});Best Practices
- Check Peppol Registration: Before creating a company, check if the company is already registered in the Peppol network.
- Validate data: Ensure company information is accurate before creating or updating
- Handle errors: Implement proper error handling for API responses
- Check before delete: Ensure a company is not in use before deleting it
- Limit company creation: Create only the companies you need to avoid clutter
Next Steps
Sending Invoices
Create and send invoices from your companies.
Sending Credit Notes
Issue credit notes to correct invoices.
Working with Webhooks
Receive events across your companies and teams.
Company Verification
Verify a company before it can participate on the Peppol network.
Verifying Recipients
Check recipients before sending documents.
Complete API Reference
Explore all endpoints and models.