Autentikasi

Setiap request ke protected endpoint wajib menyertakan API key. Ada dua cara:

Cara 1 — Header X-API-Key (direkomendasikan)

curl -X POST https://wa.codepod.my.id/api/send \
  -H "Content-Type: application/json" \
  -H "X-API-Key: wa_your_api_key_here" \
  -d '{"to":"6281234567890","message":"Halo dari cURL"}'
const BASE = 'https://wa.codepod.my.id';
const API_KEY = 'wa_your_api_key_here';

const res = await fetch(BASE + '/api/send', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': API_KEY
  },
  body: JSON.stringify({
    to: '6281234567890',
    message: 'Halo dari Node.js'
  })
});
const data = await res.json();
console.log(data);
<?php
$ch = curl_init('https://wa.codepod.my.id/api/send');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Content-Type: application/json',
    'X-API-Key: wa_your_api_key_here'
  ],
  CURLOPT_POSTFIELDS => json_encode([
    'to' => '6281234567890',
    'message' => 'Halo dari PHP'
  ])
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
import requests

BASE = "https://wa.codepod.my.id"
API_KEY = "wa_your_api_key_here"

res = requests.post(
    f"{BASE}/api/send",
    headers={
        "Content-Type": "application/json",
        "X-API-Key": API_KEY
    },
    json={
        "to": "6281234567890",
        "message": "Halo dari Python"
    }
)
print(res.json())

Cara 2 — Header Authorization: Bearer

curl -X POST https://wa.codepod.my.id/api/send \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer wa_your_api_key_here" \
  -d '{"to":"6281234567890","message":"Halo"}'

Admin key (untuk generate/revoke API key & pairing) hanya bisa via X-API-Key, tidak bisa via Bearer.

Base URL

https://wa.codepod.my.id

Semua endpoint dimulai dari base URL di atas. Wajib HTTPS — HTTP tidak didukung.

Format Response

Response Sukses

{
  "success": true,
  "message_id": "BAE5A1F2C3D4E5F6",
  "to": "6281234567890",
  "status": "sent"
}

❌ Response Error

{
  "success": false,
  "error": "Pesan error yang menjelaskan masalah"
}

⛔ Rate Limit / Jam Operasional

{
  "error": "Batas harian tercapai (300/300). Coba lagi besok.",
  "remaining": 0,
  "limit": 300
}

Kode HTTP & Artinya

KodeArtiKapan
200OKRequest berhasil
201CreatedResource berhasil dibuat (generate key, tambah kontak)
400Bad RequestParameter wajib tidak diisi / format salah
403ForbiddenAPI key tidak valid
404Not FoundEndpoint atau resource tidak ditemukan
429Too Many RequestsRate limit harian tercapai / terlalu cepat
500Server ErrorWA tidak terhubung atau error internal

Rate Limit & Batasan

AturanNilai
Maksimal pesan per hari300 / API key (customizable per key)
Minimal jeda antar pesan2 detik (anti-spam)
Jam operasional06:00 — 21:00 WIB
Timeout webhook10 detik

Saat limit tercapai, response HTTP 429 dengan field remaining: 0. Cek sisa kuota via GET /api/status/me.

Kirim Pesan Teks

POST /api/send

Mengirim pesan teks ke satu nomor WhatsApp. Nomor otomatis tersimpan sebagai kontak.

Request Body

FieldTipeWajibKeterangan
tostringYaNomor tujuan, format 628xxxxxxxxxx
messagestringYaIsi pesan teks
typestringTidakDefault "text". Opsi: text, image, document
curl -X POST https://wa.codepod.my.id/api/send \
  -H "Content-Type: application/json" \
  -H "X-API-Key: wa_your_api_key_here" \
  -d '{
    "to": "6281234567890",
    "message": "Halo, ini pesan otomatis dari aplikasi kami."
  }'
const BASE = 'https://wa.codepod.my.id';
const API_KEY = 'wa_your_api_key_here';

const res = await fetch(BASE + '/api/send', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': API_KEY
  },
  body: JSON.stringify({
    to: '6281234567890',
    message: 'Halo, ini pesan otomatis dari aplikasi kami.'
  })
});
const data = await res.json();

if (data.success) {
  console.log('Terkirim! ID:', data.message_id);
} else {
  console.error('Gagal:', data.error);
}
<?php
$ch = curl_init('https://wa.codepod.my.id/api/send');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Content-Type: application/json',
    'X-API-Key: wa_your_api_key_here'
  ],
  CURLOPT_POSTFIELDS => json_encode([
    'to' => '6281234567890',
    'message' => 'Halo, ini pesan otomatis dari aplikasi kami.'
  ])
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$data = json_decode($response, true);
if ($data['success']) {
  echo "Terkirim! ID: " . $data['message_id'];
} else {
  echo "Gagal: " . $data['error'];
}
import requests

BASE = "https://wa.codepod.my.id"
API_KEY = "wa_your_api_key_here"

res = requests.post(
    f"{BASE}/api/send",
    headers={
        "Content-Type": "application/json",
        "X-API-Key": API_KEY
    },
    json={
        "to": "6281234567890",
        "message": "Halo, ini pesan otomatis dari aplikasi kami."
    }
)

data = res.json()
if data.get("success"):
    print(f"Terkirim! ID: {data['message_id']}")
else:
    print(f"Gagal: {data.get('error')}")

Response Sukses (200)

{
  "success": true,
  "message_id": "BAE5A1F2C3D4E5F6",
  "log_id": 42,
  "to": "6281234567890",
  "status": "sent"
}

Response Error

{
  "success": false,
  "error": "Parameter \"to\" (nomor tujuan) wajib"
}

Terlalu Cepat (429)

{
  "error": "Terlalu cepat. Tunggu 2 detik.",
  "retry_after_ms": 2000
}

Upload File

POST /api/upload

Upload file (gambar, PDF, dokumen) untuk dikirim via WhatsApp. File disimpan di server dan bisa digunakan di /api/send via media.path atau media.url.

Request (multipart/form-data)

FieldTipeWajibKeterangan
filefileYaFile yang akan diupload (max 10MB)
curl -X POST https://wa.codepod.my.id/api/upload \
  -H "X-API-Key: wa_your_api_key_here" \
  -F "file=@/path/ke/foto-produk.jpg"
import fs from 'fs';

const form = new FormData();
form.append('file', fs.createReadStream('/path/ke/foto.jpg'));

const res = await fetch(BASE + '/api/upload', {
  method: 'POST',
  headers: { 'X-API-Key': API_KEY },
  body: form
});
const data = await res.json();
console.log('Uploaded:', data.file.url);
<?php
$ch = curl_init('https://wa.codepod.my.id/api/upload');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ['X-API-Key: wa_your_api_key_here'],
  CURLOPT_POSTFIELDS => [
    'file' => new CURLFile('/path/ke/foto.jpg')
  ]
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
echo 'Uploaded: ' . $data['file']['url'];
import requests

with open('/path/ke/foto.jpg', 'rb') as f:
    res = requests.post(
        f"{BASE}/api/upload",
        headers={"X-API-Key": API_KEY},
        files={"file": f}
    )

data = res.json()
print(f"Uploaded: {data['file']['url']}")

Response Sukses (201)

{
  "success": true,
  "file": {
    "original_name": "foto-produk.jpg",
    "filename": "a1b2c3d4e5f6.jpg",
    "size": 245760,
    "mimetype": "image/jpeg",
    "url": "https://wa.codepod.my.id/uploads/a1b2c3d4e5f6.jpg",
    "path": "/opt/wa-gateway/uploads/a1b2c3d4e5f6.jpg"
  },
  "usage": {
    "via_url": "Gunakan di /api/send: {\"type\":\"image\",\"media\":{\"url\":\"https://wa.codepod.my.id/uploads/a1b2c3d4e5f6.jpg\"}}",
    "via_path": "Atau via path: {\"type\":\"image\",\"media\":{\"path\":\"/opt/wa-gateway/uploads/a1b2c3d4e5f6.jpg\"}}"
  }
}

Tipe File yang Didukung

KategoriTipe MIME
Gambarimage/jpeg, image/png, image/webp
Dokumenapplication/pdf, .doc, .docx, .xls, .xlsx
Audioaudio/mp4, audio/mpeg, audio/ogg, audio/opus
Lainnyatext/plain, text/csv, application/zip

Kelola File Upload

Endpoint untuk list dan hapus file yang sudah di-upload. Admin only — gunakan admin key.

GET /api/uploads

List semua file yang ada di server upload, diurut dari terbaru.

curl -H "X-API-Key: ADMIN_KEY" \
  https://wa.codepod.my.id/api/uploads

Response

{
  "success": true,
  "total": 5,
  "total_size": 2457600,
  "total_size_formatted": "2.3 MB",
  "files": [
    {
      "filename": "a1b2c3d4e5f6.jpg",
      "size": 245760,
      "size_formatted": "240.0 KB",
      "uploaded_at": "2025-07-21T07:24:30.000Z",
      "url": "https://wa.codepod.my.id/uploads/a1b2c3d4e5f6.jpg",
      "path": "/opt/wa-gateway/uploads/a1b2c3d4e5f6.jpg"
    }
  ]
}
DELETE /api/uploads/:filename

Hapus satu file berdasarkan nama file (dari response list).

curl -X DELETE \
  -H "X-API-Key: ADMIN_KEY" \
  https://wa.codepod.my.id/api/uploads/a1b2c3d4e5f6.jpg

Response

{
  "success": true,
  "message": "File dihapus",
  "file": {
    "filename": "a1b2c3d4e5f6.jpg",
    "size": 245760,
    "size_formatted": "240.0 KB",
    "deleted_at": "2025-07-21T07:30:00.000Z"
  }
}
DELETE /api/uploads

Hapus banyak file sekaligus (bulk delete).

curl -X DELETE https://wa.codepod.my.id/api/uploads \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ADMIN_KEY" \
  -d '{"files":["a1b2.jpg","b3c4.pdf"]}'

Response

{
  "success": true,
  "total": 2,
  "deleted": 2,
  "not_found": 0,
  "freed_space": 491520,
  "freed_space_formatted": "480.0 KB",
  "results": [
    {"filename": "a1b2.jpg", "deleted": true, "size": 245760},
    {"filename": "b3c4.pdf", "deleted": true, "size": 245760}
  ]
}

Kirim Gambar

POST /api/send

Mengirim gambar dengan URL publik atau path file lokal (hasil upload). Bisa ditambahkan caption.

Request Body

FieldTipeWajibKeterangan
tostringYaNomor tujuan
typestringYaHarus "image"
media.urlstringSalah satuURL gambar publik (https) — atau —
media.pathstringSalah satuPath file lokal (hasil /api/upload)
media.captionstringTidakTeks caption di bawah gambar
messagestringTidakFallback teks jika media gagal

Gunakan media.url untuk file yang sudah online, atau media.path untuk file hasil upload dari endpoint POST /api/upload.

curl -X POST https://wa.codepod.my.id/api/send \
  -H "Content-Type: application/json" \
  -H "X-API-Key: wa_your_api_key_here" \
  -d '{
    "to": "6281234567890",
    "type": "image",
    "media": {
      "url": "https://example.com/foto-produk.jpg",
      "caption": "Produk terbaru kami!"
    }
  }'
const res = await fetch(BASE + '/api/send', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': API_KEY
  },
  body: JSON.stringify({
    to: '6281234567890',
    type: 'image',
    media: {
      url: 'https://example.com/foto-produk.jpg',
      caption: 'Produk terbaru kami!'
    }
  })
});
const data = await res.json();
<?php
$payload = json_encode([
  'to' => '6281234567890',
  'type' => 'image',
  'media' => [
    'url' => 'https://example.com/foto-produk.jpg',
    'caption' => 'Produk terbaru kami!'
  ]
]);

$ch = curl_init('https://wa.codepod.my.id/api/send');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Content-Type: application/json',
    'X-API-Key: wa_your_api_key_here'
  ],
  CURLOPT_POSTFIELDS => $payload
]);
echo curl_exec($ch);
curl_close($ch);
import requests

res = requests.post(
    f"{BASE}/api/send",
    headers={
        "Content-Type": "application/json",
        "X-API-Key": API_KEY
    },
    json={
        "to": "6281234567890",
        "type": "image",
        "media": {
            "url": "https://example.com/foto-produk.jpg",
            "caption": "Produk terbaru kami!"
        }
    }
)
print(res.json())

Response Sukses

{
  "success": true,
  "message_id": "BAE5A1F2C3D4E5F6",
  "log_id": 43,
  "to": "6281234567890",
  "status": "sent"
}

Kirim Dokumen

POST /api/send

Mengirim file dokumen (PDF, Word, Excel, dll) via URL publik atau path file lokal.

Request Body

FieldTipeWajibKeterangan
tostringYaNomor tujuan
typestringYa"document" atau "audio"
media.urlstringSalah satuURL file publik (https) — atau —
media.pathstringSalah satuPath file lokal (hasil /api/upload)
media.filenamestringTidakNama file yang ditampilkan (default: "document")
messagestringTidakFallback teks jika media gagal

Gunakan media.url untuk file yang sudah online, atau media.path untuk file hasil upload dari endpoint POST /api/upload.

curl -X POST https://wa.codepod.my.id/api/send \
  -H "Content-Type: application/json" \
  -H "X-API-Key: wa_your_api_key_here" \
  -d '{
    "to": "6281234567890",
    "type": "document",
    "media": {
      "url": "https://example.com/invoice-001.pdf"
    }
  }'
const res = await fetch(BASE + '/api/send', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': API_KEY
  },
  body: JSON.stringify({
    to: '6281234567890',
    type: 'document',
    media: {
      url: 'https://example.com/invoice-001.pdf'
    }
  })
});
const data = await res.json();
<?php
$ch = curl_init('https://wa.codepod.my.id/api/send');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Content-Type: application/json',
    'X-API-Key: wa_your_api_key_here'
  ],
  CURLOPT_POSTFIELDS => json_encode([
    'to' => '6281234567890',
    'type' => 'document',
    'media' => ['url' => 'https://example.com/invoice-001.pdf']
  ])
]);
echo curl_exec($ch);
curl_close($ch);
import requests

res = requests.post(
    f"{BASE}/api/send",
    headers={
        "Content-Type": "application/json",
        "X-API-Key": API_KEY
    },
    json={
        "to": "6281234567890",
        "type": "document",
        "media": {
            "url": "https://example.com/invoice-001.pdf"
        }
    }
)
print(res.json())

Response Sukses

{
  "success": true,
  "message_id": "BAE5A1F2C3D4E5F6",
  "log_id": 44,
  "to": "6281234567890",
  "status": "sent"
}

Kirim ke Grup

POST /api/send

Mengirim pesan ke grup WhatsApp. Gunakan ID grup (format: 628xxxxxxxxxx-123456@g.us).

FieldTipeWajibKeterangan
tostringYaID grup (dari GET /api/groups)
messagestringYaIsi pesan
typestringTidak"group" atau "text"
curl -X POST https://wa.codepod.my.id/api/send \
  -H "Content-Type: application/json" \
  -H "X-API-Key: wa_your_api_key_here" \
  -d '{
    "to": "6281234567890-123456@g.us",
    "message": "Pengumuman penting untuk semua anggota!"
  }'
const res = await fetch(BASE + '/api/send', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': API_KEY
  },
  body: JSON.stringify({
    to: '6281234567890-123456@g.us',
    message: 'Pengumuman penting untuk semua anggota!'
  })
});
const data = await res.json();
<?php
$ch = curl_init('https://wa.codepod.my.id/api/send');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Content-Type: application/json',
    'X-API-Key: wa_your_api_key_here'
  ],
  CURLOPT_POSTFIELDS => json_encode([
    'to' => '6281234567890-123456@g.us',
    'message' => 'Pengumuman penting untuk semua anggota!'
  ])
]);
echo curl_exec($ch);
curl_close($ch);
import requests

res = requests.post(
    f"{BASE}/api/send",
    headers={
        "Content-Type": "application/json",
        "X-API-Key": API_KEY
    },
    json={
        "to": "6281234567890-123456@g.us",
        "message": "Pengumuman penting untuk semua anggota!"
    }
)
print(res.json())

Response Sukses

{
  "success": true,
  "message_id": "BAE5A1F2C3D4E5F6",
  "log_id": 45,
  "to": "6281234567890-123456@g.us",
  "status": "sent"
}

Broadcast (Kirim Banyak)

POST /api/send/bulk

Mengirim pesan yang sama ke banyak nomor sekaligus. Hanya teks.

FieldTipeWajibKeterangan
toarrayYaArray nomor tujuan, format ["628xx","628yy"]
messagestringYaIsi pesan
curl -X POST https://wa.codepod.my.id/api/send/bulk \
  -H "Content-Type: application/json" \
  -H "X-API-Key: wa_your_api_key_here" \
  -d '{
    "to": ["6281234567890", "6289876543210", "628111222333"],
    "message": "Info penting: besok libur!"
  }'
const res = await fetch(BASE + '/api/send/bulk', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': API_KEY
  },
  body: JSON.stringify({
    to: ['6281234567890', '6289876543210', '628111222333'],
    message: 'Info penting: besok libur!'
  })
});
const data = await res.json();
console.log(`Terkirim: ${data.sent}/${data.total}, Gagal: ${data.failed}`);
<?php
$ch = curl_init('https://wa.codepod.my.id/api/send/bulk');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Content-Type: application/json',
    'X-API-Key: wa_your_api_key_here'
  ],
  CURLOPT_POSTFIELDS => json_encode([
    'to' => ['6281234567890', '6289876543210'],
    'message' => 'Info penting: besok libur!'
  ])
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
echo "Terkirim: {$data['sent']}/{$data['total']}, Gagal: {$data['failed']}";
import requests

res = requests.post(
    f"{BASE}/api/send/bulk",
    headers={
        "Content-Type": "application/json",
        "X-API-Key": API_KEY
    },
    json={
        "to": ["6281234567890", "6289876543210", "628111222333"],
        "message": "Info penting: besok libur!"
    }
)

data = res.json()
print(f"Terkirim: {data['sent']}/{data['total']}, Gagal: {data['failed']}")
# Detail per nomor: data['results']

Response Sukses

{
  "success": true,
  "total": 3,
  "sent": 3,
  "failed": 0,
  "results": [
    {"to": "6281234567890", "success": true, "message_id": "ABC123"},
    {"to": "6289876543210", "success": true, "message_id": "DEF456"},
    {"to": "628111222333", "success": true, "message_id": "GHI789"}
  ]
}

Kuota Tidak Cukup (429)

{
  "error": "Sisa kuota hari ini tidak cukup untuk 50 pesan",
  "remaining": 5,
  "needed": 50
}

List Grup

GET /api/groups

Mendapatkan daftar grup WhatsApp yang diikuti oleh nomor gateway.

curl -H "X-API-Key: wa_your_api_key_here" \
  https://wa.codepod.my.id/api/groups
const res = await fetch(BASE + '/api/groups', {
  headers: { 'X-API-Key': API_KEY }
});
const data = await res.json();
data.groups.forEach(g => console.log(g.id, g.name));
<?php
$ch = curl_init('https://wa.codepod.my.id/api/groups');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['X-API-Key: wa_your_api_key_here']);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
foreach ($data['groups'] as $g) echo $g['id'] . ' ' . $g['name'] . "\n";
import requests

res = requests.get(
    f"{BASE}/api/groups",
    headers={"X-API-Key": API_KEY}
)
data = res.json()
for g in data.get("groups", []):
    print(g["id"], g["name"])

Response

{
  "success": true,
  "total": 3,
  "groups": [
    {
      "id": "6281234567890-123456@g.us",
      "name": "Komunitas Codepod",
      "participants": 45
    }
  ]
}

Detail Grup

GET /api/groups/:id

Mendapatkan info detail + daftar anggota grup.

curl -H "X-API-Key: wa_your_api_key_here" \
  https://wa.codepod.my.id/api/groups/6281234567890-123456@g.us

Response

{
  "success": true,
  "group": {
    "id": "6281234567890-123456@g.us",
    "name": "Komunitas Codepod",
    "description": "Grup diskusi programming",
    "participants": [
      {"id": "6281234567890@s.whatsapp.net", "name": "Admin"},
      {"id": "6289876543210@s.whatsapp.net", "name": "Member 1"}
    ]
  }
}

List Kontak

GET /api/contacts

Melihat daftar kontak yang tersimpan. Support pencarian via ?search=.

# Semua kontak
curl -H "X-API-Key: wa_your_api_key_here" \
  https://wa.codepod.my.id/api/contacts

# Cari kontak
curl -H "X-API-Key: wa_your_api_key_here" \
  "https://wa.codepod.my.id/api/contacts?search=budi"
const res = await fetch(
  BASE + '/api/contacts?search=budi',
  { headers: { 'X-API-Key': API_KEY } }
);
const data = await res.json();
console.log(data.contacts);
<?php
$ch = curl_init('https://wa.codepod.my.id/api/contacts?search=budi');
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ['X-API-Key: wa_your_api_key_here']
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($data['contacts']);
import requests

res = requests.get(
    f"{BASE}/api/contacts",
    headers={"X-API-Key": API_KEY},
    params={"search": "budi"}
)
print(res.json())

Response

{
  "success": true,
  "total": 2,
  "contacts": [
    {"id": 1, "name": "Budi Santoso", "phone": "6281234567890"},
    {"id": 2, "name": "Siti Aminah", "phone": "6289876543210"}
  ]
}

Tambah Kontak

POST /api/contacts

Menambah kontak secara manual. Nomor otomatis juga tersimpan saat kamu mengirim pesan.

FieldTipeWajibKeterangan
namestringYaNama kontak
phonestringYaNomor WA, format 628xxxxxxxxxx
curl -X POST https://wa.codepod.my.id/api/contacts \
  -H "Content-Type: application/json" \
  -H "X-API-Key: wa_your_api_key_here" \
  -d '{"name":"Budi Santoso","phone":"6281234567890"}'
const res = await fetch(BASE + '/api/contacts', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': API_KEY
  },
  body: JSON.stringify({
    name: 'Budi Santoso',
    phone: '6281234567890'
  })
});
const data = await res.json();
console.log(data.contact);
<?php
$ch = curl_init('https://wa.codepod.my.id/api/contacts');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Content-Type: application/json',
    'X-API-Key: wa_your_api_key_here'
  ],
  CURLOPT_POSTFIELDS => json_encode([
    'name' => 'Budi Santoso',
    'phone' => '6281234567890'
  ])
]);
echo curl_exec($ch);
curl_close($ch);
import requests

res = requests.post(
    f"{BASE}/api/contacts",
    headers={
        "Content-Type": "application/json",
        "X-API-Key": API_KEY
    },
    json={
        "name": "Budi Santoso",
        "phone": "6281234567890"
    }
)
print(res.json())

Response (201 Created)

{
  "success": true,
  "contact": {
    "id": 3,
    "name": "Budi Santoso",
    "phone": "6281234567890"
  }
}

Hapus Kontak

DELETE /api/contacts/:id

Menghapus kontak berdasarkan ID (didapat dari list contacts).

curl -X DELETE https://wa.codepod.my.id/api/contacts/3 \
  -H "X-API-Key: wa_your_api_key_here"

Response

{"success": true, "message": "Kontak dihapus"}

Daftar Webhook

POST /api/webhook

Mendaftarkan URL webhook untuk menerima notifikasi pesan masuk secara real-time. Satu API key hanya bisa punya satu webhook.

FieldTipeWajibKeterangan
urlstringYaURL endpoint kamu yang akan menerima POST
eventsstringTidakDefault "incoming"
curl -X POST https://wa.codepod.my.id/api/webhook \
  -H "Content-Type: application/json" \
  -H "X-API-Key: wa_your_api_key_here" \
  -d '{"url":"https://app-anda.com/webhook"}'
const res = await fetch(BASE + '/api/webhook', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': API_KEY
  },
  body: JSON.stringify({
    url: 'https://app-anda.com/webhook'
  })
});
const data = await res.json();
<?php
$ch = curl_init('https://wa.codepod.my.id/api/webhook');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    'Content-Type: application/json',
    'X-API-Key: wa_your_api_key_here'
  ],
  CURLOPT_POSTFIELDS => json_encode([
    'url' => 'https://app-anda.com/webhook'
  ])
]);
echo curl_exec($ch);
curl_close($ch);
import requests

res = requests.post(
    f"{BASE}/api/webhook",
    headers={
        "Content-Type": "application/json",
        "X-API-Key": API_KEY
    },
    json={"url": "https://app-anda.com/webhook"}
)
print(res.json())

Response

{
  "success": true,
  "webhook": {
    "id": 1,
    "url": "https://app-anda.com/webhook",
    "events": "incoming",
    "active": true
  }
}

Lihat / Hapus Webhook

GET /api/webhook

Melihat webhook yang terdaftar.

curl -H "X-API-Key: wa_your_api_key_here" \
  https://wa.codepod.my.id/api/webhook
DELETE /api/webhook

Menghapus webhook.

curl -X DELETE https://wa.codepod.my.id/api/webhook \
  -H "X-API-Key: wa_your_api_key_here"

Format Payload Webhook

Setiap kali ada pesan masuk ke nomor gateway, server akan mengirim POST ke URL webhook kamu dengan format berikut:

Payload (dikirim ke webhook kamu)

{
  "event": "message",
  "api_key_prefix": "wa_abc",
  "message": {
    "from": "6281234567890@s.whatsapp.net",
    "type": "text",
    "body": "Halo, saya mau tanya...",
    "timestamp": "2025-07-21T10:30:00.000Z",
    "isGroup": false
  }
}
FieldTipeKeterangan
eventstringSelalu "message"
api_key_prefixstringPrefix API key pemilik webhook
message.fromstringNomor pengirim (format JID: 628xx@s.whatsapp.net)
message.typestringTipe: text, image, document, dll
message.bodystringIsi pesan (jika teks)
message.timestampstringWaktu pesan diterima (ISO 8601)
message.isGroupbooleantrue jika dari grup

Contoh handler Node.js (Express)

// Di aplikasi kamu — endpoint yang menerima webhook
app.post('/webhook', express.json(), (req, res) => {
  const { event, message } = req.body;

  if (event === 'message') {
    // Ambil nomor pengirim (bersihkan @s.whatsapp.net)
    const from = message.from.replace('@s.whatsapp.net', '');

    console.log(`Pesan dari ${from}: ${message.body}`);

    // Auto-reply misalnya
    // await sendWA(from, 'Terima kasih, pesan Anda kami terima.');
  }

  // WAJIB: balas 200 OK agar gateway tahu webhook berhasil
  res.sendStatus(200);
});

Contoh handler PHP

<?php
// webhook.php — endpoint penerima
$input = file_get_contents('php://input');
$data = json_decode($input, true);

if ($data['event'] === 'message') {
    $from = str_replace('@s.whatsapp.net', '', $data['message']['from']);
    $body = $data['message']['body'];

    // Log atau proses
    file_put_contents('wa-log.txt', "[{$from}] {$body}\n", FILE_APPEND);
}

// Wajib 200 OK
http_response_code(200);

Log Pesan

GET /api/messages

Melihat riwayat pengiriman pesan (metadata saja, bukan isi pesan).

ParamTipeDefaultKeterangan
limitinteger50Maksimal 200
offsetinteger0Untuk pagination
statusstring-Filter: sent, pending, failed
curl -H "X-API-Key: wa_your_api_key_here" \
  "https://wa.codepod.my.id/api/messages?limit=20&status=sent"

Response

{
  "success": true,
  "total": 2,
  "messages": [
    {
      "id": 42,
      "recipient": "6281234567890",
      "message_type": "personal",
      "status": "sent",
      "wa_message_id": "BAE5A1F2C3D4E5F6",
      "error": null,
      "created_at": "2025-07-21 10:30:00"
    }
  ]
}

Cek Kuota API Key

GET /api/status/me

Melihat sisa kuota harian untuk API key kamu.

curl -H "X-API-Key: wa_your_api_key_here" \
  https://wa.codepod.my.id/api/status/me

Response

{
  "success": true,
  "wa": {
    "status": "connected",
    "user": { "phone": "628xxxxxxxxxx" }
  },
  "api_key": {
    "name": "Aplikasi Sekolah",
    "prefix": "wa_abc",
    "daily_limit": 300,
    "remaining_today": 247
  }
}

Status WA (Public)

GET /api/status

Endpoint publik — tidak perlu API key. Mengecek status koneksi WhatsApp dan statistik global.

curl https://wa.codepod.my.id/api/status

Response (Connected)

{
  "success": true,
  "wa": {
    "status": "connected",
    "user": { "phone": "628xxxxxxxxxx" },
    "qr_available": false
  },
  "stats": {
    "active_keys": 5,
    "today_sent": 142,
    "pending": 0,
    "today_failed": 3
  }
}

Response (Menunggu Pairing)

{
  "success": true,
  "wa": {
    "status": "qr",
    "user": null,
    "qr_available": true
  },
  "stats": { ... }
}