How to [get started] with our APIs

Getting Started

What is an App

An app is a container for storing API keys used to access chosen API products. When creating an app you can choose one or more products. We have packaged our APIs into products. Available products can be viewed by navigating to the API's page.

Our products are grouped by category to assist you to find the correct product. If you believe there is need for a new product, please email your idea.


Before any of the Landsbankinn APIs can be used, you need to obtain an API key. After Sign up or Login you can obtain API key by creating a new app under My Apps.

API key

An API key is used to authenticate your client/application. To use your API key, simply add an apikey header to your request with your API key as the value.

        curl -X GET \ \
        -H 'apikey: p4G6QmpkktBuvsjeMxUsNcwFuLMO7mZy'

(You need to replace p4G6QmpkktBuvsjeMxUsNcwFuLMO7mZy with your apikey)

Remember to keep your API key safe, take care to keep it secure. If your API key is publicly exposed others might start using it, which could lead to its suspension or even cause your account to be disabled. Best practices include not embedding API keys directly in code, not storing API keys in files inside your application's source tree, and deleting unneeded API keys.

Obtaining an API key

After registration, your next step is to obtain an API key and write your first application. Navigate to My apps and create your app by clicking on the Add a new app button. When creating an app, giving it a meaningful and descriptive name is a good way to remember its purpose.

A callback URL is used in the "three-legged OAuth" (OAuth's authorization code grant type) scenario allowing developers to specify a callback URL when an app is registered. The callback URL points to an external site, such as When the app requires user credentials, it doesn't ask for a username and password; instead, it forwards the end-user to the callback URL site, where they log in, which allows the app to get an OAuth access token to use in place of their username and password.

Landsbankinn provides two environments: sandbox, which is used to test functionality, and production. We will automatically approve apps in the sandbox environment. When your application is ready, you should create a new app on the production environment. Keep in mind that it may take a couple of days (banking days) before your app is approved. Finally, select the products you want to access.

Authentication overview

Landsbankinn APIs utilize OpenID Connect Code Flow for authentication. The image below describes the flow of OpenID Connect Code Flow.

  1. The user of the 3rd party app initiates the login.
  2. The app requires authorization so it opens a link to the Landsbankinn authorization endpoint on the authorization server.
  3. The user enters its credentials (user pass on the sandbox environment or PKI Sim (Rafrænt skilríki) on the production environment).
  4. The authorization server sends a code to the specified redirect url. This is the registered endpoint in the client app.
  5. The app sends the code to the code flow server.
  6. The code flow server bundles the code with the client secret needed to complete the login.
  7. The authorization server returns an access, refresh and id token to the code flow server.
  8. The code flow server returns the tokens to the application.

To complete the authentication the application should validate the ID token. How you validate the ID token client side is outside the scope of this documentation, but the JWKS endpoint needed to validate the token can be found in the well know configuration endpoint


The first step of OAuth 2 is to get authorization from the user. For browser-based or mobile apps, this is usually accomplished by displaying an interface provided by the service to the user. Examples to create code flow server can be found at Code Flow server section.

  1. Create a login link
    • url - Authorization endpoint for sandbox is and for production
    • response_type=code - Indicates that your server expects to receive an authorization code. This is the only method allowed.
    • client_id - The Consumer Key you received when you first created the application
    • redirect_uri - Indicates the URI to return the user to after authorization is complete. This must be the same redirect URL that is registered with the App.
    • scope - One or more scope values indicating which parts of the user's account you wish to access
    • state - A random string generated by your application, which you'll verify later. Or string containing special information used in the login process.
    • Example:
      - client_id=ydQ...
      - response_type=code
      - state=x1rdfba1nwbefizu10eljk3e8shwygwgy3v66rpq
      - redirect_uri=
      - scope=profile openid customer accounts payments
    • Scopes as listed under scopes_supported in the well-known JSON document
    • Data is required to be URL encoded.
  2. Postback from the authorization server
    • code=AUTH_CODE_HERE - This is the code you received in the query string from the authorization server
      - code=MB5_8Fl...
      - state=x1rdfba1nwbefizu10eljk3e8shwygwgy3v66rpq
  3. Token Exchange
    • code=AUTH_CODE_HERE - This is the code you received in the query string
    • redirect_uri=REDIRECT_URI - Must be identical to the redirect URI provided in the original link
    • Post Url: https://$code-flow-server/authenticate?code=$code-retrieved-from-step1&redirect_uri=
    • Example response:
    • {
    • Remember to URL encoded data.


The authorization on the Landsbankinn apis are enforced by http headers. The open apis need apikey, and the authorized apis need an apikey and a access token.

The apikey is sent in with the apikey header. The apikey is unique to the client app and has access to the requested products (apis) on the app registration (on the production environment, the products will be in a pending stated until manually approved). You cannot use an apikey to call apis that the app has not been given access to.

The access token is sent in with an Authorization header. It is a bearer token so you send in the header with the value Bearer <YOUR_JWT_TOKEN>. It has a lifetime of 20 minutes.

You can read more about JWT tokens here.

Code Flow server

It is the responsibility of the 3rd party to host a Code Flow server where the client secret is kept. Javascript clients cannot keep a secret since they run in the browser, so the Code Flow part of the OpenID Connect needs to run server side.

The details on how to write this server is beyond the scope of this documentation. However, we have implemented a C# NuGet package that implements this server and you are free to use, as well as an Azure deployment script to install the server with minimal effort (you will have to have an Azure account, but the deployment is by default on a free tier).

Here is the link to the one click Azure deployment:

Here is the link to the source of the underlying NuGet package used in the deployment (the documentation is in the deployment repository):

Here is the link to the NuGet package:

Authentication URLs


Discovery endpoint


Discovery endpoint

You can read more about OpenID Connect here

Sandbox environment

We created the sandbox environment for you to try your ideas, to test your applications and for general exploration of the functionalities we expose. We encourage you to start your journey by experimenting with our APIs. There is one big difference between sandbox and production, and that is that we allow you to analyse throughput, max response time, min response time, message count and error count in the production environment.


All endpoints in our API that return an array of resource items are paged. The page size is controlled by the service developer, but has a default value of 50.

To request a paged resource, the optional page query is used.

  • If the page query is omitted, the first page is always returned.
  • Page resources start at page 1.

Paging response headers

When a paged endpoint is called, headers that are included in the response give information about the paged result and the full data set.


The Link header is used to reference linked resources. Multiple Link headers are attached to the response of the paged resource and point to the first page, next page, previous page, and the last page of the resource.


The x-paging-* headers are four and show raw information about the requested resource.

  • X-Paging-CurrentPage tells you the current page in the response.
  • X-Paging-TotalPages tells you the total amount of pages.
  • X-Paging-PerPage tells you how many resource items there are on each page.
  • X-Paging-TotalItems tells you the total amount of available items.

Link: <
X-Paging-CurrentPage: 3
X-Paging-TotalPages: 7
X-Paging-PerPage: 50
X-Paging-TotalItems: 320



All API endpoints that return an array of resource items can be sorted.

To sort a response, the optional sortby query is used. The sortby query is a comma-delimited list of properties and sort directions. The sort directions are asc for ascending and desc for descending.
Ascending is the default direction.

Example (Example url has not been url formatted for readability.)


        [ {
            "id": "3",
            "property1": "value3",
            "property2": {
              "subProperty1": "subvalue3", "subProperty2": {
                "subSubProperty1": "subsubvalue3"
            "created": "2018-09-27T09:59:47.492Z" 
            "id": "2", 
            "property1": "value2", 
            "property2": { 
                "subProperty1": "subvalue2", 
                "subProperty2": { 
                    "subSubProperty1": "subsubvalue2" 
            "created": "2018-09-26T16:15:52.937Z" 
            "id": "4", 
            "property1": "value2", 
            "property2": { 
                "subProperty1": "subvalue2", 
                "subProperty2": { 
                    "subSubProperty1": "subsubvalue2" 
            "created": "2018-09-25T13:19:11.383Z" 
            "id": "1", 
            "property1": "value1", 
            "property2": { 
                "subProperty1": "subvalue1", 
                "subProperty2": { 
                    "subSubProperty1": "subsubvalue1" 
            "created": "2018-09-27T09:44:22.115Z" 

GET -\=property1,created desc

Selective response

All endpoints in our API can filter the response to only return the fields you want. To filter a response, the optional fields query is used. The fields query is a comma-delimited list of the fields that you want in your response. This works when requesting a single resource as well as when requesting an array of resources.






                "property1": "value1",
                "property2": {
                    "subProperty1": "subvalue1",
                    "subProperty2": {
                        "subSubProperty1": "subsubvalue1"

GET -,property2.subProperty1,property2.subProperty2.subSubProperty

Response errors

Our API endpoints respond differently to validation errors and other errors.

Validation errors

Validation errors are serialized into a JSON object where the property names are the property names on the incoming model that failed validation. The value of the properties are arrays of strings that contain the validation error messages.

            "property1": [ "Property1 is required" ],
            "property2.subProperty1": [
                "SubProperty1 cannot be longer that 5 characters."


Other errors

Response codes

Our API endpoints try to return status codes that are as semantically correct as possible. The documentation for our API endpoints describes the specific response codes for each endpoint.

Status code Test Description
200 OK The request was successful and the response contains a body.
201 CREATED The request was successful and a resource was created. The response body contains the newly created resource.
202 ACCEPTED The request started an asynchronous process. This process could be successful or fail.
204 NO CONTENT The request was successful, but the response body is empty.
400 BAD REQUEST There was a data validation error.
401 UNAUTHORIZED Access token is missing, invalid, expired, or insufficient or the API key is invalid, missing, or insufficient.
404 NOT FOUND The resource requested doesn't exist.
415 UNSUPPORTED MEDIA TYPE The request body is formatted in a way that the endpoint doesn't understand.
500 INTERNAL SERVER ERROR Technical error on our end.