Към съдържанието
Sursa Developers

Синхронизация на вашата система със собствен източник

Собственият източник свързва система, за която няма вграден конектор: вашето уики, системата ви за заявки към поддръжката, база данни, експорт от каквото и да е място. Вашият код изпраща документи до Sursa, а Sursa ги превръща в карти в колекцията и папките, за които е настроен източникът, със същото търсене, отговори, проверка и права като картите от всеки друг източник.

За разлика от директния запис на карти, собственият източник следи какво сте изпратили. В края на пълна синхронизация Sursa архивира всеки документ, който не сте изпратили, така че изтриванията във вашата система стигат до Sursa без допълнителна работа.

Настройка на източника

Администраторът създава източника в Sursa в Sources → New source → Custom source (източници, нов източник, собствен източник) и избира:

  • колекцията и по желание папка за картите му;
  • режима на папките: всички карти в избраната папка или подпапки, които повтарят path на всеки документ;
  • правата: правата на колекцията или „as in the source“ (както в източника), при което всеки документ посочва кой може да го вижда.

Страницата на източника показва неговото ID; примерите използват 42.

Избор на ключ

КлючЗапочва сМоже да прави
Ключ на източникаkbsrc_Запис на документи в този един източник. Нищо друго: не може да чете и да търси. Създайте го на страницата на източника в раздела API keys.
Ключ на организацията с обхвата import:writekb_Запис във всеки собствен източник на организацията и четене на състоянието му. За създаване на източник и ключовете му е нужен обхватът admin.

Ключът на източника е най-безопасният избор за една интеграция, особено за такава, която работи в платформа на трета страна. Ключ на организацията с import:write е подходящ за услуга, която захранва няколко източника.

И двата ключа се изпращат по един и същ начин и всички операции за изпращане (push) се намират под /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даВашият стабилен идентификатор на документа, до 512 знака. Повторното изпращане на същия идентификатор заменя документа.
titleдаЗаглавие на картата, до 500 знака. За файл – по подразбиране името на файла.
contentда, освен ако няма файлДо 5 MB.
content_typeнеhtml (по подразбиране), markdown или text. HTML се изчиства от скриптове, стилове, формуляри и вградени обекти.
urlнеВръзка към документа във вашата система, показвана в картата.
pathнеПапки, като масив (["Support", "Billing"]) или низ ("Support/Billing"), до 10 нива.
permissionsне{"everyone": true} или {"emails": [...], "groups": [...]}. Използва се, когато правата на източника са „as in the source“.
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; ключът на източника не може да ги създава.

Два начина за изпращане

Директните актуализации са подходящи за системи, които ви съобщават за всяка промяна, например уебхук от системата ви за поддръжка или стъпка в 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}Премахва един документ. Кодирайте идентификатора за 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"]
}

Всеки изтрит идентификатор получава собствен запис в 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) пристигат чрез уебхук и в лентата със събития.

Повторни опити

  • Изпращайте Idempotency-Key с всяка заявка POST. Повторен пакет със същия ключ връща първия резултат.
  • Дори без ключа документ със същия 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; изпращайте по-малко и по-големи пакети.