The final step before being able to query financial data on a connection, is to create that very connection. This is quite an involved step that requires these actions:

  1. Construction of an Authorisation URL which is then given to your user.
  2. Users give their consent to this process and sign in to whichever financial institution we are connecting to.
  3. A code is generated and must be exchanged to finalise the process

Lets walk through these steps now with an example.

Authorisation Requests

You are going to be making a request to the identity server ( and
POST /oidc/request


Pushed Authorisation Request

What you are about to make is called a PAR or pushed authorisation request. You have a number of ways to make an authorisation request, but find that this is the most straightforward for all languages. More information can be found here: PAR


To authenticate ourselves when you make this request, the body of the request takes two parameters:

client_assertion=<JWT Explained Below>

For client_assertion above you will need to generate a JWT signed by your private JWKS. As mentioned in creating a client guide, your JWT library should allow all this functionality. Your JWT needs to have these properties:

  "iss": "your client id",
  "sub": "your client id",
  "jti": "A unique identifier for the token, which can be used to prevent reuse",
  "aud": "our token endpoint, i.e.(",
  "iat": "the time at which the token was issued",
  "exp": "the time at which the token will expire"

You may find that your JWT library handles values like jti, iat, exp for you automatically.


When creating an authorisation URL, you need to specify a set of claims that gives extra information on how the connection will be made.


Basic Claims

This guide aims to cover the basics, and because of this wont go into detail about the large amount of claims you can pass into an auth request. If you want more information and a deeper dive visit this section of our docs: Claims

A claim request is simply a JSON object that describes what information you wish to request. All our claims we support currently belong to the id_token. Here are the claims you will use:

  "id_token": {
    "sub": { // When using Ongoing Access you need to provide the user this is for
      "essential": true,
      "value": "Your UserId"
    "mh:con_id": { // This states you want the connection ID returned in the resulting ID Token
      "essential": true

This is all that is needed for our basic AIS auth request.


The final important area of the auth request body is the scopes. We use scopes to both describe the access the user is granting and the way in which you would like the user to identify themselves.


All The Scopes

You will only use basic scopes for this guide, but if you want to see a list of all the scopes you can provide visit this documentation: Scopes

For this request you want to simply have the user connect to a test bank:

scope=openid id:test

This asks for 2 scopes openid and id:test.

openid scope is a required scope that simply states you will be using the OpenID Connect interface.

id:testscope is the financial institution you want to connect to. In this case id:test indicates you would like to display a list of test banks for the user who is consenting to choose from. You could instead pass id:{bank_id}with a specific bank id to skip this choice.


Choose A Specific Bank

In our example above you are passing in id:test for the bank we want to connect to. If you wanted to choose a specific bank you would need to pass in a bankId.

Bank Ids are a way for us to differentiate between the different financial institutions you can connect to. These can be found here: Connections

For more information on bank connections see this documentation page: Banks

Creating The Auth Request

Lastly you need to also provide some identity and security information.

  • client_id - This is your clientId
  • redirect_uri - This is one of your previously defined redirect URIs from the client configuration. This is where the consent journey will end once the user has consented, passing the code to be exchanged.
  • response_type - This is the previously defined response type from the client configuration. In your case thats: code id_token
  • state - This is a security value that can prevent attacks such as CRSF. In this example it can be blank
  • nonce - This is a security value that can prevent replay attacks. In this example it can be blank

Let's put this all together now in the final combined request to the Authorisation Request endpoint:

curl --location --request POST '' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id={}' \
--data-urlencode 'redirect_uri={}' \
--data-urlencode 'response_type={}' \
--data-urlencode 'scope=openid id:test' \
--data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer' \
--data-urlencode 'client_assertion={Your JWT}' \
--data-urlencode 'claims={
  "id_token": {
      "sub": {
        "essential": true,
        "value": "{Your UserId}"
      "mh:con_id": {
        "essential": true

You should get a successful response that looks something like this:

	"request_uri": "urn:ietf:params:oauth:request_uri:m4enL-UeWzej6eEqT-NeC",
	"expires_in": 1691571826

This value can be used to construct the auth URL:

What’s Next

Now you have your URL, lets connect that account