bunq API Documentation
SDK'sPostman Collection
  • Getting Started
    • Welcome to the bunq API documentation
    • Tools
      • Software Development Kits (SDKs)
        • PHP
          • Usage
          • Tests
          • Exceptions
        • Java
          • Usage
          • Tests
          • Exceptions
        • Python
          • Usage
          • Tests
          • Exceptions
        • C#
          • Usage
          • Tests
          • Exceptions
      • Postman
      • Android Emulator
      • Developers Portal
  • Basics
    • bunq API Objects
      • User
      • Monetary Account
      • Payment
      • RequestInquiry
      • Card
      • Attachment and Note Attachment
    • API Context, Device Installation and Session
    • Authentication
      • API Keys
      • OAuth
    • Pagination
    • Errors
    • Rate Limits
    • Response body formatting
    • Moving to production
    • Headers
  • NOT SO BASICS
    • Signing
      • Python Code Example
        • Full main.py
        • Full bunq_lib.py
        • Full signing.py
      • PHP Code Example
    • Callbacks (Webhooks)
  • PSD2
    • Are you a Third Party Provider (TPP)? Start here!
      • Register as a TPP
      • Change your avatar
    • Account Information Service Provider (AISP)
    • Payment Initiation Service Provider (PISP)
    • Card-Based Payment Instrument Issuer (CBPII)
  • Support
    • FAQ
    • bunq status page
    • Terms and Conditions
  • TUTORIALS
    • Your first payment
      • Introduction
      • Creating a sandbox user and getting an API key
      • Creating the API Context
        • Creating the Installation
        • Device Registration
        • Start a Session
      • Setting up a sandbox user
        • Retrieving my user details
        • Getting sandbox money on the user account
        • Sandbox version of the bunq app
      • First Payments
    • Receiving payments on your website using bunq.me
    • How to manage your cards
      • Introduction
      • Ordering a card
      • Setting the card Limit and changing the PIN code
  • API Reference
    • Start here
    • Additional Transaction Information Category
    • Additional Transaction Information Category User Defined
    • Attachment
    • Attachment Public
    • Avatar
    • Billing Contract Subscription
    • bunqme
      • bunqme Tab
      • bunqme Fundraiser Profile
      • bunqme Tab Response
      • bunqme Fundraiser Result
    • Callback URL OAuth
    • Cards
      • Card
      • Card-Batch
      • Card Credit
      • Card Debit
      • Card Name
      • Card Replace
  • Confirmation Of Funds
  • Content and Exports
  • Currency Cloud
    • Currency cloud Benificiairy
    • Payment Quote
  • Currency Conversion
    • Convert
    • Quotes
  • Customer Statements
  • Devices
  • Draft Payment
  • Event
  • Exports
    • Export Annual Overview
    • Export RIB
    • Export Statement Card
  • Generated CVC2
  • Ideal Merchant Transaction
  • Insights
  • Installation
  • Invoice
  • Invoice Export
  • Legal Name
  • Limit
  • Mastercard Action
  • Monetary Account
    • Monetary Account Bank
    • Monetary Account Card
    • Monetary Account External
    • Monetary Account External Savings
    • Monetary Account Joint
    • Monetary Account Savings
    • Monetary Account Savings External
  • Name
  • Note Text & Attachment
    • Adyen Card Transaction
    • Switch Service Payment
    • bunqme fundraiser result
    • Draft Payment
    • Ideal Merchant Transaction
    • Mastercard Action
    • Open Banking Merchant
    • Payment Batch
    • Payment Delayed
    • Payment
    • Request Inquiry Batch
    • Request Response
    • Schedule Payment
    • Schedule Request
    • Sofort
    • Whitelist Result
  • Notification Filter
    • Notification Filter Email
    • Notification Filter Failure
    • Notification Filter Push
    • Notification Filter URL
  • OAuth
  • Payment
    • Payment
    • Payment Auto Allocate
    • Payment Batch
  • Payment Auto Allocation
  • Payment Service Provider
    • Payment Service Provider Credential
    • Payment Service Provider Draft Payment
    • Payment Service Provider Issuer Transaction
  • Request
    • Request Inquiry
    • Request Inquiry Batch
    • Request Response
  • Sandbox Users
  • Schedule
    • Schedule Instance
    • Schedule Payment
    • Schedule Payment Batch
  • Server Error
  • Server Public Key
  • Session
  • [deprecated] Share Invite Monetary Account Inquiry
  • Share Invite Monetary Account Response
  • Sofort Merchant Transaction
  • Statement
  • Switch Service Payment
  • Token QR Request Sofort
  • Transferwise
    • Transferwise Currency
    • Transferwise Quote
    • Transferwise Recipient
    • Transferwise Recipient Requirement
    • Transferwise Transfer
    • Transferwise Transfer Requirement
    • Transferwise User
  • Tree Progress
  • User
    • User Person
    • User Company
    • User Payment Service Provider
  • Whitelist SSD
    • Whitelist SSD One Off
    • Whitelist SSD Recurring
  • Content
Powered by GitBook
On this page
  • Installation
  • Getting Started
  • Core Concepts
  • Making API Calls
  • Working with Resources
  • Advanced Features
  • Error Handling
  • Examples
  • Troubleshooting

Was this helpful?

  1. Getting Started
  2. Tools
  3. Software Development Kits (SDKs)
  4. Python

Usage

Installation

Install the bunq Python SDK using pip:

pip install bunq_sdk --upgrade

Getting Started

Creating an API Context

Before you can make any API calls, you need to create an API context. This involves registering your API key and device, and creating a session.

from bunq.sdk.context.api_context import ApiContext
from bunq.sdk.context.bunq_context import BunqContext
from bunq import ApiEnvironmentType

# Create an API context for production
api_context = ApiContext.create(
    ApiEnvironmentType.PRODUCTION, # SANDBOX for testing
    "YOUR_API_KEY",
    "My Device Description"
)

# Save the API context to a file for future use
api_context.save("bunq_api_context.conf")

# Load the API context into the SDK
BunqContext.load_api_context(api_context)

Note: Initializing an API context is a heavy operation and should only be done once per device.

Saving and Restoring the API Context

After creating an API context, you can save it to a file and restore it in future sessions:

# Save API context
api_context.save("bunq_api_context.conf")

# Restore API context
api_context = ApiContext.restore("bunq_api_context.conf")
BunqContext.load_api_context(api_context)

PSD2 Integration

The SDK supports PSD2 (Payment Services Directive 2) integration, allowing you to act as a PSD2 Service Provider:

api_context = ApiContext.create_for_psd2(
    ApiEnvironmentType.SANDBOX,
    certificate,             # Your eIDAS certificate
    private_key,             # Your private key
    certificate_chain,       # Your certificate chain
    "PSD2 Device Description"
)

api_context.save("bunq_psd2_api_context.conf")

Note: For sandbox environments, any certificate meeting basic criteria will be accepted. For production, you'll need a valid eIDAS certificate.

Safety Considerations

The file storing your API context (e.g., bunq_api_context.conf) contains sensitive information that provides access to your bunq account. Store this file in a secure location and ensure it's not accessible to unauthorized users.

Core Concepts

API Context

The API context contains your authentication credentials and session information for interacting with the bunq API. It includes:

  • API key

  • Installation token

  • Session token

  • Server public key

  • Environment type (Sandbox or Production)

User Context

The user context represents the user you're authenticated as and provides access to account-specific operations:

# Access the user context
user_context = BunqContext.user_context()

# Get the user ID
user_id = user_context.user_id

# Get the primary monetary account
primary_account = user_context.primary_monetary_account

Monetary Accounts

Monetary accounts are banking accounts within bunq. A user can have multiple monetary accounts, with one designated as the primary account.

Making API Calls

The SDK follows a consistent pattern for API calls. Each endpoint has a corresponding class with methods for supported operations.

Creating Objects

To create a new resource:

from bunq.sdk.model.generated.endpoint import PaymentApiObject
from bunq.sdk.model.generated.object_ import AmountObject, PointerObject

# Create a payment
payment_id = PaymentApiObject.create(
    amount=AmountObject("10.00", "EUR"),
    counterparty_alias=PointerObject("EMAIL", "recipient@example.com"),
    description="Payment for services"
).value

Reading Objects

To retrieve a specific resource:

from bunq.sdk.model.generated.endpoint import MonetaryAccountBankApiObject

# Get a monetary account
monetary_account = MonetaryAccountBankApiObject.get(account_id).value

Updating Objects

To update an existing resource:

from bunq.sdk.model.generated.endpoint import CardApiObject

# Update a card's settings
CardApiObject.update(
    card_id=123,
    monetary_account_current_id=456
)

Deleting Objects

To delete a resource:

from bunq.sdk.model.generated.endpoint import SessionApiObject

# Delete a session
SessionApiObject.delete(session_id)

Listing Objects

To retrieve a list of resources:

from bunq.sdk.model.generated.endpoint import PaymentApiObject
from bunq import Pagination

# Create pagination settings
pagination = Pagination()
pagination.count = 10  # Number of items per page

# List payments with pagination
payments = PaymentApiObject.list(params=pagination.url_params_count_only).value

Working with Resources

Payments

Make payments between accounts:

from bunq.sdk.model.generated.endpoint import PaymentApiObject
from bunq.sdk.model.generated.object_ import AmountObject, PointerObject

# Make a payment to another user
payment_id = PaymentApiObject.create(
    amount=AmountObject("5.00", "EUR"),
    counterparty_alias=PointerObject("EMAIL", "recipient@example.com"),
    description="Lunch payment"
).value

# Make a payment to another account of the same user
payment_id = PaymentApiObject.create(
    amount=AmountObject("5.00", "EUR"),
    counterparty_alias=PointerObject("IBAN", "NL12BUNQ1234567890"),
    description="Transfer to savings"
).value

# Create a batch of payments
from typing import List

def create_payment_batch(payments_list: List[PaymentApiObject]):
    return PaymentBatchApiObject.create(payments_list).value

Monetary Accounts

Create and manage monetary accounts:

from bunq.sdk.model.generated.endpoint import MonetaryAccountBankApiObject

# Create a new monetary account
account_id = MonetaryAccountBankApiObject.create(
    currency="EUR",
    description="Savings Account"
).value

# Close a monetary account
MonetaryAccountBankApiObject.update(
    monetary_account_id=account_id,
    status="CANCELLED",
    sub_status="REDEMPTION_VOLUNTARY",
    reason="OTHER",
    reason_description="No longer needed"
)

Cards

Manage debit cards:

from bunq.sdk.model.generated.endpoint import CardDebitApiObject
from bunq.sdk.model.generated.object_ import CardPinAssignmentObject
from bunq.sdk.context.bunq_context import BunqContext

# Get allowed card name
card_name = CardNameApiObject.list().value[0].possible_card_name_array[0]

# Create a pin code assignment
pin_code_assignment = CardPinAssignmentObject(
    "PRIMARY",
    "MANUAL",
    "1234",
    BunqContext.user_context().primary_monetary_account.id_
)

# Order a new debit card
card_id = CardDebitApiObject.create(
    second_line="MY CARD",
    name_on_card=card_name,
    type_="MASTERCARD",
    product_type="MASTERCARD_DEBIT",
    alias=primary_alias,
    pin_code_assignment=[pin_code_assignment]
).value

# Update a card
from bunq.sdk.model.generated.endpoint import CardApiObject

CardApiObject.update(
    card_id=card_id,
    monetary_account_current_id=account_id
)

Attachments and Avatars

Work with attachments and avatars:

from bunq.sdk.model.generated.endpoint import AttachmentPublicApiObject
from bunq.sdk.model.generated.endpoint import AttachmentPublicContentApiObject
from bunq.sdk.model.generated.endpoint import AvatarApiObject
from bunq.sdk.http.api_client import ApiClient

# Upload a public attachment
custom_headers = {
    ApiClient.HEADER_CONTENT_TYPE: "image/jpeg",
    ApiClient.HEADER_ATTACHMENT_DESCRIPTION: "Profile picture",
}

# Read file contents
with open("picture.jpg", "rb") as file:
    attachment_contents = file.read()

# Create attachment
attachment_uuid = AttachmentPublicApiObject.create(
    attachment_contents, 
    custom_headers
).value

# Create an avatar using the attachment
avatar_uuid = AvatarApiObject.create(attachment_uuid).value

# Retrieve attachment content
attachment_content = AttachmentPublicContentApiObject.list(attachment_uuid).value

Requests

Create and respond to payment requests:

from bunq.sdk.model.generated.endpoint import RequestInquiryApiObject
from bunq.sdk.model.generated.endpoint import RequestResponseApiObject
from bunq.sdk.model.generated.object_ import AmountObject

# Create a payment request
request_id = RequestInquiryApiObject.create(
    AmountObject("10.00", "EUR"),
    counterparty_alias,
    "Please pay for dinner",
    allow_bunqme=False
).value

# Accept a payment request
RequestResponseApiObject.update(
    request_response_id,
    monetary_account_id,
    status="ACCEPTED"
)

Sharing

Share accounts with other bunq users:

from datetime import datetime, timedelta
from bunq.sdk.model.generated.endpoint import DraftShareInviteBankApiObject
from bunq.sdk.model.generated.object_ import DraftShareInviteEntryObject, ShareDetailObject, ShareDetailReadOnlyObject

# Set expiration date (1 hour from now)
expiration_date = (datetime.utcnow() + timedelta(hours=1)).isoformat()

# Define share details (what the connected person can see/do)
share_detail = ShareDetailObject(read_only=ShareDetailReadOnlyObject(True, True, True))
share_settings = DraftShareInviteEntryObject(share_detail)

# Create share invite
draft_id = DraftShareInviteBankApiObject.create(expiration_date, share_settings).value

Generating Share QR Code

from bunq.sdk.model.generated.endpoint import DraftShareInviteBankQrCodeContentApiObject

# Get QR code content
qr_content = DraftShareInviteBankQrCodeContentApiObject.list(draft_id).value

# Save QR code as an image
with open('connect-qr.png', 'wb') as f:
    f.write(qr_content)

Advanced Features

Pagination

The SDK supports pagination for listing resources:

from bunq import Pagination

# Create a pagination object
pagination = Pagination()
pagination.count = 5  # Number of items per page

# Get the first page
response = PaymentApiObject.list(params=pagination.url_params_count_only)
pagination_info = response.pagination

# Check if there's a previous page
if pagination_info.has_previous_page():
    # Get the previous page
    previous_page = PaymentApiObject.list(
        params=pagination_info.url_params_previous_page
    ).value

# Check if there's a next page
if pagination_info.has_next_page_assured():
    # Get the next page
    next_page = PaymentApiObject.list(
        params=pagination_info.url_params_next_page
    ).value

Notification Filters

Set up notification filters (webhooks) to receive updates when certain events occur:

from bunq.sdk.model.core.notification_filter_url_user_internal import NotificationFilterUrlUserInternal
from bunq.sdk.model.core.notification_filter_push_user_internal import NotificationFilterPushUserInternal
from bunq.sdk.model.generated.object_ import NotificationFilterUrl, NotificationFilterPush

# Create a URL notification filter for account mutations
notification_filter = NotificationFilterUrl("MUTATION", "https://your-webhook.com/callback")
all_notification_filter = [notification_filter]

# Set up user-level URL notifications
created_filters = NotificationFilterUrlUserInternal.create_with_list_response(
    all_notification_filter
).value

# Create a push notification filter
push_filter = NotificationFilterPush("MUTATION")
all_push_filter = [push_filter]

# Set up user-level push notifications
created_push_filters = NotificationFilterPushUserInternal.create_with_list_response(
    all_push_filter
).value

# Clear all notification filters
NotificationFilterUrlUserInternal.create_with_list_response()  # Empty list clears filters

Setting up Account-Specific Notification Filters

You can also set up notification filters for specific monetary accounts:

from bunq.sdk.model.core.notification_filter_url_monetary_account_internal import NotificationFilterUrlMonetaryAccountInternal
from bunq.sdk.model.generated.object_ import NotificationFilterUrl

# Create a notification filter
notification_filter = NotificationFilterUrl("MUTATION", "https://your-webhook.com/account-callback")

# Set up notification filter for a specific monetary account
NotificationFilterUrlMonetaryAccountInternal.create_with_list_response(
    monetary_account_id,    
    [notification_filter]
)

# Clear notification filters for a specific account
NotificationFilterUrlMonetaryAccountInternal.create_with_list_response(
    monetary_account_id,
    []  # Empty list clears filters
)

OAuth

Use OAuth for authentication:

from bunq.sdk.model.core.oauth_authorization_uri import OauthAuthorizationUri
from bunq.sdk.model.core.oauth_response_type import OauthResponseType
from bunq.sdk.model.generated.endpoint import OauthClient

# Create an OAuth client
oauth_client = OauthClient("My OAuth Client")

# Generate an authorization URI
authorization_uri = OauthAuthorizationUri.create(
    OauthResponseType(OauthResponseType.CODE),
    "https://your-redirect-uri.com/callback",
    oauth_client,
    "state_token"
).get_authorization_uri()

# Direct user to the authorization URI
print("Please visit:", authorization_uri)

Session Management

Manage API sessions:

from bunq.sdk.model.generated.endpoint import SessionApiObject
from bunq.sdk.context.bunq_context import BunqContext

# Delete the current session
SessionApiObject.delete(0)

# Reset the API context session
BunqContext.api_context().reset_session()

# Save the updated API context
BunqContext.api_context().save("bunq_api_context.conf")

Error Handling

The SDK uses exceptions to handle errors:

from bunq.sdk.exception.api_exception import ApiException
from bunq.sdk.exception.bunq_exception import BunqException

try:
    # API call that might fail
    MonetaryAccountBankApiObject.get(invalid_account_id)
except ApiException as e:
    # Handle API-specific errors
    print(f"API error: {e.message}")
    print(f"Response ID: {e.response_id}")  # Useful for support
except BunqException as e:
    # Handle general SDK errors
    print(f"SDK error: {e.message}")
except Exception as e:
    # Handle other exceptions
    print(f"Unexpected error: {str(e)}")

Examples

Example: Making a Payment

from bunq.sdk.context.api_context import ApiContext
from bunq.sdk.context.bunq_context import BunqContext
from bunq.sdk.model.generated.endpoint import PaymentApiObject
from bunq.sdk.model.generated.object_ import AmountObject, PointerObject

# Load API context
api_context = ApiContext.restore("bunq_api_context.conf")
BunqContext.load_api_context(api_context)

# Create a payment
payment_id = PaymentApiObject.create(
    amount=AmountObject("5.00", "EUR"),
    counterparty_alias=PointerObject("EMAIL", "recipient@example.com"),
    description="Test payment"
).value

print(f"Payment created with ID: {payment_id}")

Example: Listing Transactions

from bunq.sdk.context.api_context import ApiContext
from bunq.sdk.context.bunq_context import BunqContext
from bunq.sdk.model.generated.endpoint import PaymentApiObject
from bunq import Pagination

# Load API context
api_context = ApiContext.restore("bunq_api_context.conf")
BunqContext.load_api_context(api_context)

# Create pagination
pagination = Pagination()
pagination.count = 10

# List payments
payments = PaymentApiObject.list(params=pagination.url_params_count_only).value

# Display payments
for payment in payments:
    print(f"ID: {payment.id_}")
    print(f"Amount: {payment.amount.value} {payment.amount.currency}")
    print(f"Description: {payment.description}")
    print("---")

Troubleshooting

Common Issues and Solutions

  1. Authentication Failures

    • Ensure your API key is valid

    • Check that your API context file is up-to-date

    • Try refreshing your session with BunqContext.api_context().ensure_session_active()

  2. Expired Sessions

    • Sessions automatically expire; use api_context.ensure_session_active() to refresh if needed

    • The SDK will usually handle this automatically

  3. Missing Permissions

    • Ensure your API key has the necessary permissions for the actions you're trying to perform

  4. Resource Not Found

    • Verify that the resource IDs you're using are correct

    • Check if the resources still exist (e.g., a monetary account may have been closed)

  5. Rate Limiting

    • The bunq API has rate limits; implement exponential backoff if you encounter rate limiting

PreviousPythonNextTests

Last updated 21 days ago

Was this helpful?

For additional help, refer to the or the .

bunq Developer Portal
bunq forum