The Webhook events HTTP **`POST`** requests have custom headers containing the digital signature of the event that enable you to establish:

  • Integrity

  • Confidentiality

  • Idempotency

  • Non-repudiation

  • Authentication

for the event.

# Custom HTTP headers

HeaderDescription
**`x-8x8-tenant-id`**Contains your tenant ID This information matches the information in **[Configuration Manager](🔗)** **> Home > Profile > Tenant Label**
**`x-8x8-event-id`**The unique ID that is used to determine that the event notification you received is distinct from previous ones.
**`x-8x8-signature`**The **[digital signature](🔗)** which enables you to establish identity and confirms that the message has not been compromised. If the signature is not valid, the message can be dropped. See **[signature](🔗)** for validation information.
**`x-8x8-transmission-time`**The header for the request timestamp. This is different from the event timestamp that you may receive in the payload. If you are not able to confirm the event with a 2XX code, then 8x8 will retry the event after a brief delay. The transmission time changes at each retry.
**`x-8x8-retry`**Indicates the retry attempt for the same event.
**`x-8x8-customer-id`**The unique customer ID.

# Signature

The JSON Web Signature (JWS) with detached content and an unencoded payload.

The JWS is as specified according to [RFC 7515](🔗) which consists of:

  • A [JOSE Header](🔗)

  • [Data to be Signed](🔗) (not present if detached)

  • The JWS signature value

### JOSE Header

The JOSE Header describes the cryptographic operations applied to JWS.

The Chat API signature consists of:

  • **`alg`**: The **`alg`** (algorithm) header parameter identifies the cryptographic algorithm used to secure JWS (**[RFC 7515 Section 4.1.1](🔗)**)

  • **`kid`**: The **`kid`** (key ID) header parameter is a hint indicating which key was used to secure JWS (**[RFC 7515 Section 4.1.4](🔗)**)

    The **`kid`** is the ID of the keys resource used to sign JWS

    You can use this kid to fetch the **[public key](🔗)** and use it to validate JWS

  • **`b64`**: The **`b64`** header parameter stores password hashes computed with encoding **[RFC 7797 Section 3](🔗)**)

    Because the payload is not encoded, this value is **false**

  • **crit**: the **`crit`** (Critical) header parameter **[RFC 7515 Section 4.1.11](🔗)**

    This list contains **`b64`** encoding. **[RFC 7797 Section 6](🔗)**

### Data to be signed

The unencoded detached payload is in JSON format containing the following properties:

KeyDescription
**`checksum`** longThe checksum of the **`POST`** payload. You must: - Serialize the byte array with UTF-8 encoding - Compute the CRC32 checksum of the encoded body The CRC32 checksum value should be expressed in decimal format.
**`tt`** long**Transmission Time** - this value can be obtained from the **x-8x8-transmission-time** header
\__\`cid_\`\_ string**Customer ID** - this value can be obtained from the **x-8x8-customer-id** header
**`tid`** string**Tenant ID** - this value can be obtained from the **x-8x8-tenant-id** header
**`eid`** string**Event ID** - this value can be fetched from the **x-8x8-event-id** header
**`retry`** long**Retry attempt** - this value can be fetched from the **x-8x8-retry** header

Note:

Since a signature is computed for this payload, the order of keys is of critical importance. Review and adhere to the following order.

The keys are lexicographically ordered as follows:

  1. **`checksum`**

  2. **`cid`**

  3. **`eid`**

  4. **`retry`**

  5. **`tid`**

  6. **`tt`**

For example:



The request should resemble the following:



# Signature validation

To validate a signature:

  1. Obtain the request payload and compute the CRC32 **`checksum`** value for it.

    Note that **`checksum`** should be presented in decimal format.

  2. Extract all of the critical HTTP headers described in [**list of custom HTTP headers**](🔗)

  3. Reconstruct the detached payload of the JWS signature as shown in section [data to be signed](🔗)

    This UTF8 encoded JSON will be your **JWS Payload**

  4. Construct JWS Signing Input

    ASCII(BASE64URL(UTF8(JWS Protected Header)) || '.' || (JWS Payload))

  5. Obtain the public key ID from the JOSE Header

  6. Obtain the public key in JWK format from the [public key API](🔗)

  7. Validate the **JWS Signature** against the **JWS Signing Input** using the RS256 algorithm and the obtained key