For developers
A public API per business, and signed outgoing events. The same locks and limits that govern the interface govern these too.
Public API
A key is created in the business settings, carries an identifying prefix and is limited to the scopes you choose. One request — and WeHub picks the channel and instance by the recipient, sends text while the reply window is open and an approved template when it is not, through the same gates as sending from the inbox.
- Smart send: channel: auto picks WhatsApp, Messenger, Instagram or email by the recipient and the open window.
- Meta templates with named or positional parameters, media from a URL, and an idempotency key against double sends.
- Template management from the API: create with a header, variables and buttons, check the approval status, delete — and an outgoing event when Meta approves or rejects.
- Contacts and conversations: create, read, update, look up by identity — and a delivery status per message.
- The OpenAPI document, a request builder and the full guide inside the account.
curl https://api.wehub.co.il/api/v1/public/messages \
-H "Authorization: Bearer wh_live_…" \
-H "Idempotency-Key: order-12345-shipped" \
-H "Content-Type: application/json" \
-d '{
"to": "+972521234567",
"channel": "auto",
"text": "ההזמנה יצאה למשלוח",
"template": {
"name": "order_shipped",
"language": "he",
"body": { "name": "דנה", "order": "12345" }
}
}'Outgoing webhooks
Each event is delivered as a POST carrying an HMAC-SHA256 signature and a timestamp. If the endpoint does not answer there are five retries at growing intervals, plus a delivery log on the integrations screen.
The events
message.receivedMessage receivedmessage.sentMessage sentmessage.deliveredMessage deliveredmessage.readMessage readmessage.failedSend failedconversation.openedConversation openedconversation.assignedConversation assignedconversation.closedConversation closedcsat.receivedSatisfaction score receivedcall.endedCall endedtemplate.status_changedTemplate status changed
Verifying the signature
Compare in constant time. A timestamp older than 5 minutes is rejected.
const signed = `${timestamp}.${rawBody}`;
const expected = crypto
.createHmac('sha256', webhookSecret)
.update(signed)
.digest('hex');
crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(req.header('X-Wehub-Signature')),
);The full documentation
The OpenAPI spec, per-business keys and the webhook delivery log live inside the account, so you work against the real keys of the business.
Your own integration card
If all you want is to show data from your system inside a conversation, you do not need the API. Configure one URL, receive a signed POST with the contact identity, and return JSON.
Start with a call, end with a live channel
After the intro call we open your account, and a short wizard connects the first channel and invites the team. It ends by having you message yourself and watch it land.