Headless flow
This page details how to set up headless authentication for Swedish BankID. This means that you can provide your own user interface within your app or website.
Set up the API client
1. Get client credentials
Before you can make a request to the Authentication REST API, you need to set up an API client to obtain client credentials. How to do this is described in Accessing Signicat API products > Set up an API client.
2. Obtain access token
You use the client credentials in a request to obtain an access token. The access token needs to be passed in as an HTTP Bearer authentication header when sending the requests. For more details, see Accessing Signicat API products > Obtaining an access token.
The access token needs to be passed in as an HTTP Bearer authentication header when sending the requests.
Implement the authentication flow
1. Build the authentication request (CreateSession)
This section describes how to send a request to the CreateSession endpoint, to create a session and start an authentication.
To begin the authentication flow, your application must first start a session by utilising the CreateSession endpoint. The endpoint will automatically create 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 this endpoint will contain an authentication URL, to which you can redirect the end-user to start their transaction.
To create a 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: QR code flow
Here is an example request body for a headless authentication, using the QR code flow. This example also applies to the App Launch flow (just replace QR
with APP_LAUNCH
). If the authentication completes successfully, the final result will contain the attributes that were requested.
{
"allowedProviders": ["sbid"],
"flow": "headless",
"additionalParameters": {
"sbid_flow": "QR",
"sbid_end_user_ip": "123.123.123.123",
"sbid_intention_text": "VGVzdCBpbnRlbnRpb24gdGV4dAo="
},
"prefilledInput": {
"nin": "1234567890"
},
"requestedAttributes": [
"name",
"firstName",
"lastName",
"dateOfBirth",
"nin"
]
}
Request example: Phone flow
When using the Phone flow, you must prefill the nin
(national identity number) of the user, otherwise the transaction will fail. You can prefill nin
in the prefilledInput
object in the request. See Prefill user information for more information.
Here is an example request body for headless authentication, using the Phone flow:
{
"allowedProviders": ["sbid"],
"flow": "headless",
"additionalParameters": {
"sbid_auth_type": "PHONE",
"sbid_phone_initiator": "OPERATOR"
},
"requestedAttributes": [
"name",
"firstName",
"lastName",
"nin",
"dateOfBirth",
"sbidAge",
"sbidOcspResponse",
"sbidXmlSignature",
"sbidOcspResponderId",
"sbidVerificationTime",
"sbidVerificationSignature"
],
"prefilledInput": {
"nin": "196809179176"
}
}
Field descriptions
To initialise a headless authentication with BankID, you must specify the following required fields in the initial request:
Field | Required | Example value | Description |
---|---|---|---|
allowedProviders | Yes | ["sbid"] | MUST have the value ["sbid"] . |
flow | Yes | headless | MUST have the value headless . |
For more detailed field descriptions, see the API reference.
Control the user flow (additionalParameters)
You use additionalParameters
to control the headless flow:
Field | Required | Example value | Description |
---|---|---|---|
sbid_flow | Yes | QR | Specify QR to launch the QR code flow or APP_LAUNCH to launch the BankID app flow. Note: Regardless of whether QR or APP_LAUNCH is specified here, the API responses will contain the necessary data to conduct an app launch flow. However, to get the necessary data for a QR flow, the value MUST be given as QR , and in order to complete the APP_LAUNCH flow, the value MUST be given as APP_LAUNCH. |
sbid_require_mrtd | No | true or false | Adds the MRTD check to a normal authentication. When this is set to true, you must also include sbidMrtd in the requestedAttribute . Note: You must validate that the sbidMrtd value is returned as true to prevent any tampering with the sbid_require_mrtd parameter. For feature details, see the About page page. |
sbid_auth_type | No | NORMAL or PHONE | Controls which type of flow is started for Swedish BankID: - NORMAL launches the regular Authentication flow (can be further specified by sbid_flow ) . - PHONE launches the Phone flow. Notes: - For the Phone flow to work, you must also include sbid_phone_initiator and enable the Phone flow in the Dashboard configuration. - You must send nin as prefilled. |
sbid_phone_initiator | No | USER or OPERATOR | Defines the default selected radio button in the first screen of the Phone flow: - USER means the User radio button is selected as default. - OPERATOR means the Operator button is selected as default. |
sbid_end_user_ip | Yes | 123.123.123.123 | IP address representing the user-agent/device of the end-user as seen by your service. This could be gathered from the requests you receive from the end user's user-agent/device. This must be in a valid IPv4 or IPv6 format. |
sbid_intention_text | No | VGVzdCBpbnRlbnRpb24gdGV4dAo= | A text specifying the intention of the authentication. Notes: - Must be encoded in UTF8 Base64 format. - Max length of the Base64 encoded string: 1500 characters. For more details, see Define intention text. |
sbid_intention_text_format | No | simpleMarkdownV1 | Defines the format of the intention text to be simpleMarkdownV1. For more details, see Define intention text. |
User information (requestedAttributes)
You can request the following attributes from users of Swedish BankID. These attributes are common for both the redirect and headless flows.
You add them in the requestedAttributes
as shown in the request examples above.
Attribute | sub-field | Example value in response | Description |
---|---|---|---|
name | Sven Svensson | The full name of the end-user | |
firstName | Sven | The first name of the end-user. | |
lastName | Svensson | The surname of the end-user. | |
dateOfBirth | 1990-02-17 | The date of birth of the end-user (ISO 8601 format). | |
idpId | 199002171234 | Personal identifier set by the identity provider. | |
nin | value | 199002171234 | The national identity number (“personnummer”) of the end-user. |
type | PERSON | The type of national identity number. Always PERSON for Swedish BankID. | |
issuingCountry | SE | The issuing country of the national identity. Always SE for Swedish BankID. | |
sbidDeviceIp | 3.127.53.67 | The IP address of the end-user's device where the BankID app was run during the authentication. | |
sbidCertificateNotBefore | 2022-10-18T22:00:00.000Z | The time from when the certificate is valid. | |
sbidCertificateNotAfter | 2023-10-19T21:59:59.000Z | The time the certificate expires. | |
sbidOcspResponderId | C=SE, O=Testbank A AB (publ), SERIALNUMBER=111111111111, CN=Testbank A Customer CA1 v1 for BankID Test OCSP Signing | The responder ID of the certificate used to sign the OCSP response (extracted from sbidOcspResponse ). | |
sbidOcspResponse | MIIHfgoBAKCCB3cwggdzBgkrBgEF... | Base64 encoded OCSP response for end user's BankID certificate | |
sbidXmlSignature | PD94bWwgdmVyc2lvbj0iMS4wIiBl... | Base64 encoded XML signature returned by BankID as proof of authentication | |
sbidMrtd | true | Required in the MRTD check when the sbid_require_mrtd additional parameter is set to true. Note: You must validate that the sbidMrtd value is returned as true to prevent any tampering with the sbid_require_mrtd parameter. |
Prefill user information (prefilledInput)
You can use the prefilledInput
parameter to prefill the national identity number of the end-user. If this is prefilled, only the user of that nin
value will be able to authenticate.
This is not a required parameter, unless using the Phone flow. Then prefilling is mandatory.
nin
Prefilling of user information only applies to the national identification number (nin
) for Swedish BankID. You cannot prefill other user data.
Example: "prefilledInput": {"nin": "1234567890"}
Response
Here is an example response for the session creation:
{
"id": "3d07c219-...",
...
"idpData": {
"autoStartToken": "db65b172-c9a4-43e3-82bf-0db09d7f922e",
"qrData": "bankid.c157aec7-e179-424..."
}
}
Field descriptions
The response to the session creation will contain an idpData
field, which in turn contains the necessary data that you need in your frontend.
Field | Example value | Description |
---|---|---|
autoStartToken | db65b172-c9a4-43e3-82bf-0db09d7f922e | Must be used when building the URL for launching the BankID app on the same device. - iOS: https://app.bankid.com/?autostarttoken=<autoStartToken>&redirect=<urlToYourAppOrWebPage> - Android (modern): https://app.bankid.com/?autostarttoken=<autoStartToken>&redirect=null - Android 4 and 5: bankid:///?autostarttoken=<autoStartToken>&redirect=null |
qrData | bankid.c157aec7-e179-424d-bee7-d54c9ece06fa.0.5b6b54c5a8939fa152da2a9689bf 50c14233ada0c79a67a2a52b1f8ba579ff35 | Initial data to display in a QR code. The QR code must be updated with the qrData you receive as a result of every request to get the session status. Only available if you started the session with "sbid_flow": "QR" |
What you need to do with the response
Based on the type of flow you are using, do the following:
- QR: Display a QR code to the end-user with the
idpData.qrData
as content. For more details, see the separate QR code flow section below. - APP_LAUNCH: Display a launch button for triggering the app launch URL. For more details, see the description of
autoStartToken
in the table above and the separate APP_LAUNCH flow section below.
Errors
HTTP Status Code | Error code | Description |
---|---|---|
400 | idp:sbid:already-in-progress | A request for the given NIN (National Identity Number) is already in progress. Both sessions are cancelled. |
400 | idp:sbid:invalid-parameter | You have sent an invalid parameter to BankID’s infrastructure, for example an invalid end-user IP address (see sbid_end_user_ip in the additionalParameters table above). |
500 | idp:sbid:rp-service-error | Failed to create a transaction towards BankID’s infrastructure. |
500 | idp:server-problem | Internal server error occurred while creating the session. |
2. Obtain user information (GetSession)
You use the GetSession endpoint to poll for information regarding the session and ongoing authentication.
Once the authentication is successful, the response will contain the user information requested in the CreateSession call that was done earlier.
Request
No data specific for Swedish BankID needs to be provided in this request.
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
Content of idpData
The response will contain an idpData
field, which contains necessary input data for your frontend.
If you are using the QR flow, you must update your QR code with the data received in the qrData
field.
Field | Example value | Description |
---|---|---|
qrData | bankid.c157aec7-e179-424d-bee7-d54c9ece06fa.0.5b6b54c5a8939fa152da2a9689bf50c14233ada0c79a67a2a52b1f8ba579ff35 | Updated data to display in a QR code. Only available if you started the session with "sbid_flow": "QR" and you received status WAITING_FOR_USER . |
sbidStatus | OUTSTANDING_TRANSACTION | Can be used to get more detailed status information, which can be used to make decisions. See possible values in the Status table below. |
Status
In the response you will get a top level status in the status
field. For some of these statuses you will find a more detailed status in idpData.sbidStatus
.
To prevent your integration from breaking if we add more statuses to idpData.sbidStatus
and error.code
, please handle unexpected values as follows:
- Unknown
idpData.sbidStatus
with top level statusWAITING_FOR_USER
: Treat asOUTSTANDING_TRANSACTION
- Unknown
error.code
with top level statusERROR
: Treat as an unknown error
Here are some response examples with different statuses (see the Status table below for descriptions of the different statuses):
Example response: WAITING_FOR_USER
{
"id": "4c88a3e2-b10e-4148-914d-f3f93f1ad76f",
"status": "WAITING_FOR_USER",
"idpData": {
"sbidStatus": "OUTSTANDING_TRANSACTION",
"qrData": "bankid.c157aec7-e179-424d-bee7-d54c9ece06fa.0.5b...",
},
...
}
Example response: ABORT
{
"id": "4c88a3e2-b10e-4148-914d-f3f93f1ad76f",
"status": "ABORT",
...
}
Example response: ERROR
{
"id": "4c88a3e2-b10e-4148-914d-f3f93f1ad76f",
"status": "ERROR",
"error": {
"code": "idp:sbid:timeout",
...
},
...
}
Status overview
Status | idpData.sbidStatus | error.code | Description |
---|---|---|---|
WAITING_FOR_USER | OUTSTANDING_TRANSACTION | The user has not started to authenticate yet. End-user guidance: Instruct the user on what they need to do (e.g. scan QR code or click a button to launch the app). BankID recommends the RFA13 or RFA1 user messages, but these do not take the QR code into consideration. | |
NO_CLIENT | The BankID app has not been started yet. For all practical purposes this can be treated the same way as OUTSTANDING_TRANSACTION . | ||
STARTED | No BankID found on device yet. This may take a few seconds. BankID recommends you to continue polling if you get this status. For mobile device you can in practice choose to stop polling if you get this status more than a few times in a row. End-user guidance: Instruct the user that they need to wait. BankID recommends the RFA14 or RFA15 user messages. In practice though, it might not make sense to show such long messages which in the majority of cases will only be shown until the next poll. | ||
USER_SIGN | The user has started to authenticate. End-user guidance: Instruct the user to complete the authentication in their app. BankID recommends RFA9, but this is a bit misleading for fingerprint. | ||
SUCCESS | The authentication is successful. Authentication result is present in the response. | ||
ABORT | The session was cancelled by the end-user. | ||
CANCELLED | The session was cancelled by you or the end-user. | ||
ERROR | idp:sbid:timeout | The BankID session was not completed in time. | |
idp:sbid:cert-error | The end-user certificate could not be trusted (invalid security code, revoked or invalid certificate). | ||
idp:sbid:start-failed | The BankID app was not started within a certain time limit. | ||
idp:sbid:rp-service-error | An error occurred when contacting the BankID service. | ||
idp:sbid:cancelled | The session was cancelled since someone started a parallel session for the user (security feature by BankID). | ||
idp:sbid:unknown-error | Unknown error occurred. |
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
WAITING_FOR_USER
status you want to read theidpData.sbidStatus
and handle the response accordingly. See information in the Status table above on what to do. - For
SUCCESS
status you will find the authentication result in thesubject
field. - For
ABORT
status you can assume that the end-user intentionally cancelled the transaction. - For
ERROR
status you can check theerror.code
field to see what kind of error occurred. - For
CANCELLED
status you or the end-user has cancelled the transaction.
If you get statuses that are not listed here, see Backwards compatibility in the start of this section.
Cancel a session (optional)
You can stop an ongoing authentication session by using the Cancel flow endpoint.
This is useful if you want to:
- Provide a way for your end-users to cancel the transaction, both at Signicat and Swedish 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": "sbid",
...
}
Errors
HTTP Status Code | error.code | Description |
---|---|---|
500 | idp:server-problem | Internal server error occurred while cancelling the session. |
How to complete a headless flow
The following sections describe how you can set up a complete headless flow for QR code and APP_LAUNCH, using the above information.
QR code flow
For the QR code flow, you must display an “animated” QR code to the end-user. Animating the QR code is done by updating the content of the displayed QR code for every status call. This is a mandatory security feature of Swedish BankID.
The process is as follows:
- Create a new session with
sbid_flow
set toQR
. - Take the
idpData.qrData
from the initial response and display as a QR code to the end-user. - Poll for status every 1 to 3 seconds. If you receive top level status
WAITING_FOR_USER
:- If
idpData.sbidStatus
isOUTSTANDING_TRANSACTION
orNO_CLIENT
, you must update the displayed QR code with the content of theidpData.qrData
returned in the status responses. - For other values of
idpData.sbidStatus
, see the description in the Status table above for information on what to show. Continue polling until the value forstatus
is eitherSUCCESS
,ABORT
, orERROR
, at which point the session is finalized.
- If
APP_LAUNCH flow
The APP_LAUNCH flow is for launching the Swedish BankID app on a mobile device or a desktop computer. You can only launch the app on the same device as you are displaying the launch button.
The process is as follows:
- Create a new session with
sbid_flow
set toAPP_LAUNCH
. - Take the
autoStartToken
from the initial response and build a launch URL as described in the Status table above. Display a launch button/link with that URL. - Poll for status every 1 to 3 seconds. If you receive the top level status
WAITING_FOR_USER
:- If
idpData.sbidStatus
isOUTSTANDING_TRANSACTION
orNO_CLIENT
you should still display the launch button and keep polling. - For other values of
idpData.sbidStatus
, see the description in the the Status table above for information on what to show. Continue polling until the value forstatus
is eitherSUCCESS
,ABORT
, orERROR
, at which point the session is finalized.
- If
Next steps
Dive deeper into Authentication REST API and improve your application with advanced security features: