# Migration guide

The following guide will help you migrate from Signicat Identification API v1 to v2.

# Endpoints: v1 -> v2 mapping

v1 v2
Base URL: https://api.idfy.io/identification Base URL: https://api.idfy.io/identification/v2
GET /session?requestId={id} GET /sessions/{id}
POST /session POST /sessions
PUT /sessions/invalidate?requetsId={id} POST /sessions/{id}/invalidate
GET /log/filter/{year} GET /sessions
Note: Active sessions is not included in this list. The session data returned from this endpoint does contain any personal information or other sensitive data about the user.
GET /log/requestId/{id} Not available
Note: Use the GET /sessions endpoint to list previously created sessions.
POST /no/bankid/mobile POST /sessions
Note: Headless BankID on mobile sessions are now created with the POST /sessions endpoint using the headless flow.

# New features

  • A simpler, cleaner REST API
  • Specify any combination of ID providers to allow for a given session
  • A modern, customizable UI with theming support
  • Support for headless Norwegian BankID and Swedish BankID
  • New IDP: SMS OTP
  • New IDP: Freja

More features will be added as the API evolves.

# Differences and migration considerations

The new API endpoints behave somewhat differently from the previous version. Simply updating the endpoint URLs will in some cases result in errors in your application.

# New statuses

v1 v2
SUCCESS success
ERROR failed
USERABORTED user_aborted
INVALIDATED invalidated
TIMEOUT timed_out
CREATED created
USERINITIATED user_initiated

# Session lifetime

A session is active for 10 minutes after its creation, after which the session URL can no longer be used. The expiry is returned as the expires property in the response when you create and retrieve a session.

We will store personal information and other sensitive data about the user for 1 hour after session creation, which means that you will have to retrieve and store the information you need on your end within this timeframe. After 1 hour, all sensitive data is deleted from our system and only a subset of the session data will be returned from the API:

  • id
  • created
  • expires
  • status
  • language
  • flow
  • provider
  • environment.userAgent
  • externalReference
  • error

# The include property

By default, when a user has identified themself, only the providerId - the user’s unique ID for a given IDP - is collected and returned as part of the session’s identity object.

To request additional information about the user, this must be specified with the include property when creating the session.

# Example

{
  "include": [
    "name",
    "date_of_birth",
    "nin"
  ]
}

The following table displays the valid values for include and the session properties that will be returned:

Value Returned properties
name identity.firstName
identity.middleName
identity.lastName
identity.fullName
date_of_birth identity.dateOfBirth
phone_number identity.phoneNumber
nin identity.nin

# New concept: flows

In the v2 API a new concept, flows, has been introduced. When creating a session you must select between one of three flows:

# Redirect

Use this flow if you intend to redirect the user to the identification URL. The user is redirected back to you when identification is completed.

# Iframe

Use this flow if you intend to embed the identification URL in an iframe. A message will be dispatched to the parent window using postMessage when the identification is completed.

# Headless

Use this flow if you want to start a session directly on the user’s device with no UI involved (typically from a backend or app to backend system). Currently only supported by Norwegian BankID on mobile and Swedish BankID.

# Iframe flow messages

When using the iframe flow, messages are sent to your page with postMessage when a session is either successful, aborted or failed due to an error. The URI of the parent window must match the URI that is specified in iframeSettings.postMessageTargetOrigin when the session is created.

You must listen to the dispatched messages by registering an event listener:

window.addEventListener('message', function(event) {
  if (event.origin !== 'https://id.idfy.io')
    return;
  
  const data = JSON.parse(event.data);
  console.log(data.status); // => 'success/aborted/error'
});

It is important to validate the origin before processing the message because the message handler accepts messages from any URI.

The origin is https://id2-test.idfy.io for our test environment, and https://id.idfy.io for production.

The message object has the following structure:

{
  "sessionId": "<sessionId>",
  "status": "<success/aborted/error>"
}

# Examples

Below are some examples on how you would use v1 and v2 to create a new session.

# Redirect flow

# v1 approach

POST /session

{
  "IdentityProvider": "NO_BANKID_MOBILE",
  "ReturnUrls": {
    "Error": "https://secure.wayneenterprises.com/error",
    "Abort": "https://secure.wayneenterprises.com/abort",
    "Success": "https://secure.wayneenterprises.com/success"
  },
  "Language": "NO",
  "GetSocialSecurityNumber": true,
  "ExternalReference": "123456789"
}

# v2 approach

POST /sessions

{
  "allowedProviders": [
    "no_bankid_mobile"
  ],
  "language": "no",
  "flow": "redirect",
  "include": [
    "name",
    "nin"
  ],
  "redirectSettings": {
    "successUrl": "https://secure.wayneenterprises.com/success",
    "abortUrl": " https://secure.wayneenterprises.com/abort",
    "errorUrl": " https://secure.wayneenterprises.com/error"
  },
  "externalReference": "123456789"
}

# Iframe flow

# v1 approach

POST /session

{
  "IdentityProvider": "NO_BANKID_MOBILE",
  "iFrame": {
    "Domain": "https://example.com",
    "WebMessaging": true
  },
  "Language": "NO",
  "GetSocialSecurityNumber": true,
  "ExternalReference": "123456789"
}

# v2 approach

POST /sessions

{
  "allowedProviders": [
    "no_bankid_mobile"
  ],
  "language": "no",
  "flow": "iframe",
  "include": [
    "name",
    "nin"
  ],
  "iframeSettings": {
    "parentDomains": ["https://secure.wayneenterprises.com"],
    "postMessageTargetOrigin": "https://secure.wayneenterprises.com"
  },
  "externalReference": "123456789"
}

# Headless flow

# v1 approach

POST /no/bankid/mobile

{
  "MobileNumber": "99887766",
  "DateOfBirth": "071283",
  "GetSocialSecurityNumber": true,
  "ExternalReference": "123456789"
}

# v2 approach

POST /sessions

{
  "allowedProviders": [
    "no_bankid_mobile"
  ],
  "flow": "headless",
  "include": [
    "name",
    "nin"
  ],
  "externalReference": "123456789",
  "prefilledInput": {
    "phoneNumber": "+4799887766",
    "dateOfBirth": "1983-12-07"
  }
}
Last updated: 9/8/2020, 11:18:30 AM