Lewati ke isi
CSWA.AIDocs

Referensi API v1

Semua endpoint dengan contoh permintaan & respons — dari skema yang sama dengan validasi server.

± 10 menit

Alamat dasar https://api.cswa.ai/v1. Spesifikasi mesin: https://api.cswa.ai/v1/openapi.json (OpenAPI 3.1, bisa diimpor ke Postman/Insomnia).

Kanal#

GET /channels

Daftar nomor WhatsApp (Device & API Official) di Profil. Status koneksi dan kuota pesan baru harian WhatsApp Device. Izin: pesan:baca.

Permintaan
curl -X GET "https://api.cswa.ai/v1/channels" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "data": [
    {
      "id": "chd_pr_0123456789abcdef",
      "type": "wa_device",
      "number": "6281234567890",
      "name": "Toko Rina",
      "status": "connected",
      "limits": {
        "new_messages_per_day": 200,
        "used_today": 12
      }
    },
    {
      "id": "cho_sa_0123456789abcdef",
      "type": "wa_official",
      "number": "6289876543210",
      "name": "Toko Rina Official",
      "status": "connected",
      "limits": null
    }
  ]
}

Pesan#

POST /messages

Kirim satu pesan (text, image, audio, video, document, location, contact, template). Diantre di Kotak keluar lalu dikirim lewat nomor pilihan. Tercatat di Inbox sebagai "API · nama kunci". WhatsApp API Official di luar 24 jam hanya template. Izin: pesan:kirim. Idempotency-Key wajib.

Permintaan
curl -X POST "https://api.cswa.ai/v1/messages" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"channel_id":"cho_sa_0123456789abcdef","to":"6281234567890","type":"text","text":{"body":"Halo kak, pesanan Anda sudah kami kirim 🙏"}}'
Respons 202
{
  "id": "kk_0123456789abcdef0123456789abcdef0123",
  "status": "queued",
  "conversation_id": "ct_0123456789abcdef",
  "channel_id": "cho_sa_0123456789abcdef",
  "test": false
}

GET /messages/{id}

Status satu pesan (queued, sent, delivered, read, failed). Id dari POST /messages (kk_…) disimpan 7 hari; id pesan Inbox (msg_…) juga bisa dibaca. Izin: pesan:baca.

Permintaan
curl -X GET "https://api.cswa.ai/v1/messages/kk_0123456789abcdef0123456789abcdef0123" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "id": "kk_0123456789abcdef0123456789abcdef0123",
  "status": "delivered",
  "conversation_id": "ct_0123456789abcdef",
  "message_id": "msg_0123456789abcdef",
  "error": null,
  "created_at": "2026-10-30T02:12:00.000Z",
  "sent_at": "2026-10-30T02:12:04.000Z"
}

Media#

POST /media

Unggah media (multipart `file`, atau JSON `{ url }`). Jenis berkas dibaca dari isinya. Gambar ≤ 5 MB, audio/video ≤ 16 MB, dokumen ≤ 50 MB. Disimpan 30 hari. Izin: pesan:kirim.

Permintaan
curl -X POST "https://api.cswa.ai/v1/media" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -F "[email protected]"
Respons 201
{
  "id": "md_0123456789abcdef",
  "type": "document",
  "mime": "application/pdf",
  "size": 182344,
  "filename": "katalog.pdf",
  "expires_at": "2026-11-29T02:12:00.000Z"
}

GET /media/{id}

Info media + tautan sementara (1 jam). Izin: pesan:baca.

Permintaan
curl -X GET "https://api.cswa.ai/v1/media/md_0123456789abcdef" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "id": "md_0123456789abcdef",
  "type": "image",
  "mime": "image/jpeg",
  "size": 52011,
  "filename": "produk.jpg",
  "url": "https://api.cswa.ai/v1/media/md_0123456789abcdef/content?exp=1793325000&sig=…",
  "expires_at": "2026-10-30T03:12:00.000Z"
}

GET /media/{id}/content

Isi media lewat tautan bertanda (tanpa kunci API, berlaku 1 jam). Tanpa kunci.

Percakapan#

GET /conversations

Daftar percakapan WhatsApp di Inbox. Izin: pesan:baca.

Permintaan
curl -X GET "https://api.cswa.ai/v1/conversations" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "data": [
    {
      "id": "ct_0123456789abcdef",
      "channel": {
        "id": "chd_pr_0123456789abcdef",
        "type": "wa_device",
        "number": "6281234567890"
      },
      "contact": {
        "id": "ct_0123456789abcdef",
        "name": "Dina",
        "phone": "6281311112222",
        "tags": [
          "VIP"
        ]
      },
      "last_message_at": "2026-10-30T02:12:00.000Z",
      "last_message_preview": "Ready kak?",
      "unread": 1,
      "closed": false,
      "assignee": null,
      "ai": null
    }
  ],
  "next_cursor": null
}

GET /conversations/{id}/messages

Riwayat pesan satu percakapan (terbaru dulu). Izin: pesan:baca.

Permintaan
curl -X GET "https://api.cswa.ai/v1/conversations/ct_0123456789abcdef/messages" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "data": [
    {
      "id": "msg_0123456789abcdef",
      "conversation_id": "ct_0123456789abcdef",
      "direction": "inbound",
      "type": "text",
      "text": "Halo kak, ready?",
      "origin": "audience",
      "status": "received",
      "error": null,
      "at": "2026-10-30T02:12:00.000Z",
      "media": []
    }
  ],
  "has_more": false
}

POST /conversations/{id}/assign

Tugaskan ke anggota tim (user_id) atau lepas (null). Izin: inbox:kelola.

Permintaan
curl -X POST "https://api.cswa.ai/v1/conversations/ct_0123456789abcdef/assign" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"user_id":1024}'
Respons 200
{
  "id": "ct_0123456789abcdef",
  "assignee": {
    "user_id": 1024,
    "name": "Sinta"
  }
}

POST /conversations/{id}/close

Tandai selesai (closed: false = buka lagi). Izin: inbox:kelola.

Permintaan
curl -X POST "https://api.cswa.ai/v1/conversations/ct_0123456789abcdef/close" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"closed":true}'
Respons 200
{
  "id": "ct_0123456789abcdef",
  "closed": true
}

POST /conversations/{id}/notes

Tulis catatan internal (tidak terlihat pelanggan). Izin: inbox:kelola.

Permintaan
curl -X POST "https://api.cswa.ai/v1/conversations/ct_0123456789abcdef/notes" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"text":"Sudah ditelepon, minta dikirim besok."}'
Respons 201
{
  "id": "cn_0123456789abcdef",
  "text": "Sudah ditelepon, minta dikirim besok.",
  "at": "2026-10-30T02:12:00.000Z"
}

POST /conversations/{id}/ai

AI Agent: pause (CS ambil alih), resume, atau handover ke CS. Izin: ai:kelola.

Permintaan
curl -X POST "https://api.cswa.ai/v1/conversations/ct_0123456789abcdef/ai" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"action":"pause"}'
Respons 200
{
  "id": "ct_0123456789abcdef",
  "ai": {
    "status": "manusia",
    "since": "2026-10-30T02:12:00.000Z"
  }
}

Kontak#

GET /contacts

Cari kontak WhatsApp (q = nama/nomor, tag). Izin: kontak:baca.

Permintaan
curl -X GET "https://api.cswa.ai/v1/contacts" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "data": [
    {
      "id": "ct_0123456789abcdef",
      "name": "Dina",
      "phone": "6281311112222",
      "tags": [
        "VIP"
      ],
      "channel": "wa_device",
      "stopped": false,
      "created_at": "2026-10-01T02:12:00.000Z"
    }
  ],
  "next_cursor": null
}

POST /contacts

Buat atau perbarui kontak (berdasar nomor). Izin: kontak:tulis.

Permintaan
curl -X POST "https://api.cswa.ai/v1/contacts" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"phone":"081311112222","name":"Dina","tags":["VIP","Reseller"]}'
Respons 201
{
  "id": "ct_0123456789abcdef",
  "name": "Dina",
  "phone": "6281311112222",
  "tags": [
    "VIP",
    "Reseller"
  ],
  "channel": "wa_device",
  "stopped": false,
  "created": true
}

POST /contacts/{id}/tags

Tambah tag. Izin: kontak:tulis.

Permintaan
curl -X POST "https://api.cswa.ai/v1/contacts/ct_0123456789abcdef/tags" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"tags":["VIP"]}'
Respons 200
{
  "id": "ct_0123456789abcdef",
  "tags": [
    "VIP"
  ]
}

DELETE /contacts/{id}/tags

Lepas tag (badan { tags } atau ?tag=). Izin: kontak:tulis.

Permintaan
curl -X DELETE "https://api.cswa.ai/v1/contacts/ct_0123456789abcdef/tags" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Content-Type: application/json" \
  -d '{"tags":["VIP"]}'
Respons 200
{
  "id": "ct_0123456789abcdef",
  "tags": []
}

Template#

GET /templates

Template resmi Meta & status persetujuannya. Izin: template:baca.

Permintaan
curl -X GET "https://api.cswa.ai/v1/templates" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "data": [
    {
      "channel_id": "cho_sa_0123456789abcdef",
      "name": "info_pesanan",
      "language": "id",
      "category": "UTILITY",
      "status": "APPROVED",
      "body": "Halo {{1}}, pesanan {{2}} sudah dikirim.",
      "variables": 2,
      "media_header": null
    }
  ]
}

Broadcast#

GET /broadcasts

Daftar broadcast. Izin: broadcast:kelola.

Permintaan
curl -X GET "https://api.cswa.ai/v1/broadcasts" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "data": [
    {
      "id": "wk_0123456789abcdef",
      "name": "Promo akhir bulan",
      "channel_id": "chd_pr_0123456789abcdef",
      "status": "running",
      "total": 480,
      "sent": 120,
      "failed": 2,
      "scheduled_at": "2026-10-30T02:00:00.000Z",
      "finished_at": null
    }
  ],
  "next_cursor": null
}

POST /broadcasts

Buat broadcast (penerima/tag, jadwal, jeda) — aturan anti-blokir sama dengan dasbor. Kirim massal HANYA lewat endpoint ini: kuota harian, jeda acak, STOP & laporan berlaku. WhatsApp Device memakai messages; API Official memakai template. Izin: broadcast:kelola. Idempotency-Key wajib.

Permintaan
curl -X POST "https://api.cswa.ai/v1/broadcasts" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"channel_id":"chd_pr_0123456789abcdef","name":"Promo akhir bulan","tags":["Pelanggan"],"messages":[{"text":"Halo {name}, diskon 20% sampai Minggu ini 🎉"}],"delay_seconds":20}'
Respons 201
{
  "id": "wk_0123456789abcdef",
  "status": "scheduled",
  "total": 480
}

GET /broadcasts/{id}

Progres & ringkasan broadcast. Izin: broadcast:kelola.

Permintaan
curl -X GET "https://api.cswa.ai/v1/broadcasts/wk_0123456789abcdef" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "id": "wk_0123456789abcdef",
  "name": "Promo akhir bulan",
  "status": "finished",
  "total": 480,
  "sent": 470,
  "failed": 4,
  "replied": 51,
  "stopped": 3,
  "note": null
}

POST /broadcasts/{id}/pause

Jeda broadcast. Izin: broadcast:kelola.

Permintaan
curl -X POST "https://api.cswa.ai/v1/broadcasts/wk_0123456789abcdef/pause" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)"
Respons 200
{
  "id": "wk_0123456789abcdef",
  "status": "paused"
}

POST /broadcasts/{id}/resume

Lanjutkan broadcast yang dijeda. Izin: broadcast:kelola.

Permintaan
curl -X POST "https://api.cswa.ai/v1/broadcasts/wk_0123456789abcdef/resume" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)"
Respons 200
{
  "id": "wk_0123456789abcdef",
  "status": "running"
}

Follow up#

GET /followups

Daftar follow up WhatsApp (active = aktif, paused = dijeda). Izin: followup:kelola.

Permintaan
curl -X GET "https://api.cswa.ai/v1/followups" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "data": [
    {
      "id": "wf_0123456789abcdef",
      "name": "Ingatkan promo",
      "channel_type": "wa_device",
      "channel_id": "chd_pr_0123456789abcdef",
      "active": true,
      "status": "scheduled",
      "source": {
        "type": "broadcast",
        "broadcast_id": "wk_0123456789abcdef",
        "condition": "noreply"
      },
      "steps": 1,
      "current_step": 1,
      "stop_when": {
        "type": "replied"
      },
      "next_run_at": "2026-10-31T02:00:00.000Z",
      "last_run_at": null,
      "last_result": null
    }
  ],
  "next_cursor": null
}

POST /followups

Buat follow up berseri (sumber broadcast atau daftar penerima, maks 10 langkah). Aturan sama dengan dasbor: WhatsApp Device memakai messages dengan jeda minimal setelan admin; API Official memakai template yang disetujui Meta. Berhenti bila pelanggan membalas (bawaan) — STOP selalu berhenti. Izin: followup:kelola.

Permintaan
curl -X POST "https://api.cswa.ai/v1/followups" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"name":"Ingatkan promo","channel_id":"chd_pr_0123456789abcdef","source":{"type":"broadcast","broadcast_id":"wk_0123456789abcdef","condition":"noreply"},"steps":[{"when":{"type":"after_broadcast","amount":1,"unit":"days","time":"09:00"},"messages":[{"text":"Halo {name}, promonya tinggal hari ini ya 🙏"}]}],"stop_when":{"type":"replied"}}'
Respons 201
{
  "id": "wf_0123456789abcdef",
  "name": "Ingatkan promo",
  "channel_type": "wa_device",
  "channel_id": "chd_pr_0123456789abcdef",
  "active": true,
  "status": "scheduled",
  "source": {
    "type": "broadcast",
    "broadcast_id": "wk_0123456789abcdef",
    "condition": "noreply"
  },
  "steps": 1,
  "current_step": 1,
  "stop_when": {
    "type": "replied"
  },
  "next_run_at": "2026-10-31T02:00:00.000Z",
  "last_run_at": null,
  "last_result": null
}

GET /followups/{id}

Detail & progres satu follow up. Izin: followup:kelola.

Permintaan
curl -X GET "https://api.cswa.ai/v1/followups/wf_0123456789abcdef" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "id": "wf_0123456789abcdef",
  "name": "Ingatkan promo",
  "channel_type": "wa_device",
  "channel_id": "chd_pr_0123456789abcdef",
  "active": true,
  "status": "scheduled",
  "source": {
    "type": "broadcast",
    "broadcast_id": "wk_0123456789abcdef",
    "condition": "noreply"
  },
  "steps": 1,
  "current_step": 1,
  "stop_when": {
    "type": "replied"
  },
  "next_run_at": "2026-10-31T02:00:00.000Z",
  "last_run_at": null,
  "last_result": null
}

POST /followups/{id}/pause

Jeda follow up (langkah yang sedang dikirim dibiarkan selesai). Izin: followup:kelola.

Permintaan
curl -X POST "https://api.cswa.ai/v1/followups/wf_0123456789abcdef/pause" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)"
Respons 200
{
  "id": "wf_0123456789abcdef",
  "name": "Ingatkan promo",
  "channel_type": "wa_device",
  "channel_id": "chd_pr_0123456789abcdef",
  "active": false,
  "status": "paused",
  "source": {
    "type": "broadcast",
    "broadcast_id": "wk_0123456789abcdef",
    "condition": "noreply"
  },
  "steps": 1,
  "current_step": 1,
  "stop_when": {
    "type": "replied"
  },
  "next_run_at": "2026-10-31T02:00:00.000Z",
  "last_run_at": null,
  "last_result": null
}

POST /followups/{id}/resume

Lanjutkan follow up yang dijeda. Izin: followup:kelola.

Permintaan
curl -X POST "https://api.cswa.ai/v1/followups/wf_0123456789abcdef/resume" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)"
Respons 200
{
  "id": "wf_0123456789abcdef",
  "name": "Ingatkan promo",
  "channel_type": "wa_device",
  "channel_id": "chd_pr_0123456789abcdef",
  "active": true,
  "status": "scheduled",
  "source": {
    "type": "broadcast",
    "broadcast_id": "wk_0123456789abcdef",
    "condition": "noreply"
  },
  "steps": 1,
  "current_step": 1,
  "stop_when": {
    "type": "replied"
  },
  "next_run_at": "2026-10-31T02:00:00.000Z",
  "last_run_at": null,
  "last_result": null
}

GET /contacts/{id}/followups

Antrean follow up aktif yang menyasar satu kontak. Izin: followup:kelola.

Permintaan
curl -X GET "https://api.cswa.ai/v1/contacts/ct_0123456789abcdef/followups" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "contact_id": "ct_0123456789abcdef",
  "stopped": false,
  "data": [
    {
      "followup": {
        "id": "wf_0123456789abcdef",
        "name": "Ingatkan promo",
        "channel_type": "wa_device",
        "channel_id": "chd_pr_0123456789abcdef",
        "active": true,
        "status": "scheduled",
        "source": {
          "type": "broadcast",
          "broadcast_id": "wk_0123456789abcdef",
          "condition": "noreply"
        },
        "steps": 1,
        "current_step": 1,
        "stop_when": {
          "type": "replied"
        },
        "next_run_at": "2026-10-31T02:00:00.000Z",
        "last_run_at": null,
        "last_result": null
      },
      "will_skip": false,
      "reason": null
    }
  ]
}

Pesanan & tagihan#

GET /orders

Daftar pesanan Inbox › Penjualan & halaman toko (terbaru dulu). Izin: pesanan:baca.

Permintaan
curl -X GET "https://api.cswa.ai/v1/orders" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "data": [
    {
      "id": "pjl_0123456789abcdef",
      "number": "ORD-0012",
      "status": "pending_payment",
      "status_label": "Menunggu pembayaran",
      "source": "chat",
      "channel": "whatsapp",
      "conversation_id": "ct_0123456789abcdef",
      "customer": {
        "name": "Dina",
        "username": "6281311112222",
        "email": null
      },
      "items": [
        {
          "name": "Gamis Sage",
          "variant": "L",
          "type": "physical",
          "quantity": 1,
          "price": 330000
        }
      ],
      "shipping_fee": 20000,
      "discount": 0,
      "total": 350000,
      "currency": "IDR",
      "payment": {
        "id": "pjl_0123456789abcdef",
        "order_id": "pjl_0123456789abcdef",
        "number": "ORD-0012",
        "method": "mayar",
        "status": "pending",
        "amount": 350000,
        "amount_to_transfer": null,
        "payment_url": "https://contoh.myr.id/invoices/…",
        "due_at": "2026-10-31T02:12:00.000Z",
        "paid_at": null
      },
      "shipment": null,
      "created_at": "2026-10-30T02:12:00.000Z"
    }
  ],
  "next_cursor": null
}

GET /orders/{id}

Detail pesanan (item, total, pembayaran, pengiriman). Izin: pesanan:baca.

Permintaan
curl -X GET "https://api.cswa.ai/v1/orders/pjl_0123456789abcdef" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "id": "pjl_0123456789abcdef",
  "number": "ORD-0012",
  "status": "pending_payment",
  "status_label": "Menunggu pembayaran",
  "source": "chat",
  "channel": "whatsapp",
  "conversation_id": "ct_0123456789abcdef",
  "customer": {
    "name": "Dina",
    "username": "6281311112222",
    "email": null
  },
  "items": [
    {
      "name": "Gamis Sage",
      "variant": "L",
      "type": "physical",
      "quantity": 1,
      "price": 330000
    }
  ],
  "shipping_fee": 20000,
  "discount": 0,
  "total": 350000,
  "currency": "IDR",
  "payment": {
    "id": "pjl_0123456789abcdef",
    "order_id": "pjl_0123456789abcdef",
    "number": "ORD-0012",
    "method": "mayar",
    "status": "pending",
    "amount": 350000,
    "amount_to_transfer": null,
    "payment_url": "https://contoh.myr.id/invoices/…",
    "due_at": "2026-10-31T02:12:00.000Z",
    "paid_at": null
  },
  "shipment": null,
  "created_at": "2026-10-30T02:12:00.000Z"
}

POST /orders/{id}/shipment

Isi kurir & resi — status pesanan menjadi Dikirim. Sama dengan tombol Resi di Inbox: kabar resi ke pelanggan dikirim bila setelan Penjualan menyala. Pesanan halaman toko dikelola dari menu Halaman. Izin: pesanan:tulis.

Permintaan
curl -X POST "https://api.cswa.ai/v1/orders/pjl_0123456789abcdef/shipment" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"courier":"jne","tracking_number":"JP1234567890","service":"REG"}'
Respons 200
{
  "id": "pjl_0123456789abcdef",
  "number": "ORD-0012",
  "status": "shipped",
  "status_label": "Menunggu pembayaran",
  "source": "chat",
  "channel": "whatsapp",
  "conversation_id": "ct_0123456789abcdef",
  "customer": {
    "name": "Dina",
    "username": "6281311112222",
    "email": null
  },
  "items": [
    {
      "name": "Gamis Sage",
      "variant": "L",
      "type": "physical",
      "quantity": 1,
      "price": 330000
    }
  ],
  "shipping_fee": 20000,
  "discount": 0,
  "total": 350000,
  "currency": "IDR",
  "payment": {
    "id": "pjl_0123456789abcdef",
    "order_id": "pjl_0123456789abcdef",
    "number": "ORD-0012",
    "method": "mayar",
    "status": "pending",
    "amount": 350000,
    "amount_to_transfer": null,
    "payment_url": "https://contoh.myr.id/invoices/…",
    "due_at": "2026-10-31T02:12:00.000Z",
    "paid_at": null
  },
  "shipment": {
    "courier": "JNE",
    "courier_code": "jne",
    "service": "REG",
    "tracking_number": "JP1234567890",
    "status": "dikirim",
    "tracking_url": "https://www.jne.co.id/…"
  },
  "created_at": "2026-10-30T02:12:00.000Z"
}

POST /invoices

Tagihkan pesanan: link Mayar (bila Mayar aktif) atau transfer bank. Tanpa method: Mayar bila terhubung, selain itu transfer (kode unik bila Moota aktif). Id tagihan = id pesanan. message_text = teks tagihan siap dikirim ke pelanggan (TIDAK dikirim otomatis). Izin: pesanan:tulis.

Permintaan
curl -X POST "https://api.cswa.ai/v1/invoices" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"order_id":"pjl_0123456789abcdef"}'
Respons 201
{
  "invoice": {
    "id": "pjl_0123456789abcdef",
    "order_id": "pjl_0123456789abcdef",
    "number": "ORD-0012",
    "method": "mayar",
    "status": "pending",
    "amount": 350000,
    "amount_to_transfer": null,
    "payment_url": "https://contoh.myr.id/invoices/…",
    "due_at": "2026-10-31T02:12:00.000Z",
    "paid_at": null
  },
  "message_text": "Rincian pesanan #ORD-0012 …\nBayar di: https://…"
}

GET /invoices/{id}

Status bayar tagihan (refresh=true: cek langsung ke Mayar). Izin: pesanan:baca.

Permintaan
curl -X GET "https://api.cswa.ai/v1/invoices/pjl_0123456789abcdef" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "id": "pjl_0123456789abcdef",
  "order_id": "pjl_0123456789abcdef",
  "number": "ORD-0012",
  "method": "mayar",
  "status": "pending",
  "amount": 350000,
  "amount_to_transfer": null,
  "payment_url": "https://contoh.myr.id/invoices/…",
  "due_at": "2026-10-31T02:12:00.000Z",
  "paid_at": null
}

Tiket & CSAT#

GET /tickets

Daftar tiket (status open = semua yang masih aktif). Izin: tiket:kelola.

Permintaan
curl -X GET "https://api.cswa.ai/v1/tickets" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "data": [
    {
      "id": "tk_0123456789_abcd1234",
      "number": "TK-0042",
      "status": "new",
      "priority": "high",
      "category": "Komplain",
      "summary": "Barang belum sampai",
      "channel": "whatsapp",
      "conversation_id": "ct_0123456789abcdef",
      "assignee": null,
      "created_at": "2026-10-30T02:12:00.000Z"
    }
  ],
  "next_cursor": null
}

GET /tickets/{id}

Detail tiket + riwayat status (tanpa catatan internal). Izin: tiket:kelola.

Permintaan
curl -X GET "https://api.cswa.ai/v1/tickets/tk_0123456789_abcd1234" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "id": "tk_0123456789_abcd1234",
  "number": "TK-0042",
  "status": "new",
  "priority": "high",
  "category": "Komplain",
  "summary": "Barang belum sampai",
  "channel": "whatsapp",
  "conversation_id": "ct_0123456789abcdef",
  "assignee": null,
  "created_at": "2026-10-30T02:12:00.000Z"
}

PATCH /tickets/{id}

Ubah status/prioritas tiket (kabar pelanggan & CSAT seperti di Inbox). Izin: tiket:kelola.

Permintaan
curl -X PATCH "https://api.cswa.ai/v1/tickets/tk_0123456789_abcd1234" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Content-Type: application/json" \
  -d '{"status":"resolved"}'
Respons 200
{
  "id": "tk_0123456789_abcd1234",
  "number": "TK-0042",
  "status": "resolved",
  "priority": "high",
  "category": "Komplain",
  "summary": "Barang belum sampai",
  "channel": "whatsapp",
  "conversation_id": "ct_0123456789abcdef",
  "assignee": null,
  "created_at": "2026-10-30T02:12:00.000Z"
}

GET /csat

Daftar survei kepuasan (nilai, komentar, penangan). Izin: tiket:kelola.

Permintaan
curl -X GET "https://api.cswa.ai/v1/csat" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "data": [
    {
      "id": "cs_0123456789abcdef",
      "conversation_id": "ct_0123456789abcdef",
      "channel": "whatsapp",
      "scale": 5,
      "status": "answered",
      "score": 5,
      "comment": null,
      "handled_by": {
        "type": "team",
        "name": "Sinta"
      },
      "answered_at": "2026-10-30T02:12:00.000Z"
    }
  ],
  "next_cursor": null
}

Analitik#

GET /analytics/whatsapp

Angka WhatsApp yang sama dengan halaman Analitik (days 1/7/30/90 atau from–to). Izin: analitik:baca.

Permintaan
curl -X GET "https://api.cswa.ai/v1/analytics/whatsapp" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "period": {
    "from": "2026-10-01",
    "to": "2026-10-30",
    "days": 30
  },
  "totals": {
    "inbound": 1820,
    "broadcast_sent": 940,
    "followup_sent": 210,
    "auto_reply_sent": 380,
    "manual_replies": 610,
    "replied_recipients": 122,
    "new_contacts": 310,
    "stopped": 6
  },
  "previous": {
    "inbound": 1500
  },
  "daily": [
    {
      "date": "2026-10-30",
      "inbound": 61
    }
  ],
  "inbox": {
    "conversations": 402,
    "replied": 380,
    "waiting": 22,
    "response_seconds": {
      "median": 95,
      "p90": 640
    }
  },
  "orders": {
    "created": 48,
    "paid": 37,
    "paid_value": 12850000
  }
}

Webhook#

GET /webhooks

Daftar URL webhook. Izin: webhook:kelola.

Permintaan
curl -X GET "https://api.cswa.ai/v1/webhooks" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "data": [
    {
      "id": "wh_0123456789abcdef",
      "url": "https://sistem-anda.com/webhook",
      "events": [
        "message.received"
      ],
      "active": true,
      "health": "healthy",
      "last_success_at": "2026-10-30T02:12:00.000Z"
    }
  ]
}

POST /webhooks

Tambah URL webhook (rahasia ditampilkan sekali). Izin: webhook:kelola.

Permintaan
curl -X POST "https://api.cswa.ai/v1/webhooks" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://sistem-anda.com/webhook","events":["message.received","message.status"]}'
Respons 201
{
  "id": "wh_0123456789abcdef",
  "url": "https://sistem-anda.com/webhook",
  "events": [
    "message.received",
    "message.status"
  ],
  "active": true,
  "secret": "whsec_…"
}

PATCH /webhooks/{id}

Ubah URL/event, nyalakan/matikan. Izin: webhook:kelola.

Permintaan
curl -X PATCH "https://api.cswa.ai/v1/webhooks/wh_0123456789abcdef" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Content-Type: application/json" \
  -d '{"active":true}'
Respons 200
{
  "id": "wh_0123456789abcdef",
  "active": true
}

DELETE /webhooks/{id}

Hapus URL webhook. Izin: webhook:kelola.

Permintaan
curl -X DELETE "https://api.cswa.ai/v1/webhooks/wh_0123456789abcdef" \
  -H "Authorization: Bearer KUNCI_API_ANDA"

POST /webhooks/{id}/test

Uji kirim event ping (ditunggu hasilnya). Izin: webhook:kelola.

Permintaan
curl -X POST "https://api.cswa.ai/v1/webhooks/wh_0123456789abcdef/test" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)"
Respons 200
{
  "id": "dlv_0123456789abcdef",
  "status": "terkirim",
  "http": 200,
  "duration_ms": 182
}

POST /webhooks/{id}/rotate-secret

Rotasi rahasia (rahasia lama tetap ditandatangani 24 jam). Izin: webhook:kelola.

Permintaan
curl -X POST "https://api.cswa.ai/v1/webhooks/wh_0123456789abcdef/rotate-secret" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)"
Respons 200
{
  "secret": "whsec_…",
  "previous_valid_until": "2026-10-31T02:12:00.000Z"
}

GET /webhooks/{id}/deliveries

Log kiriman (disimpan sesuai batas lama simpan log). Izin: webhook:kelola.

Permintaan
curl -X GET "https://api.cswa.ai/v1/webhooks/wh_0123456789abcdef/deliveries" \
  -H "Authorization: Bearer KUNCI_API_ANDA"
Respons 200
{
  "data": [
    {
      "id": "dlv_0123456789abcdef",
      "event": "message.received",
      "status": "terkirim",
      "attempts": 1,
      "http": 200,
      "error": null,
      "created_at": "2026-10-30T02:12:00.000Z"
    }
  ],
  "next_cursor": null
}

POST /webhooks/deliveries/{id}/resend

Kirim ulang satu kiriman. Izin: webhook:kelola.

Permintaan
curl -X POST "https://api.cswa.ai/v1/webhooks/deliveries/dlv_0123456789abcdef/resend" \
  -H "Authorization: Bearer KUNCI_API_ANDA" \
  -H "Idempotency-Key: $(uuidgen)"
Respons 200
{
  "id": "dlv_0123456789abcdef",
  "status": "terkirim",
  "http": 200
}