WhatsApp Cloudflare API

Gowa API Documentation

Complete reference for sending WhatsApp messages via Cloudflare Pages proxy.

← API Tester

Overview

The Gowa API runs on Cloudflare Pages and proxies requests to your Coolify/Gowa WhatsApp service. All requests are authenticated server-side using environment variables.

Base URL

https://gowaapi.pages.dev/api

Do not call the Coolify/Gowa URL directly from client apps. Use the Cloudflare API only.

Authentication

Every request must include the device ID header:

X-Device-Id: YOUR_DEVICE_ID

If PUBLIC_API_KEY is configured, also include:

X-Api-Key: YOUR_PUBLIC_API_KEY

Phone Number Format

Use full WhatsApp JID format:

919876543210@s.whatsapp.net

Remove +, spaces, dashes, then add @s.whatsapp.net

POST Send Text Message

Send a plain text WhatsApp message to any contact or group.

https://gowaapi.pages.dev/api/send/message

Request Headers

HeaderRequiredValue
Content-TypeYesapplication/json
X-Device-IdYesYOUR_DEVICE_ID
X-Api-KeyIf setYOUR_PUBLIC_API_KEY

Request Body (JSON)

FieldTypeRequiredDescription
phonestringYesRecipient JID
messagestringYesText content
is_forwardedbooleanNoMark as forwarded
reply_message_idstringNoReply to message
durationnumberNoDisappearing seconds

cURL

curl -X POST "https://gowaapi.pages.dev/api/send/message" \
  -H "Content-Type: application/json" \
  -H "X-Device-Id: YOUR_DEVICE_ID" \
  -H "X-Api-Key: YOUR_PUBLIC_API_KEY" \
  -d '{
    "phone": "919876543210@s.whatsapp.net",
    "message": "Hello from API!",
    "is_forwarded": false
  }'

JavaScript (Fetch)

const res = await fetch("https://gowaapi.pages.dev/api/send/message", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-Device-Id": "YOUR_DEVICE_ID",
    "X-Api-Key": "YOUR_PUBLIC_API_KEY"
  },
  body: JSON.stringify({
    phone: "919876543210@s.whatsapp.net",
    message: "Hello from browser!",
    is_forwarded: false
  })
});
const data = await res.json();
console.log(data);

Python (requests)

import requests

res = requests.post(
    "https://gowaapi.pages.dev/api/send/message",
    headers={
        "X-Device-Id": "YOUR_DEVICE_ID",
        "X-Api-Key": "YOUR_PUBLIC_API_KEY"
    },
    json={
        "phone": "919876543210@s.whatsapp.net",
        "message": "Hello from Python!",
        "is_forwarded": False
    }
)
print(res.json())

PHP (cURL)

<?php
$payload = [
    "phone" => "919876543210@s.whatsapp.net",
    "message" => "Hello from PHP",
    "is_forwarded" => false
];
$ch = curl_init("https://gowaapi.pages.dev/api/send/message");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "Content-Type: application/json",
        "X-Device-Id: YOUR_DEVICE_ID",
        "X-Api-Key: YOUR_PUBLIC_API_KEY"
    ],
    CURLOPT_POSTFIELDS => json_encode($payload)
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;

Node.js (axios)

const axios = require("axios");

const res = await axios.post(
    "https://gowaapi.pages.dev/api/send/message",
    {
        phone: "919876543210@s.whatsapp.net",
        message: "Hello from Node.js!",
        is_forwarded: false
    },
    {
        headers: {
            "X-Device-Id": "YOUR_DEVICE_ID",
            "X-Api-Key": "YOUR_PUBLIC_API_KEY"
        }
    }
);
console.log(res.data);

React

import { useState } from "react";

function SendMessage() {
  const [phone, setPhone] = useState("919876543210@s.whatsapp.net");
  const [message, setMessage] = useState("");

  const send = async () => {
    const res = await fetch("https://gowaapi.pages.dev/api/send/message", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "X-Device-Id": "YOUR_DEVICE_ID",
        "X-Api-Key": "YOUR_PUBLIC_API_KEY"
      },
      body: JSON.stringify({ phone, message, is_forwarded: false })
    });
    const data = await res.json();
    console.log(data);
  };

  return (
    <div>
      <input value={phone} onChange={e => setPhone(e.target.value)} />
      <textarea value={message} onChange={e => setMessage(e.target.value)} />
      <button onClick={send}>Send</button>
    </div>
  );
}

Next.js API Route

// app/api/send/route.ts
export async function POST(req: Request) {
  const body = await req.json();
  const res = await fetch("https://gowaapi.pages.dev/api/send/message", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-Device-Id": process.env.GOWA_DEVICE_ID || "YOUR_DEVICE_ID",
      "X-Api-Key": process.env.PUBLIC_API_KEY || ""
    },
    body: JSON.stringify(body)
  });
  const data = await res.json();
  return Response.json(data);
}

POST Send Photo/Image

Send a photo with optional caption, compression, and view-once mode.

https://gowaapi.pages.dev/api/send/image

Request Headers

HeaderRequiredValue
X-Device-IdYesYOUR_DEVICE_ID
X-Api-KeyIf setYOUR_PUBLIC_API_KEY

Request Body (FormData)

FieldTypeRequiredDescription
phonestringYesRecipient JID
imagefileYes*Upload local file
image_urlstringYes*OR direct URL
captionstringNoImage caption
compressbooleanNoCompress media
view_oncebooleanNoView-once mode

* Either upload image file or provide image_url

cURL (Upload)

curl -X POST "https://gowaapi.pages.dev/api/send/image" \
  -H "X-Device-Id: YOUR_DEVICE_ID" \
  -H "X-Api-Key: YOUR_PUBLIC_API_KEY" \
  -F "phone=919876543210@s.whatsapp.net" \
  -F "caption=Photo caption" \
  -F "compress=false" \
  -F "view_once=false" \
  -F "is_forwarded=false" \
  -F "image=@photo.jpg"

cURL (URL)

curl -X POST "https://gowaapi.pages.dev/api/send/image" \
  -H "X-Device-Id: YOUR_DEVICE_ID" \
  -H "X-Api-Key: YOUR_PUBLIC_API_KEY" \
  -F "phone=919876543210@s.whatsapp.net" \
  -F "caption=Photo from URL" \
  -F "image_url=https://example.com/photo.jpg"

JavaScript (Browser Upload)

const form = new FormData();
form.append("phone", "919876543210@s.whatsapp.net");
form.append("caption", "My photo");
form.append("image", document.querySelector("#imageInput").files[0]);
form.append("compress", "false");
form.append("view_once", "false");

const res = await fetch("https://gowaapi.pages.dev/api/send/image", {
  method: "POST",
  headers: {
    "X-Device-Id": "YOUR_DEVICE_ID",
    "X-Api-Key": "YOUR_PUBLIC_API_KEY"
  },
  body: form
});
console.log(await res.json());

Python (requests)

import requests

data = {
    "phone": "919876543210@s.whatsapp.net",
    "caption": "Photo from Python",
    "compress": "false",
    "view_once": "false"
}

with open("photo.jpg", "rb") as f:
    files = {"image": ("photo.jpg", f, "image/jpeg")}
    res = requests.post(
        "https://gowaapi.pages.dev/api/send/image",
        data=data,
        files=files,
        headers={
            "X-Device-Id": "YOUR_DEVICE_ID",
            "X-Api-Key": "YOUR_PUBLIC_API_KEY"
        }
    )
    print(res.json())

React Component

function SendImage() {
  const [file, setFile] = useState(null);
  const [caption, setCaption] = useState("");

  const send = async () => {
    const form = new FormData();
    form.append("phone", "919876543210@s.whatsapp.net");
    form.append("caption", caption);
    form.append("image", file);

    await fetch("https://gowaapi.pages.dev/api/send/image", {
      method: "POST",
      headers: { "X-Device-Id": "YOUR_DEVICE_ID" },
      body: form
    });
  };

  return (
    <div>
      <input type="file" accept="image/*" onChange={e => setFile(e.target.files[0])} />
      <input value={caption} onChange={e => setCaption(e.target.value)} placeholder="Caption" />
      <button onClick={send}>Send Image</button>
    </div>
  );
}

POST Send Video

Send a video with caption, compression, GIF playback, and view-once options.

https://gowaapi.pages.dev/api/send/video

Request Body (FormData)

FieldTypeRequiredDescription
phonestringYesRecipient JID
videofileYes*Upload local file
video_urlstringYes*OR direct URL
captionstringNoVideo caption
compressbooleanNoCompress media
view_oncebooleanNoView-once mode
gif_playbackbooleanNoPlay as GIF

* Either upload video file or provide video_url

cURL (Upload)

curl -X POST "https://gowaapi.pages.dev/api/send/video" \
  -H "X-Device-Id: YOUR_DEVICE_ID" \
  -H "X-Api-Key: YOUR_PUBLIC_API_KEY" \
  -F "phone=919876543210@s.whatsapp.net" \
  -F "caption=Video caption" \
  -F "compress=false" \
  -F "view_once=false" \
  -F "gif_playback=false" \
  -F "is_forwarded=false" \
  -F "video=@video.mp4"

cURL (URL)

curl -X POST "https://gowaapi.pages.dev/api/send/video" \
  -H "X-Device-Id: YOUR_DEVICE_ID" \
  -H "X-Api-Key: YOUR_PUBLIC_API_KEY" \
  -F "phone=919876543210@s.whatsapp.net" \
  -F "caption=Video from URL" \
  -F "video_url=https://example.com/video.mp4"

Python (requests)

import requests

data = {
    "phone": "919876543210@s.whatsapp.net",
    "caption": "Video from Python",
    "compress": "false",
    "view_once": "false"
}

with open("video.mp4", "rb") as f:
    files = {"video": ("video.mp4", f, "video/mp4")}
    res = requests.post(
        "https://gowaapi.pages.dev/api/send/video",
        data=data,
        files=files,
        headers={
            "X-Device-Id": "YOUR_DEVICE_ID",
            "X-Api-Key": "YOUR_PUBLIC_API_KEY"
        }
    )
    print(res.json())

JavaScript (Browser)

const form = new FormData();
form.append("phone", "919876543210@s.whatsapp.net");
form.append("caption", "My video");
form.append("video", document.querySelector("#videoInput").files[0]);
form.append("compress", "false");
form.append("view_once", "false");

const res = await fetch("https://gowaapi.pages.dev/api/send/video", {
  method: "POST",
  headers: { "X-Device-Id": "YOUR_DEVICE_ID" },
  body: form
});
console.log(await res.json());

POST Send File/Document

Send any file type (PDF, DOCX, ZIP, etc.) with an optional caption.

https://gowaapi.pages.dev/api/send/file

Request Body (FormData)

FieldTypeRequiredDescription
phonestringYesRecipient JID
filefileYesDocument to send
captionstringNoFile caption
is_forwardedbooleanNoMark as forwarded
reply_message_idstringNoReply to message

cURL

curl -X POST "https://gowaapi.pages.dev/api/send/file" \
  -H "X-Device-Id: YOUR_DEVICE_ID" \
  -H "X-Api-Key: YOUR_PUBLIC_API_KEY" \
  -F "phone=919876543210@s.whatsapp.net" \
  -F "caption=Document caption" \
  -F "is_forwarded=false" \
  -F "file=@document.pdf"

Python (requests)

import requests

data = {
    "phone": "919876543210@s.whatsapp.net",
    "caption": "Document from Python"
}

with open("document.pdf", "rb") as f:
    files = {"file": ("document.pdf", f, "application/pdf")}
    res = requests.post(
        "https://gowaapi.pages.dev/api/send/file",
        data=data,
        files=files,
        headers={
            "X-Device-Id": "YOUR_DEVICE_ID",
            "X-Api-Key": "YOUR_PUBLIC_API_KEY"
        }
    )
    print(res.json())

JavaScript (Browser)

const form = new FormData();
form.append("phone", "919876543210@s.whatsapp.net");
form.append("caption", "My document");
form.append("file", document.querySelector("#fileInput").files[0]);
form.append("is_forwarded", "false");

const res = await fetch("https://gowaapi.pages.dev/api/send/file", {
  method: "POST",
  headers: { "X-Device-Id": "YOUR_DEVICE_ID" },
  body: form
});
console.log(await res.json());

GET Check Connected Devices

List all devices currently connected to your Gowa API.

https://gowaapi.pages.dev/api/devices

cURL

curl "https://gowaapi.pages.dev/api/devices" \
  -H "X-Api-Key: YOUR_PUBLIC_API_KEY"

JavaScript

const res = await fetch("https://gowaapi.pages.dev/api/devices", {
  headers: { "X-Api-Key": "YOUR_PUBLIC_API_KEY" }
});
const devices = await res.json();
console.log(devices);

Optional Fields Reference

FieldTypeApplies ToDescription
reply_message_idstringAllReply to previous message
durationnumberAllDisappearing duration (seconds)
is_forwardedbooleanAllMark as forwarded
compressbooleanImage, VideoCompress media
view_oncebooleanImage, VideoWhatsApp view-once
gif_playbackbooleanVideoPlay as GIF

Response Format

Success

{
  "status": 200,
  "body": {
    "code": "SUCCESS",
    "message": "Message sent",
    "results": {}
  }
}

Error

{
  "code": "ERROR",
  "message": "Reason for failure"
}

CORS & Limits

The Cloudflare API allows cross-origin requests from any domain. Headers permitted:

  • Content-Type
  • Accept
  • X-Device-Id
  • X-Api-Key

Cloudflare upload limits apply. For large files, prefer image_url or video_url parameters.