WAHOB DEVELOPERS / API REFERENCE

Public API

A focused, server-side API for contacts, conversations, and WhatsApp text messaging. This reference covers the public v1 contract currently implemented by Wahob.

Base URL  https://api.wahob.com

Overview

The public v1 API currently exposes five API-key authenticated operations, including a tenant-scoped list of approved WhatsApp templates that integrations can use to populate a template selector. Product support for Instagram, Messenger, SMS, calling, commerce, and automation does not imply public API access to those features. The endpoint list below is the complete documented v1 surface.

Server-side only. Never place API credentials in browser JavaScript, frontend bundles, mobile apps, public repositories, or client-side environment variables.

Quick start

  1. In Wahob, open Settings → API Keys and generate a key.
  2. Select only the scopes this integration needs; set an expiry where appropriate.
  3. Copy the secret at creation time. Wahob displays it once.
  4. Store both values in your server-side secret manager.
  5. Try the authenticated contacts request below.
curl -sS "https://api.wahob.com/api/v1/contacts?per_page=10" \
  -H "Accept: application/json" \
  -H "X-Api-Key: wahob_your_key" \
+  -H "X-Api-Secret: your_secret"

Authentication & API keys

The canonical public v1 authentication uses both X-Api-Key and X-Api-Secret headers on each request. Keys belong to the workspace that created them; each API query is constrained to that key’s tenant. The secret is stored as a SHA-256 hash and returned only when created. Keys may have an expiry and can be revoked by deleting them in Settings → API Keys. Key rotation is performed by creating a replacement key and revoking the old one; there is no in-place rotation endpoint.

X-Api-Key: wahob_••••••••
X-Api-Secret: <secret>

Invalid, expired, missing, or over-limit credentials currently return 401. Scope failures return 403.

Scopes & rate limits

ScopeAccessEndpoint
contacts.readReadGET /api/v1/contacts
contacts.writeCreatePOST /api/v1/contacts
messages.sendSendPOST /api/v1/messages/send
conversations.readReadGET /api/v1/conversations
templates.readList approved WhatsApp templatesGET /api/v1/templates

The key manager also accepts campaigns.read, webhooks.write, and appointment scopes, but the current public v1 router has no matching endpoints; these scopes grant no documented v1 operation. Use least privilege. Per-key limits default to 1,000 requests per minute and can be set from 10 to 10,000 per minute. The implementation emits no rate-limit headers; a limit rejection is currently reported as 401, so clients cannot reliably distinguish it from invalid credentials. Retry transient failures with exponential backoff; do not blindly retry sends.

Contacts

GET/api/v1/contacts

List contacts

Returns a tenant-scoped Laravel paginator. Optional query parameters: search (name or phone substring) and per_page (Laravel paginator page size; page is also supported by the paginator).

Authentication: API key · Required scope: contacts.read

Example response

{
  "current_page": 1,
  "data": [{ "id": 42, "name": "Priya Shah", "phone": "+919876543210", "phone_country": "IN", "phone_e164": "+919876543210", "phone_normalization_state": "VALID", "email": "priya@example.com" }],
  "per_page": 25,
  "total": 1,
  "last_page": 1,
  "next_page_url": null
}

cURL

curl -sS "https://api.wahob.com/api/v1/contacts?per_page=10" \
+  -H "Accept: application/json" \
+  -H "X-Api-Key: wahob_your_key" \
+  -H "X-Api-Secret: your_secret"
POST/api/v1/contacts

Create contact

Requires phone (string, up to 20 chars); accepts optional phone_country (two-letter ISO region), name, email, and custom_fields object. The handler creates a record with firstOrCreate using the submitted phone string. An exact same phone in the same tenant returns the existing record with HTTP 201; it does not update existing fields. Distinct strings that normalize to the same E.164 are not guaranteed to deduplicate.

Authentication: API key · Required scope: contacts.write

Request body

{
  "phone": "9876543210",
  "phone_country": "IN",
  "name": "Priya Shah",
  "email": "priya@example.com",
  "custom_fields": { "city": "Mumbai" }
}

Example response

{
  "data": {
    "id": 42,
    "phone": "9876543210",
    "phone_country": "IN",
    "phone_e164": "+919876543210",
    "phone_normalization_state": "VALID",
    "name": "Priya Shah",
    "email": "priya@example.com",
    "source": "api"
  }
}

cURL

curl -sS -X POST "https://api.wahob.com/api/v1/contacts" \
+  -H "Accept: application/json" \
+  -H "Content-Type: application/json" \
+  -H "X-Api-Key: wahob_your_key" \
+  -H "X-Api-Secret: your_secret" \
+  -d '{"phone": "9876543210","phone_country": "IN","name": "Priya Shah","email": "priya@example.com","custom_fields": { "city": "Mumbai" }}'

Phone number identity

Contact records expose phone (original submitted value), phone_country, phone_e164, and phone_normalization_state. International input beginning with + is normalized directly. A national number uses its supplied two-letter phone_country, or the tenant's configured business country when that is absent; for example IN + 9876543210 becomes +919876543210. Numbers without country context can remain COUNTRY_REQUIRED; invalid pairs become INVALID. The Contacts screen displays and copies phone_e164 when available, while preserving the original value in phone. Wahob’s message path resolves and validates the recipient before sending. Contact creation validates field shape, so inspect the returned normalization state for invalid values.

Conversations

GET/api/v1/conversations

List conversations

Returns tenant-scoped conversations ordered by latest activity, with contact id, name, and phone. Supports standard Laravel paginator query parameters such as page and per_page. The current route does not support channel, contact, or status filters, and provides no individual conversation or message-history endpoint.

Authentication: API key · Required scope: conversations.read

Example response

{
  "current_page": 1,
  "data": [{
    "id": 91,
    "channel": "whatsapp",
    "status": "open",
    "last_message_at": "2026-06-13T08:00:00.000000Z",
    "contact": { "id": 42, "name": "Priya Shah", "phone": "+919876543210" }
  }],
  "per_page": 25, "total": 1, "last_page": 1
}

cURL

curl -sS "https://api.wahob.com/api/v1/conversations?per_page=10" \
+  -H "Accept: application/json" \
+  -H "X-Api-Key: wahob_your_key" \
+  -H "X-Api-Secret: your_secret"

Approved WhatsApp templates

Fetch this list with an API key that has templates.read, then use the returned id, name, and language to populate a template selector in your integration. Results include approved templates belonging to the key’s Wahob tenant only. Pending, rejected, and disabled templates are excluded. This endpoint lists templates for selection; it does not send them.

GET/api/v1/templates

List approved templates

Returns every approved WhatsApp template for the API key's tenant, across its connected WhatsApp accounts. Use id as the selection value and show name, language, and category in the dropdown label.

Authentication: API key · Required scope: templates.read

Example response

{
  "data": [
    {
      "id": 18,
      "whatsapp_account_id": 4,
      "name": "order_update",
      "language": "en_US",
      "category": "utility",
      "body_text": "Hi {{1}}, your order {{2}} has shipped.",
      "components": [{ "type": "BODY", "text": "Hi {{1}}, your order {{2}} has shipped." }]
    }
  ]
}

cURL

curl -sS "https://api.wahob.com/api/v1/templates" \
+  -H "Accept: application/json" \
+  -H "X-Api-Key: wahob_your_key" \
+  -H "X-Api-Secret: your_secret"

WhatsApp messaging

POST/api/v1/messages/send

Send WhatsApp text

Sends text via a connected active WhatsApp phone number using Wahob’s WhatsApp outbound service. Required: phone and message (up to 4,096 characters). Optional: phone_country and phone_number_id (Wahob phone-number record id). When omitted, Wahob chooses an eligible connected number. This endpoint does not accept template, media, interactive, Instagram, Messenger, or SMS payloads. WhatsApp policy eligibility is checked by the outbound policy; a text send may be rejected when not allowed. A connected channel and eligible account configuration are required.

Authentication: API key · Required scope: messages.send

Request body

{
  "phone": "+919876543210",
  "message": "Your order has shipped.",
  "phone_number_id": 12
}

Example response

{
  "message": "Message sent",
  "data": {
    "provider_message_id": "wamid.example",
    "phone_number_id": 12
  }
}

cURL

curl -sS -X POST "https://api.wahob.com/api/v1/messages/send" \
+  -H "Accept: application/json" \
+  -H "Content-Type: application/json" \
+  -H "X-Api-Key: wahob_your_key" \
+  -H "X-Api-Secret: your_secret" \
+  -d '{"phone": "+919876543210","message": "Your order has shipped.","phone_number_id": 12}'

Incoming automation webhooks

External service → Wahob. The backend accepts GET and POST at /api/webhook/incoming/{slug}. This slug-based integration route is configured in Wahob and is not an API-key authenticated v1 endpoint. Its payload mapping and security are managed by the configured webhook/workflow; do not treat the slug as a substitute for secret handling. The route’s implementation handles inbound automation events; there is no public v1 endpoint to list or trigger workflow definitions.

curl -X POST "https://api.wahob.com/api/webhook/incoming/<configured-slug>" \
  -H "Content-Type: application/json" \
  -d '{"event":"order.updated","data":{"order_id":"example"}}'

Payload shape and response depend on the configured webhook. Confirm accepted fields in that configuration before sending production events.

Commerce and plugin callbacks

Wahob also has Shopify/WooCommerce callback routes and a WooCommerce plugin auto-connect flow. These are platform handshakes and callback URLs, not general developer CRUD APIs for orders, customers, products, or campaigns. Shopify callbacks use platform verification middleware. Use the supported Wahob commerce/plugin integration to connect a store; never copy plugin credentials or installation secrets into client code. There is no public v1 campaign, commerce, workflow, template, or outbound developer event endpoint in this reference.

APIs not available in public v1

These are common integration requests, but the public API-key contract does not currently expose them. Some related actions may exist in the Wahob dashboard, embedded widget, or provider/store integrations; those routes are not supported substitutes for a public developer API. Do not call undocumented product endpoints as an integration contract.

API areaCurrent public v1 coverage
WhatsApp template management and sendingThe API can list approved templates for selection. It does not create, edit, delete, inspect pending approval status, or send template messages. The message send endpoint accepts text only.
Conversation detail and historyNo endpoint retrieves one conversation or its message history. The list endpoint has no channel, contact, or status filters.
Contact managementNo endpoint retrieves one contact, updates or deletes a contact, or upserts by canonical phone identity. Create accepts a contact but does not update an existing record.
Message media and interactive contentNo public v1 send endpoint supports media, buttons, lists, or other interactive message payloads.
Delivery events and outbound webhooksNo public developer event subscriptions or delivery callbacks are documented for sent, delivered, read, or failed messages. The incoming automation webhook sends events into Wahob; it is not an outbound event feed.
Campaigns and workflowsNo public v1 endpoints manage campaigns, recipients, campaign analytics, workflow definitions, or workflow triggers. The accepted campaigns.read key scope has no matching v1 route.
AppointmentsNo API-key v1 endpoints expose availability, booking, or appointment management. The accepted appointments.read and appointments.write scopes do not currently unlock public v1 operations.
Commerce and catalogsNo general public v1 endpoints manage products, catalogs, orders, or customers. Store callbacks and plugin handshakes are integration-specific, not general CRUD APIs.
Other channels and callingNo public v1 endpoints send or manage Instagram, Messenger, SMS, or calling messages. Product support for a channel does not imply public API access.

Template API coverage

The API exposes approved templates through GET /api/v1/templates so integrations can populate a selector. Creating, editing, deleting, managing approval status, and sending WhatsApp templates are not available in the public API. POST /api/v1/messages/send supports text only. Template controls in the authenticated Wahob product are not part of this API-key contract.

Other developer contract gaps

  • Idempotency: mutations, including message sends, have no documented idempotency key. Reconcile an uncertain send before retrying.
  • Rate limits: throttling currently has no documented 429 response or rate-limit headers; over-limit credentials may receive 401.
  • Webhook operations: no public event-subscription, signing, retry, delivery-log, or replay contract exists.
  • Developer artifacts: there is no public OpenAPI specification, SDK/Postman collection, formal deprecation policy, or API-specific changelog documented here.
  • Key scopes: campaigns.read, webhooks.write, appointments.read, and appointments.write are accepted by key creation but do not currently grant a public v1 operation.

Errors, limits & versioning

Responses use endpoint-specific Laravel JSON structures, commonly a top-level message; there is no single structured error envelope or request ID. Validation failures use Laravel’s 422 validation response. Sending may return 422 for unavailable WhatsApp number or recipient/policy rejection, and 500 for an unexpected send failure. Auth failures are 401; missing scopes are 403. No 429 contract or retry headers are currently emitted by the public v1 limiter.

{
  "message": "The phone field is required.",
  "errors": { "phone": ["The phone field is required."] }
}

The route prefix is /api/v1. No formal compatibility or deprecation policy is currently published. Mutating public API calls have no idempotency-key contract; a network timeout after sending can leave delivery outcome unknown, so check Wahob conversation/provider records before retrying. The public API controller does not report subscription usage explicitly; plan entitlements may govern connected product features, but no public usage endpoint or guarantee is part of this contract.

Need help? Include the endpoint, approximate time, response body, and workspace name in your support request. Do not send API secrets.

Get Started