Security

API Keys and Signatures

Create integration API keys, authenticate external events, and enable HMAC request signatures for stronger production security.

Updated May 19, 2026

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.