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
  • Example Curl request
  • Request signing example
  • Troubleshooting
  • Standards and formats
  • Response Signatures

Was this helpful?

  1. NOT SO BASICS

Signing

PreviousHeadersNextPython Code Example

Last updated 2 months ago

Was this helpful?

TL:DR On signing requests

Why we need signing

For some API calls we want to make sure the content tampered with. For instance making a payment, you would not want anyone to be able to change the amount or receiving party. Adding a signature allows bunq to detect whether the request body has been tampered with.

When do you need signing

Any request that creates or accepts a payment. If you forget to sign it we'll tell you with 466

What is a signature?

A signature is nothing more than a extra header: X-Bunq-Client-Signature that you add to your API call. You'll need to write some code in your application that takes in the request body and your private key (some examples are mentioned below)

When Do You Need to Sign Requests?

Most API calls don’t need signing, but any request that creates or accepts a payment does. If you forget to sign it, you’ll get a 466 error—so keep an eye out for that!

How It Works

  • You sign the request body (not the whole request).

  • We verify the signature on our end.

  • We sign our response, so you can verify it too.

What You Need

  • A private key (which you generate when installing your API connection).

  • The public key we send you, which you’ll use to verify our responses.

Example Curl request

This is a payment to Sugardaddy for €0,10. As you can see in the header we added the X-Bunq-Client-Signature header. This is just a Base64 encoded representation of the request body.

curl --location 'https://public-api.sandbox.bunq.com/v1/user/1800297/monetary-account/1989601/payment' \
--header [other headers]' \
--header 'X-Bunq-Client-Signature: eMymd9ynLx+j5tpcoPMlaJ7vEyxIZAXWInXIRxIOyP24KF7lpvNIwElB/wiQqVXr99pua4+onqvJUNiuceInAtohJnSGDEd58GjeBthz2OHTG5I0GZyJ9S8XAuBJYbqPgFaIk2m0VelPmjAHbiA3WSH0ASMDvcht/p4n60Y1GMVESXFovU2jUWX2X2k5QhowitIBJnsf4fkvYknbispFvUTn4ESU8QQVBgwR9QJ8DpxObGYbsTKQCyTzXoKNLM1mkw3pMwHn1EZ+AmOTx5iR/xXZLvvXWDmj9rEZWms7G1+drmhkK5aV8PuvR6s11mS6laRxyS1eoCaOcqeOZs1EcQ==' \
--data-raw '{
    "amount": {
        "value": "0.10",
        "currency": "EUR"
    },
    "counterparty_alias": {
        "type": "EMAIL",
        "value": "sugardaddy@bunq.com",
        "name": "Sugar Daddy"
    },
    "description": "My payment description :)"
}'

Request signing example

Consider the following request, a POST to /v1/user/126/monetary-account/222/payment (the JSON is formatted with newlines and indentations to make it more readable - be careful to account for that when creating your signature):

Header
Value

Cache-Control:

no-cache

User-Agent:

bunq-TestServer/1.00 sandbox/0.17b3

X-Bunq-Client-Authentication:

f15f1bbe1feba25efb00802fa127042b54101c8ec0a524c36464f5bb143d3b8b

{
    "amount": {
        "value": "12.50",
        "currency": "EUR"
    },
    "counterparty_alias": {
        "type": "EMAIL",
        "value": "bravo@bunq.com"
    },
    "description": "Payment for drinks."
}

Let's sign that request. First create a variable $dataToSign containing the body of the request:

{
    "amount": {
        "value": "12.50",
        "currency": "EUR"
    },
    "counterparty_alias": {
        "type": "EMAIL",
        "value": "bravo@bunq.com"
    },
    "description": "Payment for drinks."
}

Next, create the signature of $dataToSign using the SHA256 algorithm and the private key $privateKey of the Installation's key pair. In PHP, use the following to create a signature. The signature will be passed by reference into $signature.

openssl_sign($dataToSign, $signature, $privateKey, OPENSSL_ALGO_SHA256);

Encode the resulting $signature using base64, and add the resulting value to the request under the X-Bunq-Client-Signature header. You have just signed your request, and can send it!

Troubleshooting

If you are getting error 466 for invalid signatures then it's best to test these things:

Check list:

If you run into issues, double-check these points—or just use our SDKs, which handle all of this for you.

Standards and formats

To ensure secure and valid request and response signatures, you should use the following standards: First, apply SHA256 as the cryptographic hash function to hash the data (either the request body or response body). For the signing process, use the private key with PKCS #1 v1.5 padding for RSA encryption to generate the signature. Once the signature is created, it must be base64-encoded to ensure proper transmission in HTTP headers. This ensures that the integrity and authenticity of the data are preserved, and the signature can be verified by the recipient using the corresponding public key.

Response Signatures

If you struggle with signing you might want to try our . They handle signing for you

In some cases you might also want to validate whether responses are actually sent by bunq. Here you can do the same thing. If you stored the public key of the bunq server (you received this during ) you can verify the response sent by bunq and validate that the response body matches the signature.

error
SDK's
installation