pixco

API Documentation

Everything you need to send WhatsApp messages automatically from your app — from device connection to bulk messaging.

Base URL/api/v1

Getting Started

Follow these steps to get your WhatsApp gateway ready to send messages.

1

Create Account & Choose Plan

Sign up at pixco and choose a plan: Trial for 14-day free trial, Basic for growing teams, or Pro for unlimited needs.

2

Connect WhatsApp Device

Add a device from the Devices menu in your dashboard. Scan the QR code with WhatsApp to connect your number.

Use an active WhatsApp number that is not being used on another device.
3

Create an API Key

Open the API Keys menu in your dashboard, create a new key with appropriate permissions. Use the API key in the x-api-key header.

Store your license key securely. Do not expose it in client-side code.
4

Start Sending Messages

Use the /api/v1/send/message endpoint with your API key to send WhatsApp messages from your app.

API Reference

Message endpoints use x-api-key header. Device, AI, and other endpoints accept x-api-key or Bearer JWT token.

POST/api/v1/send/messageSend Message

Send a WhatsApp message to a single recipient. Use scheduled_at (ISO 8601) to schedule future delivery.

scheduled_at is optional. If omitted, the message is sent immediately.
Headers
x-api-keyAPI key dari menu API Keys
Content-Typeapplication/json
Request Body
{
  "device_id": "id-device-dari-get-devices",
  "to": "628123456789",
  "message": "Halo dari pixco!",
  "scheduled_at": "2026-05-20T14:00:00Z"
}
Response
{
  "status": "success",
  "message_id": "uuid-message",
  "to": "628123456789",
  "status_msg": "pending"
}
POST/api/v1/send/bulkBulk Send

Send messages to multiple numbers in a single request.

Headers
x-api-keyAPI key dari menu API Keys
Content-Typeapplication/json
Request Body
{
  "device_id": "id-device-dari-get-devices",
  "targets": [
    "628111111111",
    "628222222222"
  ],
  "message": "Halo dari pixco!"
}
Response
{
  "status": "success",
  "queued": 2
}
GET/api/v1/messagesMessage List

Retrieve sent and received message history. Requires Bearer token.

Headers
AuthorizationBearer <jwt_token>
Response
{
  "data": [],
  "total": 0,
  "page": 1,
  "limit": 20
}
GET/api/v1/devicesList Devices

Retrieve all connected WhatsApp devices. Supports pagination via page & limit query params.

Headers
AuthorizationBearer <jwt_token>
Response
{
  "data": [
    {
      "id": "uuid",
      "name": "My Device",
      "status": "connected",
      "bot_enabled": false,
      "credits": 0
    }
  ],
  "total": 1,
  "page": 1,
  "limit": 20
}
GET/api/v1/devices/{id}Device Detail

Get full details of a WhatsApp device by ID, including connection status, bot config, and AI settings.

Headers
AuthorizationBearer <jwt_token>
Response
{
  "id": "uuid",
  "name": "My Device",
  "status": "connected",
  "bot_enabled": true,
  "webhook": "https://...",
  "ai_enabled": false
}
PATCH/api/v1/devices/{id}Rename Device

Change the name of a WhatsApp device.

Headers
AuthorizationBearer <jwt_token>
Content-Typeapplication/json
Request Body
{
  "name": "Nama Baru Device"
}
Response
{
  "message": "settings_updated"
}
DELETE/api/v1/devices/{id}Delete Device

Delete a device with safe workflow: logout/disconnect WhatsApp session first, then delete all related message history transactionally.

deleted_messages_count only counts messages owned by the logged-in tenant (scoped by tenant_id), not all tenants.
Headers
AuthorizationBearer <jwt_token>
Response
{
  "message": "deleted_successfully",
  "deleted_messages_count": 12,
  "device_logged_out": true
}
POST/api/v1/devicesCreate Device

Create a new WhatsApp device. Use name to label your device.

Headers
x-api-key or Authorizationx-api-key dari menu API Keys atau Bearer <jwt_token>
Content-Typeapplication/json
Request Body
{
  "name": "My WhatsApp Device",
  "phone_number": "628123456789"
}
Response
{
  "id": "uuid",
  "name": "My WhatsApp Device",
  "status": "disconnected",
  "is_active": true
}
GET/api/v1/devices/{id}/qrConnect QR Code

Get QR code to connect WhatsApp. Scan with WhatsApp > Linked Devices.

Device must be in disconnected status. QR code is temporary (expires in a few minutes).
Headers
x-api-key or Authorizationx-api-key dari menu API Keys atau Bearer <jwt_token>
Response
{
  "qr_code": "base64-encoded-qr-image"
}
POST/api/v1/devices/{id}/connect-phonePair via Phone

Pair WhatsApp using phone number. Suitable for headless/server environments.

Enter phone number with country code (62xx). Pairing code will appear, enter it in WhatsApp > Linked Devices.
Headers
x-api-key or Authorizationx-api-key dari menu API Keys atau Bearer <jwt_token>
Content-Typeapplication/json
Request Body
{
  "phone": "628123456789"
}
Response
{
  "pairing_code": "ABCD-1234"
}
POST/api/v1/devices/{id}/disconnectDisconnect

Disconnect WhatsApp device. Logs out from WhatsApp and removes the session.

Headers
x-api-key or Authorizationx-api-key dari menu API Keys atau Bearer <jwt_token>
Response
{
  "message": "Device disconnected"
}
PUT/api/v1/devices/{id}/webhookUpdate Webhook

Set or remove webhook URL for a device. Webhook receives events: incoming message, device connected/disconnected.

image
Headers
x-api-key or Authorizationx-api-key dari menu API Keys atau Bearer <jwt_token>
Content-Typeapplication/json
Request Body
{
  "webhook_url": "https://myapp.com/webhook/whatsapp"
}
Response
{
  "message": "settings_updated"
}
PATCH/api/v1/devices/{id}/botToggle Bot

Enable/disable auto-reply bot for a device. When enabled, incoming messages are processed by auto-reply rules & chaining.

Headers
x-api-key or Authorizationx-api-key dari menu API Keys atau Bearer <jwt_token>
Content-Typeapplication/json
Request Body
{
  "bot_enabled": true
}
Response
{
  "message": "operation_success"
}
PATCH/api/v1/devices/{id}/languageBot Language

Change the language used by the bot to respond (id/en).

Headers
x-api-key or Authorizationx-api-key dari menu API Keys atau Bearer <jwt_token>
Content-Typeapplication/json
Request Body
{
  "language": "id"
}
Response
{
  "message": "operation_success"
}
POST/api/v1/devices/{id}/topupTopup Device Credits

Add AI credits to a specific device. System will generate QRIS payment via pixpay.

Headers
x-api-key or Authorizationx-api-key dari menu API Keys atau Bearer <jwt_token>
Content-Typeapplication/json
Request Body
{
  "amount": 50000
}
Response
{
  "id": "uuid-order",
  "device_id": "uuid-device",
  "amount": 50000,
  "status": "pending",
  "qr_string": "base64-qr",
  "payment_url": "https://..."
}
GET/api/v1/devices/{id}/subscriptionDevice Subscription

Get the subscription (package) status of a device.

Headers
x-api-key or Authorizationx-api-key dari menu API Keys atau Bearer <jwt_token>
Response
{
  "id": "uuid",
  "device_id": "uuid",
  "package_id": "uuid",
  "package_name": "Basic",
  "starts_at": "...",
  "expires_at": "...",
  "is_active": true
}
POST/api/v1/devices/{id}/subscribeSubscribe Package

Subscribe a device to a specific package. Creates an order that must be paid via QRIS.

Headers
x-api-key or Authorizationx-api-key dari menu API Keys atau Bearer <jwt_token>
Content-Typeapplication/json
Request Body
{
  "package_id": "uuid-package",
  "no_expired": false
}
Response
{
  "id": "uuid-order",
  "status": "pending",
  "total_amount": 49000,
  "qr_string": "base64-qr"
}
GET/api/v1/devices/{id}/expiry-statusDevice Expiry

Get device expiry status (expiration date and remaining days).

Headers
x-api-key or Authorizationx-api-key dari menu API Keys atau Bearer <jwt_token>
Response
{
  "device_id": "uuid",
  "expiry_enabled": true,
  "expires_at": "2026-08-17T00:00:00Z",
  "extension_price": 10000,
  "is_expired": false,
  "remaining_days": 30
}
POST/api/v1/devices/{id}/expiry/payPay Device Extension

Extend device active period. Creates QRIS payment for extension.

Headers
x-api-key or Authorizationx-api-key dari menu API Keys atau Bearer <jwt_token>
Content-Typeapplication/json
Request Body
{
  "duration_days": 30
}
Response
{
  "order_id": "uuid",
  "qr_string": "base64-qr",
  "payment_url": "https://...",
  "amount": 10000,
  "status": "pending"
}
POST/api/v1/api-keysBuat API Key

Membuat API key baru untuk integrasi. API key digunakan pada header x-api-key untuk mengirim pesan.

License key hanya ditampilkan sekali saat dibuat. Simpan dengan aman.
Headers
AuthorizationBearer <jwt_token>
Content-Typeapplication/json
Request Body
{
  "name": "My App Integration"
}
Response
{
  "id": "uuid",
  "name": "My App Integration",
  "license_key": "pixco_xxx...",
  "is_active": true,
  "created_at": "2026-06-01T10:00:00Z"
}
GET/api/v1/api-keysDaftar API Key

Ambil daftar semua API key milik tenant. Support pagination via query page & limit, dan search via query search.

Headers
AuthorizationBearer <jwt_token>
Response
{
  "data": [
    {
      "id": "uuid",
      "name": "My Key",
      "is_active": true,
      "created_at": "..."
    }
  ],
  "total": 1,
  "page": 1,
  "limit": 20
}
DELETE/api/v1/api-keys/{id}Cabut API Key

Mencabut (revoke) API key. Key yang sudah dicabut tidak bisa digunakan lagi untuk mengirim pesan.

Headers
AuthorizationBearer <jwt_token>
Response
{
  "message": "apikey_revoked"
}
GET/api/v1/send/scheduledScheduled Messages

List scheduled messages. Includes pending and sent ones. Supports pagination via page & limit.

Headers
x-api-keyAPI key dari menu API Keys
Response
{
  "data": [
    {
      "id": "uuid",
      "to": "628xxx",
      "content": "Halo",
      "status": "pending",
      "scheduled_at": "2026-05-20T14:00:00Z"
    }
  ],
  "total": 1,
  "page": 1,
  "limit": 20
}
PUT/api/v1/send/scheduled/{id}Reschedule Message

Change the scheduled time of an existing message.

Headers
x-api-keyAPI key dari menu API Keys
Content-Typeapplication/json
Request Body
{
  "scheduled_at": "2026-05-21T10:00:00Z"
}
Response
{
  "status": "success",
  "message_id": "uuid",
  "scheduled_at": "2026-05-21T10:00:00Z"
}
DELETE/api/v1/send/scheduled/{id}Cancel Schedule

Cancel a scheduled message. The message stays in the database but the schedule is removed (scheduled_at = null).

Headers
x-api-keyAPI key dari menu API Keys
Response
{
  "status": "success",
  "message_id": "uuid"
}
PATCH/api/v1/devices/{id}/ai-addonAI Device Configuration

Enable/disable AI, configure provider, model, system prompt, guardrail, and key source (BYOK or PixAI) for a device.

JSON body. ai_guardrail_enabled defaults to true. Leave ai_guardrail_prompt empty to use the default guardrail.
Headers
AuthorizationBearer <jwt_token>
Content-Typeapplication/json
Request Body
{
  "ai_enabled": true,
  "ai_provider": "openrouter",
  "ai_model": "google/gemini-2.0-flash-001",
  "ai_use_shared_key": true,
  "ai_fallback_to_chatbot": true,
  "ai_guardrail_enabled": true,
  "ai_guardrail_prompt": "Kamu adalah asisten yang hanya menjawab dari knowledge yang disediakan.",
  "ai_api_key": "sk-xxx"
}
Response
{
  "message": "operation_success",
  "ai_enabled": true,
  "ai_provider": "openrouter",
  "ai_model": "google/gemini-2.0-flash-001",
  "ai_prompt": "",
  "ai_has_api_key": true,
  "ai_use_shared_key": true,
  "ai_fallback_to_chatbot": true,
  "ai_guardrail_enabled": true,
  "ai_guardrail_prompt": "..."
}
GET/api/v1/ai/knowledge?device_id={device_id}Knowledge List

Get all knowledge documents for a device. device_id query parameter is required.

Headers
AuthorizationBearer <jwt_token>
Response
{
  "data": [
    {
      "id": "uuid",
      "title": "Produk Kami",
      "content": "Ini adalah deskripsi produk...",
      "source_type": "text",
      "file_url": null,
      "file_orig_name": null,
      "is_active": true
    }
  ]
}
POST/api/v1/ai/knowledgeAdd Knowledge

Add a new knowledge document to a device. Supports text input or file upload (TXT/CSV/PDF, max 5 MB).

Use Content-Type: multipart/form-data. For manual text: send device_id, title, content fields. For file upload: send device_id, file (TXT/CSV/PDF, max 5 MB), and optional title.
Headers
AuthorizationBearer <jwt_token>
Content-Typemultipart/form-data
Response
{
  "message": "created",
  "data": {
    "id": "uuid-knowledge",
    "title": "Produk Kami",
    "content": "...",
    "source_type": "text",
    "is_active": true
  }
}
PUT/api/v1/ai/knowledge/{id}Edit Knowledge

Update title, content, or active status of a knowledge document.

Headers
AuthorizationBearer <jwt_token>
Content-Typeapplication/json
Request Body
{
  "title": "Produk Kami (Update)",
  "content": "Konten baru...",
  "is_active": true
}
Response
{
  "message": "updated",
  "data": {
    "id": "uuid",
    "title": "Produk Kami (Update)",
    "content": "Konten baru...",
    "is_active": true
  }
}
DELETE/api/v1/ai/knowledge/{id}Delete Knowledge

Delete a single knowledge document by ID.

Headers
AuthorizationBearer <jwt_token>
Response
{
  "message": "deleted"
}
DELETE/api/v1/ai/knowledge/all?device_id={device_id}Delete All Knowledge

Delete all knowledge documents for a device. device_id query parameter is required.

Headers
AuthorizationBearer <jwt_token>
Response
{
  "message": "deleted",
  "count": 5
}
GET/api/v1/ai/creditsCredit Balance

Get AI credit balance for your devices.

Headers
AuthorizationBearer <jwt_token>
Response
{
  "package_credits": 1000,
  "topup_credits": 500,
  "total": 1500,
  "package_reset_at": "2026-07-01T00:00:00Z"
}
POST/api/v1/ai/credits/device-topupTopup Credits

Create a device credit topup request. System will generate an order for credit topup.

Headers
AuthorizationBearer <jwt_token>
Content-Typeapplication/json
Request Body
{
  "device_id": "uuid-device",
  "amount": 50000
}
Response
{
  "id": "uuid-order",
  "device_id": "uuid-device",
  "amount": 50000,
  "status": "pending",
  "created_at": "2026-06-01T10:00:00Z"
}
GET/api/v1/ai/credits/device-ordersTopup History

Get device credit topup request history. Supports pagination via page & limit.

Admins can view all orders at GET /api/v1/admin/ai/credits/device-orders.
Headers
AuthorizationBearer <jwt_token>
Response
{
  "data": [
    {
      "id": "uuid",
      "amount": 50000,
      "status": "paid",
      "created_at": "2026-06-01T10:00:00Z"
    }
  ],
  "total": 1,
  "page": 1,
  "limit": 20
}
GET/api/v1/media/{messageId}Download Media

Download media file (image/video) from a WhatsApp message. This endpoint re-downloads from WhatsApp in real-time.

Device must be connected. Media can only be downloaded within 30 days after being sent on WhatsApp.

Device Groups

Manage device groups to organize devices and create API keys scoped to specific groups.

POST/api/v1/device-groupsCreate Device Group

Create a new group to organize WhatsApp devices. Groups help manage API keys scoped to specific devices.

Headers
AuthorizationBearer <jwt_token>
Content-Typeapplication/json
Request Body
{
  "name": "Marketing Team"
}
Response
{
  "id": "uuid",
  "name": "Marketing Team",
  "created_at": "2026-06-01T10:00:00Z"
}
GET/api/v1/device-groupsList Device Groups

Get all created device groups.

Headers
AuthorizationBearer <jwt_token>
Response
{
  "data": [
    {
      "id": "uuid",
      "name": "Marketing Team",
      "created_at": "..."
    }
  ]
}
PUT/api/v1/device-groups/{id}Edit Group

Change the name of a device group.

Headers
AuthorizationBearer <jwt_token>
Content-Typeapplication/json
Request Body
{
  "name": "Nama Baru Grup"
}
Response
{
  "message": "operation_success"
}
DELETE/api/v1/device-groups/{id}Delete Group

Delete a device group. Devices in the group become ungrouped. API keys bound to the group remain with device_group_id = null.

Headers
AuthorizationBearer <jwt_token>
Response
{
  "message": "operation_success"
}
GET/api/v1/device-groups/{id}/devicesDevices in Group

Get list of device IDs in a group.

Headers
AuthorizationBearer <jwt_token>
Response
{
  "data": [
    "uuid-device-1",
    "uuid-device-2"
  ]
}
POST/api/v1/device-groups/{id}/devicesAssign Device to Group

Add a device to a group. A device can only be in one group at a time.

Headers
AuthorizationBearer <jwt_token>
Content-Typeapplication/json
Request Body
{
  "device_id": "uuid-device"
}
Response
{
  "message": "operation_success",
  "data": {
    "id": "uuid-member",
    "device_id": "uuid-device",
    "status": "active"
  }
}
DELETE/api/v1/device-groups/{id}/devices/{deviceId}Remove from Group

Remove a device from a group. Device becomes ungrouped.

Headers
AuthorizationBearer <jwt_token>
Response
{
  "message": "operation_success"
}
GET/api/v1/device-groups/{id}/api-keysGroup API Keys

Get API keys bound to a specific group. Scoped keys can only send to devices in this group.

Headers
AuthorizationBearer <jwt_token>
Response
{
  "data": [
    {
      "id": "uuid",
      "name": "Marketing Key",
      "is_active": true,
      "device_group_id": "uuid-grup"
    }
  ]
}
POST/api/v1/group-devicesAssign Device to Group (API)

Add a device to a group. Requires group_id and device_id.

Headers
x-api-key or Authorizationx-api-key dari menu API Keys atau Bearer <jwt_token>
Content-Typeapplication/json
Request Body
{
  "group_id": "uuid-group",
  "device_id": "uuid-device"
}
Response
{
  "data": {
    "id": "uuid-member",
    "device_id": "uuid-device",
    "group_id": "uuid-group",
    "status": "active"
  }
}
GET/api/v1/group-devices/{memberId}Member Status

Get device membership status in a group, including expiry and remaining days.

Headers
x-api-key or Authorizationx-api-key dari menu API Keys atau Bearer <jwt_token>
Response
{
  "id": "uuid-member",
  "device_id": "uuid-device",
  "group_id": "uuid-group",
  "status": "active",
  "expires_at": "2026-08-17T00:00:00Z",
  "remaining_days": 30
}
POST/api/v1/group-devices/{memberId}/payExtend Group

Extend the active period of a group member via QRIS payment.

Headers
x-api-key or Authorizationx-api-key dari menu API Keys atau Bearer <jwt_token>
Content-Typeapplication/json
Request Body
{}
Response
{
  "order_id": "uuid",
  "qr_string": "base64-qr",
  "payment_url": "https://...",
  "amount": 10000,
  "status": "pending"
}