Пређите на садржај
Sursa Developers

Синхронизација вашег система помоћу сопственог извора

Сопствени извор повезује систем који нема уграђени конектор: ваш вики, ваш алат за тикете, базу података, извоз из било ког система. Ваш код шаље документе платформи Sursa, а Sursa их претвара у картице у колекцији и фолдерима за које је извор подешен, са истом претрагом, одговорима, провером и дозволама као и картице из било ког другог извора.

За разлику од директног уписа картица, сопствени извор прати шта сте послали. На крају потпуне синхронизације Sursa архивира сваки документ који нисте послали, па брисања у вашем систему стижу до платформе Sursa без додатног рада.

Подешавање извора

Администратор креира извор у платформи Sursa у Sources → New source → Custom source (извори, нови извор, сопствени извор) и бира:

  • колекцију и, по жељи, фолдер за његове картице;
  • режим фолдера: све картице у изабраном фолдеру или подфолдери који пресликавају path сваког документа;
  • дозволе: дозволе колекције или „као у извору“, где сваки документ наводи ко сме да га види.

Страница извора приказује његов ID; примери користе 42.

Избор кључа

КључПочиње саМоже да
Кључ извораkbsrc_Уписује документе у овај један извор. Ништа друго: не може да чита ни да претражује. Креирајте га на страници извора, у одељку API keys.
Кључ организације са опсегом import:writekb_Уписује у било који сопствени извор организације и чита његово стање. За креирање извора и његових кључева потребан је опсег admin.

Кључ извора је најбезбеднији избор за једну интеграцију, нарочито ако она ради на платформи треће стране. Кључ организације са import:write одговара сервису који пуни више извора.

Оба кључа се шаљу на исти начин, а свака операција слања налази се под /v1/push/sources/{source_id}. Кључ и стање извора проверите помоћу 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}

Документ

ПољеОбавезноОпис
external_idдаВаш стабилни ID документа, до 512 знакова. Поновно слање истог идентификатора замењује документ.
titleдаНаслов картице, до 500 знакова. За фајл је подразумевано име фајла.
contentда, осим ако постоји фајлДо 5 MB.
content_typeнеhtml (подразумевано), markdown или text. Из HTML садржаја уклањају се скрипте, стилови, обрасци и уграђени објекти.
urlнеЛинк ка документу у вашем систему, приказује се на картици.
pathнеФолдери, као низ (["Support", "Billing"]) или стринг ("Support/Billing"), до 10 нивоа.
permissionsне{"everyone": true} или {"emails": [...], "groups": [...]}. Користи се када су дозволе извора „као у извору“.
tagsнеДо 50 ознака, које се додају ознакама извора.
author_emailнеАко је то корисник организације, постаје власник картице.
updated_atнеКада се документ променио у вашем систему (RFC 3339).
metadataнеВаши парови кључ–вредност на картици. Погледајте Метаподаци.
categoryнеКатегорија картице: кључ једне од категорија организације.
verifiers, verify_interval_daysнеКо проверава картицу (корисници по имејл адреси и групе) и колико често, у данима.
upload_idнеФајл документа из отпремања у деловима, уместо content.
attachmentsнеДо 20 додатних фајлова документа, као листа upload_id. Сваки постаје засебна картица извора.

Уместо content, један документ може да носи фајл до 100 MB у захтеву multipart/form-data: фајл у делу file, а горња поља као JSON у делу document. Отпремања у деловима за upload_id и attachments креирају се кључем организације који има опсег import:write, са наменом import_attachment; кључ извора не може да их креира.

Два начина слања

Директна ажурирања одговарају системима који вас обавештавају о свакој измени, као што су вебхук из вашег helpdesk система или корак у алату Zapier. Пошаљите документ када се креира или промени и обришите га када се уклони:

ЗахтевШта ради
POST /v1/push/sources/{source_id}/documentsКреира или замењује један документ.
POST /v1/push/sources/{source_id}/documents/batchКреира или замењује много докумената одједном.
DELETE /v1/push/sources/{source_id}/documents/{external_id}Уклања један документ. Кодирајте ID за URL.

Измене постају картице у року од отприлике једног минута; више узастопних измена обрађује се заједно.

Синхронизације одговарају редовним извозима: шаљете све или све што се променило, а Sursa усклађује стање. Остатак овог водича говори о синхронизацијама.

Потпуна синхронизација

Синхронизација има три корака: отварање, слање и затварање.

1. Отворите синхронизацију

POST /v1/push/sources/{source_id}/syncs отвара синхронизацију и враћа њен број:

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 је initial за прву синхронизацију извора, а incremental када је нека синхронизација већ завршена. Синхронизација incremental пре било које завршене враћа sources.push_initial_required.
  • Истовремено може да буде отворена само једна синхронизација: друга враћа 409 sources.push_sync_open.
  • Синхронизација остаје отворена max_minutes минута (подразумевано 60, највише 1440). После тога истиче: ништа се не архивира, а њен број се више не прихвата. Изаберите време које је знатно дуже од трајања вашег извоза.

2. Пошаљите документе

Документе шаљите у пакетима до 500, са бројем синхронизације. Тело пакета има до 50 MiB; фајлови унутар пакета прослеђују се као 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"}}
    ]
  }'

Одговор садржи резултат за сваки документ, редоследом којим сте их послали:

{
  "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…"}
  ]
}
ПољеЗначење
resultШта се сада десило са документом: created, updated, unchanged, deleted, not_found, error или skipped (у атомском пакету који није примењен).
statusДокле је документ стигао на путу до картице: pending, processing (картица је уписана и индексира се), indexed, failed или removed.
card_idКартица документа, када постоји.
versionХеш садржаја и поља. Исти документ послат поново има исту верзију и добија unchanged.
error, reasonЗашто документ није успео. reason је стабилан код: content_invalid, file_rejected, too_large, limit_reached, index_failed или batch_rejected (други документ атомског пакета није успео).

Подразумевано се сваки документ пакета примењује засебно: један лош документ не зауставља остале.

Документи који се нису променили од последње синхронизације не морају поново да се шаљу. Потврдите их по идентификатору помоћу POST /v1/push/sources/{source_id}/syncs/{sync_number}/touch, до 1000 идентификатора по захтеву, како би их потпуно усклађивање задржало:

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. Затворите синхронизацију

POST /v1/push/sources/{source_id}/syncs/{sync_number}/close завршава синхронизацију:

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Ефекат
completeПотпуно усклађивање. Сваки документ извора који у овој синхронизацији није ни послат ни потврђен архивира се. Користите га само када сте послали све.
complete_incrementalПримењује оно што сте послали и ништа не архивира.
failedНишта не архивира и задржава оно што је већ послато. Додајте reason (на пример API_ERROR) и error_details за дневник.

Затворите са failed кад год се ваш извоз заустави на пола пута: complete после делимичног извоза архивирао би сваки документ до ког нисте стигли. Понављање истог затварања враћа исти резултат.

После затварања Sursa претвара документе у картице у року од отприлике једног минута. Страница извора приказује сваку синхронизацију са бројем послатих и архивираних докумената, а GET /v1/push/sources/{source_id}/syncs/{sync_number} враћа исте бројаче.

Инкременталне синхронизације

Између потпуних синхронизација шаљите само оно што се променило:

  1. Отворите синхронизацију са "type": "incremental".
  2. Пошаљите измењене документе, а идентификаторе уклоњених ставите у deletes (в. у наставку).
  3. Затворите са complete_incremental.

С времена на време, на пример једном недељно, покрените потпуну синхронизацију да бисте ухватили све што је инкрементално покретање пропустило.

Брисање докумената у пакету

Пакет може да уклања документе заједно са онима које уписује. Наведите њихове идентификаторе у deletes:

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

Сваки обрисани ID добија сопствену ставку у results, са result deleted или not_found ако извор нема такав документ. Поновно брисање истог идентификатора не прави штету.

Атомски пакети

Неке измене имају смисла само заједно, на пример документ и онај који га замењује. Пошаљите "atomic": true и пакет ће бити примењен у потпуности или уопште неће: ако било који документ не прође провере, ништа из пакета се не примењује, а одговор је 422 са кодом sources.push_batch_rejected и резултатом сваког документа у error.details.results: документи који нису успели имају error, а остали skipped.

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

Без atomic пакет се примењује документ по документ. Атомске пакете користите за повезане измене, а обичне пакете за масовна пуњења, где један лош документ не треба да задржи остале.

Провера резултата сваког документа

Одговор на пакет вам каже како је сваки документ уписан. Претварање у картицу дешава се након тога, па status још може да буде pending. Да бисте пронашли документе синхронизације који нису постали картице:

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

Свака ставка има external_id, title, status, card_id, version и reason, а листа се дели на странице помоћу cursor. status прихвата и pending, processing, indexed и removed.

Уместо да питате, можете и да добијате обавештења: догађаји import.sync_completed (синхронизација је затворена и обрађена, са укупним бројевима) и import.document_failed (документ није постао картица, са својим reason) стижу преко вебхука и у фиду догађаја.

Поновни покушаји

  • Уз сваки POST пошаљите Idempotency-Key. Поновљени пакет са истим кључем враћа први резултат.
  • Чак и без кључа, документ са истим external_id никада не постаје друга картица: добија unchanged или updated.
  • Ако се процес заустави усред синхронизације, отворите нову пошто стара истекне или затворите стару са failed ако још имате њен број, па поново покрените синхронизацију.

Ограничења

ОграничењеВредност
Садржај једног документа5 MB
Фајл у захтеву са једним документом100 MB
Докумената по пакету500
Тело захтева са пакетом50 MiB
Идентификатора по захтеву touch1000
Докумената по изворуЗависи од плана: од 100.000
Отворена синхронизацијаПодразумевано 60 минута, највише 24 сата

Документ изнад ограничења броја докумената извора у пакету не успева, са разлогом limit_reached; захтев са једним документом враћа 409 са кодом sources.push_too_many_documents. Ограничења учесталости важе као и за сваки други захтев; погледајте Ограничења учесталости и квоте.

Честе грешке

ОдговорУзрокШта урадити
401 sources.push_key_invalidКључ је погрешан, опозван или припада другом извору.Проверите кључ и ID извора у путањи.
400 sources.push_document_invalidНедостаје обавезно поље или је прекорачено ограничење.Исправите документ; у обичном пакету не успева само тај документ.
409 sources.push_sync_openДруга синхронизација је још отворена.Затворите је или сачекајте да истекне.
409 sources.push_sync_closedСинхронизација је затворена или је истекла.Отворите нову синхронизацију; за дуге извозе повећајте max_minutes.
403 sources.feature_disabledИзвори нису део плана организације.Обратите се администратору.
429Превише захтева.Сачекајте Retry-After; шаљите мање пакета, а веће.