Siirry sisältöön
Sursa Developers

Järjestelmän synkronointi mukautetulla lähteellä

Mukautettu lähde yhdistää järjestelmän, jolle ei ole valmista liitintä: wikisi, tikettijärjestelmäsi, tietokannan, viennin mistä tahansa. Koodisi lähettää asiakirjoja Sursaan, ja Sursa tekee niistä kortteja siihen kokoelmaan ja niihin kansioihin, jotka lähteelle on määritetty. Näillä korteilla on sama haku, vastaukset, vahvistus ja käyttöoikeudet kuin minkä tahansa muun lähteen korteilla.

Toisin kuin korttien kirjoittaminen suoraan, mukautettu lähde pitää kirjaa siitä, mitä olet lähettänyt. Täyden synkronoinnin lopussa Sursa arkistoi jokaisen asiakirjan, jota et lähettänyt, joten järjestelmässäsi tehdyt poistot päätyvät Sursaan ilman lisätyötä.

Lähteen määrittäminen

Ylläpitäjä luo lähteen Sursassa kohdassa Sources → New source → Custom source (lähteet → uusi lähde → mukautettu lähde) ja valitsee:

  • korttien kokoelman ja valinnaisesti kansion;
  • kansiotilan: kaikki kortit valittuun kansioon tai alikansiot, jotka vastaavat kunkin asiakirjan path-kenttää;
  • käyttöoikeudet: kokoelman käyttöoikeudet tai ”as in the source” (kuten lähteessä), jolloin jokainen asiakirja luettelee, kuka saa nähdä sen.

Lähteen sivulla näkyy sen tunnus; esimerkit käyttävät tunnusta 42.

Avaimen valinta

AvainAlkuMitä sillä voi tehdä
Lähdeavainkbsrc_Kirjoittaa asiakirjoja tähän yhteen lähteeseen. Ei mitään muuta: sillä ei voi lukea eikä hakea. Luo se lähteen sivun API keys -osiossa.
Organisaation avain, jolla on käyttöalue import:writekb_Kirjoittaa organisaation mihin tahansa mukautettuun lähteeseen ja lukee sen tilan. Lähteen ja sen avainten luomiseen tarvitaan käyttöalue admin.

Lähdeavain on turvallisin valinta yksittäiselle integraatiolle, varsinkin sellaiselle, joka toimii kolmannen osapuolen alustalla. Organisaation avain, jolla on import:write, sopii palvelulle, joka syöttää tietoja useisiin lähteisiin.

Molemmat avaimet lähetetään samalla tavalla, ja kaikki push-päätepisteet ovat polun /v1/push/sources/{source_id} alla. Tarkista avain ja lähteen tila GET /v1/push/sources/{source_id} -pyynnöllä:

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}

Asiakirja

KenttäPakollinenKuvaus
external_idkylläAsiakirjan pysyvä tunnuksesi, enintään 512 merkkiä. Saman tunnuksen lähettäminen uudelleen korvaa asiakirjan.
titlekylläKortin otsikko, enintään 500 merkkiä. Tiedostolle oletuksena tiedoston nimi.
contentkyllä, ellei mukana ole tiedostoaEnintään 5 Mt.
content_typeeihtml (oletus), markdown tai text. HTML:stä poistetaan skriptit, tyylit, lomakkeet ja upotetut objektit.
urleiLinkki asiakirjaan järjestelmässäsi; näkyy kortissa.
patheiKansiot taulukkona (["Support", "Billing"]) tai merkkijonona ("Support/Billing"), enintään 10 tasoa.
permissionsei{"everyone": true} tai {"emails": [...], "groups": [...]}. Käytetään, kun lähteen käyttöoikeuksiksi on valittu ”as in the source”.
tagseiEnintään 50 tunnistetta, jotka lisätään lähteen tunnisteisiin.
author_emaileiJos tämä on organisaation käyttäjä, hänestä tulee kortin omistaja.
updated_ateiMilloin asiakirja muuttui järjestelmässäsi (RFC 3339).
metadataeiOmat avain–arvo-parisi kortissa. Ks. Metatiedot.
categoryeiKortin luokka: jonkin organisaation luokan avain.
verifiers, verify_interval_dayseiKuka vahvistaa kortin (käyttäjät sähköpostiosoitteen mukaan ja ryhmät) ja kuinka usein, päivinä.
upload_ideiAsiakirjan tiedosto osissa tehdystä latauksesta content-kentän sijaan.
attachmentseiEnintään 20 muuta asiakirjan tiedostoa luettelona upload_id-tunnuksia. Kustakin tulee lähteen oma kortti.

content-kentän sijaan yksittäinen asiakirja voi sisältää enintään 100 Mt:n tiedoston multipart/form-data-pyynnössä: tiedosto file-osassa ja yllä olevat kentät JSON-muodossa document-osassa. upload_id- ja attachments-kenttien osissa tehtävät lataukset luodaan organisaation avaimella, jolla on käyttöalue import:write, käyttötarkoituksella import_attachment; lähdeavain ei voi luoda niitä.

Kaksi tapaa lähettää

Suorat päivitykset sopivat järjestelmiin, jotka kertovat sinulle jokaisesta muutoksesta, kuten tukipalvelusi webhook tai Zapierin vaihe. Lähetä asiakirja, kun se luodaan tai sitä muutetaan, ja poista se, kun se poistetaan:

PyyntöTekee
POST /v1/push/sources/{source_id}/documentsLuo tai korvaa yhden asiakirjan.
POST /v1/push/sources/{source_id}/documents/batchLuo tai korvaa monta asiakirjaa kerralla.
DELETE /v1/push/sources/{source_id}/documents/{external_id}Poistaa yhden asiakirjan. URL-koodaa tunnus.

Muutoksista tulee kortteja noin minuutin kuluessa; useat peräkkäiset muutokset käsitellään yhdessä.

Synkronoinnit sopivat säännöllisiin vienteihin: lähetät kaiken tai kaiken muuttuneen, ja Sursa täsmäyttää tiedot. Tämän oppaan loppuosa käsittelee synkronointeja.

Täysi synkronointi

Synkronoinnissa on kolme vaihetta: avaa, lähetä, sulje.

1. Avaa

POST /v1/push/sources/{source_id}/syncs avaa synkronoinnin ja palauttaa sen numeron:

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 on lähteen ensimmäisessä synkronoinnissa initial ja sen jälkeen incremental, kun jokin synkronointi on valmistunut. incremental-synkronointi ennen ensimmäistä valmistunutta palauttaa koodin sources.push_initial_required.
  • Vain yksi synkronointi voi olla kerrallaan auki: toinen palauttaa vastauksen 409 sources.push_sync_open.
  • Synkronointi pysyy auki max_minutes-ajan (oletuksena 60, enintään 1 440). Sen jälkeen sen voimassaolo päättyy: mitään ei arkistoida, eikä sen numeroa enää hyväksytä. Valitse aika, joka on reilusti pidempi kuin vientisi kestää.

2. Lähetä asiakirjat

Lähetä asiakirjat enintään 500 asiakirjan erinä synkronoinnin numeron kanssa. Erän runko on enintään 50 MiB; erän sisällä tiedostot välitetään upload_id-tunnuksina.

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

Vastauksessa on tulos jokaiselle asiakirjalle siinä järjestyksessä, jossa lähetit ne:

{
  "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…"}
  ]
}
KenttäMerkitys
resultMitä asiakirjalle tapahtui nyt: created, updated, unchanged, deleted, not_found, error tai skipped (atomisessa erässä, jota ei toteutettu).
statusMissä vaiheessa asiakirja on matkalla kortiksi: pending, processing (kortti on kirjoitettu ja sitä indeksoidaan), indexed, failed tai removed.
card_idAsiakirjan kortti, kun se on olemassa.
versionSisällön ja kenttien tiiviste. Uudelleen lähetetyllä samalla asiakirjalla on sama versio, ja sen tulos on unchanged.
error, reasonMiksi asiakirja epäonnistui. reason on pysyvä koodi: content_invalid, file_rejected, too_large, limit_reached, index_failed tai batch_rejected (atomisen erän jokin toinen asiakirja epäonnistui).

Oletuksena erän jokainen asiakirja käsitellään erikseen: yksi virheellinen asiakirja ei pysäytä muita.

Asiakirjoja, jotka eivät ole muuttuneet edellisen synkronoinnin jälkeen, ei tarvitse lähettää uudelleen. Kuittaa ne tunnuksen mukaan POST /v1/push/sources/{source_id}/syncs/{sync_number}/touch -pyynnöllä, enintään 1 000 tunnusta pyyntöä kohden, jotta täysi täsmäytys säilyttää ne:

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. Sulje

POST /v1/push/sources/{source_id}/syncs/{sync_number}/close päättää synkronoinnin:

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"}'
statusVaikutus
completeTäysi täsmäytys. Jokainen lähteen asiakirja, jota ei tässä synkronoinnissa lähetetty eikä kuitattu, arkistoidaan. Käytä tätä vain, kun lähetit kaiken.
complete_incrementalToteuttaa lähettämäsi muutokset eikä arkistoi mitään.
failedEi arkistoi mitään ja säilyttää jo lähetetyn. Lisää lokia varten reason (esimerkiksi API_ERROR) ja error_details.

Sulje tilalla failed aina, kun vientisi pysähtyy kesken: complete osittaisen viennin jälkeen arkistoisi jokaisen asiakirjan, jota et ehtinyt lähettää. Saman sulkemisen toistaminen palauttaa saman tuloksen.

Sulkemisen jälkeen Sursa tekee asiakirjoista kortteja noin minuutin kuluessa. Lähteen sivu näyttää jokaisen synkronoinnin lähetettyjen ja arkistoitujen asiakirjojen määrineen, ja GET /v1/push/sources/{source_id}/syncs/{sync_number} palauttaa samat laskurit.

Inkrementaaliset synkronoinnit

Lähetä täysien synkronointien välillä vain se, mikä on muuttunut:

  1. Avaa synkronointi arvolla "type": "incremental".
  2. Lähetä muuttuneet asiakirjat ja laita poistettujen asiakirjojen tunnukset deletes-kenttään (ks. alla).
  3. Sulje tilalla complete_incremental.

Aja aika ajoin täysi synkronointi, esimerkiksi viikoittain, jotta saat kiinni kaiken, mikä inkrementaalisilta ajoilta jäi huomaamatta.

Asiakirjojen poistaminen erässä

Erä voi poistaa asiakirjoja samalla, kun se kirjoittaa toisia. Luettele poistettavien tunnukset deletes-kentässä:

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

Jokainen poistettu tunnus saa oman kohtansa results-kentässä: sen result on deleted tai not_found, jos lähteessä ei ole tällaista asiakirjaa. Saman tunnuksen poistaminen uudelleen on vaaratonta.

Atomiset erät

Jotkin muutokset ovat järkeviä vain yhdessä, esimerkiksi asiakirja ja sen korvaava asiakirja. Lähetä "atomic": true, niin erä toteutetaan kokonaan tai ei lainkaan: jos jokin asiakirja ei läpäise tarkistuksiaan, erästä ei toteuteta mitään, ja vastaus on 422 koodilla sources.push_batch_rejected sekä jokaisen asiakirjan tuloksella error.details.results-kentässä: epäonnistuneilla asiakirjoilla on error, muilla skipped.

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

Ilman atomic-kenttää erä toteutetaan asiakirja kerrallaan. Käytä atomisia eriä toisiinsa liittyviin muutoksiin ja tavallisia eriä massalatauksiin, joissa yksi virheellinen asiakirja ei saa pidätellä muita.

Kunkin asiakirjan tuloksen tarkistaminen

Erän vastaus kertoo, miten kukin asiakirja kirjoitettiin. Kortiksi muuttaminen tapahtuu jälkeenpäin, joten status voi vielä olla pending. Näin löydät synkronoinnin asiakirjat, joista ei tullut kortteja:

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

Jokaisella kohdalla ovat kentät external_id, title, status, card_id, version ja reason, ja lista sivutetaan cursor-parametrilla. status hyväksyy myös arvot pending, processing, indexed ja removed.

Voit myös saada ilmoituksen kysymättä: tapahtumat import.sync_completed (synkronointi on suljettu ja käsitelty, ja mukana ovat sen kokonaismäärät) ja import.document_failed (asiakirjasta ei tullut korttia, ja mukana on sen reason) saapuvat webhookin kautta ja tapahtumasyötteeseen.

Uusintayritykset

  • Lähetä Idempotency-Key jokaisen POST-pyynnön mukana. Samalla avaimella toistettu erä palauttaa ensimmäisen tuloksen.
  • Ilman avaintakaan asiakirjasta, jolla on sama external_id, ei koskaan tule toista korttia: sen tulos on unchanged tai updated.
  • Jos prosessi pysähtyy kesken synkronoinnin, avaa uusi synkronointi, kun vanhan voimassaolo on päättynyt, tai sulje vanha tilalla failed, jos sen numero on vielä tiedossasi, ja aja synkronointi uudelleen.

Rajat

RajaArvo
Yhden asiakirjan sisältö5 Mt
Tiedosto yhden asiakirjan pyynnössä100 Mt
Asiakirjoja erässä500
Erän pyynnön runko50 MiB
Tunnuksia touch-pyynnössä1 000
Asiakirjoja lähdettä kohdenRiippuu paketista: vähintään 100 000
Avoin synkronointiOletuksena 60 minuuttia, enintään 24 tuntia

Asiakirja, joka ylittää lähteen asiakirjarajan, epäonnistuu erässä syyllä limit_reached; yksittäisen asiakirjan pyyntö palauttaa 409-vastauksen ja koodin sources.push_too_many_documents. Nopeusrajoitukset koskevat näitä pyyntöjä kuten mitä tahansa muitakin; ks. Nopeusrajoitukset ja kiintiöt.

Yleiset virheet

VastausSyyMitä tehdä
401 sources.push_key_invalidAvain on väärä tai peruttu, tai se kuuluu toiselle lähteelle.Tarkista avain ja polussa oleva lähteen tunnus.
400 sources.push_document_invalidPakollinen kenttä puuttuu tai raja ylittyy.Korjaa asiakirja; tavallisessa erässä vain tämä asiakirja epäonnistuu.
409 sources.push_sync_openToinen synkronointi on vielä auki.Sulje se tai odota, kunnes sen voimassaolo päättyy.
409 sources.push_sync_closedSynkronointi on suljettu, tai sen voimassaolo on päättynyt.Avaa uusi synkronointi; kasvata max_minutes-arvoa pitkiä vientejä varten.
403 sources.feature_disabledLähteet eivät sisälly organisaation pakettiin.Ota yhteyttä ylläpitäjään.
429Liian monta pyyntöä.Odota Retry-After-ajan verran; lähetä harvempia ja suurempia eriä.