Sign your requests [Payouts API]

All POST requests to Payouts APIs must be signed by including a valid Tl-Signature HTTP header.

When you sign your requests to our APIs, you ensure a second layer of security on top of the authorisation bearer token, guaranteeing that the payload has not been tampered with.


Supported algorithms

The only supported signing algorithm for POST requests to Payouts API is ES512.

ES512 belongs to the family of Elliptic Curve Digital Signature Algorithms (ECDSA).

To sign an HTTP request using ECDSA you will need to generate an Elliptic Curve (EC) key pair. You will need:

  • a public key, to be uploaded in the new Payments Settings page in our Console.
  • a private key, to be used for signing requests, which you should not share with anyone outside of your organisation. ES512, in particular, requires a key pair that uses the P-521 family of elliptic curves (also known as secpt521r1).

Generate a signing key pair

You can generate a key pair using openssl.

  1. To generate the private key, run:
docker run --rm -v ${PWD}:/out -w /out -it alpine/openssl ecparam -genkey -name secp521r1 -noout -out ec512-private-key.pem
  1. You can then obtain the public key by running:
docker run --rm -v ${PWD}:/out -w /out -it alpine/openssl ec -in ec512-private-key.pem -pubout -out ec512-public-key.pem
  1. Go to Console > Payments Settings and upload the file ec512-public-key.pem.

Sign your requests with our libraries

In our public repository we maintain libraries in a range of languages, which provide methods for signing and verifying according to the scheme described later. Our backend libraries also make use of these signing libraries for the API requests.

E.g. Java com.truelayer.truelayer-signing

// `Tl-Signature` value to send with the request.
String tlSignature = Signer.from(kid, privateKey)
        .header("Idempotency-Key", idempotencyKey)

Sign your requests without using libraries


Manual signing

We encourage the use of our signing libraries mentioned previously for easier integration.

To manually generate Tl-Signature headers, or verify webhook signatures, it’s still recommended to refer to TrueLayer/truelayer-signing reference implementations & examples.

In particular see the document describing the signing scheme.

Test your signing logic

You can send a POST request to our /test endpoint to verify that you have correctly implemented request signing.

curl -X POST \
    -H "Authorization: Bearer ${access_token}" \
    -H "Tl-Signature: ${signature}" \
    --data '{"nonce":"9f952b2e-1675-4be8-bb39-6f4343803c2f"}' \

The /test endpoint will validate your Tl-Signature header and return a 200 OK in case of success, it does not perform any kind of validation on the body schema.