API Referansı

WhatsMod Public API

Kendi sisteminizden WhatsApp üzerinden OTP, mesaj ve medya gönderin. Bearer token, JSON body, REST. WordPress/WooCommerce/OpenCart plugin'lerimiz bu API'nin üzerine kurulu.

Hızlı Başlangıç

  1. 1
    Hesap aç + token üret. app.whatsmod.io → Ayarlar → API Tokens → Yeni Token. Scope seçin: otp (OTP), messages.send (mesaj gönder), messages.read (durum/geçmiş oku) veya * (tam erişim). En az yetki ilkesi: yalnız ihtiyacın olan scope'u ver.
  2. 2
    WhatsApp hesabı bağlayın. Numaranızı QR kodla bağlayın (Ayarlar → Numaralar). Aktif ve connected olmalı.
  3. 3
    İsteği atın. Aşağıdaki curl örneğini kopyalayın, wsk_... yerine token'ınızı yapıştırın, telefon numarasını güncelleyin.
  4. 4
    Cevabı alın. HTTP 202 + JSON: {sent: true, messageId: "...", creditsRemaining: 498}

Kimlik Doğrulama

Tüm isteklerde Authorization: Bearer wsk_... header'ı zorunlu. Token wsk_ önekiyle başlar ve 52 karakterdir. Sadece üretildiği anda bir kez gösterilir — güvenli bir yerde saklayın.

Scope kontrolü (zorunlu): Her endpoint belirli bir scope ister — OTP → otp, mesaj gönderme → messages.send, durum/geçmiş okuma → messages.read (veya hepsi için *). Kısıtlı token (örn. OTP-only), WordPress/WooCommerce/OpenCart plugin'leri için önerilir — güvenlik için tam yetki vermeyin. Token ayrıca tek bir numaraya (allowedAccountId) kilitlenebilir; o token başka numaradan gönderemez.

Endpoint'ler

Base URL: https://gw.whatsmod.io

GET/api/public/v1/accountsscope: geçerli token

Tenant'ınızın bağlı WhatsApp numaralarını listeler. Mesaj gönderirken kullanılacak accountId buradan alınır.

İstek (curl)
curl https://gw.whatsmod.io/api/public/v1/accounts \
  -H "Authorization: Bearer wsk_YOUR_TOKEN"
Cevap
{
  "data": [
    {
      "id": "ck...",
      "phoneNumber": "905XXXXXXXXX",
      "displayName": "Satış",
      "status": "connected",
      "lastSeenAt": "2026-05-25T10:00:00.000Z"
    }
  ]
}
POST/api/public/v1/messagesscope: messages.send veya *

Metin mesajı gönderir (maks 4096 karakter). 202 Accepted → mesaj kuyruğa alındı. Çift gönderimi önlemek için Idempotency-Key header'ı ekleyin (aşağıda Idempotency bölümü).

İstek (curl)
curl -X POST https://gw.whatsmod.io/api/public/v1/messages \
  -H "Authorization: Bearer wsk_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 9f1c2e4a-8b3d-4c5e-a1b2-c3d4e5f6a7b8" \
  -d '{
    "accountId": "ck...",
    "to": "+905XXXXXXXXX",
    "text": "Merhaba! Siparişiniz hazır."
  }'
Cevap
{
  "message": {
    "id": "ck...",
    "status": "pending",
    "creditsUsed": 1
  }
}
JavaScript / TypeScript örneği
const res = await fetch('https://gw.whatsmod.io/api/public/v1/messages', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.WHATSMOD_TOKEN}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': crypto.randomUUID(),
  },
  body: JSON.stringify({
    accountId: 'ck...',
    to: '+905XXXXXXXXX',
    text: 'Merhaba! Siparişiniz hazır.',
  }),
});
const data = await res.json();
POST/api/public/v1/messages/mediascope: messages.send veya *

Medya (image/video/audio/document/sticker) + opsiyonel caption gönderir. multipart/form-data, maks 100 MB. Idempotency-Key desteklenir.

İstek (curl)
curl -X POST https://gw.whatsmod.io/api/public/v1/messages/media \
  -H "Authorization: Bearer wsk_YOUR_TOKEN" \
  -H "Idempotency-Key: 9f1c2e4a-8b3d-4c5e-a1b2-c3d4e5f6a7b8" \
  -F "accountId=ck..." \
  -F "to=+905XXXXXXXXX" \
  -F "type=image" \
  -F "caption=Ürün görseli" \
  -F "file=@/path/to/product.jpg"
Cevap
{
  "message": {
    "id": "ck...",
    "status": "pending",
    "creditsUsed": 1
  }
}
GET/api/public/v1/messages/{messageId}scope: messages.read veya *

Tek bir mesajın durumunu döner: pending/queued/sent/delivered/read/failed, kullanılan kredi ve teslim/okundu zaman damgaları.

İstek (curl)
curl https://gw.whatsmod.io/api/public/v1/messages/ck... \
  -H "Authorization: Bearer wsk_YOUR_TOKEN"
Cevap
{
  "id": "ck...",
  "direction": "outbound",
  "type": "text",
  "status": "delivered",
  "creditsUsed": 1,
  "deliveredAt": "2026-05-25T10:01:00.000Z",
  "readAt": null,
  "createdAt": "2026-05-25T10:00:00.000Z"
}
GET/api/public/v1/conversations/{conversationId}/messagesscope: messages.read veya *

Bir sohbetin mesaj geçmişini yeniden → eskiye döner. Cursor sayfalama: ?limit=50&cursor=... ; yanıttaki nextCursor sonraki sayfa için kullanılır.

İstek (curl)
curl "https://gw.whatsmod.io/api/public/v1/conversations/ck.../messages?limit=50" \
  -H "Authorization: Bearer wsk_YOUR_TOKEN"
Cevap
{
  "items": [
    {
      "id": "ck...",
      "direction": "inbound",
      "type": "text",
      "content": "Merhaba",
      "status": "read",
      "createdAt": "2026-05-25T09:59:00.000Z"
    }
  ],
  "nextCursor": "ck...",
  "hasMore": true
}
POST/api/public/v1/otp/sendscope: otp veya *

WhatsApp üzerinden OTP kodu gönderir. Rate limit: token başına saatlik 500, telefon başına dakikada 1. WordPress/WooCommerce/OpenCart/PrestaShop/Magento eklentileri bunu kullanır.

İstek (curl)
curl -X POST https://gw.whatsmod.io/api/public/v1/otp/send \
  -H "Authorization: Bearer wsk_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+905XXXXXXXXX",
    "code": "123456",
    "site": "Siteniz"
  }'
Cevap
{
  "sent": true,
  "messageId": "ck...",
  "wamid": "3EB0...",
  "creditsRemaining": 498,
  "expiresAt": "2026-05-25T14:40:12.000Z"
}
PHP örneği
<?php
$ch = curl_init('https://gw.whatsmod.io/api/public/v1/otp/send');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
  'Authorization: Bearer ' . $token,
  'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
  'phone' => '+905XXXXXXXXX',
  'code' => '123456',
  'site' => 'Siteniz',
]));
$resp = json_decode(curl_exec($ch), true);
curl_close($ch);
JavaScript / TypeScript örneği
const res = await fetch('https://gw.whatsmod.io/api/public/v1/otp/send', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.WHATSMOD_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    phone: '+905XXXXXXXXX',
    code: '123456',
    site: 'Siteniz',
  }),
});
const data = await res.json();
GET/api/public/v1/balancescope: otp veya *

Mevcut kredi bakiyenizi, plan ve hesap limitinizi döndürür.

İstek (curl)
curl https://gw.whatsmod.io/api/public/v1/balance \
  -H "Authorization: Bearer wsk_YOUR_TOKEN"
Cevap
{
  "creditBalance": 12450,
  "plan": "pro",
  "accountLimit": 5
}

Webhook'lar

Tenant panelinizden (Ayarlar → Webhooks) URL kaydedin, aşağıdaki event tiplerinden seçim yapın. POST isteği JSON body ile ulaşır. Wait-and-retry 3 kez.

otp.sentOTP başarıyla WhatsApp'a iletildi.
otp.failedOTP gönderimi başarısız oldu (kredi/telefon/teknik).
otp.rate_limitedRate limit aşıldı — abuse tespiti.
message.newYeni gelen mesaj (müşteriden WhatsApp üzerinden).
message.updateMesaj durumu değişti (sent/delivered/read/failed).
conversation.updateSohbet güncellendi (departman, durum, atama).
account.statusWhatsApp hesap durumu değişti (connected/disconnected/banned).
# OTP başarılı webhook örneği
POST https://your-server.com/webhooks/whatsmod HTTP/1.1
Content-Type: application/json

{
  "event": "otp.sent",
  "phone": "+9054*****76",
  "status": "sent",
  "messageId": "ck...",
  "wamid": "3EB0...",
  "tokenId": "ck...",
  "accountId": "ck...",
  "sourceHost": "siteniz.com",
  "userAgent": "whatsmod-wp/1.0.0",
  "occurredAt": "2026-04-24T14:35:12Z"
}

Güvenlik: Webhook payload'ında ham OTP kodu asla yer almaz. Telefon numaraları maskelenir (ilk 5 + son 2 karakter). Hassas bilgi sızması riski yoktur.

Rate Limit'ler

KuralLimitHata
Aynı telefona OTPDakikada 1RATE_LIMITED · HTTP 429
Token başına OTPSaatte 500RATE_LIMITED · HTTP 429
API token isteği (global)Dakikada 600RATE_LIMITED · HTTP 429

Kurumsal paket kullanıcıları için özel limitler satış ekibimizden talep edilebilir.

Idempotency (Çift Gönderim Önleme)

Ağ kopması veya zaman aşımında isteği güvenle tekrarlayabilmek için POST /messages ve POST /messages/media isteklerine Idempotency-Key header'ı ekleyin (8-255 karakter, UUID önerilir).

  • Aynı anahtarla tekrar denenen istek mesajı yeniden GÖNDERMEZ; ilk sonucu aynen döner ve yanıta Idempotent-Replay: true header'ı eklenir.
  • Yalnız başarılı gönderim 24 saat saklanır. Hata olursa (kredi/ağ) anahtar serbest bırakılır — gerçek bir retry sorunsuz çalışır.
  • Aynı anahtarla eşzamanlı ikinci istek IDEMPOTENCY_IN_PROGRESS (HTTP 409) döner — kısa bir bekleyip tekrar deneyin.

Her mantıksal gönderim için yeni bir anahtar üretin (örn. crypto.randomUUID()). Aynı anahtarı farklı içerikle tekrar kullanırsanız, ikinci içerik gönderilmez — ilk gönderimin sonucu döner.

Hata Kodları

KodHTTPAçıklama
MISSING_TOKEN401Authorization header'ı yok veya Bearer formatında değil.
INVALID_TOKEN401Token bulunamadı — revoke edilmiş veya yanlış.
TOKEN_EXPIRED401Token süresi dolmuş.
INSUFFICIENT_SCOPE403Token bu endpoint için yetkisiz. OTP → scope=otp, mesaj gönderme → messages.send, okuma → messages.read (veya *) gerekir.
ACCOUNT_NOT_ALLOWED403Token tek bir numaraya kısıtlı (allowedAccountId); farklı bir accountId ile gönderim yapılamaz.
TENANT_SUSPENDED403İşletme hesabınız askıda.
INSUFFICIENT_CREDITS402Kredi bakiyesi yetersiz. Paket yenileyin.
ACCOUNT_NOT_CONNECTED409Hedef WhatsApp numarası bağlı değil (disconnected/banned). Numarayı QR ile yeniden bağlayın.
IDEMPOTENCY_IN_PROGRESS409Aynı Idempotency-Key ile bir istek hâlâ işleniyor. Birazdan tekrar deneyin.
INVALID_IDEMPOTENCY_KEY400Idempotency-Key 8-255 karakter olmalı (UUID önerilir).
RATE_LIMITED429Rate limit aşıldı. Dakikada 1 / saatte 500 (OTP), global dakikada 600.
INVALID_PHONE400Telefon formatı hatalı. +905XXXXXXXXX bekleniyor.
INVALID_CODE400OTP kodu 4-8 rakam olmalı.
NO_ACCOUNT503OTP için: token'a atanmış/aktif WhatsApp hesabı yok.
SEND_FAILED502WhatsApp gönderimi başarısız (ağ/Baileys hatası).

Hata formatı: {code: "...", message: "...", details?: {...}}

Güvenlik

  • Tüm istekler HTTPS (TLS 1.3) üzerinden. HTTP kabul edilmez.
  • Token'lar DB'de SHA-256 hash olarak saklanır — plain hiçbir yerde yok.
  • OTP kodları da sadece SHA-256 hash olarak audit log'unda tutulur (ham kod yok).
  • Scope'lu token'lar yalnız izinli endpoint'lere erişir (otp / messages.send / messages.read) — zorlama sunucu tarafında yapılır.
  • Token tek bir WhatsApp hesabına allowedAccountId ile kilitlenir ve gönderimde zorlanır — ele geçirilen token'ın blast radius'unu küçültür.
  • Idempotency-Key ile güvenli retry — ağ kopmasında çift mesaj gönderimi engellenir.
  • Webhook payload'ları telefon numaralarını maskeler, OTP kodu ASLA webhook'ta yer almaz.

Postman ile Hızlı Test

Tüm endpoint'ler Postman collection olarak hazır. İndir, token\'ını yapıştır, test isteği at.

Hızlı başlangıç: 1) Her iki JSON\'u indir, Postman\'a Import et. 2) Environment\'ı aktif et (sağ üstte). 3) apiToken değerine wsk_... yapıştır. 4) "OTP — Gönder" isteğinin body\'sinde telefonu güncelle, Send.

SDK'lar

Her dilde HTTP isteği yazmak yerine hazır client kullanın. Tam TypeScript desteği, typed errors, retry-safe.

📦
JavaScript / TypeScript
@whatsmod/client
npm install @whatsmod/client
import { WhatsMod } from '@whatsmod/client';
const client = new WhatsMod({ apiToken: 'wsk_...' });
await client.otp.send({ phone: '+905...', code: '123456' });
🐘
PHP
whatsmod/client
composer require whatsmod/client
$client = new \WhatsMod\Client(['api_token' => 'wsk_...']);
$client->otp->send(['phone' => '+905...', 'code' => '123456']);

Yardıma mı ihtiyacınız var?

Özel entegrasyon, rate limit artırımı veya kurumsal SLA için iletişime geçin.