Integration API keys identify which WApp Chat tenant owns an incoming automation event.
Create and revoke keys from https://wapp.chat/whatsapp/integrations.
Authentication #
Send the key in one of these headers:
x-wappchat-key: wchat_live_...
or:
Authorization: Bearer wchat_live_...
The server stores a hash of the key. The raw key is shown only when it is created.
Revocation #
Deleted keys are revoked and cannot authenticate new requests. Existing event logs remain for auditing.
Use key revocation when:
- a user leaves the business
- an integration is no longer used
- a key may have been exposed
- a partner app is replaced
Optional HMAC Signing #
For higher-trust integrations, use request signing.
Then every external event must include:
x-wappchat-timestamp: 1779111111
x-wappchat-signature: sha256=<hex-hmac>
The signed payload is:
{unix_timestamp}.{raw_json_body}
The signature uses HMAC SHA-256 with the integration secret.
Node Example #
const body = JSON.stringify({
event: 'lead.created',
source: 'my-crm',
idempotency_key: 'lead.created:lead_123',
contact: {
name: 'Alex',
phone: '919999999999'
},
payload: {
service: 'demo'
}
});
const timestamp = Math.floor(Date.now() / 1000).toString();
const secret = '<integration-secret>';
const key = await crypto.subtle.importKey(
'raw',
new TextEncoder().encode(secret),
{ name: 'HMAC', hash: 'SHA-256' },
false,
['sign']
);
const digest = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(`${timestamp}.${body}`));
const signature = [...new Uint8Array(digest)]
.map((byte) => byte.toString(16).padStart(2, '0'))
.join('');
await fetch('https://wapp.chat/api/whatsapp/automation/events', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-wappchat-key': '<integration-api-key>',
'x-wappchat-timestamp': timestamp,
'x-wappchat-signature': `sha256=${signature}`
},
body
});
Signature Tolerance #
Requests outside the timestamp tolerance are rejected to reduce replay risk.