Send SMS from Spring Boot with the SendiMessage API
Spring Boot 3 uses RestClient for a compact, testable send service: property-injected key pair, JSON body, onStatus for error handling. Register it as a bean and inject it wherever domain events need to reach a customer.
A @PostMapping controller receives webhooks; verify the signature header in a filter or in the handler before applying the event.
What this integration enables
Architecture
- Your application eventAn order ships, a booking nears, a ticket updates
- Spring Boot server codeBuilds the request with credentials from the environment
- SendiMessage APIPOST /send-message returns the queued message
- Managed messaging lineSMS, or iMessage on supported lines and destinations
- Webhook eventsDelivery status and incoming replies post back to your endpoint
Example request
// application.properties:// sendimessage.key=${SENDIMESSAGE_KEY}// sendimessage.secret=${SENDIMESSAGE_SECRET}@Servicepublic class MessageService {private final RestClient client;public MessageService(@Value("${sendimessage.key}") String apiKey,@Value("${sendimessage.secret}") String apiSecret) {this.client = RestClient.builder().baseUrl("https://api.sendimessage.com/v1").defaultHeader("X-API-Key", apiKey).defaultHeader("X-API-Secret", apiSecret).build();}public Map<String, Object> send(String to, String content) {return client.post().uri("/send-message").contentType(MediaType.APPLICATION_JSON).body(Map.of("number", to, "content", content)).retrieve().onStatus(HttpStatusCode::isError, (req, res) -> {throw new IllegalStateException("SendiMessage error " + res.getStatusCode());}).body(new ParameterizedTypeReference<>() {}); // {message_handle=4e828182-…, status=QUEUED, …}}}@RestControllerclass SendiMessageWebhookController {@PostMapping("/webhooks/sendimessage")public ResponseEntity<Void> handle(@RequestBody Map<String, Object> event) {// Verify the SendiMessage-Signature header before trusting the event.return ResponseEntity.ok().build();}}
Delivery events and incoming replies
Point a Spring Boot route at your webhook URL to receive delivery status and incoming replies. Verify the signature header before processing.
// "outbound" event → your spring-boot endpoint// Verify the SendiMessage-Signature header (t={timestamp},v1=HMAC-SHA256 of// "{timestamp}.{raw body}", keyed with your webhook secret), then use// GET /v2/messages/{message_handle} for authoritative state and match it to// your contact_id in spring-boot.
Limitations and honest notes
- iMessage delivery is available on supported messaging lines and destinations. Recipients without iMessage receive SMS when fallback is configured — never assume universal iMessage availability.
- Messages are accepted asynchronously — the API returns status QUEUED and final status arrives via webhook or the message endpoints.
- No official SDK for this ecosystem yet — the example uses plain HTTP against the REST API. Official SDKs are published for JavaScript/TypeScript (npm: sendimessage), Python (PyPI: sendimessage), PHP (Composer: sendimessage/sdk), and Go (github.com/sendimessage/sendimessage-go). Every SDK is dependency-free and covers the full public API surface.
Security considerations
- Keep the API key pair in server configuration or environment variables, never in the repository.
- Verify webhook signatures before trusting delivery or reply events.
Frequently asked questions
Is there an official Spring Boot package for SendiMessage?
Can Spring Boot receive message replies?
Ready to connect Spring Boot?
Request a messaging line and a SendiMessage integration specialist will review your Spring Boot workflow and guide the setup.