> ## Documentation Index
> Fetch the complete documentation index at: https://invopop-dk.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# NemHandel supplier registration guide

> Register suppliers on the NemHandel network to send and receive invoices in Denmark.

export const dkUnregisterWorkflow = {
  "name": "Unregister from NemHandel",
  "description": "Release a party's NemHandel registration so it no longer sends or receives invoices",
  "schema": "org/party",
  "steps": [{
    "id": "b0ebea5e-8907-11f1-8000-920007eb4d91",
    "name": "Set state",
    "provider": "silo.state",
    "summary": "Set state to `processing`{.state .processing}",
    "config": {
      "state": "processing"
    }
  }, {
    "id": "b0ec50f2-8907-11f1-8000-920007eb4d91",
    "name": "Unregister party from NemHandel",
    "provider": "gov-dk.unregister"
  }, {
    "id": "b0ecc1fe-8907-11f1-8000-920007eb4d91",
    "name": "Set state",
    "provider": "silo.state",
    "summary": "Set state to `void`{.state .void}",
    "config": {
      "state": "void"
    }
  }],
  "rescue": [{
    "id": "b0ed13f2-8907-11f1-8000-920007eb4d91",
    "name": "Set state",
    "provider": "silo.state",
    "summary": "Set state to `error`{.state .error}",
    "config": {
      "state": "error"
    }
  }]
};

export const dkRegisterWorkflow = {
  "name": "NemHandel register party",
  "description": "Register a party to send and receive invoices via NemHandel",
  "schema": "org/party",
  "steps": [{
    "id": "c3e2b400-4f6a-11f1-9c2d-0242ac120012",
    "name": "Set state",
    "provider": "silo.state",
    "summary": "Set state to `processing`{.state .processing}",
    "config": {
      "state": "processing"
    }
  }, {
    "id": "e3af78f6-88d1-11f1-8000-920007eb4d91",
    "name": "Sign agreement for Denmark",
    "provider": "gov-dk.sign"
  }, {
    "id": "e3af9d5e-88d1-11f1-8000-920007eb4d91",
    "name": "Wait for Denmark agreement approval",
    "provider": "gov-dk.wait.approval"
  }, {
    "id": "c3e2b401-4f6a-11f1-9c2d-0242ac120012",
    "name": "Register party with NemHandel",
    "provider": "gov-dk.register"
  }, {
    "id": "c3e2b402-4f6a-11f1-9c2d-0242ac120012",
    "name": "Set state",
    "provider": "silo.state",
    "summary": "Set state to `registered`{.state .registered}",
    "config": {
      "state": "registered"
    }
  }],
  "rescue": [{
    "id": "c3e2b403-4f6a-11f1-9c2d-0242ac120012",
    "name": "Set state",
    "provider": "silo.state",
    "summary": "Set state to `error`{.state .error}",
    "config": {
      "state": "error"
    }
  }]
};

export const WorkflowDiagram = ({workflow}) => {
  const stateColors = {
    processing: "yellow",
    sent: "blue",
    received: "blue",
    registered: "green",
    completed: "green",
    error: "red"
  };
  const StateChip = ({state, label}) => <Badge size="sm" color={stateColors[state] || "gray"} icon="square-small" iconType="solid">
      {label.charAt(0).toUpperCase() + label.slice(1)}
    </Badge>;
  const providerIcons = {
    "silo.state": "https://silo.invopop.com/images/status.svg",
    "silo.close": "https://silo.invopop.com/images/check-badge.svg",
    "silo.if": "https://assets.invopop.com/apps/silo/if.svg",
    "silo.folder": "https://silo.invopop.com/images/folder.svg",
    "silo.modify": "https://silo.invopop.com/images/modify.svg",
    "silo.correct": "https://silo.invopop.com/images/replace.svg",
    "silo.sleep": "https://assets.invopop.com/icons/sleep.svg",
    silo: "https://assets.invopop.com/apps/silo/icon.svg",
    "sequence.enumerate": "https://sequence.invopop.com/images/enumerate.svg",
    "transform.job.create": "https://transform.invopop.com/images/jobs.svg",
    webhook: "https://webhook.invopop.com/icon.svg",
    lookup: "https://lookup.invopop.com/icon.png",
    dropbox: "https://dropbox.invopop.com/icon.png",
    pdf: "https://pdf.invopop.com/file-pdf.svg",
    peppol: "https://assets.invopop.com/apps/peppol/icon.svg",
    ubl: "https://assets.invopop.com/apps/ubl/logo.svg",
    cii: "https://assets.invopop.com/apps/cii/logo.svg",
    "gov-dk": "https://assets.invopop.com/flags/dk.svg",
    "gov-fi": "https://assets.invopop.com/flags/fi.svg",
    "gov-fr": "https://assets.invopop.com/flags/fr.svg",
    "chorus-pro": "https://assets.invopop.com/apps/chroruspro/icon.svg",
    "gov-es": "https://assets.invopop.com/apps/gov-es/icon.svg",
    "gov-es.sii": "https://assets.invopop.com/apps/sii/icon.svg",
    "gov-es.ticketbai": "https://assets.invopop.com/apps/ticketbai/icon.svg",
    "gov-es.facturae": "https://assets.invopop.com/apps/facturae/icon.svg",
    verifactu: "https://assets.invopop.com/apps/verifactu/icon.svg",
    "gov-pl": "https://assets.invopop.com/apps/ksef/icon.svg",
    "gov-sa": "https://assets.invopop.com/apps/zatca/icon.svg",
    "gov-ar": "https://assets.invopop.com/apps/arca/icon.svg",
    "at-pt": "https://assets.invopop.com/apps/at-pt/icon.svg",
    "sat-mx": "https://assets.invopop.com/apps/sat-mexico/icon.svg",
    "sw-sapien": "https://assets.invopop.com/apps/sw-sapien/icon.svg",
    "sdi-it": "https://assets.invopop.com/apps/sdi-italy/icon.svg",
    "ticket-it": "https://assets.invopop.com/apps/agenzia-entrate/icon.svg",
    "nfe-br": "https://assets.invopop.com/apps/notas-fiscais-eletronicas-brazil/icon.svg",
    chargebee: "https://assets.invopop.com/apps/chargebee/icon.svg",
    stripe: "https://assets.invopop.com/apps/stripe/icon.svg",
    email: "https://assets.invopop.com/apps/email/icon.svg",
    cron: "https://assets.invopop.com/apps/cron/icon.svg",
    ilyda: "https://assets.invopop.com/apps/ilyda/icon.svg",
    invoicexpress: "https://assets.invopop.com/apps/invoicexpress/icon.svg",
    plemsi: "https://assets.invopop.com/flags/co.svg"
  };
  const iconFor = provider => {
    const parts = (provider || "").split(".");
    for (let i = parts.length; i > 0; i--) {
      const url = providerIcons[parts.slice(0, i).join(".")];
      if (url) return url;
    }
    return null;
  };
  const StepIcon = ({provider}) => {
    const url = iconFor(provider);
    return <span title={provider} className="flex h-7 w-7 shrink-0 items-center justify-center rounded-md border border-gray-950/10 bg-white dark:border-white/10 dark:bg-white/5">
        {url ? <img src={url} alt="" className="h-4 w-4" /> : null}
      </span>;
  };
  const renderSummary = summary => {
    const nodes = [];
    const re = /`([^`]+)`(\{[^}]*\})?/g;
    let last = 0;
    let m;
    let k = 0;
    while ((m = re.exec(summary)) !== null) {
      if (m.index > last) nodes.push(summary.slice(last, m.index));
      const attrs = m[2] || "";
      if (attrs.indexOf(".state") >= 0) {
        const state = (attrs.match(/\.state\s+\.([\w-]+)/) || [])[1] || m[1];
        nodes.push(<StateChip key={k++} state={state} label={m[1]} />);
      } else if (attrs) {
        nodes.push(<span key={k++} className="text-sm font-medium text-gray-700 dark:text-gray-300">
            {m[1]}
          </span>);
      } else {
        nodes.push(<code key={k++} className="text-sm rounded bg-gray-100 px-1 font-mono text-sm dark:bg-white/10">
            {m[1]}
          </code>);
      }
      last = m.index + m[0].length;
    }
    if (last < summary.length) nodes.push(summary.slice(last));
    return nodes;
  };
  const NoteRow = ({text}) => <div className="mt-4 mb-1 font-mono text-sm leading-5 text-gray-400 dark:text-gray-500">{"// " + text}</div>;
  const renderSteps = (steps, counter) => (steps || []).map(step => {
    counter.n += 1;
    const n = counter.n;
    const branches = (step.next || []).filter(b => b.steps && b.steps.length > 0);
    return <div key={step.id || "step-" + n}>
          {step.notes ? <NoteRow text={step.notes} /> : null}
          <div className="mt-2.5 flex items-center">
            <span className="absolute left-0 w-10 text-center font-mono text-sm text-gray-400 select-none dark:text-gray-500">
              {n}
            </span>
            <div className="flex min-w-0 flex-1 items-center gap-2 rounded-xl border border-gray-950/5 bg-white px-2 py-2 dark:border-white/10 dark:bg-gray-900">
              <StepIcon provider={step.provider} />
              <span className="text-sm shrink-0 font-medium text-gray-900 dark:text-gray-100">{step.name}</span>
              {step.summary ? <span className="text-sm min-w-0 truncate text-gray-500 dark:text-gray-400">{renderSummary(step.summary)}</span> : null}
            </div>
          </div>
          {branches.length > 0 ? <div className="ml-5 border-l border-gray-200 -my-1 py-1 pl-6 dark:border-white/10">
              {branches.map((branch, bi) => <div key={branch.code || branch.status || bi}>
                  <div className="mt-4">
                    <span className="rounded-md bg-gray-200/70 px-2 py-1 font-mono text-sm text-gray-600 dark:bg-white/10 dark:text-gray-300">
                      {branch.code || branch.status}
                    </span>
                  </div>
                  {renderSteps(branch.steps, counter)}
                </div>)}
            </div> : null}
        </div>;
  });
  const counter = {
    n: 0
  };
  const wf = workflow || ({});
  return <div className="not-prose relative my-5 rounded-2xl border border-gray-950/5 bg-gray-50 py-3 pr-4 pb-5 pl-12 dark:border-white/10 dark:bg-white/[0.03]">
      {renderSteps(wf.steps, counter)}
      {wf.rescue && wf.rescue.length > 0 ? <div className="mt-6 border-t border-dashed border-gray-300 dark:border-white/10">
          <NoteRow text="If any step fails" />
          {renderSteps(wf.rescue, counter)}
        </div> : null}
    </div>;
};

## Introduction

[NemHandel](https://erhvervsstyrelsen.dk/nemhandel) is Denmark's national e-invoicing network, managed by the Danish Business Authority (Erhvervsstyrelsen). Invoicing Danish public authorities through it has been mandatory since 2005, and Danish businesses use the same network for B2B invoices.

Before a supplier can send or receive invoices on the network through Invopop's NemHandel access point, the supplier must be registered as a NemHandel participant, which requires its representative to sign an authorization agreement. This guide walks you through that onboarding process. Once a supplier is registered, continue with the companion guide: [Denmark: Issuing invoices](/guides/dk-nemhandel).

| -               | Sandbox                                 | Live                                    |
| --------------- | --------------------------------------- | --------------------------------------- |
| **Environment** | Official NemHandel test network         | NemHandel production                    |
| **Agreement**   | Signed by the supplier's representative | Signed by the supplier's representative |

<Note>
  The authorization agreement must be signed in both environments — the sandbox targets NemHandel's official test network and follows the same signing and approval flow as production.
</Note>

## Prerequisites

To register a supplier in Denmark, you will need:

* Supplier details, including the company name, CVR number (8-digit Danish business registration number), address, and a contact email.
* The supplier's representative — someone with signing authority, such as a director — available to sign the NemHandel authorization agreement online.

## Setup

All of the following steps must be carried out from the [Invopop Console](https://console.invopop.com).

<Steps>
  <Step title="Connect the NemHandel Denmark app">
    1. Navigate to **Configuration** → **Apps**
    2. Find **NemHandel Denmark** in the app discovery list
    3. Click **Connect** to activate

    See the [NemHandel Denmark app](/apps/nemhandel-denmark) page for the full list of actions it provides.
  </Step>

  <Step title="Create the registration workflow">
    <Card iconType="duotone" title="NemHandel register party workflow" icon="code-branch" href="https://console.invopop.com/redirect/workflows/new?template=dk-dk-register" horizontal>
      Add to my workspace →
    </Card>

    <Tabs>
      <Tab title="Workflow">
        <WorkflowDiagram workflow={dkRegisterWorkflow} />
      </Tab>

      <Tab title="Code">
        Copy and paste into a new [Empty Party workflow](https://console.invopop.com/redirect/workflows/new?template=empty-party) code view.

        ```json Example NemHandel register party workflow theme={"system"}
        {
            "name": "NemHandel register party",
            "description": "Register a party to send and receive invoices via NemHandel",
            "schema": "org/party",
            "steps": [
                {
                    "id": "c3e2b400-4f6a-11f1-9c2d-0242ac120012",
                    "name": "Set state",
                    "provider": "silo.state",
                    "summary": "Set state to `processing`{.state .processing}",
                    "config": {
                        "state": "processing"
                    }
                },
                {
                    "id": "e3af78f6-88d1-11f1-8000-920007eb4d91",
                    "name": "Sign agreement for Denmark",
                    "provider": "gov-dk.sign"
                },
                {
                    "id": "e3af9d5e-88d1-11f1-8000-920007eb4d91",
                    "name": "Wait for Denmark agreement approval",
                    "provider": "gov-dk.wait.approval"
                },
                {
                    "id": "c3e2b401-4f6a-11f1-9c2d-0242ac120012",
                    "name": "Register party with NemHandel",
                    "provider": "gov-dk.register"
                },
                {
                    "id": "c3e2b402-4f6a-11f1-9c2d-0242ac120012",
                    "name": "Set state",
                    "provider": "silo.state",
                    "summary": "Set state to `registered`{.state .registered}",
                    "config": {
                        "state": "registered"
                    }
                }
            ],
            "rescue": [
                {
                    "id": "c3e2b403-4f6a-11f1-9c2d-0242ac120012",
                    "name": "Set state",
                    "provider": "silo.state",
                    "summary": "Set state to `error`{.state .error}",
                    "config": {
                        "state": "error"
                    }
                }
            ]
        }
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Create the unregistration workflow">
    <Info>You can skip this step if you don't plan to unregister suppliers.</Info>

    <Card iconType="duotone" title="Unregister from NemHandel workflow" icon="code-branch" href="https://console.invopop.com/redirect/workflows/new?template=dk-dk-unregister" horizontal>
      Add to my workspace →
    </Card>

    <Tabs>
      <Tab title="Workflow">
        <WorkflowDiagram workflow={dkUnregisterWorkflow} />
      </Tab>

      <Tab title="Code">
        Copy and paste into a new [Empty Party workflow](https://console.invopop.com/redirect/workflows/new?template=empty-party) code view.

        ```json Example unregister from NemHandel theme={"system"}

        {
            "name": "Unregister from NemHandel",
            "description": "Release a party's NemHandel registration so it no longer sends or receives invoices",
            "schema": "org/party",
            "steps": [
                {
                    "id": "b0ebea5e-8907-11f1-8000-920007eb4d91",
                    "name": "Set state",
                    "provider": "silo.state",
                    "summary": "Set state to `processing`{.state .processing}",
                    "config": {
                        "state": "processing"
                    }
                },
                {
                    "id": "b0ec50f2-8907-11f1-8000-920007eb4d91",
                    "name": "Unregister party from NemHandel",
                    "provider": "gov-dk.unregister"
                },
                {
                    "id": "b0ecc1fe-8907-11f1-8000-920007eb4d91",
                    "name": "Set state",
                    "provider": "silo.state",
                    "summary": "Set state to `void`{.state .void}",
                    "config": {
                        "state": "void"
                    }
                }
            ],
            "rescue": [
                {
                    "id": "b0ed13f2-8907-11f1-8000-920007eb4d91",
                    "name": "Set state",
                    "provider": "silo.state",
                    "summary": "Set state to `error`{.state .error}",
                    "config": {
                        "state": "error"
                    }
                }
            ]
        }
        ```
      </Tab>
    </Tabs>
  </Step>
</Steps>

## Register a supplier

<Steps>
  <Step title="Upload the party">
    Create a silo entry with the supplier's `org/party` document, either by pasting it in the Console or via the [API](/api-ref/silo/entries/create-an-entry-put). A Danish CVR number in the `tax_id` is enough — the NemHandel participant identifier is derived from it automatically:

    ```json Denmark supplier example theme={"system"}
    {
        "$schema": "https://gobl.org/draft-0/org/party",
        "name": "Tavleleverandøren ApS",
        "tax_id": {
            "country": "DK",
            "code": "16356700"
        },
        "people": [
            {
                "name": {
                    "given": "Hugo Jensen"
                }
            }
        ],
        "addresses": [
            {
                "num": "11",
                "street": "Leverandørvej",
                "locality": "Dyssegård",
                "code": "2870",
                "country": "DK"
            }
        ],
        "emails": [
            {
                "addr": "faktura@tavleleverandoren.dk"
            }
        ]
    }
    ```
  </Step>

  <Step title="Run the registration workflow">
    Run the **NemHandel register party** workflow on the party entry. The workflow publishes a public **signing link** in the entry's meta section and pauses.
  </Step>

  <Step title="Have the representative sign the agreement">
    Share the signing link with the supplier's representative. They fill in their full name, their role in the company, and a contact email, then sign the authorization agreement by typing or drawing their signature.
  </Step>

  <Step title="Wait for approval">
    Once signed, the agreement is submitted for approval. The workflow resumes automatically when it is approved, registers the supplier as a NemHandel participant, and sets the entry's state to `registered`. From that point the supplier can send invoices and receive documents addressed to its participant identifier.
  </Step>
</Steps>

## Unregister a supplier

To take a supplier off the network, run the **Unregister from NemHandel** workflow on the same party entry. It releases the participant registration so the supplier no longer sends or receives invoices through Invopop, and sets the entry's state to `void`.

<Warning>
  Unregistering removes the participant from the NemHandel registry, so the supplier stops sending and receiving invoices immediately. To onboard the supplier again, run the registration workflow on the same party entry — the signed authorization agreement is reused, so the representative doesn't need to sign again.
</Warning>

At this point, you're ready to start sending invoices on behalf of the supplier. Head over to the [Denmark issuing invoices guide](/guides/dk-nemhandel) to continue.

## FAQ

<AccordionGroup>
  <Accordion title="What is the NemHandel authorization agreement?">
    Before a company can be registered on NemHandel, its representative must sign an authorization agreement allowing Invopop and its NemHandel access point to exchange documents on the company's behalf. The registration workflow publishes a public signing link on the party entry; the representative opens it, fills in their name, role, and contact email, signs, and the agreement is submitted for approval. The workflow waits until the agreement is approved before registering the participant.
  </Accordion>

  <Accordion title="Who should sign the agreement?">
    Someone entitled to represent the company — typically a director or another person with signing authority. The signer provides their full name, their role in the company, and a contact email, and can sign by typing or drawing their signature.
  </Accordion>

  <Accordion title="Can I run the registration workflow more than once?">
    Yes. The registration steps are safe to re-run: an already-signed agreement or an already-registered participant is detected and skipped, so retrying a failed or interrupted registration won't create duplicates.
  </Accordion>
</AccordionGroup>

More available in our [Denmark FAQ](/faq/denmark) section

***

<AccordionGroup>
  <Accordion title="🇩🇰 Invopop resources for Denmark">
    |            |                                                                                                                                                                                                                                                                                        |
    | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | Compliance | <Icon icon="https://assets.invopop.com/flags/dk.svg" /> [Invoicing compliance in Denmark](/compliance/denmark)<br /> <Icon icon="timeline" /> [Compliance timeline](/timelines/denmark)                                                                                                |
    | Apps       | <Icon icon="https://assets.invopop.com/flags/dk.svg" /> [NemHandel Denmark](/apps/nemhandel-denmark)<br /> <Icon icon="https://assets.invopop.com/apps/peppol/icon.svg" /> [Peppol](/apps/peppol)                                                                                      |
    | Guides     | <Icon icon="book" /> [Supplier registration guide](/guides/dk-nemhandel-supplier)<br /> <Icon icon="book" /> [Issuing invoices guide](/guides/dk-nemhandel)<br /> <Icon icon="book" /> [Peppol guide](/guides/peppol)<br /> <Icon icon="book" /> [Chargebee guide](/guides/cb-denmark) |
    | FAQ        | <Icon icon="square-question" /> [Denmark FAQ](/faq/denmark)                                                                                                                                                                                                                            |
    | GOBL       | <Icon icon="https://assets.invopop.com/icons/gobl.svg" /> [Denmark Tax Regime](https://docs.gobl.org/regimes/dk)<br /> <Icon icon="https://assets.invopop.com/icons/gobl.svg" /> [EU EN 16931 Addon](https://docs.gobl.org/addons/eu-en16931-v2017)                                    |
    | GitHub     | <Icon icon="github" /> [gobl.dk.oioubl](https://github.com/invopop/gobl.dk.oioubl)<br /> <Icon icon="github" /> [gobl.ubl](https://github.com/invopop/gobl.ubl)                                                                                                                        |
  </Accordion>
</AccordionGroup>

<Card title="Participate in our community" icon="forumbee" href="https://community.invopop.com" arrow="true" horizontal>
  Ask and answer questions about invoicing in Denmark →
</Card>
