WhatsApp API v1

WhatsApp API Documentation

Send messages, manage templates, and access contacts from any application.

Quick Start

1. Get an API Key

Log into the platform at social.slick.company, go to Settings, and create an API key under "WhatsApp API Keys".

2. Authenticate

Include your API key in every request:

# Header (recommended)
X-API-Key: slick_your_api_key_here

# Or query parameter
?api_key=slick_your_api_key_here

3. Set Business ID

If your API key is scoped to a business, it's automatic. Otherwise pass business_id in the request body, query string, or X-Business-ID header.

Available businesses: warpoint, notebook

Base URL

https://social.slick.company/api/v1/whatsapp

Template Lifecycle

WhatsApp requires message templates to be approved by Meta before use. The lifecycle is:

  1. Create a template via API → status: draft
  2. Submit to Meta for review → status: submitted
  3. Wait 24-48h. Platform auto-polls every 30 min → status: approved or rejected
  4. Send messages using the approved template

Free-form text messages (without templates) can only be sent within a 24-hour window after the customer messages you first.

Endpoints

POST /send Send a single message

Send a WhatsApp message to one recipient using a template or free-form text.

ParameterTypeRequiredDescription
business_idstringYesBusiness slug, e.g. "notebook"
tostringYesPhone number in international format, e.g. "+96512345678"
template_namestring*Meta-approved template name. Use this OR template_id.
template_idstring*Template ID from this platform (name resolved automatically)
languagestringNoTemplate language code. Default: "ar"
parametersobjectNoTemplate variables: {"body": ["value1", "value2"]}
textstringNoFree-form text (24h window only). Overrides template fields.

Example

curl -X POST https://social.slick.company/api/v1/whatsapp/send \
  -H "X-API-Key: slick_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "business_id": "notebook",
    "to": "+96512345678",
    "template_name": "hello_world",
    "language": "en"
  }'

Response

{
  "ok": true,
  "result": {
    "messages": [{"id": "wamid.HBgLOTY1MTIzNDU2NzgVAgA..."}]
  }
}
POST /send-bulk Send bulk messages

Send a template message to multiple recipients. Provide a list of phone numbers OR a segment name to pull contacts from the database. Runs in the background.

ParameterTypeRequiredDescription
business_idstringYesBusiness slug
template_namestringYesApproved template name
languagestringNoDefault: "ar"
recipientsstring[]NoPhone numbers array. If empty, uses segment.
segmentstringNoContact segment: "customers", "vip", "all"

Example — send to a segment from the database

curl -X POST https://social.slick.company/api/v1/whatsapp/send-bulk \
  -H "X-API-Key: slick_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "business_id": "notebook",
    "template_name": "promo_sale",
    "segment": "customers"
  }'

Example — send to specific numbers

curl -X POST https://social.slick.company/api/v1/whatsapp/send-bulk \
  -H "X-API-Key: slick_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "business_id": "warpoint",
    "template_name": "tournament_invite",
    "language": "ar",
    "recipients": ["+96565965089", "+96599887766", "+96555443322"]
  }'

Response

{
  "ok": true,
  "campaign_id": "api-1a2b3c4d",
  "recipients": 1103,
  "status": "sending",
  "message": "Sending to 1103 recipients in background"
}
GET /templates List message templates

Get all WhatsApp message templates. Filter by status to get only approved ones ready for sending.

Query ParamDescription
business_idFilter by business slug
statusdraft, submitted, approved, or rejected
curl "https://social.slick.company/api/v1/whatsapp/templates?business_id=notebook&status=approved" \
  -H "X-API-Key: slick_your_key"

Response

{
  "templates": [
    {
      "id": "tpl-abc123",
      "name": "hello_world",
      "category": "MARKETING",
      "language": "en",
      "body_text": "Hello! Welcome to Notebook.",
      "status": "approved",
      "meta_template_id": "123456789"
    }
  ],
  "count": 1
}
POST /templates Create a message template

Create a new template as a draft. Use {{1}}, {{2}} for variables in the body.

ParameterTypeRequiredDescription
business_idstringYesBusiness slug
namestringYesTemplate name (lowercase, underscores, no spaces)
body_textstringYesMessage body (max 1024 chars)
categorystringNoMARKETING (default), UTILITY, AUTHENTICATION
languagestringNoDefault: "ar"
header_typestringNo"text", "image", "video", or empty
footer_textstringNoFooter (max 60 chars)
curl -X POST https://social.slick.company/api/v1/whatsapp/templates \
  -H "X-API-Key: slick_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "business_id": "notebook",
    "name": "order_update",
    "body_text": "Hi {{1}}, your order #{{2}} is on its way! Track: {{3}}",
    "category": "UTILITY",
    "language": "en"
  }'
POST /templates/{id}/submit Submit template to Meta for approval

Submit a draft template to Meta for review. Approval typically takes 24-48 hours. The platform polls every 30 minutes and updates status automatically.

curl -X POST https://social.slick.company/api/v1/whatsapp/templates/tpl-abc123/submit \
  -H "X-API-Key: slick_your_key"

Response

{"ok": true, "status": "submitted", "meta_template_id": "123456789"}
GET /contacts List contacts

Retrieve contacts from the database. Contacts are synced daily from business databases and can be added via API.

Query ParamDescription
business_idFilter by business
segmentFilter by segment (e.g. "customers", "vip")
curl "https://social.slick.company/api/v1/whatsapp/contacts?business_id=warpoint" \
  -H "X-API-Key: slick_your_key"

Response

{
  "contacts": [
    {"id": "c-xxx", "phone": "+96565965089", "name": "Ahmed", "segment": "customers", "opted_in": true}
  ],
  "count": 1030
}
POST /trigger Trigger template via webhook (OTP, notifications)

Fire-and-forget endpoint for sending a template with variables. Ideal for OTPs, order confirmations, booking reminders. Language is auto-detected from the template database. For AUTHENTICATION templates (like OTP), the copy-code button parameter is automatically included.

ParameterTypeRequiredDescription
tostringYesPhone number in international format
template_namestringYesApproved template name (e.g. "send_otp")
variablesstring[]NoValues for {{1}}, {{2}}, etc.
languagestringNoAuto-detected from DB if omitted

Example — Send OTP

curl -X POST https://social.slick.company/api/v1/whatsapp/trigger \
  -H "X-API-Key: slick_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+96566477000",
    "template_name": "send_otp",
    "variables": ["847291"]
  }'

Example — Booking Reminder

curl -X POST https://social.slick.company/api/v1/whatsapp/trigger \
  -H "X-API-Key: slick_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+96599887766",
    "template_name": "system_booking_reminder_new",
    "variables": ["Ahmed", "VR Arena", "Tomorrow 6 PM"]
  }'

Example — Discount Notification

curl -X POST https://social.slick.company/api/v1/whatsapp/trigger \
  -H "X-API-Key: slick_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+96566477000",
    "template_name": "discount_reminder",
    "variables": ["Fahad", "15", "2026-05-01", "66477000", "Fahad", "15", "May 1st 2026", "66477000"]
  }'

Response

{"ok": true, "result": {"messages": [{"id": "wamid.HBgL..."}]}}

How to use for OTP in your app

// Node.js example - send OTP from your backend
const otp = Math.floor(100000 + Math.random() * 900000); // 6-digit OTP

await fetch('https://social.slick.company/api/v1/whatsapp/trigger', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': 'slick_your_warpoint_key'
  },
  body: JSON.stringify({
    to: '+96566477000',
    template_name: 'send_otp',
    variables: [String(otp)]
  })
});
POST /contacts Add a contact
ParameterTypeRequiredDescription
business_idstringYesBusiness slug
phonestringYesInternational format
namestringNoContact name
segmentstringNoe.g. "customers", "leads", "vip"
curl -X POST https://social.slick.company/api/v1/whatsapp/contacts \
  -H "X-API-Key: slick_your_key" \
  -H "Content-Type: application/json" \
  -d '{"business_id": "warpoint", "phone": "+96599887766", "name": "Fahad", "segment": "vip"}'

Integration Examples

Node.js

const API_KEY = 'slick_your_key_here';
const BASE = 'https://social.slick.company/api/v1/whatsapp';

async function sendWhatsApp(to, templateName, bizId = 'notebook') {
  const res = await fetch(`${BASE}/send`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'X-API-Key': API_KEY },
    body: JSON.stringify({ business_id: bizId, to, template_name: templateName, language: 'ar' }),
  });
  return res.json();
}

// Usage
const result = await sendWhatsApp('+96512345678', 'order_confirmation');

Python

import requests

API_KEY = 'slick_your_key_here'
BASE = 'https://social.slick.company/api/v1/whatsapp'

def send_whatsapp(to, template_name, biz_id='notebook'):
    return requests.post(f'{BASE}/send',
        headers={'X-API-Key': API_KEY, 'Content-Type': 'application/json'},
        json={'business_id': biz_id, 'to': to, 'template_name': template_name, 'language': 'ar'}
    ).json()

result = send_whatsapp('+96512345678', 'order_confirmation')

PHP

$apiKey = 'slick_your_key_here';
$base = 'https://social.slick.company/api/v1/whatsapp';

$ch = curl_init("$base/send");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json', "X-API-Key: $apiKey"],
    CURLOPT_POSTFIELDS => json_encode([
        'business_id' => 'notebook', 'to' => '+96512345678',
        'template_name' => 'order_confirmation', 'language' => 'ar',
    ]),
    CURLOPT_RETURNTRANSFER => true,
]);
$result = json_decode(curl_exec($ch), true);

Go

package main

import (
    "bytes"
    "encoding/json"
    "net/http"
)

func sendWhatsApp(to, template, bizID string) (map[string]interface{}, error) {
    body, _ := json.Marshal(map[string]string{
        "business_id": bizID, "to": to, "template_name": template, "language": "ar",
    })
    req, _ := http.NewRequest("POST", "https://social.slick.company/api/v1/whatsapp/send", bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("X-API-Key", "slick_your_key_here")

    resp, err := http.DefaultClient.Do(req)
    if err != nil { return nil, err }
    defer resp.Body.Close()

    var result map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&result)
    return result, nil
}

Error Codes

HTTPMeaningCommon Cause
401UnauthorizedMissing or invalid API key
400Bad RequestMissing required fields
404Not FoundTemplate or endpoint not found
500Server ErrorMeta API failure

All errors include an "error" field. If WhatsApp is not configured: {"error":"WhatsApp not configured","status":"not_configured"}

Rate Limits & Notes