WAservix Spring Boot integration
Connect WAservix to your Spring Boot app: send WhatsApp messages from your own WhatsApp number, check delivery and receive replies by webhook. Copy the examples, add your key and run.
Requirements
Spring Boot 3.2+ (RestClient) with spring-boot-starter-web.
Add your API key
Create a key under WAservix → Devices → API key (it starts with wpk_). Keep it on your server, in an environment variable or secret store. Never put it in a website, a mobile app or a public repository.
# application.properties (values come from the environment)
waservix.api-key=${WASERVIX_KEY}
waservix.webhook-secret=${WASERVIX_WEBHOOK_SECRET}
Set up the client
Base URL https://tekservix.com/waservix/api. Send the key as Authorization: Bearer wpk_….
@Configuration
class WaservixConfig {
@Bean
RestClient waservixClient(@Value("${waservix.api-key}") String apiKey) {
return RestClient.builder()
.baseUrl("https://tekservix.com/waservix/api")
.defaultHeader("Authorization", "Bearer " + apiKey)
.build();
}
}
// Inject it: @Autowired RestClient restClient;
Send a WhatsApp message
Messages are queued and sent one at a time per number, so the answer comes back at once with "status": "in_progress" and a msgId.
Map<String, Object> body = Map.of("to", "+250788123456", "text", "Hello Aline, your order is ready");
String json = restClient.post()
.uri("/send-message")
.contentType(MediaType.APPLICATION_JSON)
.body(body)
.retrieve() // throws on 4xx/5xx
.body(String.class);
Send a document or image
Use imageUrl, videoUrl, audioUrl or documentUrl with a public https link. Groups work too: put the group JID (…@g.us) in to.
Map<String, Object> body = Map.of("to", "+250788123456", "text", "Your invoice", "documentUrl", "https://example.com/inv-1042.pdf", "fileName", "Invoice-1042.pdf");
String json = restClient.post()
.uri("/send-message")
.contentType(MediaType.APPLICATION_JSON)
.body(body)
.retrieve() // throws on 4xx/5xx
.body(String.class);
Check message status
status is queued, sent, delivered, read, played or failed. Webhooks tell you without polling.
String json = restClient.get()
.uri("/messages/58213/info")
.retrieve()
.body(String.class);
Receive WhatsApp messages by webhook
Set a webhook URL and events for the number under WAservix → Devices. Each request carries X-Webhook-Signature, which equals that device’s webhook secret. Compare it in constant time, answer 2xx quickly and process the message after answering (we retry 3 times).
// imports: com.fasterxml.jackson.databind.JsonNode, java.nio.charset.StandardCharsets, java.security.MessageDigest
@RestController
class WaservixWebhook {
@Value("${waservix.webhook-secret}") String secret;
@PostMapping("/webhooks/wapenda")
ResponseEntity<Void> receive(@RequestBody JsonNode event, @RequestHeader(value = "X-Webhook-Signature", required = false) String sig) {
if (sig == null || !MessageDigest.isEqual(secret.getBytes(StandardCharsets.UTF_8), sig.getBytes(StandardCharsets.UTF_8)))
return ResponseEntity.status(401).build();
if ("messages.received".equals(event.path("event").asText())) {
JsonNode m = event.path("data").path("messages");
System.out.println(m.path("key").path("cleanedSenderPn").asText() + ": " + m.path("messageBody").asText());
}
return ResponseEntity.ok().build();
}
}
Errors, limits and retries
Every answer has success; errors add a readable message. 401 means a wrong key, 402 no active plan for this number or phone, 409 the number or phone isn’t connected, 429 too many requests (300 a minute per key): wait for the Retry-After seconds and try again. Retry 5xx and network errors with a back-off, but don’t blindly retry a send that may have worked: check its status first, or you could send twice.
Full list of endpoints and fields: WAservix API reference.
Questions
Is this the official WhatsApp Business API?
No. WAservix links your own number as a companion device, like WhatsApp Web, so there is no Meta approval. Only message people who expect to hear from you: WhatsApp can ban numbers that spam.
Can I call the API from a mobile app or browser?
Don’t. Anyone could read the key from the app or page. Call the API from your server and let your app talk to your server.