Receive status updates on your resources

Status updates for a payment are received via webhooks. A webhook is an HTTP request sent by Truelayer, everytime a status change occurs for a payment. You can configure the URI for this webhook in your Console.

You can find out more about console configuration.

Truelayer payment APIs will send only three of the statuses in the lifecycle of a payment. Failed, Executed and Settled. For more information about statuses, check out our page on payment statuses.

Header structure of the requests:

X-TL-Webhook-TimestamptimestampTime that the webhook was sent to you. This will be in the following format: 2020-05-18T10:17:47Z.
TL-SignaturestringJSON web signature with a detached payload of the form {HEADER}..{SIGNATURE}

More detailed information about the fields in the JSON body of the webhook request is as following:






Type of the event.
Possible values:



Unique event UUID



UUID of the payment for which the webhook is being sent



Version of the event



Time of the event if the event is payment_executed



Time of the event if the event is payment_settled



Time of the event if the event is payment_failed


json object

Source of the payment for which the event is being sent



UUID of the user associated to the payment

Some example requests


  "type": "payment_executed",
  "event_version": 1,
  "event_id": "b8d4dda0-ff2c-4d77-a6da-4615e4bad941",
  "payment_id": "60c0a60ed8d7-4e5b-ac79-401b1d8a8633",
  "executed_at": "2021-12-25T15:00:00.000Z",
  "payment_source": {
    "account_identifiers": [],
    "id": "string",
    "account_holder_name": "string"


  "type": "payment_failed",
  "event_version": 1,
  "event_id": "b8d4dda0-ff2c-4d77-a6da-4615e4bad941",
  "payment_id": "60c0a60ed8d7-4e5b-ac79-401b1d8a8633",
  "failed_at": "2021-12-25T15:00:00.000Z",
  "failure_stage": "authorizing",
  "failure_reason": "provider_rejected"


  "type": "payment_settled",
  "event_version": 1,
  "event_id": "b8d4dda0-ff2c-4d77-a6da-4615e4bad941",
  "payment_id": "60c0a60ed8d7-4e5b-ac79-401b1d8a8633",
  "settled_at": "2021-12-25T15:00:00.000Z",
  "payment_source": {
    "account_identifiers": [
        "type": "sort_code_account_number",
        "sort_code": "111111",
        "account_number": "00000111"
        "type": "iban",
        "iban": "GB11CLRB01011100000111"
    "id": "1f111d3c-9427-43be-1111-1111219d111c",
    "account_holder_name": "HOLDER NAME"
  "user_id": "ec01ece1-1dbe-48f1-82b2-bce8cfa44d08"

Validate the received webhook signature

We recommend developers to use our signing libraries to verify the signatures of the received webhooks.


For the best development experience, use our signing libraries to verify signatures.

Verifying the signature manually

In order to verify that the webhook is coming from Truelayer (to prevent spoof attacks), you should validate the signature that comes with the webhook in the headers.

The value of the TL-Signature header contains a JSON Web Signature (JWS) with a detached payload. It takes the form {HEADER}..{SIGNATURE}.

The JWS header contains the following values:

algstringThe algorithm used to sign the webhook. We currently use the ES512 algorithm.
jkustringThe URI of the JSON Web Key Set (JWKS), a hosted page where a list of public keys owned by TrueLayer can be found.
kidstringThe ID of the key used to sign the webhook, used to retrieve the correct key from the JWKS.

The steps for verifying the signature are as follows:

1. Verify the jku field in the token header matches the expected value as listed below. If not, the signature should be rejected as invalid.
- Sandbox:
- Production:
2. Use the jku value to retrieve the JWKS. This may be cached for some time, but if verification fails, the JWKS must be retrieved again to ensure that all keys are up-to-date. TrueLayer may rotate or revoke keys at any time.
3. Retrieve the relevant public key by using the kid to look up the relevant value from the JWKS.
4. Use a JWT library to verify the JWS headers combined with the payload.

Here is how to create the content for which you need to verify the signature

  • The HTTP VERB (capitalized), followed by a space, then the absolute path (without trailing slashes)
    Example: POST /webhook-endpoint, followed by a newline character \n
  • For each header specified in tl_headers, in the same order (and with the same casing):
    - The header name, followed by a colon, a space, then the header value, for example:
    content-type: application/json, followed by a newline character \n
  • The serialized HTTP request body (if sending a body)

The following example shows what a JWS payload might look like:

POST /webhook-endpoint
content-type: application/json
x-tl-webhook-timestamp: 2022-02-16T16:21:14Z    
  "type": "payment_executed",
  "event_version": 1,
  "event_id": "373920a2-61b0-438e-a525-48d3bfcf2762",
  "payment_id": "7f97fcbb-44b6-44bc-ae96-955d6e94cfd9",
  "executed_at": "2022-02-16T16:21:14.503Z"

Did this page help you?