For the complete documentation index, see llms.txt. You can also append .md to any page URL to get its markdown version.
Skip to main content
For the complete documentation index, see llms.txt.

For the complete documentation index, see llms.txt

Headless flow

This guide shows you how to set up headless authentication for Norwegian BankID. This means that you can provide your own user interface within your app or website.

The headless flow supports the following authentication types:

  • Normal
  • Payment / Payment 3DS
  • Safe Conversation (Call centre)
BankID Biometric and app requirement

Please note the following requirements when using the headless flow:

  • It only supports the BankID Biometric product type (substantial level of assurance).
  • End-users must have the BankID app installed on their device to complete the authentication successfully. If end-users do not have the BankID app, an error message will be returned. In this case we recommend that you direct the end-users to the redirect flow.
  • The national identity number (nin) must be prefilled.
Feature descriptions

For an introduction to the different authentication types, see the About page.

Prerequisites

  1. Follow the steps on the Initial preparations page to establish a connection with Norwegian BankID.
  2. For the complete documentation index, see llms.txt

    Before you can start making requests to the Authentication REST API, you need to learn how to connect to it. To do this, see Connect to Signicat APIs Quick start guide.

    Ensure that you set the Authentication REST API permission for your API client. When you have obtained an access token and are ready to make an API request, return here to resume this guide.

    Learn more about the Signicat Authentication REST API

1. Build the authentication request (Create a new session)

For the complete documentation index, see llms.txt

This section describes how to make an HTTP POST request to the /sessions endpoint, to create a new session and start an authentication.

To begin the authentication flow, your application must first start a session by utilising the /sessions endpoint. The endpoint automatically creates a session when you send a request. The flow and resulting information from the transaction depends on the parameters you pass in the body.

The response from the headless authentication request returns the necessary data directly in the idpData object, which you use to drive the authentication in your own custom user interface.

To create a new session, send a POST request to https://api.signicat.com/auth/rest/sessions?signicat-accountId={accountId}.

You can find your accountId in the Signicat Dashboard.

The following sub-sections show examples and descriptions of attributes that you can include in the request.

Request example

Here are some example authentication requests for creating a new session:

For the complete documentation index, see llms.txt

{
"allowedProviders": ["nbid"],
"flow": "headless",
"additionalParameters": {
"nbid_auth_type": "NORMAL"
},
"requestedAttributes": [
"dateOfBirth",
"firstName",
"lastName",
"name",
"nin",
"idpId"
],
"prefilledInput": {
"nin": "17029012345"
}
}

If the authentication completes successfully, then the final result contains the attributes that were requested.

Attributes are described in more detail in the following sections.

Initialise authentication

To initialise a headless authentication with Norwegian BankID, you must specify the following required fields in the initial request:

For more detailed field descriptions, see the API reference.

Control the user flow (additionalParameters)

You use additionalParameters to control the headless flow:

Prefill user information (prefilledInput)

National identity number must be prefilled

When using the headless flow, you must prefill the nin (national identity number) of the user, otherwise the transaction will fail.

"prefilledInput": {"nin": "17029012345"}

For conceptual documentation about prefilling, see the eID and Wallet Hub guide > Prefilling user information.

Payment data (paymentPrefillData)

For the complete documentation index, see llms.txt

When you want the end-user to approve a payment before the authentication, you set the additional parameter nbid_auth_type to PAYMENT (as shown shown in the examples above), and you must prefill data about the payment in the paymentPrefillData object.

Mandatory

The paymentPrefillData object is mandatory for payment.

Here is an example of a complete paymentPrefillData object:

{...},
"paymentPrefillData": {
"reference": "composite-payment-1234",
"payments": [
{
"reference": "individual-payment-56",
"amount": "100",
"currency": "NOK",
"receiver": "ACME AS"
},
{
"reference": "individual-payment-78",
"amount": "200",
"currency": "NOK",
"receiver": "ACME AS"
}
]
}

These are the mandatory attributes inside the paymentPrefillData object:

User information (requestedAttributes)

You can request the following user information in the requestedAttributes object:

For the complete documentation index, see llms.txt

Response example

Here are example responses for creating a new session for a Norwegian BankID headless flow:

For the complete documentation index, see llms.txt

{
"id": "425cbb48--...",
"accountId": "a-sdge-...",
"status": "CREATED",
"idpData": {
"bindingMessage": "Snedig redning"
},
"allowedProviders": [
"nbid"
],
"flow": "headless",
"requestedAttributes": [
"dateOfBirth",
"firstName",
"lastName",
"name",
"nin",
"idpId"
],
"sessionLifetime": 1200,
"expiresAt": "2026-06-29T11:08:34.9495067+00:00"
}

The CREATED status means the end-user has not started to authenticate yet. The response also contains an idpData field, which contains necessary input data for your frontend, here to use the bindingMessage.

End-user authentication

To implement the headless flow, follow this sequence of events:

  1. Collect the national identity number (nin): Ask the end-user for their nin and validate it.
  2. Create a new session: Send the nin in the prefilledInput object of your request. This triggers a push notification to the end-user's BankID app.
  3. Share the binding message: The API response includes a bindingMessage.
    • Normal / Payment: Display this message on the screen in your app or website.
    • Safe Conversation: Display the message in your agent interface for the support agent to read aloud (PHONE) or the end-user to see in the chat interface (CHAT).
  4. User confirmation: Ask the end-user to open their BankID app. What they see next depends on the flow:
    • Normal / Safe Conversation: The app displays three different messages. The end-user must select the message that matches the one shown (or spoken) to them.
    • Payment / Payment 3DS: The app first displays one binding message, which the end-user must confirm. After confirmation, the app shows the payment details, which the end-user must confirm.
  5. Authenticate: The end-user completes the final authentication step in their BankID app (e.g., using biometrics or a PIN).

See also the high-level feature descriptions of the different flows with screen examples on the About page.

2. Obtain user information (Get session status)

For the complete documentation index, see llms.txt

Make an HTTP GET request to the /sessions endpoint to poll for information regarding the session and ongoing authentication.

Upon successful authentication, a response is returned that contains the user information requested in the "Create a new session" call carried out earlier.

Request

No data specific for Norwegian BankID needs to be provided in this request.

For the complete documentation index, see llms.txt

To get the status of a session, send a GET request to https://api.signicat.com/auth/rest/sessions/{id}.

You can find the id value in the response that was returned when you created the session.

Response

The "Get session status" response contains a status field, which indicates the current status of the session. Below you can see example responses for a successfully completed headless authentication session for the different flows:

For the complete documentation index, see llms.txt

{
"id": "91160261-...",
"accountId": "a-sdge-...",
"status": "SUCCESS",
"provider": "nbid",
"subject": {
"id": "fOthqpBQyuYxNPyuj...",
"idpId": "9578-6000-4-2595757",
"name": "Kari Nordmann",
"firstName": "Kari",
"lastName": "Nordmann",
"dateOfBirth": "1990-02-17",
"nin": {
"value": "17029012345",
"issuingCountry": "NO",
"type": "BIRTH"
}
},
"loa": "substantial",
"allowedProviders": [
"nbid"
],
"flow": "headless",
"requestedAttributes": [
"dateOfBirth",
"firstName",
"lastName",
"name",
"nin",
"idpId"
],
"sessionLifetime": 1200,
"expiresAt": "2026-06-29T14:54:14.9449404+00:00"
}

Status overview

In the session responses you will get a top level status in the status field.

For the complete documentation index, see llms.txt

What you need to do with the response

Depending on the top level status you receive in the response, you need to handle the response a bit differently:

  • For CREATED status you want to read the bindingMessage and handle the response accordingly.
  • For SUCCESS status you will find the authentication result in the subject field.
  • For ABORT status you can assume that the end-user intentionally cancelled the transaction.
  • For ERROR status you can check the error.code field to see what kind of error occurred. See more details in the Error statuses section below.
  • For CANCELLED status you or the end-user has cancelled the transaction. For more details, see the Cancel a session section below.

We recommend that you poll for status every 3 seconds until the value for status is either SUCCESS, ABORT, ERROR, or CANCELLED, at which point the session is finalized.

Error codes

Create a session (error codes)

These are the error codes you might get from "Create a session":

idp:nbid:user-does-not-exist

The provided NIN could not be verified to belong to a user with a valid BankID app.

Recommended action: See the detail of the error message. If the end-user does not have the BankID app, we recommend that you direct the end-users to the redirect flow.

Example:

{
"status": 400,
"code": "idp:nbid:user-does-not-exist",
"title": "The user does not exist",
"detail": "The user is not registered with a BankID App or one that is sufficiently up to date",
"type": "https://developer.signicat.com/identity-methods/nbid/errors.html#idp:nbid:user-does-not-exist",
"traceId": "759141deb360964de14288365fbc2398"
}
idp:request-validation-failed

Something in the request to start the session was invalid.

Recommended action: See the detail of the error message for the specific field that could not be verified.

Example:

{
"status": 400,
"code": "idp:request-validation-failed",
"title": "Validation of request failed",
"detail": "Some detail specifying what in the request was invalid",
"type": "https://signicat.atlassian.net/wiki/spaces/HUB/pages/193592885339/Error+codes#idp:request-validation-failed",
"traceId": "7fc6f75104e124d3003d718672a1926f"
}
unexpected_error

Something unexpected went wrong. This can be any number of things.

Recommended action: Retry the session creation.

Example:

{
"status": 500,
"code": "unexpected_error",
"title": "An unexpected error has occurred.",
"type": "https://developer.signicat.com/docs/dashboard/error-codes/",
"traceId": "7c16b67eac18a90853b0a3263a5a4421"
}

Get session status (error codes)

You might get the following error code from "Get session status":

idp:nbid:unknown-error

Something unexpected went wrong. This can be any number of things.

Recommended action: Retry the session creation.

Example:

{
"id": "cfa3d4f3-fd38-41f5-a1fc-a59400271b4b",
"accountId": "a-sdge-oyNgetJTcOc5ba7Sj5ZR",
"status": "ERROR",
"error": {
"type": "https://signicat.atlassian.net/wiki/spaces/HUB/pages/193592885339/Error+codes#idp:nbid:unknown-error",
"title": "Unknown error",
"detail": "An unknown error occurred",
"code": "idp:nbid:unknown-error"
},
"allowedProviders": [
"nbid"
],
"flow": "headless",
"requestedAttributes": [
"dateOfBirth",
"firstName",
"lastName",
"idpId",
"nin"
],
"sessionLifetime": 1200,
"expiresAt": "2026-08-19T11:45:13.9869903+00:00"
}

Cancel a session (optional)

You can stop an ongoing authentication session by using the Cancel Authentication Session endpoint.

This is useful if you want to:

  • Provide a way for your end-users to cancel the transaction, both at Signicat and Norwegian BankID (via a link/button). It is especially useful if you lock the transaction to a particular national identity number.
  • Cancel an ongoing transaction for a particular national identity number before starting a new transaction for the same person.

A successful cancellation returns 200 OK of type CANCELLED.

Example response

{
"id": "3d07c219-0a88-45be-9cfc-91e9d095a1e9",
"accountId": "string",
"status": "CANCELLED",
"provider": "nbid",
...
}

Next steps

Dive deeper into Authentication REST API and improve your application with advanced security features: