Sync API (1.0.0)

Download OpenAPI specification:Download

Kontent.ai Support: support@kontent.ai License: MIT Terms of Service

About Sync API

Sync API is a secure REST API that provides read-only access to your Kontent.ai project.

Use Sync API to keep content in your apps up to date. Sync API lets you know if your content items changed in Delivery API or Delivery Preview API.

Early access availability

Sync API is currently provided through an early access program. This means the API capabilities might change in the future.

To activate Sync API for your subscription, contact our support or your Customer Success Manager.

Why use Sync API?

Use Sync API to update content in your apps. Sync API can be especially useful if you need to:

  • Keep content synchronization async. If your app gets offline from time to time, you can fetch and process updates when online.
  • Filter the type of synchronized content. Want to know about changes in specific items? Provide their types when you initialize the content synchronization.
  • React to content changes in your own time. Need to update your search index with latest changes once or twice a day? Synchronize the changes in an interval that suits you best.

Sync API compared to webhooks

Both webhooks and Sync API are tools you can use to react to changes in your live and preview content. You can use them together or separately.

Webhooks give you real-time notifications about changes in your content items. Webhooks are great if you need immediate updates. For example, when reporting latest news or advancements in a sports match. However, immediate updates also mean your app needs to be always available to process those updates quickly.

Sync API gives you a list of recently changed content items. These can be changes to any content item in any language or just a specific type of localized content.

Authentication

Bearer authentication

Sync API is built on top of Delivery REST API. If you enable secure access for Delivery REST API or want to sync changes in preview content, you need to authenticate your synchronization requests with a shared Delivery API key.

If your use case requires authentication, send your sync requests over HTTPS and use the Authorization header in the following format: Authorization: Bearer <YOUR_API_KEY>. To get your API key, go to Kontent.ai > Project settings > API keys. Requests with an incorrect or missing Authorization header will fail with an error.

Security Scheme Type: HTTP
HTTP Authorization Scheme bearer
Bearer format: "<YOUR_API_KEY>"

Postman collection

Try the Kontent.ai APIs with Postman! 📫 The Postman collection is regularly updated and contains endpoints for all Kontent.ai APIs, just like you see in the API references.

API limitations

API requests limit

Sync API works on top of Delivery API.

  • Sync requests for changes in live content, i.e., Delivery API, count towards the overall API Calls limit set in our Fair Use Policy.
  • Sync requests for changes in preview content, i.e., Delivery Preview API, do NOT count towards the API Calls limit.

Rate limitation

Rate limits specify the number of requests you can make to Sync API within a specific time window.

For cached requests served from our CDN, we don't enforce any rate limits. These are repeated requests for cached data. You can make an unlimited number of requests to the CDN.

For uncached requests that reach Sync API, we enforce a rate limitation of 100 requests per second and 2000 requests per minute. These are unique requests for uncached data.

When you reach the rate limit, the API rejects the request and responds with a 429 HTTP error. This error comes with the Retry-After header that tells you how many seconds you need to wait before retrying your request. Each failed request is perfectly safe to retry. If you begin to receive 429 errors, reduce the frequency of your requests.

Errors

The API returns standard HTTP status codes to indicate the success or failure of a request. In general, status codes in the 2xx range indicate a successful request, status codes in the 4xx range indicate errors caused by an incorrect input (for example, providing incorrect API key), and status codes in the 5xx range indicate an error on our side.

HTTP status codes summary

Status code Description
400 Bad Request The request was not understood. Check your request for a missing required parameter or an invalid query parameter value.
401 Unauthorized The provided API key expired, is in the wrong format, or is missing. Try copying and using the current API key for your project.
403 Forbidden The provided API key is valid but doesn't provide permission for the specified resource.
404 Not Found The requested resource doesn't exist. Try checking the resource name for typos.
405 Method Not Allowed The requested HTTP method is not supported for the specified resource.
429 Too Many Requests The rate limit for the API has been exceeded. Try your request again after a few seconds as specified in the Retry-After header.
5xx Internal Error or Service Unavailable Something went wrong on our side. Try your request again after a few seconds and use a retry policy.

Resolving errors

For troubleshooting failed requests, the API provides error messages defined in a consumable format to help you identify and fix the issue.

Error object in Delivery API.

message
required
string

The error message explaining what caused the error.

request_id
string or null

The performed request's unique ID.

error_code
integer <int32> [ 1 .. 500 ]

The internal error code for the type of error. Used for finding patterns among error requests.

specific_code
integer <int32>

Only useful for finding reasons behind failed requests in specific cases.

{
  • "message": "The continuation token specified in the 'X-Continuation' request header is malformed.",
  • "request_id": "d9b4b4e4750ee210",
  • "error_code": 107,
  • "specific_code": 0
}

If you cannot identify and resolve an issue with your API call, you can contact us with the response status and the request ID you get in the error response.

Filtering

When initializing content synchronization, you can filter the content you want to synchronize by language, content type, and collection.

Filtering operators

For filtering by content types and collections, you can use any of the following filtering operators. For filtering by language, only the equal sign operator (=) is allowed. The filtering operators are case-sensitive.

Operator Description Example
Equals to [eq] and = Property value is equal to the specified operator value. language=en-US system.type[eq]=article system.collection[eq]=default
Doesn't equal to [neq] Property value doesn't equal the specified operator value. system.type[neq]=article system.collection[neq]=default
Matches one from the list [in] Property value equals to one of the values in the specified list of values. system.type[in]=article,post system.collection[in]=global,campaigns
Matches none from the list [nin] Property value doesn't equal to any of the values in the specified list of values. system.type[nin]=home,page system.collection[nin]=global,campaigns

Synchronization

When you synchronize changes, you get a list of delta updates for each content item that had been changed or deleted since last synchronization. A delta update is similar to a webhook notification, it provides metadata about the changed content item, not the content item itself.

How to sync changes

Synchronize recent changes in your content items by following these steps:

  1. Initialize a content synchronization. When initializing, you can specify the content types, collections, and the language of the content items you want to sync.
  2. Store the X-Continuation token from the initialization response. This token identifies your content synchronization and its parameters.
  3. Get delta updates and process them.
    1. Synchronize recent changes using the X-Continuation token.
    2. Process the changes.
    3. Store the X-Continuation token from the sync response.
  4. Repeat step 3 until you get an empty sync response.

When there aren't any more changes to synchronize, you should wait a while before synchronizing again (step 3). The wait time depends on your use case. It can be five minutes, an hour, or a day.

Content item delta object

Metadata specifying a content item in a specific language and the time of the item's last change.

codename
string [ 1 .. 60 ] characters

The content item's codename.

id
string <uuid>

The content item's internal ID.

type
string [ 1 .. 60 ] characters

The content item's type codename.

language
string

The codename of the language that the content is in.

Check details on how to get content in different languages.

collection
string

The content item's collection codename. For projects without collections enabled, the value is default.

change_type
string

Determines whether the content item was modified or deleted since the last synchronization.

Enum: Description
changed

The content item was added or modified in Delivery API.

deleted

The content item was deleted from Delivery API.

timestamp
string <date-time>

ISO-8601 formatted date and time in UTC of the last change to the content item. The timestamp identifies when the change occurred in Delivery API.

{
  • "codename": "my_article",
  • "id": "335d17ac-b6ba-4c6a-ae31-23c1193215cb",
  • "type": "article",
  • "language": "en-US",
  • "collection": "default",
  • "change_type": "changed",
  • "timestamp": "2022-10-20T13:03:06.1310204Z"
}

Initialize content synchronization

post/{project_id}/sync/init

Initializes synchronization of changes in content items based on the specified parameters. After the initialization, you'll get an X-Continuation token in the response. Use the token to synchronize changes in the content items matching the initialization criteria.

If you don't specify any initialization parameters, content synchronization will be initialized for all content items in all languages in the specified project.

SecurityBearer authentication
Request
path Parameters
project_id
required
string

Identifies your project.

If you're using environments, the project ID becomes environment ID and specifies one of the project's environments.

Example: 975bf280-fd91-488c-994c-2f04416e5ee3
query Parameters
system.type
string

Specifies the content types of the content items you want to sync. The content types are specified using their codenames. Check the available filtering operators you can use.

If the content type codename is changed after the initialization, you need to initialize a new sync. For example, if you sync changes for items based on the type article and the type codename is later renamed to news_article, there won't be any content items based on the type article anymore. In such case, the API returns an empty response.

Example: system.type=article
system.collection
string

Specifies the collections of the content items you want to sync. The collections are specified using their codenames. Check the available filtering operators you can use.

If you filter your sync to a specific collection, content items moved outside that collection won't appear in API response. For example, if you sync changes for items in the Default collection and a content item moves to an other collection, the content item is no longer in the Default collection and doesn't match the initial sync criteria.

Example: system.collection=article
language
string

Determines the language of content items you want to sync. Language is specified using its codename. If you omit language, the synchronization is initialized for content items in all languages.

Sync API follows language fallbacks as configured in the Localization settings of your project. This means the API might return changes in content items outside the specified language. For example, when you sync content items in Spanish and the Spanish language falls back to English, you can get changes for English content items if some of the content items aren't translated to Spanish yet.

Example: language=en-US
Responses
200

Content synchronization was initialized.

400

The provided continuation token is invalid.

Request samples
curl --request POST \
  --url https://deliver.kontent.ai/<YOUR_PROJECT_ID>/sync/init
Response samples
application/json
{
  • "items": [ ]
}

Synchronize changes in content items

get/{project_id}/sync

Retrieve a list of delta updates to recently changed content items in the specified project. The types of items you get is determined by the X-Continuation token you use.

SecurityBearer authentication
Request
path Parameters
project_id
required
string

Identifies your project.

If you're using environments, the project ID becomes environment ID and specifies one of the project's environments.

Example: 975bf280-fd91-488c-994c-2f04416e5ee3
header Parameters
X-Continuation
required
string

Determines which content changes to synchronize next. You get a new X-Continuation token every time you initialize a content synchronization or synchronize recent changes.

Example: eyJwcm9qZWN0X2lkIjoiNGE4YjQ0ZmEtNzg1Yy0wMGFlLTRkNWMtMDI5ZGU3NDI4Y2FiIiwidGltZXN0YW1wIjoiMjAyMi0xMC0yMFQwOTo1MzozMC4wMTA3MjAxWiIsImZpbHRlciI6IiIsInZlcnNpb24iOiIxLjAifQ==
Responses
200

Delta updates of content items that changed since the previous sync

400

The provided continuation token is invalid.

Request samples
// Tip: Find more about JS/TS SDKs at https://kontent.ai/learn/javascript
const KontentDelivery = require('@kontent-ai/delivery-sdk');

const deliveryClient = KontentDelivery.createDeliveryClient({
  projectId: '<YOUR_PROJECT_ID>'
});

const response = await deliveryClient.syncChanges().toPromise();

// Store the X-Continuation token in a persistent storage for later use
const continuationToken = response.xContinuationToken;

for (const item of response.data.items) {
  if (item.changeType === "changed") {
    // Add logic for case when a content item is changed
  } else if (item.changeType === "deleted") {
    // Add logic for case when a content item is deleted
  }
}

// Synchronize the next batch of changes
const nextResponse = await deliveryClient.syncChanges().withContinuationToken(continuationToken).toPromise();
Response samples
application/json
{
  • "items": [
    • {
      • "codename": "hello_world",
      • "id": "7adfb82a-1386-4228-bcc2-45073a0355f6",
      • "type": "article",
      • "language": "default",
      • "collection": "default",
      • "change_type": "changed",
      • "timestamp": "2022-10-06T08:38:40.0088127Z"
      },
    • {
      • "codename": "bye__world",
      • "id": "42a3cfbd-4967-43e7-987b-e1e69c483e26",
      • "type": "article",
      • "language": "default",
      • "collection": "default",
      • "change_type": "deleted",
      • "timestamp": "2022-10-06T08:38:47.3613558Z"
      }
    ]
}