What is your developer-dependent CMS actually costing you? Calculate your costs and get a full report
What is your developer-dependent CMS actually costing you? Calculate your costs and get a full report
APIs
When to use Content Sync instead of the Fetch API or GraphQL, how the sync token works, and how to run incremental syncs from webhooks with the @agility/content-sync SDK.
Agility gives you three ways to read content: the Content Fetch API (REST), the GraphQL API, and Content Sync. The first two answer a question each time you ask. Content Sync copies your content into a store you own and keeps that copy up to date, so your app reads locally instead of calling Agility.
This guide explains when to use each one, how the sync token works, and how to drive incremental syncs from webhooks. For the endpoint reference, see Content Sync API. For the JavaScript SDK, see Content Sync JS SDK.
| Content Fetch API (REST) | GraphQL API | Content Sync | |
|---|---|---|---|
| What you get | One item, list, page or sitemap per request | Exactly the fields you select, several queries in one request | Every content item and page that changed since your last sync |
| Where your app reads from | Agility, on each request (through the CDN) | Agility, on each request | Your own store (files, database, cache) |
| Filtering and sorting | filter, sort, take (max 250), skip | Same filter syntax, per list | Whatever your store supports |
| Counts towards API rate limits | Uncached requests do | Uncached requests do | Only the sync calls themselves |
| Best for | Server-rendered and statically built sites, most apps | Pulling many related lists and fields in one round trip | Offline use, very high read volume, copying content into another system |
Some rules of thumb:
You can mix them. A common pattern is Sync for a search index or cache, and the Fetch API for preview.
The Sync API is part of the Content Fetch API. It has two endpoints, one for content items and one for pages:
GET https://api.aglty.io/{guid}/{fetch|preview}/{locale}/sync/items?syncToken={token}&pageSize={n}
GET https://api.aglty.io/{guid}/{fetch|preview}/{locale}/sync/pages?syncToken={token}&pageSize={n}
Both take your APIKey header like any other Fetch API request. pageSize defaults to 500. Each response is an object with the items (or pages) in that batch and the next token. The shape (values are placeholders):
{
"items": [
{ "contentID": 0, "properties": { "state": 2, "referenceName": "..." }, "fields": { } }
],
"syncToken": 0
}
Each item has the same shape as an item from the Fetch API, so the field shapes in Field Types and What the APIs Return apply.
Use the fetch API type and a fetch key to sync published content, or preview and a preview key to sync the latest saved content for a preview environment.
The sync token is a number that marks how far through the change history you have read. Think of it as a bookmark.
syncToken=0. You get the first batch of everything, plus a new token.@agility/content-sync SDK stops as soon as the returned token is not greater than the one it sent.0. You only receive what changed since then.Things to get right:
0 as "rebuild". To start over (for example after you clear your store, or if your store and token get out of step), sync from 0 again.Sync returns removals as well as changes. An item that was deleted or unpublished comes back with properties.state set to 3 (Deleted). Remove it from your store when you see that state. The @agility/content-sync SDK does this for both content items and pages.
You don't need to poll. Let Agility tell you when something changed, then sync from your stored token:
contentID, referenceName, state, languageCode); the sync call gives you the current data, including removals.languageCode to sync only the locale that changed.Webhook delivery is at-least-once, so the same event can arrive twice. Syncing from a stored token is naturally safe here: a second sync with nothing new returns nothing. For signatures, retries and the webhook-id header, see Verifying Signed Webhooks and Webhook Events and Payload Reference.
Run a scheduled sync as well (for example nightly) as a safety net in case a webhook delivery is missed. Because it starts from your stored token, it costs almost nothing when nothing changed.
The @agility/content-sync package (version 1.2.5 at the time of writing) runs this loop for you:
npm install @agility/content-sync
import agilitySync from "@agility/content-sync"
const syncClient = agilitySync.getSyncClient({
guid: process.env.AGILITY_GUID,
apiKey: process.env.AGILITY_API_FETCH_KEY,
languages: ["en-us"],
channels: ["website"],
isPreview: false
})
await syncClient.runSync()
What runSync() does, per locale:
0 the first time) and syncs content items, then pages, 100 at a time.By default the store is the local filesystem, under .agility-files. You can plug in your own store (a database, Redis, or anything else) by implementing the store interface. See Content Sync JS SDK for the interface and for reading content back with syncClient.store. Call clearSync() to empty the store and start from scratch.
Sync from 0 again when:
With the SDK, call clearSync() and then runSync(). With your own code, clear your store and the stored tokens, then sync from 0. A full sync reads every item, so on a large instance run it outside peak hours.