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 received
  • message.sentMessage sent
  • message.deliveredMessage delivered
  • message.readMessage read
  • message.failedSend failed
  • conversation.openedConversation opened
  • conversation.assignedConversation assigned
  • conversation.closedConversation closed
  • csat.receivedSatisfaction score received
  • call.endedCall ended
  • template.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.

Docs inside the account

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.