Webhooks
Details on subscripting to webhook events
Please contact support to enable webhooks
How CLEAR uses webhooks
CLEAR uses webhooks to notify your application in real time when an event happens. Webhooks differ from regular API requests as they originate from CLEAR's servers rather than your own. This enables webhooks to inform your application about events happening outside of a traditional request context. An example of such an event could be a manual review submission.
A single webhook request notifies your application of an event, which may be any of the event types below. Additionally, the webhook can include additional data in its payload, such as the ID of the verification that was manually reviewed.
Event types
| Event | API name |
|---|---|
| Verification Session Created | event_verification_session_created_v1 |
| Verification Session Completed | event_verification_session_completed_v1 |
| Verification Session Status Update | event_verification_session_status_update_v1 |
Request body example
{
"event_id": "event_gS8XPhiNFOssvZ345ekOAdMnKBRb8oGGP",
"event_type": "event_verification_session_created_v1",
"object_name": "event",
"created_at": 1679707372.697349,
"data": {
"verification_session_id": "verify_U2uXnRZrN52397ycZfVmHodhHO0Xhbr0wH"
}
}Subscribing to events
In your Console webhook configuration, you can select which webhook events you want to subscribe to. You should only select the events that are relevant to your application, so you don't put unnecessary stress on your server. Note that all the webhook requests will be sent to the same webhook URL, regardless of event type. The body of the webhook will contain which type of event triggered it. The shape of this webhook is given below.
How to receive webhooks
To receive webhooks, you need a server that can receive HTTPS requests from CLEAR. Webhooks we send to you will always have authentication headers proving the request came from us. Details on authentication are described below.
Handling requests from CLEAR
Your server should handle the verification request and then immediately return an HTTP 200 response. If we don't receive a 200 response within 5 seconds, we will consider the request to have failed (see details below). If you need to complete a long operation in response to a webhook, you will need to complete that task after the webhook request has completed.
@app.route('/clear_webhook', methods=['POST'])
def handle_webhook(request: Request):
authenticate_webhook_request(request)
check_request_signature(request)
payload = request.json()
if payload["event_type"] == "verification_completed":
handle_verification_completed(payload["data"]["verification_id"])
return 200
Retries and failures
If your server responds with something other than a 200 (including 3XX redirect responses), or does not respond within 5 seconds, the webhook request will be considered to have failed. In this case, our server will try sending the webhook again, with increasing backoff, until about 30 hours have passed. At that point, we will mark the webhook as failed and make no further attempts to send it.
Authentication and security
Bearer token authentication
All webhook requests should be authenticated using the Bearer token included in the Authorization header. The value for this header is provided to you via the Console, and you should store it like a password or API key.
HMAC signatures
You can also verify that the request body originated from CLEAR using the HMAC signature header. If you elect to add this layer of security, we will generate an additional shared secret value, which you should store, and we will use this value to sign our requests in an X-CLEAR-HMAC-SHA256 request header.
To calculate the value of this header, CLEAR uses SHA256 to hash the HMAC secret concatenated with the request body. This value is sent in the X-CLEAR-HMAC-SHA256 request header. To validate the signature, calculate this value on your end and compare the result with the result from the header. This helps confirm that not only is the message from us, but also that the message not been altered.
Example
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import hmac
# authenticate Bearer token (required)
def authenticate_webhook_request(request: Request):
# fetch token from wherever you store secrets
token = secret.get("clear-webhook-token")
auth_header = request.headers.get("Authorization")
if auth_header[:7] != "Bearer":
raise UnauthorizedRequest
token_from_header = auth_header[7:]
if token != token_from_header:
raise UnauthorizedRequest
# authenticate HMAC signature (recommended)
def check_request_signature(request: Request):
# fetch shared secret from wherever you store secrets
token = secret.get("clear-webhook-hmac-secret")
body = request.body
# get signature from header
expected_signature = request.headers.get('X-CLEAR-HMAC-SHA256')
# calculate the signature from body and shared secret
h = hmac.HMAC(token.encode("utf-8"), hashes.SHA256())
h.update(body)
# check the signature
try:
h.verify(bytes.fromhex(expected_signature))
except Exception:
raise UnauthorizedRequestChanging webhook secrets
You can generate new secrets (bearer token and HMAC shared secret) via the Console. When you generate new secrets, they will take effect immediately and revoking previous credentials. Please contact support if you require this operation to be time-delayed and we can perform it manually.
Using HTTPS
All webhooks will be delivered over HTTPS. Any webhook endpoints with an http:// prefix will result in errors.
Guarantees
Webhooks are designed to be robust to various factors outside CLEAR's (and your) control. This includes network conditions and unexpected downtime. Retries are a critical part of this design that can also lead to some unexpected circumstances when receiving webhooks:
- Webhooks may be received out of order.
- Rarely, the same webhook event may be received twice. If this occurs, the
event_idwill be the same in the two instances.
Testing your webhook integration
You can test your webhook integration when setting up your webhook endpoint on the Console. The test button will fire an example event that your server should respond to like the other webhooks. If this request fails, you will receive an alert on the Console that the test event was not received properly.
Updated 2 days ago