Sending and receiving Peppol documents in Norway for your own company

Getting started with Peppol e-invoicing for your own Norwegian company: register and verify the company, send Peppol invoices and credit notes, pick up incoming documents, go live. Organisation numbers under scheme 0192, registered in ELMA, the Norwegian receiver register, and checked against Enhetsregisteret.

This guide walks through everything needed to exchange Peppol documents for a company registered in Norway, assuming you are setting up your own Norwegian company, and that the company sends and receives documents over Peppol. Change any of the three answers at the top of the page to get the guide for a different situation.

What you are setting up

You are putting one company, your own or one you represent, on the Peppol network, so it can exchange invoices electronically with its customers and suppliers.

The setup is a one-time affair: registering the company and getting it verified takes a few minutes in the Recommand dashboard, and there is nothing to gain from automating something you do once. What you do integrate is the part that repeats: sending and receiving documents. Our existing integrations can also connect Recommand to accounting or invoicing software you already use, with no code at all.

A single team can hold several companies at no extra cost, useful if you run more than one legal entity, and the document volume of all of them counts towards one plan.

Onboarding companies that are not yours?

If you are building e-invoicing or Peppol integration into a product for your own customers, and will be registering their companies rather than only your own, switch the first answer above to Many companies. The API is the same; what changes is how companies, verification and billing are organised.

Peppol in Norway

Norway is one of the oldest Peppol countries: public sector buyers have required EHF invoices for years, and EHF Billing 3.0 is Peppol BIS Billing 3.0. Documents are exchanged as Peppol BIS 3 UBL over the standard Peppol billing process, through Recommand's own access point.

What is specific to Norway:

  • A B2B mandate in two steps. From 1 January 2027, businesses with a bookkeeping obligation must issue e-invoices to other such businesses. Until receiving becomes mandatory as well, on 1 January 2030, the obligation in practice applies when the buyer can receive them, which means being registered in ELMA or on Peppol.
  • Receivers are registered in ELMA. ELMA (Elektronisk mottakeradresseregister) is the Norwegian receiver register, run by the Norwegian Digitalisation Agency. Norwegian companies that receive through Recommand are published there rather than on Recommand's own SMP. Senders find them the usual way, through the Peppol network.
  • The organisation number is the Peppol address. Norwegian companies are published under scheme 0192 with their 9-digit organisasjonsnummer, so a Norwegian Peppol address looks like 0192:123456785.
  • Organisations are checked against Enhetsregisteret. An organisation number that the Norwegian register of legal entities does not know, or has deleted, is not registered as a receiver, and a registration is removed when the organisation is deleted from the register later.
  • Representatives are checked for signing authority. During verification, the representative is held against the people Enhetsregisteret lists as able to sign for the company or holding procuration.

Create your account and API credentials

  1. Sign up at app.recommand.eu/signup.
  2. Your account starts with a team. The team holds your company, your subscription and your document history, and you can invite colleagues to it.
  3. Create an API key on the API keys page. Note the key, the secret and your team ID.
  4. Check the credentials with a request that needs no data of its own:
curl -X GET https://app.recommand.eu/api/core/auth/verify \
  -u key_xxx:secret_xxx

It answers {"success": true} when the key and secret are accepted, and 401 when they are not, so it tells you about your credentials and nothing else.

All endpoints in this guide live under https://app.recommand.eu/api/v1 and accept HTTP Basic authentication with the key as username and the secret as password. If you would rather not store a long-lived secret, JWT API keys and OAuth2 with a JWT assertion are available too, see the authentication guide.

Not planning to write any code?

Sending and receiving can also be driven entirely from the dashboard or through an integration, and each section below says how. The dashboard is available in English, Dutch, French and German; pick your language on the account page.

Try it safely first

You do not have to get anything right the first time. Everything below, adding the company, registering it, sending and receiving, can be done in a playground team first, where nothing is delivered over the real Peppol network, nothing is registered on it, and nothing is billed.

Open the team switcher at the top of the dashboard and pick Add playground. Give it a name, leave the Peppol Test Network box unticked, and you are switched into the new team straight away. There is nothing to set up beyond that.

Add a company to that team and use it as both sender and recipient to watch a document travel end to end. When the flow does what you want, repeat it once in your real team.

Two things worth knowing before you start:

  • POST /:companyId/generate takes the same body as the send endpoint minus the email delivery options, which have no meaning when nothing is delivered, and returns the exact XML that sending would produce, fully validated, without transmitting, storing or billing it. Raw XML is not accepted here: there is nothing to generate from a document you already have. It also returns the resolved documentType, doctypeId and processId.
  • Failure addresses. In a playground that is not connected to the Peppol Test Network, sending to 404:404 or 0208:1234567894 always fails, so you can exercise your error handling. Any other unregistered recipient is skipped without an error.

A playground stays useful after you are live, too: it is the safest place to try a new invoice layout or a new integration. See how can I test without sending real invoices.

Playgrounds are separate

Playground companies are not registered on the Peppol network and playground documents never leave it, so nothing you do there affects your real company.

Register the company

You are registering one company, once, so the dashboard is the shortest path.

  1. Open Companies and start the company wizard.
  2. Fill in the legal name, address and country, plus the identifiers described in the next section.
  3. Choose whether the company should also receive documents over Peppol, or only send them.
  4. Save. The company is registered on the Peppol network as part of this step: its identifiers and the document types for its country are set up for you.

Right after saving, the dashboard offers the verification step, which the section below covers. Note the company's ID from its detail page. Every API call for sending and receiving takes it in the path.

Rather create it from code?

The create company endpoint does exactly the same thing, and returns the company id and a verificationUrl in one response. It is worth using when company creation is part of a flow you are automating, which is likely the case if you are registering many companies. Switch the first answer above to Many companies for that version.

More than one entity?

Add each legal entity as its own company: run the wizard again. There is no per-company fee, and all of them share your document volume.

Norwegian identifiers and Peppol address

FieldNorwegian value
country"NO"
enterpriseNumberThe organisasjonsnummer, exactly 9 digits
enterpriseNumberSchemeOptional: "0192"
vatNumberOptional: NO + organisation number + MVA, for companies in the VAT register
company.json
{
  "name": "Eksempel AS",
  "address": "Storgata 1",
  "postalCode": "0155",
  "city": "Oslo",
  "country": "NO",
  "enterpriseNumber": "123456785",
  "vatNumber": "NO123456785MVA"
}

The organisation number is checked against its format and its check digit (modulo 11), and registered as the company's Peppol identifier: 0192: followed by the organisation number. The VAT number is written into the documents the company sends, but it is not registered as a Peppol identifier.

Only 0192 in ELMA

ELMA registers Norwegian organisation numbers and nothing else. A Norwegian company registered in ELMA therefore carries 0192 identifiers only: adding an identifier under another scheme, such as a GLN (0088), is refused with an error that names the scheme. Without an organisation number the company has no Peppol address, so enterpriseNumber is effectively required in Norway.

The organisation has to exist

Before a 0192 identifier is published as a receiver on the production network, the organisation number is looked up in Enhetsregisteret:

  • a number the register does not know is refused, with a message that says so;
  • a number the register has deleted is refused, with the date it was deleted.

When an organisation is deleted from Enhetsregisteret later, its 0192 identifier is removed and the company stops receiving on it. The team members get an email about it.

On the test network, organisation numbers are not looked up, so you can test with synthetic organisations.

Registering for both directions

Sending needs no registration of its own; receiving does. So register the company as a recipient, which is the default:

{
  "isSmpRecipient": true
}

What that means:

  • The company becomes findable on the Peppol network and can be delivered to through Recommand's access point, while sending its own documents out through the same access point.
  • Recipient registration is exclusive. If the company already receives through another Peppol provider, registration fails until it is deregistered there. What that takes depends on the country, which the next section covers.
  • The document types the company accepts are registered along with it, based on its country. Which ones those are is covered further down.
  • The company is only published once it is verified.

Sending first, receiving later

If the company still receives elsewhere and you do not want to move that yet, register it with isSmpRecipient: false and start with sending only. Flipping the field later publishes it as a recipient.

Registration in ELMA

A Norwegian company registered as a recipient is published in ELMA under its organisation number, with the processes its document types belong to, and with its name and contact details (name, email address and phone number) as the participant's contact. When the company's name, email address or phone number changes, the ELMA entry is updated with it.

Senders find the company the usual way, and the verify endpoint finds it shortly after it is registered.

On the test network, Norwegian companies are registered in ELMA's test environment in the same way.

Moving an existing Norwegian registration

Recipient registration is exclusive. How a Norwegian company that already receives elsewhere moves to Recommand depends on where it is registered:

  • In ELMA, through another service provider. When the verified company is registered, Recommand asks ELMA to transfer the participant to it. If ELMA does not allow the transfer, the registration fails with a message that names the organisation number, and the current provider has to transfer it to Recommand in ELMA.
  • On another SMP. The company has to be deregistered there first. ELMA does not take over participants with SML migration keys, so they do not apply to Norwegian companies.

If you do not know who the current provider is, look the organisation number up as a recipient (0192:123456785): the verify endpoint returns the SMP it is published on.

Verify the company

A company cannot exchange documents on Peppol until an authorised representative has confirmed their identity. The company object exposes this as isVerified, and it stays false until the check is done.

For Norwegian companies, the representative's authority is held against Enhetsregisteret:

  1. Open the verification URL (from the create-company response, the dashboard, or a fresh one from the verify company endpoint).
  2. Pick your name from the list. The list shows the people Enhetsregisteret names for signature (signatur) or procuration (prokura). Someone who is not on it cannot verify the company and is asked to contact support@recommand.eu. When the register lists nobody, the representative types their name instead, and it is checked the same way.
  3. Complete the identity check. When the representative may act for the company alone, isVerified flips to true and the company is published in ELMA.

Of the people on the list, a representative may act alone when the register says they can sign or hold procuration on their own, or when they hold a role with full rights, such as general manager (daglig leder), chair of the board (styrets leder) or owner of a sole proprietorship (innehaver).

When the register cannot settle it

Some cases need a person to look at them, for example a board member who may only sign together with others, or a register entry that cannot be interpreted. The identity check still runs, and the verification is then held for review by our team: isVerified stays false until it is decided, and the representative is told so during the verification.

Verifying once, in the dashboard

You have one company, and it is verified once. There is nothing here worth automating: open Companies in the dashboard, pick the company and start verification. If you are authorised to act for the company, complete the check yourself; otherwise use the button to forward the link to whoever is.

The page is self-contained and works in any browser. The person completing it does not need a Recommand account.

That is the whole step. From here on the API takes over: sending and receiving documents is what you actually integrate.

Changing identifiers resets verification

Updating the company's vatNumber or enterpriseNumber sets isVerified back to false, and the company has to be verified again before it can exchange documents.

Pick the document format

Send Peppol BIS 3 UBL, over the standard Peppol billing process. EHF Billing 3.0, the Norwegian invoice format, is Peppol BIS Billing 3.0, so there is no separate Norwegian document type to select:

What you senddoctypeId
Invoicenot needed, defaults to Peppol BIS 3 UBL
Credit notenot needed, defaults to Peppol BIS 3 UBL

Peppol BIS 3 has a rule of its own for Norwegian sellers: a VAT number, when there is one, has to be written as NO + organisation number + MVA, for example NO123456785MVA.

Before a first send to a new recipient, check that the recipient exists with the verify endpoint. That lookup also tells you whether a Norwegian buyer can receive e-invoices over Peppol at all.

Send a document

One endpoint sends everything: POST /:companyId/send. The companyId is the sender, recipient is the Peppol address of the receiver, and document is the invoice or credit note as JSON. Recommand will validate the document and generate the XML.

Already producing UBL or CII XML?

Raw XML sending is supported as well: set documentType to xml and pass the document string in document, along with the correct doctypeId. See working with raw UBL.

curl -X POST https://app.recommand.eu/api/v1/{companyId}/send \
  -u key_xxx:secret_xxx \
  -H "Content-Type: application/json" \
  -d @send-invoice.json
send-invoice.json
{
  "recipient": "0208:0123456789",
  "documentType": "invoice",
  "document": {
    "invoiceNumber": "INV-2026-001",
    "issueDate": "2026-08-17",
    "dueDate": "2026-09-16",
    "currency": "EUR",
    "buyer": {
      "name": "Customer Company",
      "street": "Customer Street 1",
      "city": "Antwerp",
      "postalZone": "2000",
      "country": "BE",
      "vatNumber": "BE0987654321"
    },
    "paymentMeans": [{ "iban": "BE68539007547034" }],
    "lines": [
      {
        "name": "Consulting Services",
        "quantity": "10.00",
        "unitCode": "HUR",
        "netPriceAmount": "100.00",
        "vat": { "category": "S", "percentage": "21.00" }
      }
    ]
  }
}

The seller block is filled in from your company when you leave it out, which is usually what you want: it keeps your registered identifiers and the document in agreement. The full field reference lives in sending invoices and sending credit notes.

Worth wiring up while you are here:

  • Validation errors. Outgoing documents are always validated. A success: false response with errors keyed by field path is a document the recipient would have rejected. Surface it wherever the data was typed.
  • Delivery outcomes. success: true confirms the send request succeeded. Check deliveryStatus and deliveries, and subscribe to delivery status webhooks for outcomes reported later.
  • Email fallback. Pass email.to with when: "on_peppol_failure" to fall back to email on Peppol failure, including one reported after the send returns, or send with recipient: null for email-only delivery. See email delivery and notifications.
  • PDFs. pdfGeneration.enabled attaches a generated PDF of the document. You can also attach an existing PDF (or other files) via attachments; see adding attachments.

For a full field reference, see sending invoices and sending credit notes.

Sending without writing code

The same send is available two other ways, and they mix freely with the API:

  • From the dashboard. Send document takes the recipient and the invoice lines, previews what the recipient will get, and remembers your usual settings. You can also drop an existing UBL or CII XML file into the upload zone if your software already produces one.
  • From your accounting or invoicing software. If you use one of the supported tools, let it do the work: your invoices flow to Recommand and out over Peppol without retyping. See integrations for the current list, including Microsoft Business Central, Exact Online, Yuki, ClearFacts, ERPNext and Harvest.

Every outgoing document is validated

Whichever route you use, Recommand validates a document before it leaves. If a field is missing or malformed, the send request returns a validation error. Track delivery separately for failures reported after sending. See the troubleshooting guide for the errors you are most likely to run into.

Document types registered for you

When you register a Norwegian company as a recipient, it is published in ELMA for the two document types of EHF Billing 3.0 (Peppol BIS Billing 3.0):

Document typeProcess
Invoice (Peppol BIS 3 UBL)urn:fdc:peppol.eu:2017:poacc:billing:01:1.0
Credit note (Peppol BIS 3 UBL)urn:fdc:peppol.eu:2017:poacc:billing:01:1.0

Anything sent to the company in one of these formats is accepted, validated, stored and handed to you. A sender who tries a document type the company is not published for gets an error before delivery, which is exactly the point of the registration.

You can add document types with the create company document type endpoint, as long as ELMA offers them. A document type that ELMA does not offer is refused with an error that names it.

Pick up incoming documents

Once the company is published as a recipient, everything sent to it arrives in Recommand automatically. There are two ways to get the documents into your own systems.

Register an endpoint once with the create webhook endpoint and events are pushed to you as they happen, document.received among them:

curl -X POST https://app.recommand.eu/api/v1/webhooks \
  -u key_xxx:secret_xxx \
  -H "Content-Type: application/json" \
  -d @create-webhook.json
create-webhook.json
{
  "url": "https://your-app.example/webhooks/recommand",
  "companyId": null,
  "secret": "your_webhook_signing_secret"
}

Pass a secret and verify the HMAC SHA-256 signature on every delivery before you trust the payload, then acknowledge with a 200 before doing the heavy processing. Both are covered in working with webhooks.

Polling the inbox

If you would rather pull, the inbox endpoint lists unread documents, and mark as read drops one off the list once your system has it. Fetch details, the original XML or a rendered PDF from the documents endpoints.

Receiving without writing code

  • In the dashboard. Incoming invoices appear under Sent and received, with the original XML, a readable rendering, attachments and the delivery history.
  • By email. Add notification email addresses per company so incoming documents land in the mailbox your bookkeeping already watches, attachments included. See email delivery and notifications.
  • In your accounting software. Forward incoming documents straight to Exact Online, Yuki, ClearFacts or another supported tool, see integrations.

Two things worth setting up early, whichever route you take:

  • Labels and suppliers to keep documents organised as volume grows, see suppliers and labels.
  • Rules to act on incoming documents automatically: forwarding, labelling, notifying, see rules.

The full picture, including retries and idempotency, is in receiving documents.

Going live

A short list before you start sending or receiving real invoices:

  • A valid subscription, so sending is not blocked. Playgrounds skip that check; production does not.
  • The company verified, with isVerified true. Until then it cannot exchange documents.
  • Errors surfaced, not swallowed. Validation errors name the field that is wrong; put that in front of whoever can fix it rather than logging it.
  • Webhook endpoint hardened, if you took that route: signature verification, a fast 200, retries and idempotency on your side.
  • One real document sent and received, ideally between two companies you control, so you have seen both ends.
  • Notification addresses set, so incoming documents also reach a mailbox somebody reads.

Tell your customers and suppliers

Once you are live, your Peppol address is public on the network: suppliers can find and reach you without any action from you. Ask customers who still email PDFs to switch, and let your accountant know where the documents now land.

Where to get help

  • Troubleshooting. Common rejections, delivery failures and validation errors are collected in the troubleshooting guide.
  • Questions. The FAQ covers Peppol, addressing, VAT and billing.
  • Email. support@recommand.eu:include the company ID and, for a delivery problem, the document ID.
  • Discord. Join the server for release announcements and quick questions.
  • Keep track of changes. New endpoints and behaviour are recorded in the changelog.