Stránkovanie a synchronizácia
Zoznamy vracajú vždy jednu stránku. Táto stránka vysvetľuje obálku zoznamu, filtre, vďaka ktorým je dopytovanie a inkrementálna synchronizácia lacná, a pravidlá, ktoré držia synchronizáciu správnu. Anglická verzia: Pagination and sync.
Obálka zoznamu a jej polia
Section titled “Obálka zoznamu a jej polia”Zoznam vracia {"data": [...], "next_cursor": "...", "has_more": true}. Na poslednej stránke je next_cursor rovný null a has_more je false. Prázdny výsledok je prázdne pole, nikdy chyba. Ďalšiu stránku načítate tak, že next_cursor pošlete ako parameter cursor. Výnimkou je zoznam produktov, ktorý si drží starší tvar s next_cursor a voliteľným total a nemá has_more.
Veľkosť stránky, triedenie a kurzor
Section titled “Veľkosť stránky, triedenie a kurzor”Parameter limit prijíma 1 až 100 a predvolene je 50, iná hodnota vráti 400 INVALID_PARAMETER. Parameter sort berie jedno z polí uvedených pri koncovom bode, so znamienkom - na začiatku pre zostupné poradie, predvolene -created_at. Kurzor je nepriehľadný a viaže sa na triedenie a filtre požiadavky, ktorá ho vytvorila. S inými filtrami alebo iným triedením vráti 400 INVALID_CURSOR, preto pri listovaní držte všetky parametre rovnaké a meňte len cursor.
Dopytovanie nových záznamov cez created_after
Section titled “Dopytovanie nových záznamov cez created_after”Parameter created_after vráti záznamy vytvorené v danom okamihu alebo neskôr, vo formáte ISO 8601 (napríklad 2026-10-11T08:00:00Z, samotný dátum alebo dátum a čas bez pásma sa berie ako UTC). Hranica je vrátane, takže najnovší záznam, ktorý už máte, príde ešte raz. Vždy preto deduplikujte podľa id. Zoraďte vzostupne cez sort=created_at, aby nový záznam nikdy neposunul stránky, ktoré ste ešte nečítali.
Synchronizácia zmien cez updated_since
Section titled “Synchronizácia zmien cez updated_since”Parameter updated_since vráti záznamy zmenené v danom okamihu alebo neskôr, čo je presne to, čo potrebuje inkrementálna synchronizácia. Zoraďte podľa updated_at vzostupne, zapamätajte si najväčšie updated_at, ktoré ste spracovali, a použite ho ako ďalšie updated_since. Zdroj bez updated_at tento parameter odmietne s 400 UNSUPPORTED_FILTER. Filter vypisuje záznamy, ktoré ešte existujú, preto odstránenia zachytávajte webhookmi, napríklad lead.archived, alebo občas urobte úplné prečítanie.
Deduplikácia podľa id
Section titled “Deduplikácia podľa id”Každý zdroj má stabilné id (UUID, produkty majú uuid). Berte čítanie ako upsert podľa id: ten istý záznam sa môže legitímne objaviť dvakrát, raz na hranici dvoch synchronizácií a raz po úprave. Aj doručenia webhookov sú aspoň raz, a ich obálka nesie stabilné id udalosti na rovnaký účel (pozri Webhooky).
Inkrementálna synchronizácia v Node.js
Section titled “Inkrementálna synchronizácia v Node.js”Ukážka prečíta všetky leady zmenené od kontrolného bodu a vráti nový kontrolný bod. Potrebuje Node.js 18 alebo novší a oprávnenie leads:read.
const BASE = "https://api.dakoty.com/api/v1/public";const headers = { Authorization: `Bearer ${process.env.DAKOTY_API_KEY}` };
async function* listAll(path, params = {}) { let cursor = null; do { const qs = new URLSearchParams({ limit: "100", ...params }); if (cursor) qs.set("cursor", cursor); const res = await fetch(`${BASE}${path}?${qs}`, { headers }); if (!res.ok) throw new Error(`${res.status} ${await res.text()}`); const page = await res.json(); yield* page.data; cursor = page.has_more ? page.next_cursor : null; } while (cursor);}
export async function syncLeads(checkpoint, store) { let latest = checkpoint; for await (const lead of listAll("/leads", { updated_since: checkpoint, sort: "updated_at" })) { store.set(lead.id, lead); if (lead.updated_at && lead.updated_at > latest) latest = lead.updated_at; } return latest;}Inkrementálna synchronizácia v Pythone
Section titled “Inkrementálna synchronizácia v Pythone”Rovnaká slučka s balíkom requests. Parametre params nemeňte medzi stránkami, inak kurzor prestane platiť.
import osimport requests
BASE = "https://api.dakoty.com/api/v1/public"HEADERS = {"Authorization": f"Bearer {os.environ['DAKOTY_API_KEY']}"}
def list_all(path, **params): cursor = None while True: query = {"limit": 100, **params} if cursor: query["cursor"] = cursor r = requests.get(BASE + path, headers=HEADERS, params=query, timeout=30) r.raise_for_status() page = r.json() yield from page["data"] if not page["has_more"]: return cursor = page["next_cursor"]
def sync_leads(checkpoint, store): latest = checkpoint for lead in list_all("/leads", updated_since=checkpoint, sort="updated_at"): store[lead["id"]] = lead latest = max(latest, lead["updated_at"] or latest) return latestPresné vyhľadanie cez find koncové body
Section titled “Presné vyhľadanie cez find koncové body”Ak chcete pred vytvorením zistiť, či záznam už existuje, použite koncové body /find pre firmy, kontakty, leady a faktúry. Hľadajú presnú zhodu, vyžadujú aspoň jeden parameter dopytu (pri firmách napríklad registration_id, email alebo phone) a pri žiadnej zhode vrátia prázdny zoznam. Vytvorenie leadu vie deduplikovať aj samo cez dedupe=company, pozri referenciu API.