Preskoči na sadržaj
Sursa Developers

Sinkronizacija vašeg sustava putem vlastitog izvora

Vlastiti izvor povezuje sustav koji nema ugrađeni konektor: vaš wiki, vaš alat za prijave, bazu podataka, izvoz iz bilo kojeg mjesta. Vaš kod šalje dokumente u Sursu, a Sursa od njih stvara kartice u zbirci i mapama za koje je izvor postavljen, s istim pretraživanjem, odgovorima, provjerom i dopuštenjima kao i kartice iz bilo kojeg drugog izvora.

Za razliku od izravnog zapisivanja kartica, vlastiti izvor prati što ste poslali. Na kraju potpune sinkronizacije Sursa arhivira svaki dokument koji niste poslali, pa brisanja u vašem sustavu stižu u Sursu bez dodatnog rada.

Postavljanje izvora

Administrator stvara izvor u Sursi u Sources → New source → Custom source (izvori, novi izvor, vlastiti izvor) i odabire:

  • zbirku i, po želji, mapu za njegove kartice;
  • način rada s mapama: sve kartice u odabranoj mapi ili podmape koje zrcale path svakog dokumenta;
  • dopuštenja: dopuštenja zbirke ili način zrcaljenja („kao u izvoru”), u kojem svaki dokument navodi tko ga smije vidjeti.

Stranica izvora prikazuje njegov ID; primjeri koriste 42.

Odabir ključa

KljučPočinje sMože
Ključ izvorakbsrc_Zapisivati dokumente u ovaj jedan izvor. Ništa drugo: ne može čitati ni pretraživati. Stvorite ga na stranici izvora u odjeljku API keys.
Ključ organizacije s opsegom import:writekb_Zapisivati u bilo koji vlastiti izvor organizacije i čitati njegovo stanje. Za stvaranje izvora i njegovih ključeva potreban je opseg admin.

Ključ izvora najsigurniji je izbor za jednu integraciju, osobito onu koja radi na platformi treće strane. Ključ organizacije s opsegom import:write prikladan je za uslugu koja puni više izvora.

Oba se ključa šalju na isti način, a svaka se operacija slanja (push) nalazi unutar /v1/push/sources/{source_id}. Ključ i stanje izvora provjerite pomoću GET /v1/push/sources/{source_id}:

curl https://api.sursa.com/v1/push/sources/42 \
  -H "Authorization: Bearer $SURSA_SOURCE_KEY"
{"source_id": 42, "name": "Helpdesk articles", "documents": 1840, "open_sync": null}

Dokument

PoljeObaveznoOpis
external_iddaVaš stabilan ID dokumenta, do 512 znakova. Ponovno slanje istog ID-a zamjenjuje dokument.
titledaNaslov kartice, do 500 znakova. Za datoteku zadano ime datoteke.
contentda, osim ako postoji datotekaDo 5 MB.
content_typenehtml (zadano), markdown ili text. HTML se čisti od skripti, stilova, obrazaca i ugrađenih objekata.
urlnePoveznica na dokument u vašem sustavu, prikazuje se na kartici.
pathneMape, kao niz (["Support", "Billing"]) ili niz znakova ("Support/Billing"), do 10 razina.
permissionsne{"everyone": true} ili {"emails": [...], "groups": [...]}. Koristi se kad su dopuštenja izvora postavljena na način zrcaljenja („kao u izvoru”).
tagsneDo 50 oznaka, koje se dodaju oznakama izvora.
author_emailneAko je to korisnik organizacije, postaje vlasnik kartice.
updated_atneKad se dokument promijenio u vašem sustavu (RFC 3339).
metadataneVaši parovi ključ–vrijednost na kartici. V. Metapodaci.
categoryneKategorija kartice: ključ jedne od kategorija organizacije.
verifiers, verify_interval_daysneTko provjerava karticu (korisnici prema e-adresi i grupe) i koliko često, u danima.
upload_idneDatoteka dokumenta iz učitavanja u dijelovima, umjesto content.
attachmentsneDo 20 dodatnih datoteka dokumenta, kao popis vrijednosti upload_id. Svaka postaje zasebna kartica izvora.

Umjesto content pojedinačni dokument može nositi datoteku do 100 MB u zahtjevu multipart/form-data: datoteku u dijelu file, a gornja polja kao JSON u dijelu document. Učitavanja u dijelovima za upload_id i attachments stvaraju se ključem organizacije s opsegom import:write i namjenom import_attachment; ključ izvora ne može ih stvoriti.

Dva načina slanja

Izravna ažuriranja prikladna su za sustave koji vas obavještavaju o svakoj promjeni, kao što je webhook iz vašeg sustava za podršku ili korak u Zapieru. Pošaljite dokument kad se stvori ili promijeni, a izbrišite ga kad se ukloni:

ZahtjevŠto radi
POST /v1/push/sources/{source_id}/documentsStvara ili zamjenjuje jedan dokument.
POST /v1/push/sources/{source_id}/documents/batchStvara ili zamjenjuje mnogo dokumenata odjednom.
DELETE /v1/push/sources/{source_id}/documents/{external_id}Uklanja jedan dokument. Kodirajte ID za URL.

Promjene postaju kartice u roku od otprilike jedne minute; više uzastopnih promjena obrađuje se zajedno.

Sinkronizacije su prikladne za redovite izvoze: šaljete sve ili sve što se promijenilo, a Sursa usklađuje stanje. Ostatak ovog vodiča govori o sinkronizacijama.

Potpuna sinkronizacija

Sinkronizacija ima tri koraka: otvaranje, slanje i zatvaranje.

1. Otvorite sinkronizaciju

POST /v1/push/sources/{source_id}/syncs otvara sinkronizaciju i vraća njezin broj:

curl -X POST https://api.sursa.com/v1/push/sources/42/syncs \
  -H "Authorization: Bearer $SURSA_SOURCE_KEY" \
  -H "Idempotency-Key: sync-2026-10-24" \
  -H "Content-Type: application/json" \
  -d '{"type": "initial", "max_minutes": 180}'
{"sync_number": 7, "type": "initial", "status": "open", "opened_at": "2026-10-24T02:00:00Z",
 "expires_at": "2026-10-24T05:00:00Z", "pushed": 0, "removed": 0}
  • type je initial za prvu sinkronizaciju izvora, a incremental nakon što je neka sinkronizacija dovršena. Sinkronizacija incremental prije ijedne dovršene vraća sources.push_initial_required.
  • Istodobno može biti otvorena samo jedna sinkronizacija: druga vraća 409 sources.push_sync_open.
  • Sinkronizacija ostaje otvorena max_minutes minuta (zadano 60, najviše 1440). Nakon toga istječe: ništa se ne arhivira, a njezin se broj više ne prihvaća. Odaberite vrijeme znatno dulje od trajanja vašeg izvoza.

2. Pošaljite dokumente

Dokumente šaljite u paketima od najviše 500, s brojem sinkronizacije. Tijelo paketa može imati do 50 MiB; datoteke unutar paketa prosljeđuju se kao upload_id.

curl -X POST https://api.sursa.com/v1/push/sources/42/documents/batch \
  -H "Authorization: Bearer $SURSA_SOURCE_KEY" \
  -H "Idempotency-Key: sync-7-batch-1" \
  -H "Content-Type: application/json" \
  -d '{
    "sync_number": 7,
    "documents": [
      {"external_id": "faq-shipping", "title": "Shipping", "content_type": "markdown",
       "content": "# Shipping\n\nWe ship worldwide within 5 days.", "path": ["Support"]},
      {"external_id": "faq-refunds", "title": "Refunds", "content_type": "html",
       "content": "<p>Refunds take 14 days.</p>", "path": ["Support", "Billing"],
       "permissions": {"groups": ["Support"]}, "metadata": {"article_id": "1042"}}
    ]
  }'

Odgovor sadrži rezultat za svaki dokument, redoslijedom kojim ste ih poslali:

{
  "results": [
    {"external_id": "faq-shipping", "result": "unchanged", "status": "indexed", "card_id": "8c1d…", "version": "5e0f…"},
    {"external_id": "faq-refunds", "result": "updated", "status": "pending", "card_id": "3f2c…", "version": "a91b…"}
  ]
}
PoljeZnačenje
resultŠto se sada dogodilo s dokumentom: created, updated, unchanged, deleted, not_found, error ili skipped (u atomarnom paketu koji nije primijenjen).
statusGdje se dokument nalazi na putu do kartice: pending, processing (kartica je zapisana i indeksira se), indexed, failed ili removed.
card_idKartica dokumenta, kad postoji.
versionSažetak sadržaja i polja. Isti dokument poslan ponovno ima istu verziju i daje unchanged.
error, reasonZašto dokument nije uspio. reason je stabilan kod: content_invalid, file_rejected, too_large, limit_reached, index_failed ili batch_rejected (neki drugi dokument atomarnog paketa nije uspio).

Zadano se svaki dokument paketa primjenjuje zasebno: jedan loš dokument ne zaustavlja ostale.

Dokumente koji se nisu promijenili od posljednje sinkronizacije ne morate ponovno slati. Potvrdite ih prema ID-u pomoću POST /v1/push/sources/{source_id}/syncs/{sync_number}/touch, do 1000 ID-ova po zahtjevu, kako bi ih potpuno usklađivanje zadržalo:

curl -X POST https://api.sursa.com/v1/push/sources/42/syncs/7/touch \
  -H "Authorization: Bearer $SURSA_SOURCE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"external_ids": ["faq-contact", "faq-hours"]}'

3. Zatvorite sinkronizaciju

POST /v1/push/sources/{source_id}/syncs/{sync_number}/close završava sinkronizaciju:

curl -X POST https://api.sursa.com/v1/push/sources/42/syncs/7/close \
  -H "Authorization: Bearer $SURSA_SOURCE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status": "complete"}'
statusUčinak
completePotpuno usklađivanje. Arhivira se svaki dokument izvora koji u ovoj sinkronizaciji nije ni poslan ni potvrđen. Koristite ga samo kad ste poslali sve.
complete_incrementalPrimjenjuje ono što ste poslali i ništa ne arhivira.
failedNišta ne arhivira i zadržava ono što je već poslano. Za zapisnik dodajte reason (na primjer API_ERROR) i error_details.

Zatvorite s failed kad god se vaš izvoz zaustavi na pola puta: complete nakon djelomičnog izvoza arhivirao bi svaki dokument do kojeg niste stigli. Ponavljanje istog zatvaranja vraća isti rezultat.

Nakon zatvaranja Sursa u roku od otprilike jedne minute od dokumenata stvara kartice. Stranica izvora prikazuje svaku sinkronizaciju s brojem poslanih i arhiviranih dokumenata, a GET /v1/push/sources/{source_id}/syncs/{sync_number} vraća iste brojače.

Inkrementalne sinkronizacije

Između potpunih sinkronizacija šaljite samo ono što se promijenilo:

  1. Otvorite sinkronizaciju s "type": "incremental".
  2. Pošaljite promijenjene dokumente, a ID-ove uklonjenih stavite u deletes (v. u nastavku).
  3. Zatvorite s complete_incremental.

S vremena na vrijeme, na primjer jednom tjedno, pokrenite potpunu sinkronizaciju kako biste uhvatili sve što je inkrementalno pokretanje propustilo.

Brisanje dokumenata u paketu

Paket može uklanjati dokumente zajedno s onima koje zapisuje. Navedite njihove ID-ove u deletes:

{
  "sync_number": 8,
  "documents": [{"external_id": "faq-shipping", "title": "Shipping", "content": "…"}],
  "deletes": ["faq-old-returns", "faq-fax"]
}

Svaki izbrisani ID dobiva vlastitu stavku u results, s result deleted ili not_found ako izvor nema takav dokument. Ponovno brisanje istog ID-a je bezopasno.

Atomarni paketi

Neke promjene imaju smisla samo zajedno, na primjer dokument i onaj koji ga zamjenjuje. Pošaljite "atomic": true i paket se primjenjuje u cijelosti ili se uopće ne primjenjuje: ako bilo koji dokument ne prođe provjere, ništa se iz paketa ne primjenjuje, a odgovor je 422 s kodom sources.push_batch_rejected i rezultatom svakog dokumenta u error.details.results: dokumenti koji nisu uspjeli imaju error, a ostali skipped.

{"sync_number": 8, "atomic": true, "documents": […], "deletes": ["faq-old-returns"]}

Bez atomic paket se primjenjuje dokument po dokument. Atomarne pakete koristite za povezane promjene, a obične pakete za skupna punjenja, kod kojih jedan loš dokument ne bi smio zadržati ostale.

Provjera rezultata svakog dokumenta

Odgovor na paket govori vam kako je svaki dokument zapisan. Pretvaranje u karticu događa se naknadno, pa status može još biti pending. Da biste pronašli dokumente sinkronizacije koji nisu postali kartice:

curl "https://api.sursa.com/v1/push/sources/42/syncs/7/documents?status=failed" \
  -H "Authorization: Bearer $SURSA_SOURCE_KEY"

Svaka stavka ima external_id, title, status, card_id, version i reason, a popis se straniči pomoću cursor. status prima i pending, processing, indexed i removed.

Umjesto da pitate, možete i primati obavijesti: događaji import.sync_completed (sinkronizacija je zatvorena i obrađena, s ukupnim brojevima) i import.document_failed (dokument nije postao kartica, s razlogom reason) stižu putem webhooka i u feedu događaja.

Ponovni pokušaji

  • Uz svaki POST pošaljite Idempotency-Key. Ponovljeni paket s istim ključem vraća prvi rezultat.
  • Čak i bez ključa dokument s istim external_id nikada ne postaje druga kartica: rezultat je unchanged ili updated.
  • Ako se proces zaustavi usred sinkronizacije, otvorite novu nakon što stara istekne ili zatvorite staru s failed ako još imate njezin broj, a zatim ponovno pokrenite sinkronizaciju.

Ograničenja

OgraničenjeVrijednost
Sadržaj jednog dokumenta5 MB
Datoteka u zahtjevu s jednim dokumentom100 MB
Dokumenata po paketu500
Tijelo zahtjeva s paketom50 MiB
ID-ova po zahtjevu touch1000
Dokumenata po izvoruOvisi o planu: od 100.000
Otvorena sinkronizacijaZadano 60 minuta, najviše 24 sata

Dokument iznad ograničenja broja dokumenata izvora u paketu ne uspijeva s razlogom limit_reached; zahtjev s jednim dokumentom vraća 409 s kodom sources.push_too_many_documents. Ograničenja učestalosti primjenjuju se kao i na svaki drugi zahtjev; v. Ograničenja učestalosti i kvote.

Česte pogreške

OdgovorUzrokŠto učiniti
401 sources.push_key_invalidKljuč je pogrešan, opozvan ili pripada drugom izvoru.Provjerite ključ i ID izvora u putanji.
400 sources.push_document_invalidNedostaje obavezno polje ili je prekoračeno ograničenje.Ispravite dokument; u običnom paketu ne uspijeva samo taj dokument.
409 sources.push_sync_openDruga je sinkronizacija još otvorena.Zatvorite je ili pričekajte da istekne.
409 sources.push_sync_closedSinkronizacija je zatvorena ili je istekla.Otvorite novu sinkronizaciju; za duge izvoze povećajte max_minutes.
403 sources.feature_disabledIzvori nisu dio plana organizacije.Obratite se administratoru.
429Previše zahtjeva.Pričekajte koliko navodi Retry-After; šaljite manje paketa, ali većih.