Keeping a copy in sync
Load the full dataset once. After that, each request returns only what was added, changed or removed since the last one, so you never need to delete and reload everything.
The three steps
- Load everything once. Download
GET /v1/exports/conferences(gzipped JSON Lines, one record per line) and insert every record into your table, keyed byid. Save the response'sX-Sync-Tokenheader. - Ask for what changed. As often as you like (daily, hourly), call
GET /v1/conferences/changes?since=<saved token>. - Apply each entry, then save the new token. An entry with
"deleted": truemeans remove thatid; anything else is the full current record, so replace your row (insert it if it's new). Then savenext_sync_token. Ifhas_moreis true, call again straight away with it.
The same works for journals. Keep one token per dataset.
Example (Python)
import gzip, json, os, requests
API = "https://api.orbytelgroup.com/v1"
HEADERS = {"Authorization": "Bearer " + os.environ["ORBYTEL_KEY"]}
def initial_load(db):
r = requests.get(f"{API}/exports/conferences", headers=HEADERS, timeout=300)
r.raise_for_status()
for line in gzip.decompress(r.content).splitlines():
db.upsert(json.loads(line)) # keyed by record["id"]
db.save_token(r.headers["X-Sync-Token"])
def sync(db):
token = db.load_token()
while True:
r = requests.get(f"{API}/conferences/changes",
params={"since": token}, headers=HEADERS, timeout=60)
if r.status_code == 410: # license changed: start again
return initial_load(db)
r.raise_for_status()
page = r.json()
for record in page["data"]:
if record.get("deleted"):
db.delete(record["id"]) # fine if you never had it
else:
db.upsert(record)
token = page["next_sync_token"]
db.save_token(token) # after applying the page
if not page["has_more"]:
break
Good to know
- Changes appear about a minute after they're saved. The feed only hands out positions that are safely settled, so nothing is skipped.
- A record can arrive twice, for example in two consecutive syncs. Because every entry is "replace your copy with this", applying it again is harmless.
- A removal can be for a record you never had (for example one outside your license). Ignore it.
- Several changes to one record arrive as one entry, in its latest state.
- Tag and organization changes count. If a tag is added to a conference, or an organization is renamed, the affected records come back in the feed.
410 Gonemeans your license changed (for example a therapy area was added). Your copy may now hold records you're no longer licensed for, or lack new ones, so reload from/exportsand continue from its token.- No token yet?
GET /v1/conferences/changeswith no parameters returns a token for "now". - Prefer dates?
?updated_since=2026-10-19works instead ofsince, removals included. A token is still more precise, because it can't miss or repeat a boundary.
Sizes and limits
- The full conference export is about 9,000 records (a few MB compressed); journals about 3,000.
/changesreturns up to 500 records per call by default, 1,000 withlimit=1000.- A daily sync typically needs one or two requests.