---
title: "SyncStack"
description: "SyncStack"
url: "https://www.contentstack.com/docs/developers/sdks/content-delivery-sdk/java/reference/syncstack"
product: "Contentstack"
doc_type: "guide"
audience:
  - developers
  - admins
version: "current"
last_updated: "2026-11-13"
---

# SyncStack

## SyncStack

The Sync API delivers the published content of a stack, then only the changes since your last sync. The SyncStack class holds one response of that API. Use this class to

*   read the items of one sync batch
*   request the next batch with the pagination token
*   store the sync token for the next subsequent sync

Every sync method of the [Stack](/docs/developers/sdks/content-delivery-sdk/java/reference/stack) class passes a SyncStack to the onCompletion(SyncStack syncStack, Error error) method of your SyncResultCallBack. On success, error is null. On failure, syncStack is null. See the [Callbacks](/docs/developers/sdks/content-delivery-sdk/java/reference/callbacks) class page for the callback signature.

## getCount

getCount returns the total\_count value of this sync response.

```
Returns: int. The response's total_count value.
ValidationThere is no client-side validation. getCount reads a value that the SDK stored when the response arrived.getCount returns 0 when the response has no total_count key.BehaviorClient-side only. getCount sends no request.getCount returns the total_count value of the response body that the sync method received.See Which values each sync call fills on the SyncStack class page for the keys each response holds.ExampleBasic usage: print the total_count value of a sync responseimport com.contentstack.sdk.Contentstack;
import com.contentstack.sdk.Error;
import com.contentstack.sdk.Stack;
import com.contentstack.sdk.SyncResultCallBack;
import com.contentstack.sdk.SyncStack;

public class PrintCountValue {
    public static void main(String[] args) throws IllegalAccessException {
        Stack stack = Contentstack.stack("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

        stack.sync(new SyncResultCallBack() {
            @Override
            public void onCompletion(SyncStack syncStack, Error error) {
                if (error != null) {
                    // The API rejected the request, or it did not complete
                    System.out.println("Request failed: " + error.getErrorCode() + " " + error.getErrorMessage());
                    return;
                }
                System.out.println("total_count: " + syncStack.getCount());
            }
        });
    }
}
```

## getItems

getItems returns the items of this sync response, one JSON object per item.

```
Returns: List<JSONObject>. The items of this sync response.
ValidationThere is no client-side validation. getItems reads a value that the SDK stored when the response arrived.On a SyncStack that a sync callback receives, getItems never returns null. It returns an empty list when the response has no items key.BehaviorClient-side only. getItems sends no request.The list holds the items array of the response, the batch that Initial Sync, Sync using pagination token or Subsequent Sync returns.The SDK copies each item into a new JSONObject. In the top-level string values of the copy, it replaces <script> with &lt;script&gt; and </script> with &lt;/script&gt;, in any letter case. Nested objects keep their original text. getJSONResponse returns the response without this change.The list holds one batch only. Use getPaginationToken to request the next batch.ExampleBasic usage: print each item of the first batchimport com.contentstack.sdk.Contentstack;
import com.contentstack.sdk.Error;
import com.contentstack.sdk.Stack;
import com.contentstack.sdk.SyncResultCallBack;
import com.contentstack.sdk.SyncStack;
import org.json.JSONObject;

import java.util.List;

public class PrintSyncItems {
    public static void main(String[] args) throws IllegalAccessException {
        Stack stack = Contentstack.stack("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

        stack.sync(new SyncResultCallBack() {
            @Override
            public void onCompletion(SyncStack syncStack, Error error) {
                if (error != null) {
                    // The API rejected the request, or it did not complete
                    System.out.println("Request failed: " + error.getErrorCode() + " " + error.getErrorMessage());
                    return;
                }
                List<JSONObject> items = syncStack.getItems();
                System.out.println(items.size() + " items in this batch");
                for (JSONObject item : items) {
                    System.out.println(item.toString());
                }
            }
        });
    }
}
```

## getJSONResponse

getJSONResponse returns the whole body of this sync response.

```
Returns: JSONObject. The whole sync response body.
ValidationThere is no client-side validation. getJSONResponse reads a value that the SDK stored when the response arrived.BehaviorClient-side only. getJSONResponse sends no request.The object holds every top-level key of the response, including keys that no other getter reads.IMPORTANT: Inside this object, the SDK stores nested objects as java.util.LinkedHashMap and arrays as java.util.ArrayList, not as JSONObject and JSONArray. So optJSONArray("items") and optJSONObject return null for keys that hold values. Read items with getItems, or read a nested value with get and cast it to java.util.List or java.util.Map.Top-level numbers and strings read normally with optInt and optString, and toString() prints the whole body as JSON.ExampleBasic usage: print the whole sync responseimport com.contentstack.sdk.Contentstack;
import com.contentstack.sdk.Error;
import com.contentstack.sdk.Stack;
import com.contentstack.sdk.SyncResultCallBack;
import com.contentstack.sdk.SyncStack;
import org.json.JSONObject;

public class PrintSyncResponse {
    public static void main(String[] args) throws IllegalAccessException {
        Stack stack = Contentstack.stack("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

        stack.sync(new SyncResultCallBack() {
            @Override
            public void onCompletion(SyncStack syncStack, Error error) {
                if (error != null) {
                    // The API rejected the request, or it did not complete
                    System.out.println("Request failed: " + error.getErrorCode() + " " + error.getErrorMessage());
                    return;
                }
                JSONObject body = syncStack.getJSONResponse();
                System.out.println(body.toString());
            }
        });
    }
}Edge case: nested values are Java collections, not JSON typesimport com.contentstack.sdk.Contentstack;
import com.contentstack.sdk.Error;
import com.contentstack.sdk.Stack;
import com.contentstack.sdk.SyncResultCallBack;
import com.contentstack.sdk.SyncStack;
import org.json.JSONObject;

import java.util.List;

public class ReadNestedSyncValue {
    public static void main(String[] args) throws IllegalAccessException {
        Stack stack = Contentstack.stack("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

        stack.sync(new SyncResultCallBack() {
            @Override
            public void onCompletion(SyncStack syncStack, Error error) {
                if (error != null) { System.out.println(error.getErrorMessage()); return; }
                JSONObject body = syncStack.getJSONResponse();

                // Prints null, because the SDK stores the items array as a java.util.List.
                System.out.println(body.optJSONArray("items"));

                Object items = body.opt("items");
                if (items instanceof List) {
                    System.out.println(((List<?>) items).size() + " items");
                }
            }
        });
    }
}
```

## getLimit

getLimit returns the limit value of this sync response.

```
Returns: int. The response's limit value.
ValidationThere is no client-side validation. getLimit reads a value that the SDK stored when the response arrived.getLimit returns 0 when the response has no limit key.BehaviorClient-side only. getLimit sends no request.getLimit returns the limit value of the response body that the sync method received.See Which values each sync call fills on the SyncStack class page for the keys each response holds.ExampleBasic usage: print the limit value of a sync responseimport com.contentstack.sdk.Contentstack;
import com.contentstack.sdk.Error;
import com.contentstack.sdk.Stack;
import com.contentstack.sdk.SyncResultCallBack;
import com.contentstack.sdk.SyncStack;

public class PrintLimitValue {
    public static void main(String[] args) throws IllegalAccessException {
        Stack stack = Contentstack.stack("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

        stack.sync(new SyncResultCallBack() {
            @Override
            public void onCompletion(SyncStack syncStack, Error error) {
                if (error != null) {
                    // The API rejected the request, or it did not complete
                    System.out.println("Request failed: " + error.getErrorCode() + " " + error.getErrorMessage());
                    return;
                }
                System.out.println("limit: " + syncStack.getLimit());
            }
        });
    }
}
```

## getPaginationToken

getPaginationToken returns the token that requests the next batch of this sync.

```
Returns: String. The token for the next batch.
ValidationThere is no client-side validation. getPaginationToken reads a value that the SDK stored when the response arrived.getPaginationToken returns null when the response has no pagination_token key, which marks the last batch.getPaginationToken also returns null when the token holds a character other than a letter, a digit, -, _ or .. The SDK then logs a warning through java.util.logging.BehaviorClient-side only. getPaginationToken sends no request.The API returns a pagination token when more records remain, and repeats until it returns a sync token instead, as Sync using pagination token describes.The SDK does not request the next batch. Pass the token to the syncPaginationToken method of the Stack class until getPaginationToken returns null.ExampleBasic usage: request every batch until the sync completesimport com.contentstack.sdk.Contentstack;
import com.contentstack.sdk.Error;
import com.contentstack.sdk.Stack;
import com.contentstack.sdk.SyncResultCallBack;
import com.contentstack.sdk.SyncStack;

public class SyncEveryBatch {
    public static void main(String[] args) throws IllegalAccessException {
        final Stack stack = Contentstack.stack("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

        stack.sync(new SyncResultCallBack() {
            @Override
            public void onCompletion(SyncStack syncStack, Error error) {
                if (error != null) {
                    // The API rejected the request, or it did not complete
                    System.out.println("Request failed: " + error.getErrorCode() + " " + error.getErrorMessage());
                    return;
                }
                System.out.println(syncStack.getItems().size() + " items in this batch");
                String paginationToken = syncStack.getPaginationToken();
                if (paginationToken != null) {
                    // More records remain: request the next batch with this same callback
                    stack.syncPaginationToken(paginationToken, this);
                } else {
                    System.out.println("Sync complete. Sync token: " + syncStack.getSyncToken());
                }
            }
        });
    }
}Recovery: resume an interrupted sync from a stored pagination tokenimport com.contentstack.sdk.Contentstack;
import com.contentstack.sdk.Error;
import com.contentstack.sdk.Stack;
import com.contentstack.sdk.SyncResultCallBack;
import com.contentstack.sdk.SyncStack;

public class ResumeSync {
    public static void main(String[] args) throws IllegalAccessException {
        Stack stack = Contentstack.stack("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

        stack.syncPaginationToken("<PAGINATION_TOKEN>", new SyncResultCallBack() {
            @Override
            public void onCompletion(SyncStack syncStack, Error error) {
                if (error != null) { System.out.println(error.getErrorMessage()); return; }
                System.out.println(syncStack.getItems().size() + " items in this batch");
                System.out.println("Next pagination token: " + syncStack.getPaginationToken());
            }
        });
    }
}
```

## getSkip

getSkip returns the skip value of this sync response.

```
Returns: int. The response's skip value.
ValidationThere is no client-side validation. getSkip reads a value that the SDK stored when the response arrived.getSkip returns 0 when the response has no skip key.BehaviorClient-side only. getSkip sends no request.getSkip returns the skip value of the response body that the sync method received.See Which values each sync call fills on the SyncStack class page for the keys each response holds.ExampleBasic usage: print the skip value of a sync responseimport com.contentstack.sdk.Contentstack;
import com.contentstack.sdk.Error;
import com.contentstack.sdk.Stack;
import com.contentstack.sdk.SyncResultCallBack;
import com.contentstack.sdk.SyncStack;

public class PrintSkipValue {
    public static void main(String[] args) throws IllegalAccessException {
        Stack stack = Contentstack.stack("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

        stack.sync(new SyncResultCallBack() {
            @Override
            public void onCompletion(SyncStack syncStack, Error error) {
                if (error != null) {
                    // The API rejected the request, or it did not complete
                    System.out.println("Request failed: " + error.getErrorCode() + " " + error.getErrorMessage());
                    return;
                }
                System.out.println("skip: " + syncStack.getSkip());
            }
        });
    }
}
```

## getSyncToken

getSyncToken returns the token that the next subsequent sync starts from.

```
Returns: String. The token for the next subsequent sync.
ValidationThere is no client-side validation. getSyncToken reads a value that the SDK stored when the response arrived.getSyncToken returns null when the response has no sync_token key. A response without it has more batches to follow.getSyncToken also returns null when the token holds a character other than a letter, a digit, -, _ or .. The SDK then logs a warning through java.util.logging.BehaviorClient-side only. getSyncToken sends no request.The API returns the sync token on the last batch of a sync, as Sync using pagination token describes.Store the token and pass it to the syncToken method of the Stack class later. Subsequent Sync then returns only the changes since that sync.ExampleBasic usage: store the sync token after an initial syncimport com.contentstack.sdk.Contentstack;
import com.contentstack.sdk.Error;
import com.contentstack.sdk.Stack;
import com.contentstack.sdk.SyncResultCallBack;
import com.contentstack.sdk.SyncStack;

public class StoreSyncToken {
    public static void main(String[] args) throws IllegalAccessException {
        Stack stack = Contentstack.stack("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

        stack.sync(new SyncResultCallBack() {
            @Override
            public void onCompletion(SyncStack syncStack, Error error) {
                if (error != null) {
                    // The API rejected the request, or it did not complete
                    System.out.println("Request failed: " + error.getErrorCode() + " " + error.getErrorMessage());
                    return;
                }
                String syncToken = syncStack.getSyncToken();
                if (syncToken == null) {
                    System.out.println("More batches remain. Use getPaginationToken first.");
                    return;
                }
                System.out.println("Store this sync token: " + syncToken);
            }
        });
    }
}Subsequent sync: read the changes since a stored sync tokenimport com.contentstack.sdk.Contentstack;
import com.contentstack.sdk.Error;
import com.contentstack.sdk.Stack;
import com.contentstack.sdk.SyncResultCallBack;
import com.contentstack.sdk.SyncStack;

public class SubsequentSync {
    public static void main(String[] args) throws IllegalAccessException {
        Stack stack = Contentstack.stack("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

        stack.syncToken("<SYNC_TOKEN>", new SyncResultCallBack() {
            @Override
            public void onCompletion(SyncStack syncStack, Error error) {
                if (error != null) { System.out.println(error.getErrorMessage()); return; }
                System.out.println(syncStack.getItems().size() + " changed items");
                System.out.println("New sync token: " + syncStack.getSyncToken());
            }
        });
    }
}
```

## getUrl

getUrl is meant to return the URL of the sync request.

```
Returns: String. The request URL field, which is always null.
ValidationThere is no client-side validation.BehaviorKnown issue: getUrl always returns null, because the SDK never stores the request URL. Do not rely on it. The sync methods send their requests to /v3/stacks/sync on the host of the stack.Client-side only. getUrl sends no request.ExampleBasic usage: getUrl returns nullimport com.contentstack.sdk.Contentstack;
import com.contentstack.sdk.Error;
import com.contentstack.sdk.Stack;
import com.contentstack.sdk.SyncResultCallBack;
import com.contentstack.sdk.SyncStack;

public class PrintSyncUrl {
    public static void main(String[] args) throws IllegalAccessException {
        Stack stack = Contentstack.stack("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

        stack.sync(new SyncResultCallBack() {
            @Override
            public void onCompletion(SyncStack syncStack, Error error) {
                if (error != null) {
                    // The API rejected the request, or it did not complete
                    System.out.println("Request failed: " + error.getErrorCode() + " " + error.getErrorMessage());
                    return;
                }
                // Prints null in this release.
                System.out.println(syncStack.getUrl());
            }
        });
    }
}
```

## SyncStack | Java Delivery SDK | Contentstack

The SyncStack class in the Java Delivery SDK holds one Sync API response, with its items and the pagination or sync token for the next request.