How to Send WhatsApp Messages from Java (No OkHttp Required)
Send WhatsApp messages from Java using the built-in java.net.http.HttpClient — no OkHttp or Retrofit dependency required. Session setup, QR auth, and production error handling.
Meta Description: Send WhatsApp messages from Java using the built-in java.net.http.HttpClient — no OkHttp or Retrofit dependency required. Session setup, QR auth, and production error handling.
Introduction
Most Java WhatsApp tutorials reach for OkHttp or Retrofit before writing a single request. You don't need either — Java 11 shipped java.net.http.HttpClient in the standard library, and the WhatsApp Messaging API is plain REST over HTTPS.
In this guide, you'll send a real WhatsApp message from Java in under 5 minutes, using nothing outside the JDK.
What you'll need:
- •Java 11+ (for
java.net.http.HttpClient) - •A RapidAPI account (free)
- •5 minutes
Let's send a message.
Step 1: Get Your API Key (30 seconds)
- 1.Go to RapidAPI Hub
- 2.Search for "Whatsapp messaging bot"
- 3.Click Subscribe (Free plan available, no card required)
- 4.Open API Settings and copy your X-RapidAPI-Key
Step 2: Create a WhatsApp Session
A session is the WhatsApp account the API sends on behalf of — create it once, then reuse it.
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse;
public class WhatsAppClient {
private static final String API_KEY = System.getenv("RAPIDAPI_KEY");
private static final String API_HOST = "whatsapp-messaging-bot.p.rapidapi.com";
private static final String BASE_URL = "https://" + API_HOST;
private static final HttpClient CLIENT = HttpClient.newHttpClient();
static HttpResponse<String> call(String method, String path, String jsonBody) throws Exception {
HttpRequest.Builder builder = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + path))
.header("x-rapidapi-key", API_KEY)
.header("x-rapidapi-host", API_HOST)
.header("Content-Type", "application/json");
builder = jsonBody != null
? builder.method(method, BodyPublishers.ofString(jsonBody))
: builder.method(method, BodyPublishers.noBody());
return CLIENT.send(builder.build(), HttpResponse.BodyHandlers.ofString());
}
public static void main(String[] args) throws Exception {
String sessionName = "my-session";
// Create the session
var created = call("POST", "/v1/sessions", "{\"name\":\"" + sessionName + "\"}");
System.out.println("Session created: " + created.body());
// Get the QR code to authenticate
var qr = call("GET", "/v1/sessions/" + sessionName + "/auth/qr", null);
System.out.println("Scan this with WhatsApp → Linked Devices:");
System.out.println(qr.body());
}
}javac WhatsAppClient.java
RAPIDAPI_KEY=your_key_here java WhatsAppClientOpen WhatsApp on your phone → Settings → Linked Devices → Link a Device, and scan the printed QR code.
Step 3: Send Your First Message
static HttpResponse<String> sendText(String chatId, String text, String session) throws Exception {
String body = String.format(
"{\"chatId\":\"%s\",\"text\":\"%s\",\"session\":\"%s\"}",
chatId, text, session
);
return call("POST", "/v1/sendText", body);
}
public static void main(String[] args) throws Exception {
var result = sendText("14155552671", "Hello from Java!", "my-session");
System.out.println(result.statusCode() == 200 || result.statusCode() == 201
? "Message sent."
: "Send failed: " + result.body());
}Check your phone — that's a real WhatsApp message sent from Java with zero external dependencies.
For production code, swap the hand-built JSON strings for a real serializer (Jackson or Gson) once your payloads get more complex than a couple of fields.
Step 4: Sending Images and Files
Same call() helper, different endpoint and payload:
static HttpResponse<String> sendImage(String chatId, String imageUrl, String caption, String session) throws Exception {
String body = String.format(
"{\"chatId\":\"%s\",\"image\":\"%s\",\"caption\":\"%s\",\"session\":\"%s\"}",
chatId, imageUrl, caption, session
);
return call("POST", "/v1/sendImage", body);
}Both sendImage and sendFile take a public URL — the API fetches and delivers it, no upload step needed on your end. Full parameter reference for every message type is in the interactive API reference.
Production Best Practices
1. Retry with backoff
static HttpResponse<String> sendWithRetry(String chatId, String text, String session, int maxRetries) throws Exception {
HttpResponse<String> result = null;
for (int attempt = 1; attempt <= maxRetries; attempt++) {
result = sendText(chatId, text, session);
if (result.statusCode() < 400) return result;
Thread.sleep(attempt * 2000L); // 2s, 4s, 6s backoff
}
return result;
}2. Reuse one HttpClient instance
HttpClient.newHttpClient() is meant to be built once and reused — it pools connections internally. Building a new client per request (a common copy-paste mistake) throws that pooling away.
3. Confirm delivery with a webhook, not the HTTP response
A 200 from /v1/sendText means "accepted," not "delivered" — a number that isn't on WhatsApp can still return success. Register a webhook and read the message.ack event for real delivery/read status:
call("POST", "/v1/sessions/" + sessionName + "/webhooks",
"{\"webhookUrl\":\"https://yourapp.com/webhooks/whatsapp\",\"events\":[\"message.ack\"]}");Troubleshooting
| Issue | Fix |
|---|---|
| 401 Unauthorized | RAPIDAPI_KEY environment variable isn't set, or the key's been rotated in the RapidAPI dashboard. |
UnsupportedOperationException on older JDKs | java.net.http.HttpClient requires Java 11+ — check with java -version. |
| QR code expires before you scan it | QR codes are short-lived — fetch it right before you're ready to scan. |
| Message accepted but never arrives | Check message.ack via webhook — a 200 only means the API accepted the send. |
Next Steps
- •WhatsApp OTP Authentication — reuse this same Java client to send login codes instead of SMS
- •Send Files, PDFs, and Documents via WhatsApp API — full MIME type reference and size limits
- •Best WhatsApp API for Startups and Indie Hackers — how this compares on price and setup time
- •Will My Number Get Banned? — the honest version of the "unofficial APIs get you banned" warning
External references:
- •java.net.http.HttpClient documentation — Oracle's official Javadoc for every class used above
- •WhatsApp Business Platform overview — Meta's official docs, for context on how the official API differs
Try Free on RapidAPI → Get your API key in 30 seconds → Send your first Java message in 5 minutes.
Ready to Get Started?
Try the WhatsApp API free on RapidAPI with no credit card required.
Try Free on RapidAPI