> For the complete documentation index, see [llms.txt](https://doc.bunq.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://doc.bunq.com/basics/authentication/oauth/python-code-example-psd2-oauth-integration.md).

# Python Code Example PSD2 - OAuth integration

{% embed url="<https://github.com/two-trick-pony-NL/PSD2-Implementation-for-bunq-API>" %}

In the linked repository you'll find a example integration that has all the moving parts of setting up a bunq server and the oauth flow.&#x20;

## Setting up the example

In order to use the code example we expect you have a python environment set up. Simply running \`pip install -r requirements.txt\` will take care of setting up dependancies. \
\
If you are a PSD2 user you'll want to create a  `UserPaymentServiceProvider` user. These are specific users that have no banking features attached to their bunq account. If that's the case you'll want to run the `create_psd2_user.sh` script. That will register a sandbox PSD2 user for you.&#x20;

If you're just a bunq business user you can just paste your [API Keys](/basics/authentication/api-keys.md) in the `main.py` file. <br>

From there you can run \`uvicorn main:app --reload' this will kick off a uvicorn server, serving a FastAPI app on port 8000 to start the server

## Initializing your installation&#x20;

We prepared a endpoint that you'll have to run 1x it will set up the [Broken mention](broken://pages/O5LLvymwcVpljw1lv1dN). It will also register your [OAuth](/oauth.md)client and register a [Callback URL OAuth](/api-reference/callback-url-oauth.md).&#x20;

You can do so by hitting the localhost:8000/setup\_one\_time it will take a minute.

Finally that script will create a .env file that can be used going forward.&#x20;

This is a great step to remove your API key from the `main.py` file. From now on it will be read from the `.env` file.&#x20;

## Using Oauth&#x20;

You can now go to your localhost:8000/auth endpoint which will trigger a oauth request. If you have the [Android Emulator](/getting-started/tools/android-emulator.md) on a physical device you'll be able to scan the QR code that is generated and complete the oauth flow.&#x20;

What happens in the background is:&#x20;

1. The app created a oauth client in the set up. This allows us to now generate a oauth session. It is a screen with a QR code that the end-user scans with their bunq app&#x20;
2. In the app the bunq user can select which monetary accounts they grant access to.&#x20;
3. When the user completes the steps they are redirected to our app. With a authorization code from bunq. This code is immidiatly used by the app to request a access token. The app stores that access token in a database. and assosciates it to a user. We did not build a pretty page but if the oauth flow was successful you'll see a json response with: <br>

   ```
   {"message":"OAuth success","new_user_id":1}
   ```

   This means that we stored a user in our local database with id 1 that has a bunq oauth access token associated to it.&#x20;
4. So now we can retrieve data on that user. One way to do that is to visit the /docs endpoint. FastApi offers a interactive API documentation. You can also simply visit the localhost:8000/user/1 url. If you request data on behalf of a user then this happens: \
   1\. We look up the bunq access token for that user 1 in our database\
   2\. We request a session token with the access token \
   3\. We make the API call we want with that session token \
   4\. Return the results to the end-user

For instance: if you go to the user/2/accounts endpoint you'll get a summary of the [Monetary Account](/monetary-account.md)for that user:&#x20;

```json
{
  "Response": [
    {
      "MonetaryAccountBank": {
        "id": 2083712,
        "created": "2025-04-14 00:00:00.811318",
        "updated": "2025-04-14 00:00:00.811318",
        "alias": [
          {
            "type": "PHONE_NUMBER",
            "value": "+31611019364",
            "name": "+31611019364"
          },
          {
            "type": "EMAIL",
            "value": "testers+1744621019@bunq.com",
            "name": "testers+1744621019@bunq.com"
          },
          {
            "type": "IBAN",
            "value": "NL65BUNQ2090411945",
            "name": "Jodi Walker"
          }
        ],
        "avatar": {
          "uuid": "2ef45ffc-67e9-44ac-a432-a8987c5d4e9d",
          "image": [
            {
              "attachment_public_uuid": "3f3a3d92-b646-463c-ae8d-6a0393e45500",
              "height": 1023,
              "width": 1024,
              "content_type": "image/png",
              "urls": [
                {
                  "type": "ORIGINAL",
                  "url": "https://bunq-triage-model-storage-public.s3.eu-central-1.amazonaws.com/bunq_file/File/content/921ece497cd00f4e0cef3f0f63a962c31cf3f8e35311d127d5a7b23be3d074d5.png"
                }
              ]
            }
          ],
          "anchor_uuid": "5e758d81-add9-4510-89e1-ff2bd5a04146",
          "style": "NONE"
        },
        "balance": {
          "currency": "EUR",
          "value": "4118.00"
        },
        "country": "NL",
        "currency": "EUR",
        "display_name": "J. Walker",
        "daily_limit": {
          "currency": "EUR",
          "value": "5000.00"
        },
        "description": "Main",
        "public_uuid": "5e758d81-add9-4510-89e1-ff2bd5a04146",
        "status": "ACTIVE",
        "sub_status": "NONE",
        "timezone": "europe/amsterdam",
        "user_id": 1864430,
        "monetary_account_profile": null,
        "setting": {
          "color": "#FF7819",
          "icon": null,
          "default_avatar_status": "AVATAR_DEFAULT",
          "restriction_chat": "ALLOW_INCOMING",
          "sdd_expiration_action": "AUTO_ACCEPT"
        },
        "connected_cards": [],
        "budget": [],
        "all_access": [
          {
            "MonetaryAccountAccess": {
              "id": 2268800,
              "created": "2025-04-14 00:00:00.822699",
              "updated": "2025-04-14 00:00:00.822699",
              "access_type": "FULL_PERMANENT"
            }
          }
        ],
        "overdraft_limit": {
          "currency": "EUR",
          "value": "0.00"
        },
        "all_auto_save_id": []
      }
    },
    {
      "MonetaryAccountBank": {
        "id": 2083715,
        "created": "2025-04-14 09:12:06.578796",
        "updated": "2025-06-03 09:48:46.647401",
        "alias": [
          {
            "type": "IBAN",
            "value": "NL55BUNQ2090409118",
            "name": "Jodi Walker"
          }
        ],
        "avatar": {
          "uuid": "f8217171-567f-4034-ac5e-5fc281b611a6",
          "image": [
            {
              "attachment_public_uuid": "fa99b3bf-7121-4d23-9fe9-6ce48ff76285",
              "height": 1024,
              "width": 1024,
              "content_type": "image/jpeg",
              "urls": [
                {
                  "type": "ORIGINAL",
                  "url": "https://bunq-triage-model-storage-public.s3.eu-central-1.amazonaws.com/bunq_file/File/content/1fcb8573f717dc6406dbbb170367f98cbed175ca4d3bee3aeaa772fdcf284c1a.jpg"
                }
              ]
            }
          ],
          "anchor_uuid": "0477b9c1-ff11-4fcb-9bf1-9b84b1b5c27d",
          "style": "NONE"
        },
        "balance": {
          "currency": "EUR",
          "value": "1900.00"
        },
        "country": "NL",
        "currency": "EUR",
        "display_name": "J. Walker",
        "daily_limit": {
          "currency": "EUR",
          "value": "5000.00"
        },
        "description": "Main",
        "public_uuid": "0477b9c1-ff11-4fcb-9bf1-9b84b1b5c27d",
        "status": "ACTIVE",
        "sub_status": "NONE",
        "timezone": "europe/amsterdam",
        "user_id": 1864430,
        "monetary_account_profile": null,
        "setting": {
          "color": "#ff7819",
          "icon": "FINANCE",
          "default_avatar_status": "AVATAR_ICON",
          "restriction_chat": "ALLOW_INCOMING",
          "sdd_expiration_action": "AUTO_ACCEPT"
        },
        "connected_cards": [],
        "budget": [],
        "all_access": [
          {
            "MonetaryAccountAccess": {
              "id": 2268802,
              "created": "2025-04-14 09:12:06.599804",
              "updated": "2025-04-14 09:12:06.599804",
              "access_type": "FULL_PERMANENT"
            }
          }
        ],
        "overdraft_limit": {
          "currency": "EUR",
          "value": "0.00"
        },
        "all_auto_save_id": []
      }
    },
    {
      "MonetaryAccountBank": {
        "id": 2083719,
        "created": "2025-04-14 09:12:58.553604",
        "updated": "2025-04-14 09:14:06.776031",
        "alias": [
          {
            "type": "IBAN",
            "value": "NL17BUNQ2090415428",
            "name": "Jodi Walker"
          }
        ],
        "avatar": {
          "uuid": "48bb720a-6baf-4482-a78c-b8592e5fde08",
          "image": [
            {
              "attachment_public_uuid": "0e76b824-36ef-4680-9554-0c2da11f6ed9",
              "height": 1024,
              "width": 1024,
              "content_type": "image/jpeg",
              "urls": [
                {
                  "type": "ORIGINAL",
                  "url": "https://bunq-triage-model-storage-public.s3.eu-central-1.amazonaws.com/bunq_file/File/content/4c90f8a578279abd53b06840a4dd619009c2f4b9ddc4342dbf12e4fbf11bbd4a.jpg"
                }
              ]
            }
          ],
          "anchor_uuid": "fbb765b0-2eef-4c91-8060-37950b65694a",
          "style": "NONE"
        },
        "balance": {
          "currency": "EUR",
          "value": "954.00"
        },
        "country": "NL",
        "currency": "EUR",
        "display_name": "J. Walker",
        "daily_limit": {
          "currency": "EUR",
          "value": "5000.00"
        },
        "description": "Car",
        "public_uuid": "fbb765b0-2eef-4c91-8060-37950b65694a",
        "status": "ACTIVE",
        "sub_status": "NONE",
        "timezone": "europe/amsterdam",
        "user_id": 1864430,
        "monetary_account_profile": null,
        "setting": {
          "color": "#47bfff",
          "icon": "TRANSPORT",
          "default_avatar_status": "AVATAR_ICON",
          "restriction_chat": "ALLOW_INCOMING",
          "sdd_expiration_action": "AUTO_ACCEPT"
        },
        "connected_cards": [],
        "budget": [],
        "all_access": [
          {
            "MonetaryAccountAccess": {
              "id": 2268806,
              "created": "2025-04-14 09:12:58.575972",
              "updated": "2025-04-14 09:12:58.575972",
              "access_type": "FULL_PERMANENT"
            }
          }
        ],
        "overdraft_limit": {
          "currency": "EUR",
          "value": "0.00"
        },
        "all_auto_save_id": []
      }
    },
    {
      "MonetaryAccountBank": {
        "id": 2083721,
        "created": "2025-04-14 09:13:51.146459",
        "updated": "2025-04-14 09:13:51.146459",
        "alias": [
          {
            "type": "IBAN",
            "value": "NL09BUNQ2090405775",
            "name": "Jodi Walker"
          }
        ],
        "avatar": {
          "uuid": "5ac4305a-846b-46c0-bff7-b383db308acf",
          "image": [
            {
              "attachment_public_uuid": "b312f25b-fb29-4fd0-a971-79c6eaf8b8e0",
              "height": 1024,
              "width": 1024,
              "content_type": "image/jpeg",
              "urls": [
                {
                  "type": "ORIGINAL",
                  "url": "https://bunq-triage-model-storage-public.s3.eu-central-1.amazonaws.com/bunq_file/File/content/854e26c59d732cf32e7187f7ee4bcc11f8415d06f99ed59780fcc21883bd0f62.jpg"
                }
              ]
            }
          ],
          "anchor_uuid": "81802c69-3039-4d73-8138-da6e43acb7f0",
          "style": "NONE"
        },
        "balance": {
          "currency": "EUR",
          "value": "1643.00"
        },
        "country": "NL",
        "currency": "EUR",
        "display_name": "J. Walker",
        "daily_limit": {
          "currency": "EUR",
          "value": "5000.00"
        },
        "description": "Medical",
        "public_uuid": "81802c69-3039-4d73-8138-da6e43acb7f0",
        "status": "ACTIVE",
        "sub_status": "NONE",
        "timezone": "europe/amsterdam",
        "user_id": 1864430,
        "monetary_account_profile": null,
        "setting": {
          "color": "#ff2d55",
          "icon": "HEALTHCARE",
          "default_avatar_status": "AVATAR_ICON",
          "restriction_chat": "ALLOW_INCOMING",
          "sdd_expiration_action": "AUTO_ACCEPT"
        },
        "connected_cards": [],
        "budget": [],
        "all_access": [
          {
            "MonetaryAccountAccess": {
              "id": 2268808,
              "created": "2025-04-14 09:13:51.163604",
              "updated": "2025-04-14 09:13:51.163604",
              "access_type": "FULL_PERMANENT"
            }
          }
        ],
        "overdraft_limit": {
          "currency": "EUR",
          "value": "0.00"
        },
        "all_auto_save_id": []
      }
    }
  ],
  "Pagination": {
    "future_url": null,
    "newer_url": null,
    "older_url": null
  }
}
```

<br>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://doc.bunq.com/basics/authentication/oauth/python-code-example-psd2-oauth-integration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
