Whats91
Developers

Create and manage Whats91 Webhooks v2 event destinations with the canonical public API route.

Create Webhook

Summary

Create webhook destinations so Whats91 can deliver real-time message and account events to your HTTPS receiver.

Prerequisites

  • Bearer token authentication
  • A public HTTPS receiver URL
  • Selected Whats91 event keys

Whats91 Webhooks v2 deliver real-time WhatsApp events to your HTTPS endpoint. Public API v2 webhook management uses /api/v2/webhooks only; these APIs manage Whats91 outbound event destinations and do not change Meta callback override URLs or legacy Cloud API setup fields.

/api/v2/webhooks

Canonical route

Use the graph.whats91.com API v2 path for create, list, get, and update.

senderId

Sender scoped

Omit senderId for default token resolution, or pass it when a token can access multiple senders.

Create only

Secret handling

The signing secret is returned once when the webhook is created and is never returned by list, get, or update.

Authentication

Send the public API token in the Authorization header. For POST compatibility, authToken, auth_token, or token can also be sent in the JSON body.

Authorization header
Authorization: Bearer w91_public_token_here

Event Catalog

Endpoint: GET /api/v2/webhooks/events. Fetch the event catalog before creating a webhook so your integration subscribes only to supported event keys.

GET/api/v2/webhooks/events
Get event catalog
curl -X GET "https://graph.whats91.com/api/v2/webhooks/events" \
  -H "Authorization: Bearer w91_public_token_here"
Event catalog response
{
  "success": true,
  "message": "Webhook event catalog retrieved",
  "data": {
    "groups": [],
    "eventKeys": [
      "message.inbound.text",
      "message.status.delivered",
      "template.status_update"
    ]
  },
  "metadata": {
    "apiVersion": "v2",
    "requestId": "request-uuid"
  }
}

Create Webhook API

Endpoint: POST /api/v2/webhooks.

HeaderRequiredDescription
AuthorizationYesUse Authorization: Bearer w91_public_token_here.
Content-TypeYesUse Content-Type: application/json for create and update requests.
POST/api/v2/webhooks
ParameterTypeRequiredDescription
senderIdstringOptionalWhatsApp sender number. Number-scoped tokens can only manage webhooks for the assigned sender.
webhook.namestringRequiredDeveloper-facing webhook name.
webhook.endpointUrlstringRequiredHTTPS destination URL that receives Whats91 event deliveries.
webhook.eventsarrayRequiredSupported event keys from GET /api/v2/webhooks/events.
webhook.statusstringOptionalACTIVE or INACTIVE. Defaults to ACTIVE when omitted.
webhook.timeoutMsnumberOptionalDelivery timeout in milliseconds, such as 5000.
webhook.retryEnabledbooleanOptionalWhether Whats91 should retry failed deliveries.
webhook.retryMaxAttemptsnumberOptionalMaximum retry attempts when retryEnabled is true.
webhook.verificationHeaderKeystringOptionalCustom header name Whats91 sends with the verification token.
webhook.verificationTokenstringOptionalShared verification token stored encrypted/hashed and never returned by public APIs.
Create webhook request
curl -X POST "https://graph.whats91.com/api/v2/webhooks" \
  -H "Authorization: Bearer w91_public_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "senderId": "916268662275",
    "webhook": {
      "name": "CRM delivery hook",
      "endpointUrl": "https://crm.example.com/webhooks/whats91",
      "events": ["message.inbound.text", "message.status.delivered"],
      "status": "ACTIVE",
      "timeoutMs": 5000,
      "retryEnabled": true,
      "retryMaxAttempts": 3,
      "verificationHeaderKey": "X-CRM-Webhook-Token",
      "verificationToken": "shared-secret"
    }
  }'
Success Response
{
  "success": true,
  "message": "Webhook created",
  "data": {
    "webhookUid": "wh_abc",
    "uid": "wh_abc",
    "name": "CRM delivery hook",
    "endpointUrl": "https://crm.example.com/webhooks/whats91",
    "phoneNumber": "916268662275",
    "phoneNumberId": "1043189608869917",
    "events": ["message.inbound.text", "message.status.delivered"],
    "status": "ACTIVE",
    "timeoutMs": 5000,
    "retryEnabled": true,
    "retryMaxAttempts": 3,
    "verificationHeaderKey": "X-CRM-Webhook-Token",
    "hasVerificationToken": true
  },
  "signingSecret": "whsec_created_once_only",
  "metadata": {
    "apiVersion": "v2",
    "requestId": "request-uuid"
  }
}
Validation Error Response
{
  "success": false,
  "message": "Unsupported webhook event: message.invalid",
  "error_code": "VALIDATION_FAILED",
  "details": {},
  "metadata": {
    "apiVersion": "v2",
    "requestId": "request-uuid"
  }
}

signingSecret is returned only on create. Store it immediately. List, get, and update responses never return the signing secret, encrypted secret, verification token, or token hash.

Required fields

FieldTypeNotes
webhook.namestringReadable name for the destination.
webhook.endpointUrlstringHTTPS endpoint URL in production. Local development URLs are allowed only where Whats91 validation allows them.
webhook.eventsarrayOne or more supported event keys from the event catalog.

Optional fields

FieldTypeNotes
senderIdstringSender WhatsApp number for multi-number customers.
webhook.statusstringACTIVE or INACTIVE. Use INACTIVE to disable a webhook.
webhook.timeoutMsnumberDelivery timeout in milliseconds.
webhook.retryEnabledbooleanEnables retries for failed deliveries.
webhook.retryMaxAttemptsnumberMaximum delivery retry attempts.
webhook.verificationHeaderKeystringCustom verification header key, such as X-CRM-Webhook-Token.
webhook.verificationTokenstringCustom shared token sent in the verification header.

Management endpoints

ActionMethodEndpointNotes
List webhooksGET/api/v2/webhooksFilter by senderId, status, event, page, and limit.
Get one webhookGET/api/v2/webhooks/:webhookUidwebhookUid is the only public identifier for retrieval.
Update webhookPOST/api/v2/webhooks/:webhookUidAll webhook fields are optional, but at least one update field is required.

Validation errors

StatusError codeWhen it happens
401MISSING_AUTH_TOKENNo public API token was supplied.
401INVALID_AUTH_TOKENToken is missing, expired, revoked, or not tied to an active customer.
403FEATURE_NOT_AVAILABLEThe subscription does not include Webhooks v2.
400WHATSAPP_SETUP_INCOMPLETEWhats91 cannot resolve a sender context.
400VALIDATION_FAILEDInvalid name, empty events, unsupported event, invalid status, invalid timeout/retry values, invalid verification header, or missing update fields.
400WEBHOOK_ENDPOINT_INVALIDThe endpoint URL is malformed.
400WEBHOOK_ENDPOINT_REQUIRES_HTTPSThe endpoint is not HTTPS in a production context.
404WEBHOOK_NOT_FOUNDThe UID does not belong to the authenticated customer and resolved sender.
415UNSUPPORTED_CONTENT_TYPEPOST request is not JSON.

SDK Examples

Use these examples as starting points for server-side implementations.

cURL
curl -X GET "https://graph.whats91.com/api/v2/webhooks/events" \
  -H "Authorization: Bearer w91_live_xxx"
Node.js
const response = await fetch("https://graph.whats91.com/api/v2/webhooks/events", {
  method: "GET",
  headers: {
    "Authorization": "Bearer w91_live_xxx",
    "Content-Type": "application/json"
  }
});

const data = await response.json();
console.log(data);
PHP
$ch = curl_init("https://graph.whats91.com/api/v2/webhooks/events");
curl_setopt_array($ch, [
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer w91_live_xxx",
    "Content-Type: application/json"
  ]
]);

$response = curl_exec($ch);
curl_close($ch);
echo $response;
Python
import requests

response = requests.request(
    "GET",
    "https://graph.whats91.com/api/v2/webhooks/events",
    headers={
        "Authorization": "Bearer w91_live_xxx",
        "Content-Type": "application/json",
    }
)

print(response.json())
C#
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer w91_live_xxx");

var request = new HttpRequestMessage(HttpMethod.Get, "https://graph.whats91.com/api/v2/webhooks/events");

var response = await client.SendAsync(request);
Console.WriteLine(await response.Content.ReadAsStringAsync());

Frequently Asked Questions

How do I create a webhook?

Call POST /api/v2/webhooks with a destination name, HTTPS endpoint URL, event keys, and active status.

What events can webhooks send?

Webhook event keys cover message lifecycle updates and related Whats91 delivery events documented in the samples page.

Should webhook receivers verify requests?

Yes. Receivers should validate origin, use HTTPS, log payloads, and respond quickly with a successful status.

Related APIs