{"openapi":"3.1.0","info":{"title":"KirimPesan API v2","version":"2.0.0","description":"API publik KirimPesan. Autentikasi `Authorization: Bearer kp_live_…`. Rate limit 60 permintaan/menit per key (header X-RateLimit-Limit/Remaining/Reset, Retry-After saat 429). Error: `{error:{code,message,details?}}`. Nomor telepon: digit E.164 tanpa \"+\". Endpoint daftar memakai `?page&pageSize` dan mengembalikan `{data, meta:{page,pageSize,total}}`."},"servers":[{"url":"/"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"kp_live_<secret>"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]},"PageMeta":{"type":"object","properties":{"page":{"type":"integer"},"pageSize":{"type":"integer"},"total":{"type":"integer"}},"required":["page","pageSize","total"]},"MessageContent":{"type":"object","description":"MessageContent (@kp/shared MessageContentSchema), diskriminasi `type`: text|image|video|audio|voice|document|sticker|location|contact|buttons|list|poll|reaction. Teks mendukung variabel {{name}}, {{phone}}, field kustom, dan spintax {a|b}.","properties":{"type":{"type":"string"},"text":{"type":"string"},"caption":{"type":"string"},"media":{"type":"object","properties":{"url":{"type":"string"},"mimetype":{"type":"string"},"fileName":{"type":"string"}},"required":["url"]}},"required":["type"],"examples":[{"type":"text","text":"Halo {{name}}, pesanan Anda sudah dikirim."},{"type":"image","media":{"url":"https://contoh.id/promo.jpg","mimetype":"image/jpeg"},"caption":"Promo minggu ini"}]},"MessageStatus":{"type":"string","enum":["queued","sending","sent","delivered","read","played","failed","cancelled","skipped"]},"Message":{"type":"object","properties":{"id":{"type":"integer"},"deviceId":{"type":["integer","null"]},"campaignId":{"type":["integer","null"]},"direction":{"enum":["outbound","inbound"]},"source":{"type":"string"},"peer":{"type":"string"},"participant":{"type":["string","null"]},"type":{"type":"string"},"content":{"$ref":"#/components/schemas/MessageContent"},"status":{"$ref":"#/components/schemas/MessageStatus"},"statusReason":{"type":["string","null"]},"priority":{"type":"integer"},"attempts":{"type":"integer"},"sentAt":{"type":["string","null"],"format":"date-time"},"deliveredAt":{"type":["string","null"],"format":"date-time"},"readAt":{"type":["string","null"],"format":"date-time"},"failedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","peer","type","content","status","createdAt"]},"MessageWithEvents":{"allOf":[{"$ref":"#/components/schemas/Message"},{"type":"object","properties":{"events":{"type":"array","items":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/MessageStatus"},"error":{"type":["string","null"]},"at":{"type":"string","format":"date-time"}},"required":[]}}},"required":[]}]},"Device":{"type":"object","properties":{"id":{"type":"integer"},"label":{"type":["string","null"]},"phone":{"type":["string","null"]},"displayName":{"type":["string","null"]},"avatarUrl":{"type":["string","null"]},"status":{"type":"string","enum":["pending","qr","pairing","connected","reconnecting","disconnected","logged_out","banned"],"description":"Status dari DB"},"statusReason":{"type":["string","null"]},"receiveChats":{"type":"boolean"},"randomDelay":{"type":"boolean"},"delayMin":{"type":["integer","null"]},"delayMax":{"type":["integer","null"]},"dailyCap":{"type":["integer","null"]},"warmup":{"type":"boolean"},"hidePresence":{"type":"boolean"},"lastConnectedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"todaySent":{"type":"integer"},"legacyUnique":{"type":["string","null"]},"legacyAccount":{"type":"string","description":"Nilai `account` untuk API legacy (/api/send/whatsapp)"}},"required":["id","status","legacyAccount"]},"Contact":{"type":"object","properties":{"id":{"type":"integer"},"phone":{"type":"string"},"name":{"type":["string","null"]},"customFields":{"type":"object","additionalProperties":{"type":"string"}},"groups":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"}},"required":[]}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","phone"]},"ContactGroup":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"contactsCount":{"type":"integer"},"membersCount":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","name"]},"AudienceSpec":{"type":"object","properties":{"numbers":{"oneOf":[{"type":"array","items":{"type":"string"},"maxItems":100000},{"type":"string","description":"Dipisah baris baru/koma"}]},"groupIds":{"type":"array","items":{"type":"integer"},"maxItems":200,"description":"ID grup kontak"},"waGroups":{"type":"array","items":{"type":"object","properties":{"deviceId":{"type":"integer"},"gid":{"type":"string"}},"required":["deviceId","gid"]},"maxItems":50},"fileId":{"type":"string","description":"Hasil unggah Excel/CSV (dashboard)"},"mapping":{"type":"object","properties":{"phone":{"type":"string"}},"required":["phone"]}},"required":[]},"CampaignCounts":{"type":"object","properties":{"queued":{"type":"integer"},"sending":{"type":"integer"},"sent":{"type":"integer"},"delivered":{"type":"integer"},"read":{"type":"integer"},"failed":{"type":"integer"},"cancelled":{"type":"integer"},"skipped":{"type":"integer"}},"required":[]},"Campaign":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"status":{"enum":["draft","scheduled","running","paused","completed","cancelled","failed"]},"source":{"type":"string"},"rotation":{"enum":["round_robin","weighted","sequential"]},"deviceIds":{"type":"array","items":{"type":"integer"}},"content":{"$ref":"#/components/schemas/MessageContent"},"totalRecipients":{"type":"integer"},"counts":{"$ref":"#/components/schemas/CampaignCounts"},"estimatedFinishAt":{"type":["string","null"],"format":"date-time"},"delayMin":{"type":["integer","null"]},"delayMax":{"type":["integer","null"]},"sendWindowStart":{"type":["string","null"]},"sendWindowEnd":{"type":["string","null"]},"skipDuplicates24h":{"type":"boolean"},"scheduledAt":{"type":["string","null"],"format":"date-time"},"startedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","name","status"]},"CampaignCreate":{"type":"object","properties":{"name":{"type":"string","minLength":3,"maxLength":191},"deviceIds":{"type":"array","items":{"type":"integer"},"minItems":1,"maxItems":50,"description":"Perangkat pengirim (dirotasi)"},"rotation":{"enum":["round_robin","weighted","sequential"],"default":"round_robin"},"audience":{"$ref":"#/components/schemas/AudienceSpec"},"content":{"$ref":"#/components/schemas/MessageContent"},"delayMin":{"type":"integer","minimum":1,"maximum":3600,"description":"Detik; ≤ delayMax"},"delayMax":{"type":"integer","minimum":1,"maximum":3600},"sendWindowStart":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$","example":"08:00","description":"Diisi berpasangan dengan sendWindowEnd"},"sendWindowEnd":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$","example":"20:00"},"skipDuplicates24h":{"type":"boolean","default":true},"scheduledAt":{"type":"string","format":"date-time","description":"Jadwalkan; kosong + sendNow=false → draft"},"sendNow":{"type":"boolean","default":false}},"required":["name","deviceIds","audience","content"]}}},"paths":{"/api/v2/messages":{"post":{"tags":["Messages"],"summary":"Kirim satu pesan","description":"Permission API key: `wa_send`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","maxLength":200},"example":"order-1234-notif"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"deviceId":{"type":"integer"},"to":{"type":"string","description":"Nomor (digit E.164) atau JID grup"},"content":{"$ref":"#/components/schemas/MessageContent"},"priority":{"enum":["high","normal"],"default":"normal"},"skipOptOut":{"type":"boolean","default":false}},"required":["deviceId","to","content"]},"example":{"deviceId":12,"to":"6281234567890","content":{"type":"text","text":"Halo Budi, pesanan #1234 sudah dikirim."}}}}},"responses":{"201":{"description":"Sukses","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"},"example":{"id":98123,"deviceId":12,"campaignId":null,"direction":"outbound","source":"api","peer":"6281234567890","participant":null,"type":"text","content":{"type":"text","text":"Halo Budi, pesanan #1234 sudah dikirim."},"status":"queued","statusReason":null,"priority":3,"attempts":0,"sentAt":null,"deliveredAt":null,"readAt":null,"failedAt":null,"createdAt":"2026-10-18T03:00:00.000Z"}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/messages/{id}":{"get":{"tags":["Messages"],"summary":"Status pesan + timeline","description":"Permission API key: `get_wa_sent`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Sukses","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageWithEvents"},"example":{"id":98123,"deviceId":12,"campaignId":null,"direction":"outbound","source":"api","peer":"6281234567890","participant":null,"type":"text","content":{"type":"text","text":"Halo Budi, pesanan #1234 sudah dikirim."},"status":"read","statusReason":null,"priority":3,"attempts":0,"sentAt":"2026-10-18T03:00:04.000Z","deliveredAt":null,"readAt":null,"failedAt":null,"createdAt":"2026-10-18T03:00:00.000Z","events":[{"status":"sent","error":null,"at":"2026-10-18T03:00:04.000Z"},{"status":"read","error":null,"at":"2026-10-18T03:02:10.000Z"}]}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/messages/bulk":{"post":{"tags":["Messages"],"summary":"Kirim massal (membuat campaign)","description":"Permission API key: `wa_send_bulk`.","security":[{"bearerAuth":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":3,"maxLength":191},"deviceIds":{"type":"array","items":{"type":"integer"},"minItems":1,"maxItems":50},"rotation":{"enum":["round_robin","weighted","sequential"],"default":"round_robin"},"recipients":{"type":"array","items":{"type":"string"},"maxItems":100000},"groupIds":{"type":"array","items":{"type":"integer"},"maxItems":200},"content":{"$ref":"#/components/schemas/MessageContent"},"scheduledAt":{"type":"string","format":"date-time"}},"required":["name","deviceIds","content"]},"example":{"name":"Promo Oktober","deviceIds":[12],"recipients":["6281234567890","6281234567891"],"content":{"type":"text","text":"Halo {{name}}, ada promo 20% minggu ini!"}}}}},"responses":{"201":{"description":"Sukses","content":{"application/json":{"schema":{"type":"object","properties":{"campaign":{"$ref":"#/components/schemas/Campaign"},"audience":{"type":"object","properties":{"valid":{"type":"integer"},"duplicates":{"type":"integer"},"invalid":{"type":"integer"},"optedOut":{"type":"integer"}},"required":[]}},"required":["campaign","audience"]},"example":{"campaign":{"id":301,"name":"Promo Oktober","status":"running","source":"api","rotation":"round_robin","deviceIds":[12],"content":{"type":"text","text":"Halo {{name}}, ada promo 20% minggu ini!"},"totalRecipients":2,"counts":{"queued":2,"sending":0,"sent":0,"delivered":0,"read":0,"failed":0,"cancelled":0,"skipped":0},"estimatedFinishAt":"2026-10-18T03:05:00.000Z","delayMin":null,"delayMax":null,"sendWindowStart":null,"sendWindowEnd":null,"skipDuplicates24h":true,"legacy":false,"scheduledAt":null,"startedAt":"2026-10-18T03:00:00.000Z","completedAt":null,"createdAt":"2026-10-18T03:00:00.000Z"},"audience":{"valid":2,"duplicates":0,"invalid":0,"optedOut":0}}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/otp":{"post":{"tags":["OTP"],"summary":"Kirim OTP 6 digit lewat WhatsApp (pesan wajib memuat {{otp}})","description":"Permission API key: `otp`.","security":[{"bearerAuth":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"deviceId":{"type":"integer"},"phone":{"type":"string"},"message":{"type":"string","default":"Kode OTP Anda: {{otp}}"},"expire":{"type":"integer","minimum":1,"maximum":86400,"default":300}},"required":["deviceId","phone"]},"example":{"deviceId":12,"phone":"6281234567890","message":"Kode verifikasi Anda {{otp}}. Jangan berikan ke siapa pun.","expire":300}}}},"responses":{"201":{"description":"Sukses","content":{"application/json":{"schema":{"type":"object","properties":{"messageId":{"type":"integer"},"phone":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}},"required":[]},"example":{"messageId":98124,"phone":"6281234567890","expiresAt":"2026-10-18T03:05:00.000Z"}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/otp/verify":{"post":{"tags":["OTP"],"summary":"Verifikasi OTP (sekali pakai)","description":"Permission API key: `otp`.","security":[{"bearerAuth":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"phone":{"type":"string"},"otp":{"type":"string"}},"required":["phone","otp"]},"example":{"phone":"6281234567890","otp":"123456"}}}},"responses":{"200":{"description":"Sukses","content":{"application/json":{"schema":{"type":"object","properties":{"valid":{"type":"boolean"},"phone":{"type":"string"}},"required":[]},"example":{"valid":true,"phone":"6281234567890"}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/devices":{"get":{"tags":["Devices"],"summary":"Daftar perangkat","description":"Permission API key: `get_wa_accounts`.","security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Sukses","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Device"}},"example":[{"id":12,"label":"CS Toko","phone":"6281234567890","displayName":"Toko Budi","avatarUrl":null,"status":"connected","statusReason":null,"receiveChats":true,"randomDelay":true,"delayMin":3,"delayMax":8,"dailyCap":null,"warmup":false,"hidePresence":false,"lastConnectedAt":"2026-10-18T01:00:00.000Z","createdAt":"2026-09-01T08:00:00.000Z","todaySent":0,"legacyUnique":null,"legacyAccount":"6f1c0f52-6f5b-4d0e-9a51-0c8e2f6c1a11"}]}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Devices"],"summary":"Buat perangkat (QR/pairing)","description":"Permission API key: `create_whatsapp`.","security":[{"bearerAuth":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","maxLength":100},"method":{"enum":["qr","pairing"],"default":"qr"},"phone":{"type":"string","description":"Wajib untuk method=pairing"}},"required":[]},"example":{"label":"CS Toko","method":"qr"}}}},"responses":{"201":{"description":"Sukses","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Device"},"example":{"id":12,"label":"CS Toko","phone":null,"displayName":"Toko Budi","avatarUrl":null,"status":"qr","statusReason":null,"receiveChats":true,"randomDelay":true,"delayMin":3,"delayMax":8,"dailyCap":null,"warmup":false,"hidePresence":false,"lastConnectedAt":null,"createdAt":"2026-09-01T08:00:00.000Z","todaySent":0,"legacyUnique":null,"legacyAccount":"6f1c0f52-6f5b-4d0e-9a51-0c8e2f6c1a11"}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/devices/{id}/qr":{"get":{"tags":["Devices"],"summary":"QR terkini (render sebagai QR code; berganti ±20 detik)","description":"Permission API key: `create_whatsapp`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Sukses","content":{"application/json":{"schema":{"type":"object","properties":{"qr":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"}},"required":["qr"]},"example":{"qr":"2@AbCdEf…,xyz…,abc…","expiresAt":"2026-10-18T03:00:20.000Z"}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/devices/{id}/pairing-code":{"post":{"tags":["Devices"],"summary":"Minta pairing code","description":"Permission API key: `create_whatsapp`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"phone":{"type":"string","minLength":6,"maxLength":32}},"required":["phone"]},"example":{"phone":"6281234567890"}}}},"responses":{"201":{"description":"Sukses","content":{"application/json":{"schema":{"type":"object","properties":{"deviceId":{"type":"integer"},"status":{"type":"string"},"pairingCode":{"type":["string","null"]}},"required":[]},"example":{"deviceId":12,"status":"pairing","pairingCode":"ABCD-EFGH"}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/devices/{id}/groups":{"get":{"tags":["Devices"],"summary":"Grup WA perangkat","description":"Permission API key: `get_wa_groups`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Sukses","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"gid":{"type":"string"},"name":{"type":"string"},"participantsCount":{"type":"integer"},"syncedAt":{"type":["string","null"],"format":"date-time"}},"required":[]}},"example":[{"id":3,"gid":"120363000000000000@g.us","name":"Reseller","participantsCount":42,"syncedAt":"2026-10-18T01:00:00.000Z"}]}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/numbers/check":{"post":{"tags":["Devices"],"summary":"Cek nomor terdaftar di WhatsApp (maks 50)","description":"Permission API key: `validate_wa_phone`.","security":[{"bearerAuth":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"deviceId":{"type":"integer"},"numbers":{"type":"array","items":{"type":"string"},"maxItems":50}},"required":["deviceId","numbers"]},"example":{"deviceId":12,"numbers":["6281234567890","081234567891"]}}}},"responses":{"200":{"description":"Sukses","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"number":{"type":"string"},"exists":{"type":"boolean"},"jid":{"type":["string","null"]}},"required":[]}},"example":[{"number":"6281234567890","exists":true,"jid":"6281234567890@s.whatsapp.net"},{"number":"6281234567891","exists":false,"jid":null}]}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/contacts":{"get":{"tags":["Contacts"],"summary":"Daftar kontak","description":"Permission API key: `get_contacts`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"q","in":"query","required":false,"schema":{"type":"string","maxLength":200,"description":"Cari"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","pattern":"^[a-zA-Z]+:(asc|desc)$","example":"createdAt:desc"}},{"name":"groupId","in":"query","required":false,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Sukses","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Contact"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"example":{"data":[{"id":501,"phone":"6281234567890","name":"Budi","customFields":{"kota":"Bandung"},"groups":[{"id":7,"name":"Pelanggan VIP"}],"createdAt":"2026-10-01T02:00:00.000Z","updatedAt":"2026-10-01T02:00:00.000Z"}],"meta":{"page":1,"pageSize":20,"total":1}}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Contacts"],"summary":"Buat kontak","description":"Permission API key: `create_contact`.","security":[{"bearerAuth":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"phone":{"type":"string"},"name":{"type":"string"},"groupIds":{"type":"array","items":{"type":"integer"}},"customFields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["phone"]},"example":{"phone":"6281234567890","name":"Budi","groupIds":[7],"customFields":{"kota":"Bandung"}}}}},"responses":{"201":{"description":"Sukses","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contact"},"example":{"id":501,"phone":"6281234567890","name":"Budi","customFields":{"kota":"Bandung"},"groups":[{"id":7,"name":"Pelanggan VIP"}],"createdAt":"2026-10-01T02:00:00.000Z","updatedAt":"2026-10-01T02:00:00.000Z"}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/contacts/{id}":{"get":{"tags":["Contacts"],"summary":"Detail kontak","description":"Permission API key: `get_contacts`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Sukses","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contact"},"example":{"id":501,"phone":"6281234567890","name":"Budi","customFields":{"kota":"Bandung"},"groups":[{"id":7,"name":"Pelanggan VIP"}],"createdAt":"2026-10-01T02:00:00.000Z","updatedAt":"2026-10-01T02:00:00.000Z"}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Contacts"],"summary":"Ubah kontak","description":"Permission API key: `create_contact`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"phone":{"type":"string"},"name":{"type":"string"},"groupIds":{"type":"array","items":{"type":"integer"}},"customFields":{"type":"object"}},"required":[]},"example":{"name":"Budi Santoso"}}}},"responses":{"200":{"description":"Sukses","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contact"},"example":{"id":501,"phone":"6281234567890","name":"Budi Santoso","customFields":{"kota":"Bandung"},"groups":[{"id":7,"name":"Pelanggan VIP"}],"createdAt":"2026-10-01T02:00:00.000Z","updatedAt":"2026-10-01T02:00:00.000Z"}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Contacts"],"summary":"Hapus kontak","description":"Permission API key: `delete_contact`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Sukses (tanpa isi)"},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/contact-groups":{"get":{"tags":["Contacts"],"summary":"Daftar grup kontak","description":"Permission API key: `get_groups`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"q","in":"query","required":false,"schema":{"type":"string","maxLength":200,"description":"Cari"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","pattern":"^[a-zA-Z]+:(asc|desc)$","example":"createdAt:desc"}}],"responses":{"200":{"description":"Sukses","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ContactGroup"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"example":{"data":[{"id":7,"name":"Pelanggan VIP","contactsCount":120,"membersCount":120,"createdAt":"2026-09-01T02:00:00.000Z"}],"meta":{"page":1,"pageSize":20,"total":1}}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Contacts"],"summary":"Buat grup","description":"Permission API key: `create_group`.","security":[{"bearerAuth":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"example":{"name":"Pelanggan VIP"}}}},"responses":{"201":{"description":"Sukses","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactGroup"},"example":{"id":7,"name":"Pelanggan VIP","contactsCount":0,"membersCount":0,"createdAt":"2026-09-01T02:00:00.000Z"}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/contact-groups/{id}":{"patch":{"tags":["Contacts"],"summary":"Ubah grup","description":"Permission API key: `create_group`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"example":{"name":"VIP 2026"}}}},"responses":{"200":{"description":"Sukses","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactGroup"}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Contacts"],"summary":"Hapus grup (keanggotaan saja; ?deleteOrphans=true juga menghapus kontak tanpa grup lain)","description":"Permission API key: `delete_group`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"deleteOrphans","in":"query","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"204":{"description":"Sukses (tanpa isi)"},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/campaigns":{"get":{"tags":["Campaigns"],"summary":"Daftar campaign","description":"Permission API key: `get_wa_campaigns`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"q","in":"query","required":false,"schema":{"type":"string","maxLength":200,"description":"Cari"}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","pattern":"^[a-zA-Z]+:(asc|desc)$","example":"createdAt:desc"}},{"name":"status","in":"query","required":false,"schema":{"enum":["draft","scheduled","running","paused","completed","cancelled","failed"]}}],"responses":{"200":{"description":"Sukses","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Campaign"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"example":{"data":[{"id":301,"name":"Promo Oktober","status":"running","source":"api","rotation":"round_robin","deviceIds":[12],"content":{"type":"text","text":"Halo {{name}}, ada promo 20% minggu ini!"},"totalRecipients":2,"counts":{"queued":2,"sending":0,"sent":0,"delivered":0,"read":0,"failed":0,"cancelled":0,"skipped":0},"estimatedFinishAt":"2026-10-18T03:05:00.000Z","delayMin":null,"delayMax":null,"sendWindowStart":null,"sendWindowEnd":null,"skipDuplicates24h":true,"legacy":false,"scheduledAt":null,"startedAt":"2026-10-18T03:00:00.000Z","completedAt":null,"createdAt":"2026-10-18T03:00:00.000Z"}],"meta":{"page":1,"pageSize":20,"total":1}}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Campaigns"],"summary":"Buat campaign (body sama dengan dashboard POST /v1/campaigns)","description":"Permission API key: `wa_send_bulk`.","security":[{"bearerAuth":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignCreate"},"example":{"name":"Promo Oktober","deviceIds":[12],"rotation":"round_robin","audience":{"numbers":["6281234567890","6281234567891"],"groupIds":[7]},"content":{"type":"text","text":"Halo {{name}}, ada promo 20% minggu ini!"},"delayMin":5,"delayMax":15,"sendWindowStart":"08:00","sendWindowEnd":"20:00","sendNow":true}}}},"responses":{"201":{"description":"Sukses","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Campaign"},"example":{"id":301,"name":"Promo Oktober","status":"running","source":"api","rotation":"round_robin","deviceIds":[12],"content":{"type":"text","text":"Halo {{name}}, ada promo 20% minggu ini!"},"totalRecipients":2,"counts":{"queued":2,"sending":0,"sent":0,"delivered":0,"read":0,"failed":0,"cancelled":0,"skipped":0},"estimatedFinishAt":"2026-10-18T03:05:00.000Z","delayMin":null,"delayMax":null,"sendWindowStart":null,"sendWindowEnd":null,"skipDuplicates24h":true,"legacy":false,"scheduledAt":null,"startedAt":"2026-10-18T03:00:00.000Z","completedAt":null,"createdAt":"2026-10-18T03:00:00.000Z"}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/campaigns/{id}":{"get":{"tags":["Campaigns"],"summary":"Detail campaign","description":"Permission API key: `get_wa_campaigns`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Sukses","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Campaign"},"example":{"id":301,"name":"Promo Oktober","status":"running","source":"api","rotation":"round_robin","deviceIds":[12],"content":{"type":"text","text":"Halo {{name}}, ada promo 20% minggu ini!"},"totalRecipients":2,"counts":{"queued":2,"sending":0,"sent":0,"delivered":0,"read":0,"failed":0,"cancelled":0,"skipped":0},"estimatedFinishAt":"2026-10-18T03:05:00.000Z","delayMin":null,"delayMax":null,"sendWindowStart":null,"sendWindowEnd":null,"skipDuplicates24h":true,"legacy":false,"scheduledAt":null,"startedAt":"2026-10-18T03:00:00.000Z","completedAt":null,"createdAt":"2026-10-18T03:00:00.000Z"}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/campaigns/{id}/pause":{"post":{"tags":["Campaigns"],"summary":"Jeda","description":"Permission API key: `stop_wa_campaign`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Sukses","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Campaign"}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/campaigns/{id}/resume":{"post":{"tags":["Campaigns"],"summary":"Lanjutkan","description":"Permission API key: `start_wa_campaign`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Sukses","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Campaign"}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/campaigns/{id}/cancel":{"post":{"tags":["Campaigns"],"summary":"Batalkan","description":"Permission API key: `stop_wa_campaign`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Sukses","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Campaign"}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v2/usage":{"get":{"tags":["Account"],"summary":"Paket & pemakaian","description":"Permission API key: `get_subscription`.","security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Sukses","content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":["object","null"],"properties":{"id":{"type":"integer"},"name":{"type":"string"}},"required":[]},"status":{"type":"string"},"currentPeriodEnd":{"type":["string","null"],"format":"date-time"},"usage":{"type":"array","items":{"type":"object","properties":{"metric":{"type":"string"},"used":{"type":"integer"},"limit":{"type":"integer"},"periodStart":{"type":"string","format":"date-time"},"periodEnd":{"type":"string","format":"date-time"}},"required":[]}}},"required":[]},"example":{"plan":{"id":2,"name":"Bisnis"},"status":"active","currentPeriodEnd":"2026-11-18T00:00:00.000Z","usage":[{"metric":"wa_send","used":120,"limit":10000,"periodStart":"2026-10-18T00:00:00.000Z","periodEnd":"2026-11-18T00:00:00.000Z"}]}}}},"400":{"description":"Validasi gagal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"validation_failed","message":"Data yang dikirim tidak valid.","details":[{"path":"to","message":"Required"}]}}}}},"401":{"description":"API key tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Izin/paket tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Tidak ditemukan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Aturan bisnis (kuota, nomor tidak valid, …)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"quota_exceeded","message":"Kuota pesan Anda sudah habis."}}}}},"429":{"description":"Rate limit 60 req/menit per key (lihat header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}