Skip to main content

Receiving Webhooks

Webhook signing uses a symmetric key encryption strategy, that is, both QI CTVM and the integrating partner share the same key. When we configure Webhooks, we will generate a Signature Key and make it available. Every request originated in the QI system, will carry a SIGNATURE header that will be a JWT signed with this key. The encoding is performed with the HS256 algorithm.

The token carries the following claims:

ClaimDescription
timestampUTC date and time the signature was generated, in the YYYY-MM-DDTHH:MM:SS format.
methodHTTP method of the request. Always POST.
uriFull URL configured to receive the webhook.
payload_md5MD5 of the request body, in hexadecimal. Present whenever there is a body.

The request body is not signed directly. To validate its integrity, decode the token and compare payload_md5 against the MD5 of the body you received.

Below we have a python example of how to perform signature decoding:

from jose import jwt

signature_key = "UNIQUE CONFIGURED KEY"

signature_token = headers["SIGNATURE"]

decoded_token = jwt.decode(signature_token, key=signature_key, algorithms=["HS256"])
print(decoded_token)

We suggest that, in addition to comparing the signature, the integrating partner validates our IP, given that all our requests originate from the same IP, according to the environment:

EnvironmentIP
Production-
Sandbox-
Attention!

QI CTVM webhooks should not be mapped restrictively. Additional fields may be included in the webhook payloads returned in our APIs.