Developer Documentation

Send WhatsApp messages at scale. Connect numbers, manage contacts, blast personalised messages, build drip sequences, automate enrollments, and track delivery — all through one clean REST API.

REST API JSON API Key Auth Multi-tenant Automation Priority Queue
Base URL https://api.wamator.com

Introduction

Wamator is a multi-tenant WhatsApp messaging API. You register as a vendor, subscribe to a plan, and use your API key to manage sub-users, phone numbers, contacts, and messages.

All requests and responses are JSON. Authentication uses the x-api-key header. All IDs are UUIDs.
Tenant model
TermWho they are
VendorYour application (e.g. Edumess). One API key, one account, owns everything below.
Sub-userYour end customers (e.g. a school owner). Registered by you via API.
Phone NumberA WhatsApp number a sub-user connects by scanning a QR code.
ContactA message recipient. Stored per sub-user in the CRM.

Authentication

Every protected endpoint requires your vendor API key in the x-api-key request header. You get this key from your Wamator dashboard — not via an API call.

How to get your API key
1
Sign up at app.wamator.comCreate your vendor account — enter your name, company, email and password
2
Verify your emailEnter the 6-digit code sent to your inbox
3
Go to Settings → API KeyYour API key is displayed here — copy it
4
Send it as a header on every requestx-api-key: your_api_key_here
In every request — Headers tab
Keyx-api-key
Valueyour_api_key_here
Never expose your API key in frontend JavaScript or public repos. Always call from your backend server. If a key is compromised, rotate it from the Settings page on the dashboard.

Error Codes

CodeMeaning
200Success
201Resource created
400Bad request — check your body fields
401Invalid or missing API key
403Plan limit reached
404Resource not found
409Already exists
502WhatsApp gateway error
{ "detail": "No active subscription" }

Integration Flow

From zero to sending your first WhatsApp message in 7 steps.

1
Sign up at app.wamator.com → Settings → copy your API keyAll API calls are authenticated with this key via the x-api-key header
2
Subscribe to a planPOST /subscriptions/subscribe — sets your limits
3
Register sub-usersPOST /users/register — one per customer in your app
4
Add a WhatsApp numberPOST /numbers/ — attach a number to a sub-user
5
Connect it (QR scan)POST /numbers/{id}/connect — returns QR for sub-user to scan
6
Import contactsPOST /contacts/bulk — upload recipients for that sub-user
7
Blast messagesPOST /messages/blast — send personalised WhatsApp messages

Postman Setup

The fastest way to explore and test every endpoint. Import the collection and you have all 60+ requests pre-built with example bodies and headers — no manual setup.

Step 1 — Download the collection

Two ways to get it into Postman:

A
Download the file Click the link below to download the JSON file, then open Postman → Import → drag the file in.
B
Import via URL (no download needed) Open Postman → Import → switch to the Link tab → paste this URL → click ContinueImport.
https://api.wamator.com/assets/wamator-postman-collection.json
Step 2 — Set your collection variables

After importing, click the Wamator API collection in the Postman sidebar → open the Variables tab → fill in these values:

VariableValueHow to get it
base_urlhttps://api.wamator.comAlready pre-filled — leave as is
api_keyYour vendor API keyRun Register vendor or Login — copy the api_key from the response
user_idA sub-user UUIDRun Register user — copy the id
number_idA phone number UUIDRun Add number — copy the id
contact_idA contact UUIDRun Bulk import contacts — copy any returned id
list_idA list UUIDRun Create list — copy the id
sequence_idA sequence UUIDRun Create sequence — copy the id
Step 3 — First requests to run

Follow this order on your first session — each step gives you IDs you need for the next:

1
Vendors → Register vendorCopy the api_key → paste into the api_key collection variable
2
Subscriptions → Subscribe to planActivate a plan — required before adding numbers or users
3
Sub-Users → Register userCopy the id → paste into the user_id variable
4
WhatsApp Numbers → Add numberCopy the id → paste into the number_id variable
5
WhatsApp Numbers → Connect number (get QR)Share the QR with the sub-user to scan — number goes active once connected
Every request in the collection uses {{api_key}}, {{user_id}}, etc. Once you set a variable in Step 2, all requests that need it update automatically.

Vendors

Your top-level account. Sign up at app.wamator.com, verify your email, then retrieve your API key from the Settings page. The endpoints below are for managing your profile after signup.

Vendor signup is done through the web dashboard at app.wamator.com — not via this API. Once signed up, go to Settings → API Key to get your key.
Login
POST/vendors/login Retrieve your API key
Request
Response
MethodPOST
URLhttps://api.wamator.com/vendors/login
HeaderContent-Type: application/json
{
  "email": "admin@edumess.com",
  "password": "YourPassword123!"
}
{
  "status": "ok",
  "vendor": {
    "id": "7a689d72-...",
    "name": "Edumess",
    "email": "admin@edumess.com",
    "api_key": "c25325739d4bb..."
  }
}
Update profile
PUT/vendors/update 🔑 Auth required
Request
Response
MethodPUT
URLhttps://api.wamator.com/vendors/update
HeaderContent-Type: application/json
Headerx-api-key: your_api_key
// Send only the fields you want to change
{
  "name": "Edumess Africa",
  "phone_number": "2348099999999"
}
{ "status": "ok", "message": "Profile updated" }

Plans

Plans define vendor limits — phone numbers, contacts, and messages per billing period. No auth required to list.

List all plans
GET/plans/ No auth required
Request
Response
MethodGET
URLhttps://api.wamator.com/plans/
BodyNone
{
  "status": "ok",
  "plans": [
    {
      "id": "a741616a-9725-4737-b67c-59811277685e",
      "name": "Starter Plan",
      "max_phone_numbers": 3,
      "max_contacts": 1000,
      "max_messages": 1000,
      "duration_days": 30,
      "features": { "automation": false, "analytics": false },
      "prices": {
        "NG": { "price": 5000.00, "currency": "NGN" },
        "US": { "price": 9.99, "currency": "USD" }
      }
    }
  ]
}
Get single plan
GET/plans/{plan_id}
Request
MethodGET
URLhttps://api.wamator.com/plans/a741616a-9725-4737-b67c-59811277685e

Subscriptions

Subscribe your vendor to a plan. All limits are enforced at the vendor level. Subscribing to a new plan cancels the current one.

Subscribe to a plan
POST/subscriptions/subscribe 🔑 Auth required
Request
Response
MethodPOST
URLhttps://api.wamator.com/subscriptions/subscribe
HeaderContent-Type: application/json
Headerx-api-key: your_api_key
// Get plan_id from GET /plans/
{
  "plan_id": "a741616a-9725-4737-b67c-59811277685e"
}
{
  "status": "ok",
  "message": "Subscribed to Starter Plan",
  "subscription_id": "da40b398-...",
  "ends_at": "2026-08-01T19:49:04+00:00"
}
Current subscription + usage
GET/subscriptions/current 🔑 Auth required
Request
Response
MethodGET
URLhttps://api.wamator.com/subscriptions/current
Headerx-api-key: your_api_key
BodyNone
{
  "status": "ok",
  "subscription": {
    "plan_name": "Starter Plan",
    "max_contacts": 1000,
    "max_messages": 1000,
    "max_phone_numbers": 3,
    "contacts_used": 240,
    "messages_sent": 85,
    "ends_at": "2026-08-01T19:49:04+00:00",
    "status": "active"
  }
}
Subscription history
GET/subscriptions/history 🔑 Auth required
Request
MethodGET
URLhttps://api.wamator.com/subscriptions/history
Headerx-api-key: your_api_key

Sub-Users

Your end customers. In Edumess, each school owner is a sub-user. Register them when they sign up or subscribe to messaging in your app.

Use external_id to link a Wamator sub-user to your own DB record. You won't need to store the Wamator UUID separately.
Register
POST/users/register 🔑 Auth required
Request
Response
MethodPOST
URLhttps://api.wamator.com/users/register
HeaderContent-Type: application/json
Headerx-api-key: your_api_key
{
  "name": "Funcare School",
  "company_name": "Funcare International",
  "email": "admin@funcare.com",
  "external_id": "school_001"
}
{
  "status": "ok",
  "message": "User registered successfully",
  "id": "702cc6ac-8832-447c-8b7a-270ed1841a6b"
}
Save the returned id — pass it as user_id in numbers, contacts, and message requests.
List / Get / Update / Delete
GET/users/list 🔑 Auth required
Request
MethodGET
URLhttps://api.wamator.com/users/list
Headerx-api-key: your_api_key
GET/users/{user_id} 🔑 Auth required
Request
MethodGET
URLhttps://api.wamator.com/users/702cc6ac-8832-447c-8b7a-270ed1841a6b
Headerx-api-key: your_api_key
Check user subscription status
GET/users/{user_id}/subscription 🔑 Auth required
Use this to gate access in your app. Check whether a user has an active paid plan before allowing them to use your product.
Request
Response (active)
Response (inactive)
MethodGET
URLhttps://api.wamator.com/users/702cc6ac-8832-447c-8b7a-270ed1841a6b/subscription
Headerx-api-key: your_api_key
{
  "user_id": "702cc6ac-...",
  "has_active_subscription": true,
  "status": "active",
  "plan_name": "Basic School Plan",
  "plan_config_id": "b4e9a271-...",
  "billing_period": "monthly",
  "started_at": "2026-07-08T10:00:00+00:00",
  "ends_at": "2026-08-08T10:00:00+00:00",
  "messages_sent": 1240,
  "max_messages": 5000,
  "messages_remaining": 3760,
  "contacts_used": 85,
  "max_contacts": 500,
  "contacts_remaining": 415,
  "selling_price": 15000,
  "currency": "NGN"
}
{
  "user_id": "702cc6ac-...",
  "has_active_subscription": false,
  "status": "inactive",
  "plan_name": null,
  "plan_config_id": null,
  "billing_period": null,
  "started_at": null,
  "ends_at": null,
  "messages_sent": 0,
  "max_messages": 0,
  "messages_remaining": null,
  "contacts_used": 0,
  "max_contacts": 0,
  "contacts_remaining": null
}
PATCH/users/{user_id} 🔑 Auth required
Request
Response
MethodPATCH
URLhttps://api.wamator.com/users/702cc6ac-8832-447c-8b7a-270ed1841a6b
HeaderContent-Type: application/json
Headerx-api-key: your_api_key
// Only send fields to change
{
  "name": "Funcare Academy",
  "email": "info@funcare.com"
}
{ "status": "ok", "message": "User updated" }
DELETE/users/{user_id} 🔑 Auth required
Request
MethodDELETE
URLhttps://api.wamator.com/users/702cc6ac-8832-447c-8b7a-270ed1841a6b
Headerx-api-key: your_api_key
BodyNone

WhatsApp Numbers

Each sub-user connects a WhatsApp number by scanning a QR code. Once connected, messages are sent from that number.

Add a number
POST/numbers/ 🔑 Auth required
Request
Response
MethodPOST
URLhttps://api.wamator.com/numbers/
HeaderContent-Type: application/json
Headerx-api-key: your_api_key
{
  "user_id": "702cc6ac-8832-447c-8b7a-270ed1841a6b",
  "phone_number": "2349063570004",
  "label": "Funcare Main Line"
}
{
  "status": "ok",
  "message": "Number added",
  "id": "f3a1bc90-7e2d-4a11-9c33-112233445566"
}
Save the id — use it to connect the number and send messages.
Connect (get QR code)
POST/numbers/{number_id}/connect 🔑 Auth required
Request
Response
Display QR
MethodPOST
URLhttps://api.wamator.com/numbers/f3a1bc90-7e2d-4a11-9c33-112233445566/connect
Headerx-api-key: your_api_key
BodyNone
{
  "status": "ok",
  "session_id": "wa_f3a1bc90c2d1",
  "qr": {
    "qr": "data:image/png;base64,iVBORw0KGgo..."
  }
}
Show the QR image to the sub-user. They open WhatsApp → Linked Devices → Link a Device → scan.
// JavaScript
document.getElementById('qr-img').src = response.qr.qr;

// PHP
echo '<img src="' . $response['qr']['qr'] . '" />';

// HTML element
<img id="qr-img" alt="Scan to connect WhatsApp" />
Poll GET /numbers/{id}/status every 3 seconds after showing QR to detect when the sub-user scans it.
Check status
GET/numbers/{number_id}/status 🔑 Auth required
Request
Response
MethodGET
URLhttps://api.wamator.com/numbers/f3a1bc90-7e2d-4a11-9c33-112233445566/status
Headerx-api-key: your_api_key
// Connected
{ "status": "ok", "connected": true, "session_status": "CONNECTED" }

// Not yet scanned
{ "status": "ok", "connected": false, "session_status": "QR_GENERATED" }
List all numbers
GET/numbers/ 🔑 Auth required
Request
MethodGET
URLhttps://api.wamator.com/numbers/
Headerx-api-key: your_api_key
Warm-up toggle
PATCH/numbers/{number_id}/warmup 🔑 Auth required
Request
Response
MethodPATCH
URLhttps://api.wamator.com/numbers/f3a1bc90-.../warmup?enabled=true
Headerx-api-key: your_api_key
Paramsenabled (bool, required) · daily_limit (int, optional override)
// Enabled
{ "warmup_enabled": true }

// Disabled — includes warning
{
  "warmup_enabled": false,
  "warning": "Disabling warm-up on a new number increases ban risk"
}
Warm-up is ON by default for all new numbers. Numbers under 7 days old are capped at 50 sends/day, scaling up automatically over 30 days.
Number health
GET/numbers/{number_id}/health 🔑 Auth required
Request
Response
MethodGET
URLhttps://api.wamator.com/numbers/f3a1bc90-.../health
Headerx-api-key: your_api_key
{
  "number_id": "f3a1bc90-...",
  "phone_number": "2349063570004",
  "health": "healthy",
  "is_active": true,
  "age_days": 12,
  "queue_depth": 45,
  "dead_last_hour": 0,
  "warmup": {
    "enabled": true,
    "sends_today": 38,
    "daily_limit": 150
  }
}
If health is unhealthy (10+ dead sends in 1 hour), the number is auto-paused. Reconnect it via /numbers/{id}/connect.
Remove a number
DELETE/numbers/{number_id} 🔑 Auth required
Request
MethodDELETE
URLhttps://api.wamator.com/numbers/f3a1bc90-7e2d-4a11-9c33-112233445566
Headerx-api-key: your_api_key

Contacts

Recipients of your messages. Each contact belongs to a sub-user. Store rich CRM fields and use them as {{placeholder}} in message templates.

Bulk import
POST/contacts/bulk 🔑 Auth required
Request
Response
All Fields
MethodPOST
URLhttps://api.wamator.com/contacts/bulk
HeaderContent-Type: application/json
Headerx-api-key: your_api_key
{
  "contacts": [
    {
      "user_id": "702cc6ac-8832-447c-8b7a-270ed1841a6b",
      "phone_number": "2348012345678",
      "name": "Mrs. Adaeze Obi",
      "email": "adaeze@gmail.com",
      "city": "Lagos",
      "gender": "female",
      "customer_tier": "gold",
      "message_opt_in": true
    }
  ]
}
{
  "status": "ok",
  "inserted": 2,
  "skipped": 0,
  "contact_ids": [
    "ccc33333-0000-0000-0000-000000000001",
    "ddd44444-0000-0000-0000-000000000002"
  ]
}
Use the returned contact_ids to immediately assign contacts to a list or tag — e.g. pass them to POST /lists/{list_id}/contacts.
FieldTypeNotes
phone_numberstringRequired
user_idUUIDRequired
namestringUse in {{name}}
nicknamestringUse in {{nickname}}
emailstring
genderstringmale / female
citystringUse in {{city}}
statestring
countrystring
job_titlestring
company_namestringUse in {{company_name}}
customer_tierstringbronze / silver / gold / platinum / vip
message_opt_inbooleanDefault true. False = excluded from blasts.
List (paginated)
GET/contacts/ 🔑 Auth required
Request
MethodGET
URLhttps://api.wamator.com/contacts/?user_id=702cc6ac-...&page=1&limit=50
Headerx-api-key: your_api_key
Paramsuser_id · search · list_id · tag_id · opt_in (yes/no) · page (default: 1) · limit (default: 50, max: 1000)
Update / Delete
PATCH/contacts/{contact_id} 🔑 Auth required
Request
Response
MethodPATCH
URLhttps://api.wamator.com/contacts/contact-uuid-here
HeaderContent-Type: application/json
Headerx-api-key: your_api_key
{
  "updates": {
    "customer_tier": "vip",
    "city": "Abuja",
    "message_opt_in": false
  }
}
{ "status": "ok", "message": "Contact updated" }
DELETE/contacts/{contact_id} 🔑 Auth required
Request
MethodDELETE
URLhttps://api.wamator.com/contacts/contact-uuid-here
Headerx-api-key: your_api_key

Messages

Send WhatsApp messages — text blasts, single messages, media, interactive buttons, lists, location, contacts, and reactions.

Use {{name}}, {{city}}, {{nickname}}, {{company_name}}, {{customer_tier}} in templates — replaced per-contact before sending.
Blast to all contacts
POST/messages/blast 🔑 Auth required
Blast All
Blast Selected
Response
MethodPOST
URLhttps://api.wamator.com/messages/blast
HeaderContent-Type: application/json
Headerx-api-key: your_api_key
{
  "user_id": "702cc6ac-8832-447c-8b7a-270ed1841a6b",
  "phone_number_id": "f3a1bc90-7e2d-4a11-9c33-112233445566",
  "template": "Hello {{name}}, fees for this term are due Friday. Please ensure payment is made. Thank you - Funcare School."
}
MethodPOST
URLhttps://api.wamator.com/messages/blast
HeaderContent-Type: application/json
Headerx-api-key: your_api_key
{
  "user_id": "702cc6ac-...",
  "phone_number_id": "f3a1bc90-...",
  "template": "Dear {{name}}, your {{customer_tier}} offer expires soon!",
  "contact_ids": [
    "aaa11111-0000-0000-0000-000000000001",
    "bbb22222-0000-0000-0000-000000000002"
  ]
}
{
  "status": "ok",
  "batch_id": "e91f3c20-4a11-4b22-8c33-112233445566",
  "sent": 240
}
Save the batch_id to query delivery logs via GET /messages/logs?batch_id=...
Send single text
POST/messages/send 🔑 Auth required
Request
Response
MethodPOST
URLhttps://api.wamator.com/messages/send
HeaderContent-Type: application/json
Headerx-api-key: your_api_key
{
  "phone_number_id": "f3a1bc90-7e2d-4a11-9c33-112233445566",
  "to": "2348012345678",
  "text": "Hello! Your invoice is ready."
}
{ "status": "ok", "result": { ... } }
Send image
POST/messages/send-image 🔑 Auth required
Request
MethodPOST
URLhttps://api.wamator.com/messages/send-image
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "phone_number_id": "f3a1bc90-...",
  "to": "2348012345678",
  "url": "https://example.com/image.jpg",
  "caption": "Check this out!"
}
Send video
POST/messages/send-video 🔑 Auth required
Request
MethodPOST
URLhttps://api.wamator.com/messages/send-video
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "phone_number_id": "f3a1bc90-...",
  "to": "2348012345678",
  "url": "https://example.com/video.mp4",
  "caption": "Watch this!"
}
Send audio
POST/messages/send-audio 🔑 Auth required
Request
MethodPOST
URLhttps://api.wamator.com/messages/send-audio
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "phone_number_id": "f3a1bc90-...",
  "to": "2348012345678",
  "url": "https://example.com/audio.mp3"
}
Send document
POST/messages/send-document 🔑 Auth required
Request
MethodPOST
URLhttps://api.wamator.com/messages/send-document
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "phone_number_id": "f3a1bc90-...",
  "to": "2348012345678",
  "url": "https://example.com/invoice.pdf",
  "filename": "invoice.pdf"
}
Send interactive buttons
POST/messages/send-buttons 🔑 Auth required
Request
MethodPOST
URLhttps://api.wamator.com/messages/send-buttons
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "phone_number_id": "f3a1bc90-...",
  "to": "2348012345678",
  "body": "Please choose an option:",
  "buttons": [
    { "id": "btn1", "text": "Pay Now" },
    { "id": "btn2", "text": "Remind Me Later" }
  ],
  "footer": "Funcare School"
}
Send list (menu)
POST/messages/send-list 🔑 Auth required
Request
MethodPOST
URLhttps://api.wamator.com/messages/send-list
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "phone_number_id": "f3a1bc90-...",
  "to": "2348012345678",
  "title": "Our Services",
  "body": "Choose a service:",
  "button_text": "View Options",
  "sections": [
    {
      "title": "Payments",
      "rows": [
        { "id": "pay_fees", "title": "Pay School Fees", "description": "Pay for current term" },
        { "id": "pay_bus", "title": "Pay Bus Fees" }
      ]
    }
  ],
  "footer": "Funcare School"
}
Send location
POST/messages/send-location 🔑 Auth required
Request
MethodPOST
URLhttps://api.wamator.com/messages/send-location
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "phone_number_id": "f3a1bc90-...",
  "to": "2348012345678",
  "latitude": 6.5244,
  "longitude": 3.3792,
  "name": "Funcare School",
  "address": "12 School Road, Lagos"
}
Send contact card (vCard)
POST/messages/send-contact 🔑 Auth required
Request
MethodPOST
URLhttps://api.wamator.com/messages/send-contact
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "phone_number_id": "f3a1bc90-...",
  "to": "2348012345678",
  "vcard": "BEGIN:VCARD\nVERSION:3.0\nFN:Funcare School\nTEL:+2349063570004\nEND:VCARD"
}
React to a message
POST/messages/react 🔑 Auth required
Request
MethodPOST
URLhttps://api.wamator.com/messages/react
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "phone_number_id": "f3a1bc90-...",
  "message_id": "ABCD1234567",
  "emoji": "👍"
}
Check if number is on WhatsApp
POST/messages/check-number 🔑 Auth required
Request
Response
MethodPOST
URLhttps://api.wamator.com/messages/check-number
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "phone_number_id": "f3a1bc90-...",
  "phone": "2348012345678"
}
{
  "status": "ok",
  "result": {
    "id": "2348012345678@c.us",
    "isWAContact": true
  }
}
Message logs
GET/messages/logs 🔑 Auth required
Request
Response
MethodGET
URLhttps://api.wamator.com/messages/logs?batch_id=e91f3c20-...
Headerx-api-key: your_api_key
Paramsbatch_id · user_id · page · limit
{
  "status": "ok",
  "total": 240,
  "logs": [
    {
      "recipient": "2348012345678",
      "status": "delivered",
      "sent_at": "2026-07-02T20:00:01+00:00",
      "delivered_at": "2026-07-02T20:00:03+00:00"
    }
  ]
}
StatusMeaning
pendingQueued, not yet sent
sentDispatched to WhatsApp
deliveredReceived on device (double tick ✓✓)
failedFailed — see error_message

Groups

Create and manage WhatsApp groups. Send messages and media to an entire group at once.

Create a group
POST/groups/create 🔑 Auth required
Request
Response
MethodPOST
URLhttps://api.wamator.com/groups/create
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "phone_number_id": "f3a1bc90-...",
  "name": "Funcare Parents 2024",
  "participants": [
    "2348012345678",
    "2348087654321"
  ]
}
{
  "status": "ok",
  "group": {
    "id": "120363XXXXXXXXXX@g.us",
    "name": "Funcare Parents 2024"
  }
}
Save the group id (ends in @g.us) — use it to send messages to the group.
List groups
GET/groups/ 🔑 Auth required
Request
MethodGET
URLhttps://api.wamator.com/groups/?phone_number_id=f3a1bc90-...
Headerx-api-key: your_api_key
Get group info
GET/groups/{group_id} 🔑 Auth required
Request
MethodGET
URLhttps://api.wamator.com/groups/120363XXXXXXXXXX@g.us?phone_number_id=f3a1bc90-...
Headerx-api-key: your_api_key
Send text to group
POST/groups/{group_id}/send-text 🔑 Auth required
Request
MethodPOST
URLhttps://api.wamator.com/groups/120363XXXXXXXXXX@g.us/send-text
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "phone_number_id": "f3a1bc90-...",
  "group_id": "120363XXXXXXXXXX@g.us",
  "text": "Good morning parents! School resumes Monday."
}
Send image to group
POST/groups/{group_id}/send-image 🔑 Auth required
Request
MethodPOST
URLhttps://api.wamator.com/groups/120363XXXXXXXXXX@g.us/send-image
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "phone_number_id": "f3a1bc90-...",
  "group_id": "120363XXXXXXXXXX@g.us",
  "url": "https://example.com/notice.jpg",
  "caption": "Term 3 timetable"
}
Add / Remove participants
POST/groups/{group_id}/participants/add 🔑 Auth required
Request
MethodPOST
URLhttps://api.wamator.com/groups/120363XXXXXXXXXX@g.us/participants/add
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "phone_number_id": "f3a1bc90-...",
  "participants": ["2348099999999", "2348011111111"]
}
DELETE/groups/{group_id}/participants 🔑 Auth required
Request
MethodDELETE
URLhttps://api.wamator.com/groups/120363XXXXXXXXXX@g.us/participants
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "phone_number_id": "f3a1bc90-...",
  "participants": ["2348099999999"]
}

Lists

User-level segmentation containers. A contact can belong to multiple lists. Use lists to target broadcasts and trigger sequences — e.g. "School Owners", "Crusade Attendees", "VIP Customers".

Lists belong to a user, not the vendor. Always pass user_id when creating a list.
Create a list
POST/lists/ 🔑 Auth required
Request
Response
MethodPOST
URLhttps://api.wamator.com/lists/
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "user_id": "702cc6ac-8832-447c-8b7a-270ed1841a6b",
  "name": "School Owners",
  "description": "All registered school owners on Edumess"
}
{
  "id": "a1b2c3d4-...",
  "name": "School Owners",
  "description": "All registered school owners on Edumess",
  "created_at": "2026-07-03T10:00:00Z"
}
Save the id — use it in broadcasts and sequence enrollment.
Get all lists
GET/lists/?user_id={user_id} 🔑 Auth required
Request
Response
URLhttps://api.wamator.com/lists/?user_id=702cc6ac-...
Headerx-api-key: your_api_key
[
  {
    "id": "a1b2c3d4-...",
    "name": "School Owners",
    "description": "...",
    "contact_count": 240,
    "created_at": "2026-07-03T10:00:00Z"
  }
]
Add contacts to a list
POST/lists/{list_id}/contacts 🔑 Auth required
Request
Response
URLhttps://api.wamator.com/lists/a1b2c3d4-.../contacts
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "contact_ids": [
    "ccc33333-0000-0000-0000-000000000001",
    "ddd44444-0000-0000-0000-000000000002"
  ]
}
{ "added": 2, "list_id": "a1b2c3d4-..." }
Get list contacts · Remove contacts · Delete list
GET/lists/{list_id}/contacts 🔑 Auth required
Request
URLhttps://api.wamator.com/lists/a1b2c3d4-.../contacts?page=1&limit=50
Headerx-api-key: your_api_key
DELETE/lists/{list_id}/contacts Remove contacts from list🔑 Auth required
Request
URLhttps://api.wamator.com/lists/a1b2c3d4-.../contacts
Body{ "contact_ids": ["ccc33333-..."] }
DELETE/lists/{list_id} Delete list🔑 Auth required
Request
URLhttps://api.wamator.com/lists/a1b2c3d4-...
Headerx-api-key: your_api_key

Tags

Labels applied to contacts to mark their stage or status — e.g. opted-in, purchased, hot-lead. Tags drive branching logic in sequences and can be used to target broadcasts.

Create a tag
POST/tags/ 🔑 Auth required
Request
Response
URLhttps://api.wamator.com/tags/
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "user_id": "702cc6ac-...",
  "name": "purchased",
  "color": "#1DBD8C"
}
{
  "id": "e5f6a7b8-...",
  "name": "purchased",
  "color": "#1DBD8C",
  "created_at": "2026-07-03T10:00:00Z"
}
Tag contacts · Untag contacts · Get tagged contacts
POST/tags/{tag_id}/contacts Apply tag to contacts🔑 Auth required
Request
Response
URLhttps://api.wamator.com/tags/e5f6a7b8-.../contacts
HeaderContent-Type: application/json · x-api-key: your_api_key
{ "contact_ids": ["ccc33333-...", "ddd44444-..."] }
{ "tagged": 2, "tag_id": "e5f6a7b8-..." }
DELETE/tags/{tag_id}/contacts Remove tag from contacts🔑 Auth required
Request
URLhttps://api.wamator.com/tags/e5f6a7b8-.../contacts
Body{ "contact_ids": ["ccc33333-..."] }
GET/tags/{tag_id}/contacts List contacts with this tag🔑 Auth required
Request
URLhttps://api.wamator.com/tags/e5f6a7b8-.../contacts?page=1&limit=50
Headerx-api-key: your_api_key

Sequences

Named automation workflows with ordered steps. A sequence defines what messages to send, when to wait, and what conditions to branch on. You enroll contacts into sequences separately.

Step types
TypeConfig fieldsWhat it does
send_textbodySends a text message. Supports {{first_name}}, {{name}}, {{phone}}, {{email}}
send_mediaurl, caption, media_typeSends image/video/audio/document. media_type: image | video | audio | document
waitdelay_value, delay_unitPauses the sequence. delay_unit: minutes | hours | days
branchcondition, field, operator, value, yes_step, no_stepBranches based on contact data or tag
Create a sequence
POST/sequences/ 🔑 Auth required
Request
Response
URLhttps://api.wamator.com/sequences/
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "user_id": "702cc6ac-...",
  "name": "New Student Onboarding",
  "phone_number_id": "f3a1bc90-...",
  "timezone": "Africa/Lagos",
  "delivery_window_start": "09:00",
  "delivery_window_end": "20:00",
  "steps": [
    {
      "step_order": 1,
      "step_type": "send_text",
      "config": {
        "body": "Hello {{first_name}}! Welcome to Funcare School. We are excited to have you."
      }
    },
    {
      "step_order": 2,
      "step_type": "wait",
      "config": { "delay_value": 1, "delay_unit": "days" }
    },
    {
      "step_order": 3,
      "step_type": "send_text",
      "config": {
        "body": "Hi {{first_name}}, just checking in. Have you completed your registration form?"
      }
    },
    {
      "step_order": 4,
      "step_type": "wait",
      "config": { "delay_value": 2, "delay_unit": "days" }
    },
    {
      "step_order": 5,
      "step_type": "send_image",
      "config": {
        "url": "https://yourcdn.com/school-brochure.jpg",
        "caption": "Here is our school brochure, {{first_name}}. See you soon!"
      }
    }
  ]
}
{
  "id": "seq-uuid-here",
  "name": "New Student Onboarding",
  "status": "active"
}
List · Get · Update · Replace steps · Delete
GET/sequences/?user_id={user_id} 🔑 Auth required
Request
URLhttps://api.wamator.com/sequences/?user_id=702cc6ac-...
Headerx-api-key: your_api_key
GET/sequences/{sequence_id} Returns sequence + all steps🔑 Auth required
Request
URLhttps://api.wamator.com/sequences/seq-uuid-here
PATCH/sequences/{sequence_id} Update name, timezone, status, number🔑 Auth required
Request
URLhttps://api.wamator.com/sequences/seq-uuid-here
Body{ "status": "paused" } // or name, timezone, delivery_window_start/end
PUT/sequences/{sequence_id}/steps Replace all steps at once🔑 Auth required
Request
URLhttps://api.wamator.com/sequences/seq-uuid-here/steps
Body[ { "step_order": 1, "step_type": "send_text", "config": { "body": "Hi!" } }, ... ]

Enrollments

Enroll contacts into a sequence — Wamator walks them through each step automatically, respecting delays, timezone delivery windows, rate limits, and opt-outs.

A contact already enrolled (active) in the same sequence will be skipped. Opted-out contacts are also skipped automatically.
Enroll contacts into a sequence
POST/automations/{sequence_id}/enroll 🔑 Auth required
Request
Response
MethodPOST
URLhttps://api.wamator.com/automations/seq-uuid-here/enroll
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "contact_ids": [
    "ccc33333-0000-0000-0000-000000000001",
    "ddd44444-0000-0000-0000-000000000002"
  ],
  "phone_number_id": "f3a1bc90-..."
}
{
  "enrolled": 2,
  "skipped": 0,
  "enrollment_ids": [
    "enr-uuid-1",
    "enr-uuid-2"
  ],
  "skipped_details": []
}
The sequence starts immediately. Step 1 fires right away, subsequent steps fire according to their delay settings.
Track enrollment progress
GET/automations/{sequence_id}/enrollments 🔑 Auth required
Request
Response
URLhttps://api.wamator.com/automations/seq-uuid-here/enrollments?status=active&page=1
Paramsstatus (active | completed | cancelled) · page · limit
{
  "page": 1,
  "limit": 50,
  "enrollments": [
    {
      "id": "enr-uuid-1",
      "contact_id": "ccc33333-...",
      "contact_name": "Mrs. Adaeze Obi",
      "phone_number": "2348012345678",
      "current_step_order": 2,
      "status": "active",
      "enrolled_at": "2026-07-03T10:00:00Z",
      "next_run_at": "2026-07-04T09:00:00Z"
    }
  ]
}
Cancel an enrollment
DELETE/automations/{sequence_id}/enrollments/{enrollment_id} 🔑 Auth required
Request
URLhttps://api.wamator.com/automations/seq-uuid-here/enrollments/enr-uuid-1
Headerx-api-key: your_api_key

Broadcasts

One-shot blasts to a list, a tag group, or selected contacts. Messages go into the priority queue and are sent respecting rate limits and opt-outs. Template variables are substituted per contact.

Use {{first_name}}, {{name}}, {{phone}}, {{email}} in the message body — replaced per contact before sending.
Send a broadcast
POST/broadcasts/ 🔑 Auth required
By List
By Tag
Media
Response
MethodPOST
URLhttps://api.wamator.com/broadcasts/
HeaderContent-Type: application/json · x-api-key: your_api_key
// Blast to everyone in a list
{
  "user_id": "702cc6ac-...",
  "phone_number_id": "f3a1bc90-...",
  "message_type": "text",
  "body": "Hello {{first_name}}, term fees are due this Friday. Please ensure payment is made. Thank you — Funcare School.",
  "list_id": "a1b2c3d4-..."
}
// Blast to all contacts with a specific tag
{
  "user_id": "702cc6ac-...",
  "phone_number_id": "f3a1bc90-...",
  "message_type": "text",
  "body": "Exclusive offer for {{first_name}} — your VIP discount expires tonight!",
  "tag_id": "e5f6a7b8-..."
}
// Send an image to a list
{
  "user_id": "702cc6ac-...",
  "phone_number_id": "f3a1bc90-...",
  "message_type": "image",
  "media_url": "https://yourcdn.com/flyer.jpg",
  "caption": "Our end of term event is here! See you {{first_name}} \ud83c\udf89",
  "list_id": "a1b2c3d4-..."
}
{
  "batch_id": "bcast-uuid-here",
  "queued": 240,
  "total_contacts": 242,
  "skipped_opted_out": 2
}
Save batch_id to track delivery via GET /broadcasts/{batch_id}
Track broadcast delivery
GET/broadcasts/{batch_id} 🔑 Auth required
Request
Response
URLhttps://api.wamator.com/broadcasts/bcast-uuid-here
Headerx-api-key: your_api_key
{
  "batch_id": "bcast-uuid-here",
  "messages": [
    {
      "to_number": "2348012345678",
      "status": "sent",
      "processed_at": "2026-07-03T10:05:00Z"
    },
    {
      "to_number": "2348099999999",
      "status": "pending",
      "processed_at": null
    }
  ]
}
List all broadcasts
GET/broadcasts/?user_id={user_id} 🔑 Auth required
Request
URLhttps://api.wamator.com/broadcasts/?user_id=702cc6ac-...&page=1&limit=20
Headerx-api-key: your_api_key

Opt-outs

When a contact replies STOP to any message, Wamator automatically opts them out — cancels all active enrollments, removes them from future sends, and updates their contact record. You can also manage opt-outs manually.

Opted-out contacts are NEVER messaged again — not via blast, not via sequence, not via direct send. This is checked before every single message leaves the queue.
List opted-out contacts
GET/opt-outs/?user_id={user_id} 🔑 Auth required
Request
Response
URLhttps://api.wamator.com/opt-outs/?user_id=702cc6ac-...&page=1
Headerx-api-key: your_api_key
{
  "total_opted_out": 3,
  "opt_outs": [
    {
      "phone_number": "2348012345678",
      "contact_name": "Mrs. Adaeze Obi",
      "opted_out_at": "2026-07-02T14:30:00Z",
      "is_active": true
    }
  ]
}
Manually opt out a contact
POST/opt-outs/ e.g. they called to unsubscribe🔑 Auth required
Request
Response
URLhttps://api.wamator.com/opt-outs/
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "user_id": "702cc6ac-...",
  "phone_number": "2348012345678"
}
{ "message": "Contact opted out", "phone_number": "2348012345678" }
Re-enable a contact (they want back in)
DELETE/opt-outs/{phone_number}?user_id={user_id} 🔑 Auth required
Request
URLhttps://api.wamator.com/opt-outs/2348012345678?user_id=702cc6ac-...
Headerx-api-key: your_api_key
Contacts can also re-enable themselves by replying START to any message from your number — Wamator handles this automatically.

Webhooks

Register a URL on your server and Wamator will POST real-time events to it — message delivery, opt-outs, completed sequences, unhealthy numbers. No polling required.

Step 1 — Register your webhook URL
PATCH/vendors/webhook 🔑 Auth required
Request
Response
MethodPATCH
URLhttps://api.wamator.com/vendors/webhook
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "url": "https://edumess.com/api/wamator-events",
  "secret": "your-signing-secret-here",
  "events": [
    "message.sent",
    "message.delivered",
    "message.failed",
    "contact.opted_out",
    "enrollment.completed",
    "number.unhealthy"
  ]
}
{
  "status": "ok",
  "url": "https://edumess.com/api/wamator-events",
  "events": ["message.sent", "message.delivered", ...]
}
You can subscribe to any subset of events. Omit events to receive all of them.
Step 2 — Receive events on your server

Wamator will POST this JSON structure to your URL for every event:

// message.sent
{
  "event": "message.sent",
  "timestamp": "2026-07-03T10:05:00Z",
  "data": {
    "to": "2348012345678",
    "batch_id": "bcast-uuid-here",
    "enrollment_id": null,
    "message_type": "text"
  }
}

// message.delivered
{
  "event": "message.delivered",
  "timestamp": "2026-07-03T10:05:04Z",
  "data": {
    "to": "2348012345678",
    "batch_id": "bcast-uuid-here"
  }
}

// message.failed
{
  "event": "message.failed",
  "timestamp": "2026-07-03T10:07:00Z",
  "data": {
    "to": "2348099999999",
    "batch_id": "bcast-uuid-here",
    "error": "Max retries exceeded"
  }
}

// contact.opted_out
{
  "event": "contact.opted_out",
  "timestamp": "2026-07-03T11:00:00Z",
  "data": {
    "phone_number": "2348055555555",
    "contact_name": "Mrs. Adaeze Obi"
  }
}

// enrollment.completed
{
  "event": "enrollment.completed",
  "timestamp": "2026-07-05T09:00:00Z",
  "data": {
    "enrollment_id": "enr-uuid-here",
    "contact_id": "ccc33333-...",
    "sequence_id": "seq-uuid-here"
  }
}

// number.unhealthy
{
  "event": "number.unhealthy",
  "timestamp": "2026-07-03T12:00:00Z",
  "data": {
    "phone_number_id": "f3a1bc90-...",
    "phone_number": "2349063570004",
    "reason": "10+ failed sends in the last hour — number auto-paused"
  }
}
Step 3 — Verify the signature (recommended)

Every request includes an X-Wamator-Signature header. Verify it to ensure the request is from Wamator and not a third party.

// Node.js
const crypto = require('crypto');

function verifySignature(body, signature, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(body)  // raw request body as Buffer
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

// Express example
app.post('/api/wamator-events', express.raw({type: 'application/json'}), (req, res) => {
  const sig = req.headers['x-wamator-signature'];
  if (!verifySignature(req.body, sig, process.env.WAMATOR_SECRET)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }
  const event = JSON.parse(req.body);
  // handle event.event ...
  res.json({ received: true });
});

// PHP
$body    = file_get_contents('php://input');
$sig     = $_SERVER['HTTP_X_WAMATOR_SIGNATURE'];
$expected = 'sha256=' . hash_hmac('sha256', $body, getenv('WAMATOR_SECRET'));
if (!hash_equals($expected, $sig)) {
    http_response_code(401); exit;
}
$event = json_decode($body, true);
Manage your webhook
GET/vendors/webhook Get current config🔑 Auth required
Request
URLhttps://api.wamator.com/vendors/webhook
Headerx-api-key: your_api_key
GET/vendors/webhook/logs See delivery attempts + results🔑 Auth required
Request
Response
URLhttps://api.wamator.com/vendors/webhook/logs?page=1&limit=20
Headerx-api-key: your_api_key
{
  "page": 1,
  "logs": [
    {
      "event": "message.delivered",
      "delivered": true,
      "response_status": 200,
      "response_body": "{"received":true}",
      "attempt": 1,
      "created_at": "2026-07-03T10:05:04Z"
    },
    {
      "event": "contact.opted_out",
      "delivered": false,
      "response_status": 500,
      "response_body": "Internal Server Error",
      "attempt": 1,
      "created_at": "2026-07-03T11:00:00Z"
    }
  ]
}
DELETE/vendors/webhook Disable webhook (keeps config)🔑 Auth required
Request
URLhttps://api.wamator.com/vendors/webhook
Headerx-api-key: your_api_key
POST /webhooks/openwa is internal — the WhatsApp gateway calls it automatically. Never call it from your application.

Vendor Plans

White-label plan configurations. You define your own plan names and selling prices on top of Wamator's base plans. Your end-users see only your branding and prices — never Wamator's.

Before accepting payments, create at least one vendor plan config. It maps a Wamator base plan to your custom name and price.
Create a plan config
POST/vendor-plans/ 🔑 Auth required
Request
Response
MethodPOST
URLhttps://api.wamator.com/vendor-plans/
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "plan_id": "a741616a-9725-4737-b67c-59811277685e",
  "custom_name": "Edumess Starter",
  "custom_description": "For small schools — up to 1000 contacts, 1000 messages/month",
  "selling_price": 8000,
  "currency": "NGN"
}
{
  "status": "ok",
  "plan_config": {
    "id": "vpc-uuid-here",
    "plan_id": "a741616a-...",
    "custom_name": "Edumess Starter",
    "selling_price": 8000.00,
    "currency": "NGN",
    "is_active": true
  }
}
Save the id — pass it as vendor_plan_config_id when initiating a payment.
List · Get · Update · Delete
GET/vendor-plans/ List all your plan configs🔑 Auth required
Request
URLhttps://api.wamator.com/vendor-plans/
Headerx-api-key: your_api_key
PATCH/vendor-plans/{config_id} Update name, price, or active status🔑 Auth required
Request
URLhttps://api.wamator.com/vendor-plans/vpc-uuid-here
Body{ "selling_price": 9500 } // send only fields to change

Accept Payment

Two ways to collect subscription payments from your end-users. Both use Paystack under the hood. Choose based on how much UI you want to build yourself.

Which approach should I use?
ApproachWhen to useYou build
Hosted Checkout Recommended You want the fastest path. Redirect your user to a Wamator-hosted page — Wamator handles all the UI, billing period selection, and Paystack redirect. Nothing. Just a redirect URL.
API Flow (POST /pay/init) You want full control of your own UI — custom checkout page, embedded modal, etc. Your own checkout UI. You call the API and redirect to the Paystack link.
How both approaches work — end to end
1
Register your user — POST /users/registerEvery user must exist in Wamator before they can pay. Save the returned id (user_id) in your own DB.
2
User is ready to subscribe — redirect or call APIHosted: redirect to https://app.wamator.com/checkout/{vendor_id}?user_id={user_id}
API: call POST /pay/init from your backend → get payment_link → redirect user to it
3
User pays on PaystackPaystack handles card, bank transfer, USSD — your user never leaves a secure payment flow
4
Wamator webhook fires automaticallySubscription is activated for the user. Your wallet is credited with your earnings (selling price minus Wamator's base cost).
5
User is redirected back to your appTo your return_url. Show a success screen. No polling needed — subscription is already active.
Option A — API Flow: POST /pay/init

Call this from your backend server (never from frontend — your API key must stay secret). Pass the sub-user ID, the plan config they chose, and where to send them after payment.

POST/pay/init 🔑 Auth required
Request
Response
Fields
Full Example
MethodPOST
URLhttps://api.wamator.com/pay/init
HeaderContent-Type: application/json
Headerx-api-key: your_api_key
{
  "user_id": "702cc6ac-8832-447c-8b7a-270ed1841a6b",
  "vendor_plan_config_id": "vpc-uuid-here",
  "customer_email": "admin@funcare.com",
  "customer_name": "Funcare School",
  "customer_phone": "2348012345678",
  "return_url": "https://edumess.com/payment/complete"
}
{
  "status": "ok",
  "session_id": "ps-uuid-here",
  "payment_link": "https://checkout.paystack.com/abcdef123456",
  "reference": "wam-a1b2c3d4e5f6g7h8i9j0"
}
Redirect the user to payment_link immediately. After they pay, Paystack sends them to your return_url. The subscription is already active by then — no polling needed.
FieldTypeNotes
user_idUUIDRequired — must already exist via POST /users/register
vendor_plan_config_idUUIDRequired — get from GET /vendor-plans/
customer_emailstringRequired — shown on Paystack page
customer_namestringRequired — shown on Paystack page
customer_phonestringOptional
return_urlstringWhere Paystack sends the user after payment. Use your own app URL.

Complete server-side flow in Node.js (Express):

// 1. School signs up in Edumess — register them in Wamator
const userRes = await fetch('https://api.wamator.com/users/register', {
  method: 'POST',
  headers: { 'x-api-key': process.env.WAMATOR_KEY, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    name: school.name,
    email: school.email,
    external_id: school.id   // your DB id — link back later
  })
});
const { id: wamatorUserId } = await userRes.json();
// Save wamatorUserId in your DB against this school

// 2. School clicks "Subscribe to Messaging" in Edumess
// Call from your backend:
const payRes = await fetch('https://api.wamator.com/pay/init', {
  method: 'POST',
  headers: { 'x-api-key': process.env.WAMATOR_KEY, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    user_id: wamatorUserId,
    vendor_plan_config_id: 'vpc-uuid-here',  // your plan config
    customer_email: school.email,
    customer_name: school.name,
    return_url: 'https://edumess.com/payment/complete'
  })
});
const { payment_link } = await payRes.json();

// 3. Redirect the school to Paystack
res.redirect(payment_link);

// 4. Paystack calls Wamator webhook automatically
// Subscription activates. Your wallet is credited. Done.

Hosted Checkout Page

Skip building a payment UI entirely. Wamator hosts a branded checkout page for your vendor account. Register your user, then redirect them to the URL below — they pick a plan, pay, and are sent back to your app.

The checkout page shows your brand name and logo (set in Settings → Account on the dashboard). If none is set, it falls back to the Wamator brand.
How to use it — 2 steps
1
Register your user — POST /users/registerGet back a user_id. Save it in your database against your user record.
2
Redirect your user to the checkout URLThat's it. Wamator handles plan selection, billing period, Paystack payment, subscription activation, and wallet credit.
Checkout URL format
URLhttps://app.wamator.com/checkout/{your_vendor_id}?user_id={user_id}
OptionalAdd &plan={plan_config_id} to pre-select a specific plan
No authPublic URL — no API key needed in the redirect
// Minimum — user picks their own plan
https://app.wamator.com/checkout/7a689d72-...?user_id=702cc6ac-...

// Pre-select a plan (user just confirms and pays)
https://app.wamator.com/checkout/7a689d72-...?user_id=702cc6ac-...&plan=vpc-uuid-here
What the user sees on the checkout page
ElementSource
Brand name / logoYour white_label_brand_name and white_label_logo — set in dashboard Settings. Falls back to Wamator branding.
User's nameFetched from Wamator using user_id — user sees their own name. No typing needed.
Plan listAll active vendor plan configs you created via POST /vendor-plans/
Current planIf the user already has an active subscription, it's highlighted — they can upgrade to another plan
Billing periodUser selects Monthly / Quarterly (−10%) / Annual (−20%)
After paymentRedirects to https://app.wamator.com/checkout/{vendor_id}?status=success by default
Public API endpoints (no auth required)
GET/checkout/{vendor_id} Returns vendor branding + active plan configs
Response
{
  "vendor_id": "7a689d72-...",
  "brand_name": "Edumess",
  "logo_url": "https://cdn.example.com/edumess-logo.png",
  "brand_color": "#1DBD8C",
  "plans": [
    {
      "id": "vpc-uuid-here",
      "name": "School Basic",
      "description": "For schools up to 500 students",
      "price": 8000.00,
      "currency": "NGN",
      "max_messages": 5000,
      "max_contacts": 500
    }
  ]
}
GET/checkout/{vendor_id}/user?user_id={user_id} Returns user details + current active subscription
Response
{
  "id": "702cc6ac-...",
  "name": "Funcare School",
  "email": "admin@funcare.com",
  "active_plan_config_id": "vpc-uuid-here",
  "active_plan_name": "School Basic",
  "active_ends_at": "2026-08-05T00:00:00Z",
  "active_billing_period": "monthly"
}
active_plan_config_id is null if the user has no current subscription. The checkout page uses this to highlight their current plan and disable re-subscribing to the same plan.
The user_id in the checkout URL is a Wamator UUID — not sensitive on its own, but don't expose your vendor_id + user_id combination in public links if your users shouldn't be able to see each other's plan status. For internal dashboards and app redirects, this is perfectly safe.

Wallet & Payouts

Every time a subscription payment succeeds, Wamator credits your earnings to your wallet. You can view your balance and withdraw to your bank account at any time.

Get wallet balance & transactions
GET/wallet/ 🔑 Auth required
Request
Response
URLhttps://api.wamator.com/wallet/
Headerx-api-key: your_api_key
{
  "status": "ok",
  "balance": 24500.00,
  "currency": "NGN",
  "transactions": [
    {
      "type": "credit",
      "amount": 6500.00,
      "balance_after": 24500.00,
      "description": "Subscription payment received",
      "reference": "wam-a1b2c3d4e5f6",
      "created_at": "2026-07-05T10:00:00Z"
    },
    {
      "type": "debit",
      "amount": 10000.00,
      "balance_after": 18000.00,
      "description": "Withdrawal request",
      "reference": "wd-x1y2z3w4v5",
      "created_at": "2026-07-03T14:00:00Z"
    }
  ]
}
Save bank account details
POST/wallet/bank-details 🔑 Auth required
Request
Response
URLhttps://api.wamator.com/wallet/bank-details
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "bank_account_no": "0123456789",
  "bank_code": "058",
  "bank_account_name": "Edumess Technology Ltd"
}
{ "status": "ok", "message": "Bank details saved" }
Get the list of bank codes from GET /wallet/banks — returns all Nigerian banks with their Paystack codes.
Get Nigerian bank list (for bank code lookup)
GET/wallet/banks 🔑 Auth required
Request
Response
URLhttps://api.wamator.com/wallet/banks
Headerx-api-key: your_api_key
{
  "status": "ok",
  "banks": [
    { "name": "Access Bank", "code": "044" },
    { "name": "GTBank", "code": "058" },
    { "name": "Zenith Bank", "code": "057" },
    { "name": "First Bank of Nigeria", "code": "011" }
  ]
}
Withdraw to bank account
POST/wallet/withdraw 🔑 Auth required
Request
Response
URLhttps://api.wamator.com/wallet/withdraw
HeaderContent-Type: application/json · x-api-key: your_api_key
{
  "amount": 10000
}
{
  "status": "ok",
  "withdrawal_id": "wd-uuid-here",
  "amount": 10000,
  "reference": "wd-x1y2z3w4v5u6",
  "message": "Withdrawal initiated — funds will arrive in your bank account shortly"
}
You must save your bank details via POST /wallet/bank-details before withdrawing. Minimum withdrawal is ₦100.
Withdrawal history
GET/wallet/withdrawals 🔑 Auth required
Request
URLhttps://api.wamator.com/wallet/withdrawals?page=1
Headerx-api-key: your_api_key

Payment Webhook

Wamator receives payment confirmations from Paystack automatically. You do not need to call or configure this endpoint — it is documented here for transparency and debugging.

Set your Paystack webhook URL to https://api.wamator.com/webhooks/paystack in your Paystack dashboard under Settings → API Keys & Webhooks.
What happens when Paystack fires
1
Paystack sends charge.success eventWamator verifies the HMAC-SHA512 signature and matches it to the pending payment session
2
Subscription is activatedThe sub-user's subscription goes active for the plan duration. If they already have a subscription, it is extended.
3
Your wallet is creditedYour earnings (selling_price minus Wamator's base cost) are added to your wallet balance
4
You receive an emailShows customer name, amount paid, and your credited earnings

The endpoint Paystack calls (internal — do not call this yourself):

POST https://api.wamator.com/webhooks/paystack

// Headers sent by Paystack
x-paystack-signature: sha512 HMAC of raw body

// Payload (charge.success event)
{
  "event": "charge.success",
  "data": {
    "id": 12345678,
    "reference": "wam-a1b2c3d4e5f6g7h8i9j0",
    "amount": 800000,
    "currency": "NGN",
    "status": "success"
  }
}