NAV
shell

Introduction

How to add headers

curl -X POST \
  https://api.genericmobile.se/CustomerGateway/api/BankAccounts \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{ ... }'

Welcome to Generic Mobile's BankID Gateway API documentation!

This is a JSON API with base URL https://api.genericmobile.se/CustomerGateway/api. Please add Accept and Content-Type headers where applicable. Note that the legacy BankID on file is not supported, only Mobilt BankID.

Authentication

To authorize, use this code:

# With curl, add the Authorization headers like so
curl https://api.genericmobile.se/CustomerGateway/api/BankAccounts \
  -H 'Authorization: Basic bXl1c2VyOnB3ZA=='

Make sure to replace bXl1c2VyOnB3ZA== with your Base64(username:password) string.

All requests in this section require Basic Authorization. Please contact customer support to set up an account with us. And RFC 7617 on how to generate the Base64 encoded string.

Retrieve Bank Accounts

To retrieve the user's bank accounts we recommend the following schema.

  1. Ask the user for:
    1. His/her 12-digit Social Security Number, SSN.
    2. What Bank, preferably using a dropdown.
    3. If the BankID app is installed on the current device or on another device.
  2. Send an initiate request from your server.
  3. Every second, poll for status updates from your server.
  4. If the BankID is on the current device use the autoStartToken to launch the BankID app. More information about this could be found under "Launching" in BankID's own integration guide.
    If BankID is on another device, you'll need to render the QR code included in the status response for the user to scan using the BankID app.
    Note: some banks use Animated QR codes, i.e. you'll get a new QR code every second and need to update the rendered QR code since they have a short validity time.
  5. Once the request reaches a final state (success or error) stop polling.

Notes

  1. A user may only have one active BankID session at a time.
  2. A retrieve request is only valid for 10 minutes.
  3. A 3-minute cooldown may apply after some error scenarios with BankID. On consecutive failures please ask user to wait before trying again.
  4. The bank security posture changes frequently, at the time of writing this section (April 2022) only Swedbank/Sparbankerna require the onOtherDevice parameter to be set. All banks support this parameter, our recommendation is to always set it and render the UI accordingly.

Initiate Bank Accounts request

curl -X POST \
  https://api.genericmobile.se/CustomerGateway/api/BankAccounts \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Basic bXl1c2VyOnB3ZA==' \
  -d '{
    bank: <bank>,
    ssn: string,
    onOtherDevice: bool
}'

The above command returns a publicId in JSON, like this:

200 OK
{
    "publicId": "7bd12832-abf7-4fb9-8073-97e82ca62282"
}

POST https://api.genericmobile.se/CustomerGateway/api/BankAccounts

Parameter Description
bank The user's bank, see bank table.
ssn The social security number (personnummer) of whom to retrieve the bank account list from. 12-digits, no hyphens.
onOtherDevice true if BankID is on another device. false as default.

Get Bank Accounts

curl https://api.genericmobile.se/CustomerGateway/api/BankAccounts/{publicId} \
  -H 'Accept: application/json' \
  -H 'Authorization: Basic bXl1c2VyOnB3ZA=='

The above command returns JSON structured like this:

200 OK
{
  "publicId": "7bd12832-abf7-4fb9-8073-97e82ca62282",
  "bank": "SEB",
  "ssn": "19820101-1234",
  "status": "Success",
  "qr": "data:image/png;base64, iVBORw0KGgoA...SUVORK5CYII=",
  "bankIdAutostartToken": "123459c9-7d04-471f-b010-12345b5ee0e3",
  "accountNumbers": [
    {
      "number": "1234,12344560",
      "clearingNo": "1234",
      "accountNo": "12344560",
      "iban": "SE4700000000123412344560",
      "autogiroCompatible": "Unknown"
    }
  ]
}

200 OK
{
  "publicId": "123459c9-c542-49b2-af80-e9d05c25f83f",
  "bank": "FSPASB",
  "ssn": "19820101-1234",
  "status": "Failed",
  "qr": "data:image/png;base64, iVBORw0KGgo...TkSuQmCC",
  "bankIdAutostartToken": "bankid.123459c9-7d04-471f-b010-123...7adc91bb0836c3",
  "accountNumbers": [],
  "failureMessage": "Du avbröt BankID. Vänligen försök igen.",
  "failureCode": "AUTHENTICATION_ERROR"
}

GET https://api.genericmobile.se/CustomerGateway/api/BankAccounts/{publicId}

Where {publicId} is from the Initiate response.

The status could be one of "Waiting", "Success", "Failed". As long as the status is "Waiting" you should back-off a second and try again. "Success" and "Failed" are final states, no more polling is meaningful for this {publicId}.

Some banks have an additional security feature that require the user to scan a QR code if the login isn't initiated on the same device as the BankID app is installed. Or that you provide a bankIdAutostartToken when starting the BankID app. In such case the QR code is included in this response as a png image encoded using base64 and the bankIdAutostartToken as a string (see example). Most times this QR code and token is included in the first GET request you make, but some times it may take a few seconds. For some banks, this feature is customer dependent, don't assume anything, act accordingly if a QR code is present and note that the QR code may change every second (Animated QR).

failureMessage will include a human readable description in Swedish on what when wrong. failureCode is the type of failure, e.g. "AUTHENTICATION_ERROR". Those two properties are only present on failures.

autogiroCompatible will be one of "Approved", "Unapproved" or "Unknown". If you're planning to use the account information for AutoGiro you could safely hide "Unapproved" accounts, but should show others, perhaps preselect an "Approved" account.

A publicId is only valid 10 minutes from its creation. After this, 404 Not Found will be returned.

Bank

This is a list of supported banks. Use the acronym in this API.

Bank Description
OEB DanskeBank
SHB Handelsbanken
ICA Ica
LFB Länsförsäkringar
NB Nordea
SBAB SBAB
SEB SEB
SKB Skandia
SYD Sparbanken Syd
FSPA Swedbank
FSPASB Swedbank Sparbankerna

Sign with BankID

This endpoint will trigger a BankID sign request. This process can take a while to finish, it's thus constructed in two steps. First you initiate the Sign request, then you'll poll for status updates.

Initiate Sign request

curl -X POST \
  https://api.genericmobile.se/CustomerGateway/api/Sign \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Basic bXl1c2VyOnB3ZA==' \
  -d '{
    ssn: string,
    userMessage: string,
    userNonVisibleData: string
}'

The above command returns JSON structured like this:

200 OK
{
  "publicId": "61bdf9f7-1986-4e74-b539-4997344309e6",
  "autoStartToken": "f2a9d29d-290e-4ee7-b215-37aaad0facb8"
}

POST https://api.genericmobile.se/CustomerGateway/api/Sign

Parameter Description
ssn The social security number of whom to retrieve the bank account list from.
userMessage The text visible when user signs with BankID.
userNonVisibleData Text not visible to user signing.

Get Sign status

curl https://api.genericmobile.se/CustomerGateway/api/Sign/{publicId} \
  -H 'Accept: application/json' \
  -H 'Authorization: Basic bXl1c2VyOnB3ZA=='

The above command returns JSON structured like this:

200 OK
{
  "publicId": "61bdf9f7-1986-4e74-b539-4997344309e6",
  "status": "Complete",
  "ssn": "198001011234",
  "autoStartToken": "f2a9d29d-290e-4ee7-b215-37aaad0facb8",
  "givenName": "John",
  "surname": "Doe",
  "ipAddress": "127.0.0.2",
  "name": "John Doe",
  "notAfter":"2020-05-24 23:59:59+02:00",
  "notBefore":"2017-05-25 00:00:00+02:00",
  "ocspResponse":"MIIHX...1irUUw==",  // Truncated
  "signature":"PD94b...0dXJlPg==",  // Truncated
  "created":"2018-10-08 16:17:58+02:00"
}

GET https://api.genericmobile.se/CustomerGateway/api/Sign/{publicId}

Where {publicId} is from the Initiate response.

Read more about the ocspResponse on Wikipedia.

The signature, when status is Complete, contains a base64 encoded XML document. Where you have the <bankIdSignedData> containing tags like <usrVisibleData> and <usrNonVisibleData>, but also the <SignatureValue> tag. You'll want to store this document.

Keep polling every second until you reach a final state.

State Description Final
Complete Success, user has signed. Yes
NoClient No BankID found, sign process failed. Yes
Error Other error, sign process failed. Yes
OutstandingTransaction If a transaction is already active against given BankID (timeout per session is 2.5min). Could also occur as a transient state when the underlying sign process starts up. Keep polling. No
Started Process has started, keep polling. No
UserSign Intermittent state, keep polling. No
UserReq Intermittent state, keep polling. No