Auth API

The purpose of the Auth API is to handle consumer's state and if needed the input, too. Whenever consumer input is needed the associated XS2A Form can be retrieved over this API and the response to this form is sent to this API as well.

In most cases the Auth API will be accessed by the XS2A App, but in a white label integration the Auth API is called from the TPP/merchant.

The URL for the Auth API is always dependent on a Flow and can therefore be obtained from the auth_url-field in the client_token that is part of the response when starting a Flow.

Requests made towards the Auth API have to have the "Origin" header set to an appropriate origin.

environment Origin
Production The origin will be set as part of the onboarding process for white label TPPs/merchants
Integration https?://localhost:\d+

Optional available headers for Auth API endpoints:

User-Agent: The user agent from the customer
Client-Agent: A service version from your integration

Fetching the current State from the Auth API

The current state can always be retrieved by calling the Auth API endpoint via GET.

GET <decoded(client_token).auth_url> HTTP/1.1
Host: <Host>
Origin: <origin>
curl -X "GET" -H "Origin: <origin>" "<decoded(client_token).auth_url>"

Result of a successful GET-call

{
    "data": {
        "state": enum<"INITIALIZED", "PROCESSING", "CONSUMER_INPUT_NEEDED", "FINISHED", "ABORTED", "EXCEPTION">,
        "next": string,
        "result": ...
    }
}

The data property wraps the actual information in every response returned by the Auth-API and has no other purpose.

The state property holds the current state of the flow. It can be one of the following:

  • PROCESSING

The state is PROCESSING when the api processes incoming information or is polling internally for a state change. In special cases the api still allows for consumer input to be submitted while polling. This allows the consumer to switch the currently running authentication/authorization process from an asynchronous (e.g. confirming the transfer in an external app provided by the bank) to another available method.

  • CONSUMER_INPUT_NEEDED

The flow is waiting for consumer data to be received through the Auth API (e.g. XS2A App).

  • ABORTED

The flow was aborted through a close flow call

  • EXCEPTION

The flow failed with an exception.

  • FINISHED

The flow has finished.

The states ABORTED, EXCEPTION and FINISHED are terminal states, thus apart from requesting the information of the flow through the flow information call the flow cannot be interacted with.

The next property holds a url which refers to the endpoint that has to be used for the next call as it can change during the course of a flow. When called with GET it returns the latest result. This should also be used for polling if needed. When called with POST it is possible to e.g. send for example a result for an XS2A Form and retrieve a different result afterwards.

The result property

The result property wraps the actual data from the Auth API that contains the step-specific information and can be one of the following (depending on the type):

  • bank_search - indicates that the user has to select a bank. For a white label integration it is strongly advised to start a session with a preconfigured bank, instead of implementing the BankSearch.
  • form - indicates that the consumer has to provide information to continue with the flow.
  • redirect - indicates that the user should be redirected to the bank's website to provide information.
  • error - is returned in cases where the session towards the bank is unrecoverably broken.

The context property is part of result object and describes the current state of the flow. The field can be used to update a GUI in order to display more information to the consumer. Possible values for context are:

  • bank_selection - the consumer needs to select the bank to be used
  • transport_selection - there is a possibility that a consumer has to choose a different bank-account-access-method (e.g. business portal vs private portal)
  • authentication_method_selection - the consumer needs to choose one of the available authentication methods that is available at this specific bank
  • authentication - the consumer has to authenticate against the bank
  • account_selection - the consumer has several bank accounts that could be used for the current flow so the consumer is asked to select one of the possible accounts (only if no acocunt is configured in flow-creation)
  • authorization_method_selection - the consumer has to select on his/her available authorization methods before a transfer can be authorized
  • authorization - the authorization of a transfer
  • none - the current context is either not determinable, or is irrelevant

Response structure if result.type is bank_search

{
    "data": {
        "state": "CONSUMER_INPUT_NEEDED",
        "next": string,
        "result": {
            "type": "bank_search",
            "configuration": {
                "allowed_countries": array<string>,
                "preselected_country": string
            },
            "context": "bank_selection"
        }
    }
}

The configuration is only set when type is bank_search and is only relevant if a bank_search is used.

Response structure if result.type is form

{
    "data": {
        "state": "PROCESSING | CONSUMER_INPUT_NEEDED",
        "next": string,
        "result": {
            "type":  "form",
            "form": ?XS2AForm,
            "key": string,
            "context": enum< "transport_selection", "authentication_method_selection", "authentication", "account_selection", "authorization_method_selection", "authorization", "none">
        }
    }
}

The form is the payload that is present in nearly every case. The content of the form is described by the XS2A Form Scheme.

The key contains the key needed to encrypt the response to an XS2A Form. The specifics are described in Encryption.

Response structure if result.type is redirect

{
    "data": {
        "state": "CONSUMER_INPUT_NEEDED",
        "next": string,
        "result": {
            "type":  "redirect",
            "redirect": {
                "url": string,
                "id": string
            },
            "context": enum< "authentication", "authorization">
        }
    }
}

The redirect contains the url to redirect the consumer to. Furthermore an id is provided to identify redirects in case multiple subsequent redirects to the same url are required.

Response structure if result.type is error

{
    "data": {
        "state": "EXCEPTION",
        "next": string,
        "result": {
            "type": "error",
            "category": string,
            "message": string,
            "context": enum<"bank_selection", "transport_selection", "authentication_method_selection", "authentication", "account_selection", "authorization_method_selection", "authorization", "none">
        }
    }
}

The category is only set when type is error and indicates the top level error-type by showing which party has caught the error. The errors can be found in the Error handling documentation.

The message is a human-readable explanation for the error and therefore only returned when type is error.

Example Response for a successful GET-call

{
    "data": {
        "state": "CONSUMER_INPUT_NEEDED",
        "next": "https://authapi.openbanking.klarna.com/xs2a/v1/wizard/1234567890123456789",
        "result": {
            "type": "form",
            "form": {
                "version": "1.0.0",
                "form_identifier": "9a11b19e-077e-4715-904a-a9a2cc891837",
                "elements": [
                    {
                        "type": "input",
                        "key": "USERNAME",
                        "tags": [],
                        "version": "1.0.0",
                        "password": false,
                        "label": "Username",
                        "placeholder": "",
                        "prefill_value": "",
                        "read_only": false,
                        "validator": {
                            "min_length": 0,
                            "max_length": 20,
                            "required": true
                        }
                    },
                    {
                        "type": "input",
                        "key": "PASSWORD",
                        "tags": [],
                        "version": "1.0.0",
                        "password": true,
                        "label": "Password",
                        "placeholder": "",
                        "prefill_value": "",
                        "read_only": false,
                        "validator": {
                            "min_length": 6,
                            "required": true
                        }
                    }
                ]
            },
            "key": "eyJhbGciOiJSUzI1NiJ9.eyJtb2R1bHVzIjoiZDEwOTA3YzBkZjc4ZmI5ZDMyNmI1NzkyZGExZDg2OGRkNGViZWRiMmM1ODI4M2UxNTQ2NzFmMmZhNWY2OThiYTI3NWJjZGE0YjA4YTMwOTM4MWNiYWRlOGVmMzRhMTJkM2RhOTM3YjlmMjI4N2EyYTZjY2YxYWU4YWI3ZGRhZTM3ZWNmNzRkM2JlYWQ1OTdhNmY0ZjkwNWZiMzczNGIxY2FhOTk0ZDlhMmNmYjZiZjUyYzAwNmU2MDNmN2E1NGFlODM0NmZiY2VhZmQzODQwMjRlOWI4ZjkyOWI3ODNiMDc0MTljZGNlNGZkMmJlYTcxMzNhYjk3N2M2OWQ1NjVhNzZjMGU4MWZiMDk0NGM3N2NkMGJjYmU4ZmQ4YzY5MmQ3MDNlMDY0ZGYwNzE0OGUxMDRlOWU3ZGY1NDgxZjIwMmRkMjBiODk5ZTEwM2FlYTZiMjM1YjkyZDc4Y2I3MGMyNTNjMjE0NzcyNWVhYmVhMWU4NDZlM2YwZDgzNmYzODZiNzc3YmMwNmYyZWQzZjVmNzllMzA1YjIzM2I3OWQ1OGI3OWVkYjUxOTU5ZGJmYjk4MjM0YmE1MDE3MWVjM2ZlZWMxOTU4Mjc2NDg1NzEyZjI3MDk1ZGNlZDQ4NDVlYjgyMzg4YWVlMmFjOWRlMDc2YzNiMjE1YzY3OTNjMDNmODkiLCJleHBvbmVudCI6IjEwMDAxIn0.zEfK3O9geI1h4l2SaxxUnbfR3pKy0a5CUs3Bfwxgmd56JCOIIMX-l7KhefELqAALekUwFXT0RnMFWmD4DY99p1gT3ETNeZEe_Spv1ednlrVpaMOi68-FT91l3tyoo-XzycCNeTJ1aGqrttZbuMzAOqLfMnwqd0PszzN7pPEDbwEoatWpX5UpTpYQNNDigZHZOHERqaYEP2Kq0YyZUBYxqPPr_Tvm6qGB4iRB6UG3DxIdCoHV_M3fmuHCP62qI9mHArLP96CC4PcAlGnqLUkRQyWgw5Kdfqj0j5LSNq4CHYlva_KcQAFjGYyBd0GwRUrFZPE6VUWda9Lt4dk0AVY1Pw",
            "context": "authentication"
        }
    }
}

Responding to the Auth API

When the Auth API requires a information from the consumer, e.g. through a form, a redirect or the bank_search, the response needs to be sent to the Auth API as well. The POST request needs to be made towards the URL provided in the data.next property of the response of the previous GET request towards the Auth API.

POST <data.next> HTTP/1.1
Host: <Host>
Origin: <origin>
curl -X "POST" -H "Origin: <origin>" "<data.next>"

The payload of this POST request depends on the type of the response in the previous call. The response to all of these requests is the same as the one provided in the above section "Fetching the current State from the Auth API".

Responding to bank_search

If a bank_search is submitted the request payload is expected to have the following JSON structure:

{
    "bank_code": string,
    "country_code": string
}

The root element has to have two properties, namely the bank_code and the country_code which identify the selected bank.

Responding to form

If a form is submitted the request payload is expected to have the following JSON structure:

{
    "ct": string,
    "iv": string,
    "ek": string
}

It holds the encrypted data of the form response. This additional encryption only has to be done when responding to a form.

The payload of the encrypted data has to be structured as follows:

{
    "form_identifier": string,
    "data": array<{
        "key": string,
        "value": any
    }>
}

The root element has to have two properties.

One is the form_identifier that is supplied in the root element of the form.

The other is the data property that contains the data of the form, which is an array of objects with a key and a value property. This is essentially a flattened list of key-value pairs that does not reflect the possibly nested structure of the initial form data.

These Examples depict several forms and the structure of their corresponding responses.

Responding to redirect

If a redirect is submitted the request payload is expected to have the following JSON structure:

{
    "return_url": string,
    "redirect_id": string
}

The root element has to have two properties.

The return_url property has to contain the full URL - including all GET-parameters - to which the consumer was redirected from the bank website.

The redirect_id property has to hold the id of the redirect that was provided in the response of the previous call.

results matching ""

    No results matching ""