Ugrás a tartalomra
Sursa Developers

A rendszered szinkronizálása egyéni forrással

Az egyéni forrás olyan rendszert kapcsol be, amelyhez nincs beépített összekötő: a wikidet, a jegykezelő eszközödet, egy adatbázist, egy bárhonnan származó exportot. A kódod dokumentumokat küld a Sursának, a Sursa pedig kártyákat készít belőlük abban a gyűjteményben és azokban a mappákban, amelyekre a forrás be van állítva, ugyanazzal a kereséssel, válaszokkal, ellenőrzéssel és jogosultságokkal, mint bármely más forrás kártyáinál.

A kártyák közvetlen írásával ellentétben az egyéni forrás nyilvántartja, mit küldtél el. Egy teljes szinkronizálás végén a Sursa minden olyan dokumentumot archivál, amelyet nem küldtél el, így a rendszeredben történt törlések külön munka nélkül eljutnak a Sursába.

A forrás beállítása

A forrást egy adminisztrátor hozza létre a Sursában, a Sources → New source → Custom source (források → új forrás → egyéni forrás) alatt, és kiválasztja:

  • a kártyák gyűjteményét és opcionálisan egy mappát;
  • a mappamódot: minden kártya a kiválasztott mappába kerül, vagy az egyes dokumentumok path értékét tükröző almappákba;
  • a jogosultságokat: a gyűjtemény jogosultságai, vagy „ahogy a forrásban”, amikor minden dokumentum felsorolja, ki láthatja.

A forrás oldala megmutatja a forrás azonosítóját; a példák a 42 azonosítót használják.

Kulcs kiválasztása

KulcsKezdeteMire képes
Forráskulcskbsrc_Dokumentumok írása ebbe az egy forrásba. Semmi másra: nem olvashat és nem kereshet. A forrás oldalán, az API keys szakaszban hozhatod létre.
A szervezet import:write hatókörű kulcsakb_Írás a szervezet bármely egyéni forrásába és az állapotuk olvasása. Egy forrás és a kulcsai létrehozásához az admin hatókör szükséges.

Egyetlen integrációhoz a forráskulcs a legbiztonságosabb választás, különösen ha az integráció egy külső platformon fut. A szervezet import:write hatókörű kulcsa olyan szolgáltatáshoz illik, amely több forrást is táplál.

Mindkét kulcsot ugyanúgy kell elküldeni, és minden küldési végpont a /v1/push/sources/{source_id} alatt található. A kulcsot és a forrás állapotát a GET /v1/push/sources/{source_id} végponttal ellenőrizheted:

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}

A dokumentum

MezőKötelezőLeírás
external_idigenA dokumentum stabil azonosítója a te rendszeredben, legfeljebb 512 karakter. Ha ugyanazt az azonosítót újra elküldöd, a dokumentum lecserélődik.
titleigenA kártya címe, legfeljebb 500 karakter. Fájlnál alapértelmezés szerint a fájl neve.
contentigen, ha nincs fájlLegfeljebb 5 MB.
content_typenemhtml (alapértelmezett), markdown vagy text. A HTML-ből a Sursa eltávolítja a szkripteket, a stílusokat, az űrlapokat és a beillesztett objektumokat.
urlnemHivatkozás a dokumentumra a rendszeredben, a kártyán jelenik meg.
pathnemMappák, tömbként (["Support", "Billing"]) vagy karakterláncként ("Support/Billing"), legfeljebb 10 szint.
permissionsnem{"everyone": true} vagy {"emails": [...], "groups": [...]}. Akkor használatos, ha a forrás jogosultságai „ahogy a forrásban” beállításúak.
tagsnemLegfeljebb 50 címke, a forrás címkéihez adódnak hozzá.
author_emailnemHa ez a szervezet egy felhasználója, ő lesz a kártya felelőse.
updated_atnemMikor változott a dokumentum a rendszeredben (RFC 3339).
metadatanemA saját kulcs–érték párjaid a kártyán. Lásd: Metaadatok.
categorynemA kártya kategóriája: a szervezet egyik kategóriájának kulcsa.
verifiers, verify_interval_daysnemKi ellenőrzi a kártyát (felhasználók e-mail-cím szerint és csoportok), és milyen gyakran, napokban.
upload_idnemA dokumentum fájlja egy részenkénti feltöltésből, a content helyett.
attachmentsnemA dokumentum legfeljebb 20 további fájlja, upload_id értékek listájaként. Mindegyikből a forrás külön kártyája lesz.

A content helyett egyetlen dokumentum legfeljebb 100 MB-os fájlt is vihet egy multipart/form-data kérésben: a fájlt a file részben, a fenti mezőket JSON-ként a document részben. Az upload_id és az attachments mezőhöz szükséges részenkénti feltöltéseket a szervezet import:write hatókörű kulcsával kell létrehozni, import_attachment rendeltetéssel; a forráskulcs nem hozhat létre ilyet.

A küldés két módja

A közvetlen frissítések olyan rendszerekhez illenek, amelyek minden változásról értesítenek, például a helpdeskedből érkező webhook vagy egy Zapier-lépés. Küldj el egy dokumentumot, amikor létrejön vagy megváltozik, és töröld, amikor eltávolítják:

KérésMit csinál
POST /v1/push/sources/{source_id}/documentsLétrehoz vagy lecserél egy dokumentumot.
POST /v1/push/sources/{source_id}/documents/batchSok dokumentumot hoz létre vagy cserél le egyszerre.
DELETE /v1/push/sources/{source_id}/documents/{external_id}Eltávolít egy dokumentumot. Az azonosítót URL-kódold.

A változásokból körülbelül egy percen belül kártya lesz; az egymást követő változásokat a Sursa együtt dolgozza fel.

A szinkronizálások a rendszeres exportokhoz illenek: mindent elküldesz, vagy mindent, ami megváltozott, a Sursa pedig elvégzi az egyeztetést. Az útmutató további része a szinkronizálásokról szól.

Teljes szinkronizálás futtatása

A szinkronizálásnak három lépése van: megnyitás, küldés, lezárás.

1. Megnyitás

A POST /v1/push/sources/{source_id}/syncs megnyit egy szinkronizálást, és visszaadja a sorszámát:

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}
  • A type értéke a forrás első szinkronizálásánál initial, egy sikeresen befejezett szinkronizálás után pedig incremental. A befejezett szinkronizálás előtti incremental szinkronizálás sources.push_initial_required választ kap.
  • Egyszerre csak egy szinkronizálás lehet nyitva: egy második megnyitására a válasz 409 sources.push_sync_open.
  • A szinkronizálás max_minutes ideig marad nyitva (alapértelmezés szerint 60, legfeljebb 1440 percig). Ezután lejár: semmi nem archiválódik, és a sorszámát a Sursa többé nem fogadja el. Olyan időt válassz, amely bőven hosszabb, mint amennyi ideig az exportod tart.

2. Dokumentumok küldése

A dokumentumokat legfeljebb 500 darabos kötegekben küldd el, a szinkronizálás sorszámával. A köteg törzse legfeljebb 50 MiB lehet; a kötegben lévő fájlokat upload_id értékként add át.

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"}}
    ]
  }'

A válasz minden dokumentumhoz tartalmaz egy eredményt, az elküldés sorrendjében:

{
  "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…"}
  ]
}
MezőJelentése
resultMi történt most a dokumentummal: created, updated, unchanged, deleted, not_found, error vagy skipped (egy nem érvényesített atomi kötegben).
statusHol tart a dokumentum a kártyává válás útján: pending, processing (a kártya már megvan, az indexelése folyamatban), indexed, failed vagy removed.
card_idA dokumentum kártyája, amint létezik.
versionA tartalom és a mezők hash-e. Az újra elküldött azonos dokumentumnak ugyanaz a verziója, és unchanged eredményt kap.
error, reasonMiért hiúsult meg a dokumentum. A reason stabil kód: content_invalid, file_rejected, too_large, limit_reached, index_failed vagy batch_rejected (egy atomi köteg egy másik dokumentuma hiúsult meg).

Alapértelmezés szerint a köteg minden dokumentuma önállóan érvényesül: egy hibás dokumentum nem állítja meg a többit.

Azokat a dokumentumokat, amelyek a legutóbbi szinkronizálás óta nem változtak, nem kell újra elküldeni. Erősítsd meg őket azonosító szerint, újraküldés nélkül, a POST /v1/push/sources/{source_id}/syncs/{sync_number}/touch végponttal, kérésenként legfeljebb 1000 azonosítóval, hogy a teljes egyeztetés megtartsa őket:

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. Lezárás

A POST /v1/push/sources/{source_id}/syncs/{sync_number}/close befejezi a szinkronizálást:

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"}'
statusHatása
completeTeljes egyeztetés. A forrás minden olyan dokumentuma archiválódik, amelyet ebben a szinkronizálásban sem nem küldtél el, sem nem erősítettél meg. Csak akkor használd, ha mindent elküldtél.
complete_incrementalÉrvényesíti, amit elküldtél, és semmit nem archivál.
failedSemmit nem archivál, és megtartja, amit már elküldtél. A naplóhoz add meg a reason (például API_ERROR) és az error_details mezőt.

Mindig failed értékkel zárd le a szinkronizálást, ha az exportod félúton leáll: egy részleges export utáni complete minden olyan dokumentumot archiválna, amelyig nem jutottál el. Ugyanannak a lezárásnak a megismétlése ugyanazt az eredményt adja.

A lezárás után a Sursa körülbelül egy percen belül kártyákat készít a dokumentumokból. A forrás oldala minden szinkronizálást megmutat az elküldött és az archivált dokumentumok számával, és a GET /v1/push/sources/{source_id}/syncs/{sync_number} ugyanezeket a számlálókat adja vissza.

Növekményes szinkronizálások

A teljes szinkronizálások között csak azt küldd el, ami megváltozott:

  1. Nyisd meg a szinkronizálást a "type": "incremental" értékkel.
  2. Küldd el a megváltozott dokumentumokat, az eltávolítottak azonosítóit pedig tedd a deletes mezőbe (lásd lent).
  3. Zárd le a complete_incremental értékkel.

Időnként, például hetente, futtass teljes szinkronizálást, hogy mindent elkapj, ami egy növekményes futásból kimaradt.

Dokumentumok törlése kötegben

Egy köteg az általa írt dokumentumokkal együtt dokumentumokat is eltávolíthat. Sorold fel az azonosítóikat a deletes mezőben:

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

Minden törölt azonosító saját bejegyzést kap a results tömbben, deleted értékű result mezővel, vagy not_found értékkel, ha a forrásban nincs ilyen dokumentum. Ugyanannak az azonosítónak az ismételt törlése ártalmatlan.

Atomi kötegek

Bizonyos változásoknak csak együtt van értelmük, például egy dokumentumnak és annak, amely felváltja. Küldd el a "atomic": true értéket, és a köteg vagy teljes egészében érvényesül, vagy egyáltalán nem: ha bármely dokumentum elbukik az ellenőrzésen, a kötegből semmi nem érvényesül, és a válasz 422 a sources.push_batch_rejected kóddal, és az error.details.results mezőben minden dokumentum eredménye szerepel: a meghiúsult dokumentumoknál error, a többinél skipped.

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

atomic nélkül a köteg dokumentumonként érvényesül. Az atomi kötegeket az összefüggő változásokhoz használd, a szokásos kötegeket pedig a tömeges betöltésekhez, ahol egy hibás dokumentum nem tarthatja vissza a többit.

Az egyes dokumentumok eredményének ellenőrzése

A köteg válasza megmondja, hogyan íródott ki az egyes dokumentum. A kártyává alakítás ezután történik, ezért a status még lehet pending. Egy szinkronizálás azon dokumentumainak megkereséséhez, amelyekből nem lett kártya:

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

Minden bejegyzésben megvan az external_id, a title, a status, a card_id, a version és a reason, a lista pedig a cursor paraméterrel lapozható. A status a pending, a processing, az indexed és a removed értéket is elfogadja.

Kérdezés helyett értesítést is kaphatsz: az import.sync_completed (egy szinkronizálás lezárult és feldolgozásra került, az összesítő számaival) és az import.document_failed (egy dokumentumból nem lett kártya, a reason értékével) esemény webhookon és az eseménycsatornában is megérkezik.

Újrapróbálkozások

  • Minden POST kéréssel küldj Idempotency-Key fejlécet. Az ugyanazzal a kulccsal megismételt köteg az első eredményt adja vissza.
  • Kulcs nélkül sem lesz soha második kártya egy azonos external_id értékű dokumentumból: unchanged vagy updated eredményt kap.
  • Ha a folyamat egy szinkronizálás közepén leáll, a régi lejárta után nyiss újat, vagy ha még megvan a régi sorszáma, zárd le failed értékkel, és futtasd újra a szinkronizálást.

Korlátok

KorlátÉrték
Egy dokumentum tartalma5 MB
Fájl egydokumentumos kérésben100 MB
Dokumentumok kötegenként500
A kötegkérés törzse50 MiB
Azonosítók touch kérésenként1000
Dokumentumok forrásonkéntA csomagtól függ: 100 000-től
Nyitott szinkronizálásAlapértelmezés szerint 60 perc, legfeljebb 24 óra

A forrás dokumentumkorlátja fölötti dokumentum kötegben limit_reached indoklással hiúsul meg; egyetlen dokumentumot küldő kérésre a válasz 409 a sources.push_too_many_documents kóddal. A gyakorisági korlátok ugyanúgy vonatkoznak rá, mint bármely más kérésre; lásd: Gyakorisági korlátok és kvóták.

Gyakori hibák

VálaszOkMit tegyél
401 sources.push_key_invalidA kulcs hibás, visszavonták, vagy egy másik forráshoz tartozik.Ellenőrizd a kulcsot és az útvonalban szereplő forrásazonosítót.
400 sources.push_document_invalidHiányzik egy kötelező mező, vagy túllépés történt egy korláton.Javítsd a dokumentumot; szokásos kötegben csak ez a dokumentum hiúsul meg.
409 sources.push_sync_openEgy másik szinkronizálás még nyitva van.Zárd le, vagy várd meg, amíg lejár.
409 sources.push_sync_closedA szinkronizálás lezárult vagy lejárt.Nyiss új szinkronizálást; hosszú exportokhoz növeld a max_minutes értékét.
403 sources.feature_disabledA források nem részei a szervezet csomagjának.Fordulj az adminisztrátorhoz.
429Túl sok kérés.Várd ki a Retry-After idejét; küldj kevesebb, nagyobb köteget.