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

# Finvoice supplier registration guide

> Register Finnish parties so they can send and receive e-invoices.

export const fiFinvoiceRegisterWorkflow = {
  "name": "Finvoice register party",
  "description": "Register a Finnish party so it can send and receive e-invoices",
  "schema": "org/party",
  "steps": [{
    "id": "bc177ef2-9172-11f1-8c54-92000767c8b7",
    "name": "Set state",
    "provider": "silo.state",
    "summary": "Set state to `processing`{.state .processing}",
    "config": {
      "state": "processing"
    }
  }, {
    "id": "bc177f3b-9172-11f1-8204-92000767c8b7",
    "name": "Register party in Finland",
    "provider": "gov-fi.register"
  }, {
    "id": "bc177f7d-9172-11f1-bb70-92000767c8b7",
    "name": "Set state",
    "provider": "silo.state",
    "summary": "Set state to `registered`{.state .registered}",
    "config": {
      "state": "registered"
    }
  }],
  "rescue": [{
    "id": "bc177fc4-9172-11f1-a165-92000767c8b7",
    "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-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

Finland has no government clearance system: e-invoices travel through accredited operators, and every sender and receiver works through an operator account. The [Finland app](/apps/finland)'s registration provisions each of your Finnish parties its **own** account with Invopop's operator partner, activates its services, and allocates its e-invoice address.

A party must be registered before it can send or receive anything; there is no shared account to work through. A workspace can hold several Finnish parties, each registered and polled on its own.

Once a supplier is registered, continue with the companion guide: [Finvoice issuing invoices](/guides/fi-finvoice).

| -               | Sandbox                                            | Live                                                                       |
| --------------- | -------------------------------------------------- | -------------------------------------------------------------------------- |
| **Party**       | Registered against the operator's test environment | Not yet available (production access is being finalised with the operator) |
| **Environment** | Operator sandbox                                   | Not yet available                                                          |

## Prerequisites

* **The party's details**: legal name, Business ID (*y-tunnus*, e.g. `2617416-4`), and a Finnish address. The Business ID is uploaded without its hyphen as the GOBL `tax_id.code`.
* **Reception workflows configured**: registration checks that the Finland app has a sync and an import workflow configured, and fails with "reception not configured" otherwise. Follow the [receiving guide's setup](/guides/fi-finvoice-receiving#setup) first.

## E-invoice addresses

A Finnish e-invoice address is an **OVT code**: `0037` followed by the Business ID without its hyphen, sometimes with a five-character suffix for routing inside large organisations. For example, the Business ID `2617416-4` gives the OVT code `003726174164`. On Peppol, the same code is wrapped in scheme `0216`.

Registration allocates the party's address on the operator's side, so you don't need to provide one. Counterparties will ask for it, though, and you'll need your customers' addresses to send. Look any Finnish organisation up in the national registry at [verkkolaskuosoite.fi](https://verkkolaskuosoite.fi): since 2024 it mirrors the Peppol address list too, so one lookup covers both networks.

You may also meet other address forms that circulate on the Finnish network: IBAN-style addresses from the older bank channel, and operator-prefixed ones such as `TE0037…`. On party records, always use the OVT code under scheme `0216`.

## Setup

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

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

  <Step title="Set up reception">
    <Info>Registration requires the reception workflows to be configured first, because a registered party's inbox starts being polled right away. Create the sync and import workflows and configure them on the app as described in the [receiving guide](/guides/fi-finvoice-receiving#setup), then come back here.</Info>
  </Step>

  <Step title="Create the registration workflow">
    <Tabs>
      <Tab title="Workflow">
        <WorkflowDiagram workflow={fiFinvoiceRegisterWorkflow} />
      </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 Finvoice register party workflow theme={"system"}
        {
            "name": "Finvoice register party",
            "description": "Register a Finnish party so it can send and receive e-invoices",
            "schema": "org/party",
            "steps": [
                {
                    "id": "bc177ef2-9172-11f1-8c54-92000767c8b7",
                    "name": "Set state",
                    "provider": "silo.state",
                    "summary": "Set state to `processing`{.state .processing}",
                    "config": {
                        "state": "processing"
                    }
                },
                {
                    "id": "bc177f3b-9172-11f1-8204-92000767c8b7",
                    "name": "Register party in Finland",
                    "provider": "gov-fi.register"
                },
                {
                    "id": "bc177f7d-9172-11f1-bb70-92000767c8b7",
                    "name": "Set state",
                    "provider": "silo.state",
                    "summary": "Set state to `registered`{.state .registered}",
                    "config": {
                        "state": "registered"
                    }
                }
            ],
            "rescue": [
                {
                    "id": "bc177fc4-9172-11f1-a165-92000767c8b7",
                    "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 party's details. The example below shows the fields a Finnish party carries; for registration, the name and the y-tunnus are what matter:

    ```json Finland supplier example expandable theme={"system"}
    {
        "$schema": "https://gobl.org/draft-0/org/party",
        "name": "Aurora Ohjelmistot Oy",
        "tax_id": {
            "country": "FI",
            "code": "26174164"
        },
        "inboxes": [
            {
                "key": "peppol",
                "scheme": "0216",
                "code": "003726174164"
            }
        ],
        "addresses": [
            {
                "num": "12",
                "street": "Mannerheimintie",
                "locality": "Helsinki",
                "code": "00100",
                "country": "FI"
            }
        ],
        "emails": [
            {
                "addr": "laskutus@auroraohjelmistot.fi"
            }
        ]
    }
    ```
  </Step>

  <Step title="Run the registration workflow">
    Run the registration workflow on the party's silo entry, from the Console or [via the API](/api-ref/transform/jobs/create-a-job-post).
  </Step>

  <Step title="Wait for the registration to complete">
    Registration finds or creates the party's company under Invopop's partner account at the operator, activates its services, and waits until the operator reports every service in force and the party's e-invoice address allocated. Until then the job stays queued rather than reporting success on an account that can't yet receive.
  </Step>
</Steps>

Once registration completes, the party can send and receive e-invoices, and its inbox at the operator starts being polled automatically.

<Note>
  The party's e-invoice address works from the moment registration completes, but the [national registry](https://verkkolaskuosoite.fi) counterparties look addresses up in is refreshed once a night. Expect the party to become findable there the following day.
</Note>

<Warning>
  There is no self-serve deregistration yet. To offboard a party, contact [support@invopop.com](mailto:support@invopop.com).
</Warning>

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

## FAQ

<AccordionGroup>
  <Accordion title="How do I register a Finnish supplier?">
    Upload the supplier as a GOBL party with `tax_id.country = FI` and the Business ID (y-tunnus), then run the [Finland app](/apps/finland)'s registration workflow. Registration provisions the party its own operator account and allocates its e-invoice address — a party must be registered before it can send or receive anything. See the [supplier registration guide](/guides/fi-finvoice-supplier).
  </Accordion>

  <Accordion title="What Peppol scheme does Finland use for participant IDs?">
    Scheme `0216`, wrapping the party's OVT code — `0037` followed by the Business ID without its hyphen. Under Finland's Peppol Authority Specific Requirements, the OVT code is the mandatory participant identifier for Finnish organisations on Peppol. The `0037` at the start of the code itself is a country prefix, not the scheme.
  </Accordion>

  <Accordion title="What is a Finnish e-invoice address?">
    An OVT code: `0037` followed by the party's Business ID (y-tunnus) without its hyphen, sometimes with a five-character suffix for routing inside large organisations (for example `003726174164`). On Peppol, the same code is wrapped in scheme `0216` (`0216:003726174164`). You can look any counterparty up in the national registry at [verkkolaskuosoite.fi](https://verkkolaskuosoite.fi): since 2024 it mirrors the Peppol address list too, so one lookup covers both networks.
  </Accordion>

  <Accordion title="Which address form should I put on a party record?">
    The OVT code, as an inbox with scheme `0216`. Other forms circulate on the Finnish network (IBAN-style addresses from the older bank channel, operator-prefixed ones such as `TE0037…`), but the OVT code is the canonical form, and it's what the routing pre-check and the generated e-invoice use.
  </Accordion>

  <Accordion title="Why hasn't my party's registration completed yet?">
    Registration provisions the party its own account with the operator, and it only completes once every service is in force and the party's e-invoice address has been allocated on the operator's side. Until then the registration job stays queued rather than reporting success on an account that can't yet receive.
  </Accordion>

  <Accordion title="Can I register several Finnish parties in one workspace?">
    Yes. Each party gets its own operator account, its own e-invoice address, and its own reception polling schedule. Register each one separately by running the registration workflow on its party record.
  </Accordion>
</AccordionGroup>

More available in our [Finland FAQ](/faq/finland) section

***

<AccordionGroup>
  <Accordion title="🇫🇮 Invopop resources for Finland">
    |            |                                                                                                                                                                                                                                                                                        |
    | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | Compliance | <Icon icon="https://assets.invopop.com/flags/fi.svg" /> [Invoicing compliance in Finland](/compliance/finland)<br /> <Icon icon="timeline" /> [Compliance timeline](/timelines/finland)                                                                                                |
    | Apps       | <Icon icon="https://assets.invopop.com/flags/fi.svg" /> [Finland](/apps/finland)<br /> <Icon icon="https://assets.invopop.com/apps/peppol/icon.svg" /> [Peppol](/apps/peppol)                                                                                                          |
    | Guides     | <Icon icon="book" /> [Supplier registration](/guides/fi-finvoice-supplier)<br /> <Icon icon="book" /> [Issuing invoices](/guides/fi-finvoice)<br /> <Icon icon="book" /> [Receiving invoices](/guides/fi-finvoice-receiving)<br /> <Icon icon="book" /> [Peppol guide](/guides/peppol) |
    | FAQ        | <Icon icon="square-question" /> [Finland FAQ](/faq/finland)                                                                                                                                                                                                                            |
    | GOBL       | <Icon icon="https://assets.invopop.com/icons/gobl.svg" /> [Finland Tax Regime](https://docs.gobl.org/regimes/fi)<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.fi.finvoice](https://github.com/invopop/gobl.fi.finvoice)<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 Finland →
</Card>
