Java SDK
The official Java SDK for Sent provides a robust, enterprise-ready client with full support for synchronous and asynchronous operations. Built for Spring Boot, Jakarta EE, and standalone applications with builder patterns throughout.
Requirements
This library requires Java 8 or later.
Installation
<dependency>
<groupId>dm.sent</groupId>
<artifactId>sent-dm-java</artifactId>
<version>0.6.0</version>
</dependency>implementation("dm.sent:sent-dm-java:0.6.0")Quick Start
Initialize the client
import dm.sent.client.SentDmClient;
import dm.sent.client.okhttp.SentDmOkHttpClient;
// Configures using the `sentdm.apiKey` system property
// Or configures using the `SENT_DM_API_KEY` environment variable
SentDmClient client = SentDmOkHttpClient.fromEnv();Send your first message
import dm.sent.client.SentDmClient;
import dm.sent.client.okhttp.SentDmOkHttpClient;
import dm.sent.core.JsonValue;
import dm.sent.models.messages.MessageSendParams;
SentDmClient client = SentDmOkHttpClient.fromEnv();
MessageSendParams params = MessageSendParams.builder()
.addTo("+1234567890")
.addChannel("sms")
.addChannel("whatsapp")
.template(MessageSendParams.Template.builder()
.id("7ba7b820-9dad-11d1-80b4-00c04fd430c8")
.name("order_confirmation")
.parameters(MessageSendParams.Template.Parameters.builder()
.putAdditionalProperty("name", JsonValue.from("John Doe"))
.putAdditionalProperty("order_id", JsonValue.from("12345"))
.build())
.build())
.build();
var response = client.messages().send(params);
System.out.println("Sent: " + response.data().messages().get(0).id());
System.out.println("Status: " + response.data().messages().get(0).status());Client configuration
Configure the client using system properties or environment variables:
| Setter | System property | Environment variable | Required | Default value |
|---|---|---|---|---|
apiKey | sentdm.apiKey | SENT_DM_API_KEY | true | - |
baseUrl | sentdm.baseUrl | SENT_DM_BASE_URL | true | "https://api.sent.dm" |
System properties take precedence over environment variables.
import dm.sent.client.SentDmClient;
import dm.sent.client.okhttp.SentDmOkHttpClient;
// From environment variables
SentDmClient client = SentDmOkHttpClient.fromEnv();
// Or manually configure
SentDmClient client = SentDmOkHttpClient.builder()
.apiKey("your_api_key")
.build();
// Or combine both approaches
SentDmClient client = SentDmOkHttpClient.builder()
.fromEnv()
.apiKey("overridden_api_key")
.build();Don't create more than one client in the same application. Each client has a connection pool and thread pools, which are more efficient to share between requests.
Send Messages
Send a message
import dm.sent.core.JsonValue;
import dm.sent.models.messages.MessageSendParams;
import dm.sent.models.messages.MessageSendResponse;
MessageSendParams params = MessageSendParams.builder()
.addTo("+1234567890")
.addChannel("sms")
.addChannel("whatsapp")
.template(MessageSendParams.Template.builder()
.id("7ba7b820-9dad-11d1-80b4-00c04fd430c8")
.name("order_confirmation")
.parameters(MessageSendParams.Template.Parameters.builder()
.putAdditionalProperty("name", JsonValue.from("John Doe"))
.putAdditionalProperty("order_id", JsonValue.from("12345"))
.build())
.build())
.build();
MessageSendResponse response = client.messages().send(params);
System.out.println("Message ID: " + response.data().messages().get(0).id());
System.out.println("Status: " + response.data().messages().get(0).status());Test mode
Use testMode(true) to validate requests without sending real messages:
MessageSendParams params = MessageSendParams.builder()
.addTo("+1234567890")
.template(MessageSendParams.Template.builder()
.id("7ba7b820-9dad-11d1-80b4-00c04fd430c8")
.name("order_confirmation")
.build())
.testMode(true) // Validates but doesn't send
.build();
MessageSendResponse response = client.messages().send(params);
// Response will have test data
System.out.println("Validation passed: " + response.data().messages().get(0).id());Asynchronous execution
The default client is synchronous. To switch to asynchronous execution, call the async() method:
import dm.sent.client.SentDmClient;
import dm.sent.client.okhttp.SentDmOkHttpClient;
import java.util.concurrent.CompletableFuture;
SentDmClient client = SentDmOkHttpClient.fromEnv();
MessageSendParams params = MessageSendParams.builder()
.addTo("+1234567890")
.template(MessageSendParams.Template.builder()
.id("7ba7b820-9dad-11d1-80b4-00c04fd430c8")
.build())
.build();
CompletableFuture future = client.async().messages().send(params);
// Handle result
future.thenAccept(response -> {
System.out.println("Sent: " + response.data().messages().get(0).id());
}).exceptionally(throwable -> {
System.err.println("Failed: " + throwable.getMessage());
return null;
});Or create an asynchronous client from the beginning:
import dm.sent.client.SentDmClientAsync;
import dm.sent.client.okhttp.SentDmOkHttpClientAsync;
SentDmClientAsync client = SentDmOkHttpClientAsync.fromEnv();
CompletableFuture future = client.messages().send(params);Error handling
When the API returns a non-success status code, a subclass of SentDmException will be thrown:
| Status | Exception |
|---|---|
| 400 | BadRequestException |
| 401 | AuthenticationException |
| 403 | PermissionDeniedException |
| 404 | NotFoundException |
| 422 | UnprocessableEntityException |
| 429 | RateLimitException |
| >=500 | InternalServerException |
try {
var response = client.messages().send(params);
System.out.println("Sent: " + response.data().messages().get(0).id());
} catch (NotFoundException e) {
System.err.println("Contact or template not found: " + e.getMessage());
} catch (RateLimitException e) {
System.err.println("Rate limited. Retry after: " + e.retryAfter());
} catch (AuthenticationException e) {
System.err.println("Authentication failed - check API key");
} catch (SentDmException e) {
System.err.println("Error: " + e.getMessage());
}Raw responses
To access response headers, status code, or raw body, prefix any HTTP method call with withRawResponse():
import dm.sent.core.http.Headers;
import dm.sent.core.http.HttpResponse;
var response = client.withRawResponse().messages().send(params);
var statusCode = response.statusCode();
var headers = response.headers();
// Deserialize if needed
var deserialized = response.body().deserialize();Contacts
Create and manage contacts:
import dm.sent.models.contacts.ContactCreateParams;
// Create a contact
ContactCreateParams createParams = ContactCreateParams.builder()
.phoneNumber("+1234567890")
.build();
var contact = client.contacts().create(createParams);
System.out.println("Contact ID: " + contact.data().id());
// List contacts
import dm.sent.models.contacts.ContactListParams;
ContactListParams listParams = ContactListParams.builder()
.limit(100)
.build();
var contacts = client.contacts().list(listParams);
for (var c : contacts.data().data()) {
System.out.println(c.phoneNumber() + " - " + c.availableChannels());
}
// Get a contact
var contact = client.contacts().get("contact-uuid");
// Update a contact
import dm.sent.models.contacts.ContactUpdateParams;
ContactUpdateParams updateParams = ContactUpdateParams.builder()
.phoneNumber("+1987654321")
.build();
var updated = client.contacts().update("contact-uuid", updateParams);
// Delete a contact
client.contacts().delete("contact-uuid");Templates
List and retrieve templates:
// List templates
var templates = client.templates().list();
for (var template : templates.data().data()) {
System.out.println(template.name() + " (" + template.status() + "): " + template.id());
}
// Get a specific template
var template = client.templates().get("template-uuid");
System.out.println("Name: " + template.data().name());
System.out.println("Status: " + template.data().status());Spring Boot Integration
Configuration
// config/SentConfig.java
package com.example.config;
import dm.sent.client.SentDmClient;
import dm.sent.client.okhttp.SentDmOkHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SentConfig {
@Bean
public SentDmClient sentClient(@Value("${sent.api-key}") String apiKey) {
return SentDmOkHttpClient.builder()
.apiKey(apiKey)
.build();
}
}# application.yml
sent:
api-key: ${SENT_DM_API_KEY}Service Layer
// service/MessageService.java
package com.example.service;
import dm.sent.client.SentDmClient;
import dm.sent.core.JsonValue;
import dm.sent.models.messages.MessageSendParams;
import org.springframework.stereotype.Service;
@Service
public class MessageService {
private final SentDmClient sentClient;
public MessageService(SentDmClient sentClient) {
this.sentClient = sentClient;
}
public void sendWelcomeMessage(String phoneNumber, String name) {
MessageSendParams params = MessageSendParams.builder()
.addTo(phoneNumber)
.template(MessageSendParams.Template.builder()
.id("welcome-template")
.name("welcome")
.parameters(MessageSendParams.Template.Parameters.builder()
.putAdditionalProperty("name", JsonValue.from(name))
.build())
.build())
.build();
var response = sentClient.messages().send(params);
System.out.println("Sent: " + response.data().messages().get(0).id());
}
}Client customization
To temporarily use a modified client configuration, while reusing the same connection and thread pools, call withOptions():
import dm.sent.client.SentDmClient;
SentDmClient clientWithOptions = client.withOptions(optionsBuilder -> {
optionsBuilder.baseUrl("https://example.com");
optionsBuilder.maxRetries(5);
});The withOptions() method does not affect the original client.
Immutability
Each class in the SDK has an associated builder for constructing it. Each class is immutable once constructed. If the class has an associated builder, then it has a toBuilder() method for making a modified copy.
MessageSendParams params = MessageSendParams.builder()
.addTo("+1234567890")
.template(MessageSendParams.Template.builder()
.id("template-id")
.build())
.build();
// Create a modified copy
MessageSendParams modified = params.toBuilder()
.addTo("+0987654321")
.build();Source & Issues
- Version: 0.6.0
- GitHub: sentdm/sent-dm-java
- Maven Central: dm.sent:sent-dm-java
- Javadoc: javadoc.io
- Issues: Report a bug
Getting Help
- Documentation: API Reference
- Troubleshooting: Common Issues
- Support: Email support@sent.dm with your request ID