Java SDK for the Bronto SOAP API, created and maintained by the Bronto Professional Services team. It is free to use, but comes with no official support. However, you may ask questions on the Dev Q&A Forum ( or contact your Account Manager to discuss a Professional Services engagement for more assistance.
Clone or download
Latest commit f73ef38 Apr 29, 2018
Failed to load latest commit information.

Bronto Java SDK

The SDK is broken up into two projects:

  • The wsimported Java models, that live in com.bronto.api.model
  • The SDK wrapper providing a convenient API for various apps

Benefits of the SDK

  • Asynchronous web service calls
  • Retry on common network errors
  • Automatic pagination with the readAll object operations
  • Chainable request building
  • Component driven object operations

Publish Locally

The project is built SBT because it is a Superior Build Tool.

> sbt
> project bronto-api
> publishLocal



Example Code


import com.bronto.api.*;
import com.bronto.api.model.*;
import static com.bronto.api.model.ObjectBuilder.newObject;

String apiToken = "<Your API token>";
BrontoApi client = new BrontoClient(apiToken);

String sessionId = client.login();

Create new Contact

ContactOperations contactOps = new ContactOperations(client);

ContactObject contact = contactOps.newObject()
  .set("email", "")
  .set("status", ContactStatus.ONBOARDING)
  .add("listIds", listId)
  .add("fields", newObject(ContactField.class)
      .set("fieldId", fieldId)
      .set("content", value).get())

try {
    WriteResult result = contactOps.add(contact);
} catch (Exception e) {
    // Handle exception

Create / Update many Contacts


Delete a contact


Read Contacts using Read Request

Option #1: Using while loop

Calendar createdThreshold = Calendar.getInstance();
createdThreshold.add(Calendar.DATE, -7);

final ContactReadRequest readContacts = new ContactReadRequest()
    .withCreated(FilterOperator.AFTER, createdThreshold.getTime())

List<ContactObject> contacts = null;
while(contacts =; !contacts.isEmpty()) {
    for (ContactObject contact: contacts) {

Option #2: Using automatic pager

for (ContactObject contact : contactOps.readAll(readContacts)) {

Read List by Name

MailListOperations listOps = new MailListOperations(client);

MailListObject list = listOps.get(new MailListReadRequest().withName("My Example List"));

Clear List(s)


Create new Field

FieldObject field = newObject(FieldObject.class)
    .set("name", "API Field")
    .set("label", "API Field Label")
    .set("visibility", FieldVisibility.PRIVATE)
    .set("type", FieldType.TEXT).get();


Get a ContentTag

ObjectOperations<ContentTagObject> contentTagOps = client.transport(ContentTagObject.class);

ContentTagObject tag = contentTagOps.get(new ContentTagReadRequest().withId("123"));

Retrieve a Message

MessageOperations messageOps = new MessageOperations(client);
MessageObject message = messageOps.get(new MessageReadRequest().withId("123"));

 * Content from Bronto's new message editor is a JSON object rather than an HTML 
 * string. Use the new MessageContentDetector class to determine what type of 
 * content you're dealing with (MessageOperations will automatically store the 
 * content as the correct type of object - this is just a helper method for 
 * altering message content via the API).
 * Also be aware that the message content is stored in both the JSON's "body" 
 * element _and_ the "ui" element. The "ui" element is what's used to re-create the 
 * message in the message editor. Failing to change the content in the "ui" element
 * will cause your changes to be lost when the message is re-opened and saved in 
 * Bronto.
 boolean isJson = MessageContentDetector.hasJsonContent(message);

Create a Delivery

ObjectOperations<DeliveryObject> deliveryOps = client.transport(DeliveryObject.class);

DeliveryRecipientObject recipient = new DeliveryRecipientObject();

DeliveryObject delivery = deliveryOps.newObject(new Date());
delivery.setFromName("Example Sender");


Read a Delivery DeliveryReadRequest().setId(delivery.getId())).get();

Read Recipients from a Delivery

ObjectOperations<DeliveryRecipientStatObject> deliveryStats = client.transport(DeliveryRecipientStatObject.class);
DeliveryRecipientReadRequest readDelivery = new DeliveryRecipientReadRequest().setId(delivery.getId());

for (DeliveryRecipientStatObject stat : deliveryStats.readAll(readDelivery)) {
    // Do something with stat

Asynchronous Operations

All calls, with the exception of login and readAll, can be made asynchronously. This means there's two deritives of an asynchronous API call:

  • The call itself, with expected arguments, returning a Future.
  • The call with the expected arguments and an AsyncHandler (see below)

Asynchronous operations are suffixed with Async, in the class name. The request building should be transferrable.

For read calls, the AsyncReadPager exists as a convenience for paging. For write calls, the AsyncWriteHandler exists as a convenience for handling success and failure cases.

In either class, you can override the onError method to handle exception cases.

Example Code

Read Contacts

BrontoApiAsync ClientAsync client = new BrontoClientAsync(apiToken, executor);
ContactOperationsAsync contactOps = new ContactOperationsAsync(client);

Calendar createdThreshold = Calendar.getInstance();
createdThreshold.add(Calendar.DATE, -7);

final ContactReadRequest readContacts = new ContactReadRequest()
    .withCreated(FilterOperator.AFTER, createdThreshold.getTime())
    .withListId(listId);, new AsyncReadPager<ContactObject>() {
    public void readObjects(List<ContactObject> contacts) {
        for (ContactObject contact : contacts) {
            System.out.println("Contact with email: " + contact.getEmail());

Add Contacts

contactOps.addOrUpdate(Arrays.asList(contact), new AsyncWriteHandler() {
    public void onSuccessItems(List<ResultItem> results) {
        for (ResultItem result : results) {
            System.out.println("Added/Updated contact with id: " + result.getId());
    public void onErrorItems(List<ResultItem> results) {
        for (ResultItem result : results) {

Transform Field into JSON

import com.fasterxml.jackson.databind.ObjectMapper;

ObjectMapper mapper = new ObjectMapper();
Future<String> json = fieldOps.get(read, new AsyncHandler<FieldObject, String>() {
    public String onSuccess(FieldObject field) {
        return mapper.writeValue(field);
    public void onError(Exception e) {


Read Conversions

ObjectOperationsAsync<ConversionObject> conversionOps =
ConversionReadRequest conversions = new ConversionReadRequest();
for (ConversionObject conversion : conversionOps.readAll(conversions)) {
    System.out.println(String.format("Conversion id: %s (email: %s) "
            + "- item = %s", conversion.getId(), conversion.getEmail(),