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
pathsvakog 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 s | Može |
|---|---|---|
| Ključ izvora | kbsrc_ | 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:write | kb_ | 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
| Polje | Obavezno | Opis |
|---|---|---|
external_id | da | Vaš stabilan ID dokumenta, do 512 znakova. Ponovno slanje istog ID-a zamjenjuje dokument. |
title | da | Naslov kartice, do 500 znakova. Za datoteku zadano ime datoteke. |
content | da, osim ako postoji datoteka | Do 5 MB. |
content_type | ne | html (zadano), markdown ili text. HTML se čisti od skripti, stilova, obrazaca i ugrađenih objekata. |
url | ne | Poveznica na dokument u vašem sustavu, prikazuje se na kartici. |
path | ne | Mape, kao niz (["Support", "Billing"]) ili niz znakova ("Support/Billing"), do 10 razina. |
permissions | ne | {"everyone": true} ili {"emails": [...], "groups": [...]}. Koristi se kad su dopuštenja izvora postavljena na način zrcaljenja („kao u izvoru”). |
tags | ne | Do 50 oznaka, koje se dodaju oznakama izvora. |
author_email | ne | Ako je to korisnik organizacije, postaje vlasnik kartice. |
updated_at | ne | Kad se dokument promijenio u vašem sustavu (RFC 3339). |
metadata | ne | Vaši parovi ključ–vrijednost na kartici. V. Metapodaci. |
category | ne | Kategorija kartice: ključ jedne od kategorija organizacije. |
verifiers, verify_interval_days | ne | Tko provjerava karticu (korisnici prema e-adresi i grupe) i koliko često, u danima. |
upload_id | ne | Datoteka dokumenta iz učitavanja u dijelovima, umjesto content. |
attachments | ne | Do 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}/documents | Stvara ili zamjenjuje jedan dokument. |
POST /v1/push/sources/{source_id}/documents/batch | Stvara 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}
typejeinitialza prvu sinkronizaciju izvora, aincrementalnakon što je neka sinkronizacija dovršena. Sinkronizacijaincrementalprije ijedne dovršene vraćasources.push_initial_required.- Istodobno može biti otvorena samo jedna sinkronizacija: druga vraća
409sources.push_sync_open. - Sinkronizacija ostaje otvorena
max_minutesminuta (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…"}
]
}
| Polje | Značenje |
|---|---|
result | Što se sada dogodilo s dokumentom: created, updated, unchanged, deleted, not_found, error ili skipped (u atomarnom paketu koji nije primijenjen). |
status | Gdje se dokument nalazi na putu do kartice: pending, processing (kartica je zapisana i indeksira se), indexed, failed ili removed. |
card_id | Kartica dokumenta, kad postoji. |
version | Sažetak sadržaja i polja. Isti dokument poslan ponovno ima istu verziju i daje unchanged. |
error, reason | Zaš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"}'status | Učinak |
|---|---|
complete | Potpuno 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_incremental | Primjenjuje ono što ste poslali i ništa ne arhivira. |
failed | Niš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:
- Otvorite sinkronizaciju s
"type": "incremental". - Pošaljite promijenjene dokumente, a ID-ove uklonjenih stavite u
deletes(v. u nastavku). - 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
POSTpošaljiteIdempotency-Key. Ponovljeni paket s istim ključem vraća prvi rezultat. - Čak i bez ključa dokument s istim
external_idnikada ne postaje druga kartica: rezultat jeunchangediliupdated. - Ako se proces zaustavi usred sinkronizacije, otvorite novu nakon što stara istekne ili zatvorite staru s
failedako još imate njezin broj, a zatim ponovno pokrenite sinkronizaciju.
Ograničenja
| Ograničenje | Vrijednost |
|---|---|
| Sadržaj jednog dokumenta | 5 MB |
| Datoteka u zahtjevu s jednim dokumentom | 100 MB |
| Dokumenata po paketu | 500 |
| Tijelo zahtjeva s paketom | 50 MiB |
ID-ova po zahtjevu touch | 1000 |
| Dokumenata po izvoru | Ovisi o planu: od 100.000 |
| Otvorena sinkronizacija | Zadano 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
| Odgovor | Uzrok | Što učiniti |
|---|---|---|
401 sources.push_key_invalid | Ključ je pogrešan, opozvan ili pripada drugom izvoru. | Provjerite ključ i ID izvora u putanji. |
400 sources.push_document_invalid | Nedostaje obavezno polje ili je prekoračeno ograničenje. | Ispravite dokument; u običnom paketu ne uspijeva samo taj dokument. |
409 sources.push_sync_open | Druga je sinkronizacija još otvorena. | Zatvorite je ili pričekajte da istekne. |
409 sources.push_sync_closed | Sinkronizacija je zatvorena ili je istekla. | Otvorite novu sinkronizaciju; za duge izvoze povećajte max_minutes. |
403 sources.feature_disabled | Izvori nisu dio plana organizacije. | Obratite se administratoru. |
429 | Previše zahtjeva. | Pričekajte koliko navodi Retry-After; šaljite manje paketa, ali većih. |