Import dokumentů
Tento návod ukazuje, jak pomocí API karet vložit dokumenty do Sursy: několik dokumentů ze skriptu, nebo všechny dokumenty určitého systému pravidelnou úlohou. Z každého dokumentu se stane karta v kolekci. Lidé ji najdou při vyhledávání, asistent z ní odpovídá a má vlastníka, štítky, ověření a oprávnění jako každá jiná karta.
Pokud chcete, aby Sursa sama zjistila, které dokumenty byly ve vašem systému smazány, nebo pokud dokumenty odesíláte z integrační platformy, použijte místo toho vlastní zdroj. Je určený pro úplné a přírůstkové synchronizace. Tento návod popisuje přímý zápis do kolekce.
Potřebujete klíč API s rozsahem cards:write a roli, která smí zapisovat do cílové kolekce (editor nebo admin).
Ukázky používají pomocnou funkci z Rychlého startu.
Výběr správné operace
| Máte | Použijte |
|---|---|
| Záznam se stabilním identifikátorem ve vašem systému | PUT /v1/cards-by-external-id/{external_id}: vytvoření nebo nahrazení podle vašeho identifikátoru. |
| Text, který přidáte jednou, bez vlastního identifikátoru | POST /v1/cards/text |
| Soubor, který přidáte jednou | POST /v1/cards |
| Archiv ZIP s mnoha soubory | POST /v1/cards/archive |
| Soubor větší než limit jednoho požadavku | Nahrávání po částech a pak kteroukoli z operací výše. |
| Nový obsah pro kartu, kterou už máte | PUT /v1/cards/{card_id}/content |
Pro vše, co importujete víc než jednou, používejte external_id. Díky němu je každý import opakovatelný: další
spuštění aktualizuje karty, které vytvořilo, místo aby přidávalo kopie.
Vytvoření nebo nahrazení karty podle vašeho identifikátoru
PUT /v1/cards-by-external-id/{external_id} přijímá identifikátor záznamu ve vašem systému. Pokud žádná karta toto
external_id nemá, vytvoří novou (201). Pokud ho některá karta má, nahradí její obsah a údaje (200).
curl -X PUT https://api.sursa.com/v1/cards-by-external-id/kb-article-1042 \
-H "Authorization: Bearer $SURSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"collection_id": 3,
"folder_id": "0f8e2d7c-4b6a-4e1f-9c3d-2a5b8e7f1c40",
"title": "Returning a damaged item",
"content_type": "html",
"body": "<h2>Damaged items</h2><p>Send a photo within 7 days and we ship a replacement.</p>",
"tags": ["returns", "shipping"],
"metadata": {"source": "helpdesk", "article_id": "1042"}
}'Co se stane při opakování:
- Obsah se nezměnil: nová verze nevznikne. Odpověď je
200s"status": "skipped"a"reason": "unchanged". Opakovat požadavek je vždy bezpečné, i bezIdempotency-Key. - Obsah se změnil: karta dostane novou verzi a znovu se indexuje. Její název, štítky, vlastník, kategorie
a
metadatapřevezmou odeslané hodnoty;metadatase nahradí jako celek. - Kolekce a složka se uplatní jen při vytvoření karty. Chcete-li kartu později přesunout, změňte ji pomocí
PATCH /v1/cards/{card_id}.
Nová verze odebere kartě ověření, stejně jako každá změna obsahu: ověřovatel ji potvrdí znovu.
Formáty textu
content_type | Tělo je |
|---|---|
markdown (výchozí) | Markdown. |
html | HTML. Vyčistí se na jednoduché značky: nadpisy, odstavce, seznamy, tabulky a odkazy http, https a mailto. Skripty, styly, rámy, formuláře a obrázky se odstraní i se svým obsahem. |
text | Prostý text. Odstavce se oddělují prázdnými řádky. |
Čekat na kartu, nebo nečekat
Ve výchozím nastavení se požadavek vrátí, jakmile je karta připravená k nalezení, s "status": "ready" a kartou
v card. To trvá od zlomku sekundy u krátkého textu po minutu i déle u dlouhého souboru.
U hromadných importů odešlete "async": true. Odpověď přijde okamžitě s "status": "queued" a úlohou indexování
v job (s jejím job_id). Úlohu kontrolujte pomocí GET /v1/jobs/{job_id}, nebo
sledujte všechny úlohy v GET /v1/jobs/stream. Úloha skončí se status done,
error nebo canceled.
curl https://api.sursa.com/v1/jobs/48213 \
-H "Authorization: Bearer $SURSA_API_KEY"Nahrání souboru
Soubory se posílají v požadavku multipart/form-data v poli file. Sursa načte PDF, Word, Excel, PowerPoint,
tabulky OpenDocument, CSV, Markdown, HTML, AsciiDoc, e-maily (.eml), prostý text a běžné formáty obrázků.
Kontroluje, že se název souboru, deklarovaný typ a obsah shodují, a nesoulad odmítne s 415.
Chcete-li vytvořit nebo nahradit kartu se souborem podle vlastního identifikátoru, odešlete soubor na stejnou operaci
PUT /v1/cards-by-external-id/{external_id}:
curl -X PUT https://api.sursa.com/v1/cards-by-external-id/handbook-2026 \
-H "Authorization: Bearer $SURSA_API_KEY" \
-F "file=@employee-handbook.pdf" \
-F "collection_id=3" \
-F "tags=hr,policies" \
-F 'metadata={"owner_team":"people"}'Ve formuláři je tags řetězec oddělený čárkami a metadata objekt JSON zapsaný jako řetězec. Nová karta bez
title dostane jako název jméno souboru.
Chcete-li soubor přidat jednou, bez vlastního identifikátoru, použijte POST /v1/cards
se stejným formulářem a s Idempotency-Key. Nahrání souboru, který kolekce už obsahuje, vrátí "status": "skipped"
s "duplicate": true a card_id existující karty, pokud nepředáte external_id.
Velikost jednoho souboru omezuje instalace (výchozí je 200 MB). Větší soubory nebo soubory odesílané přes nespolehlivou síť nejdřív nahrajte po částech.
Nahrazení obsahu karty
Pokud už ID karty v Surse máte, PUT /v1/cards/{card_id}/content nahradí
její text nebo soubor a vše ostatní ponechá: vlastníka, štítky, ověřovatele, interval ověřování a ručně nastavenou
kategorii.
curl -X PUT https://api.sursa.com/v1/cards/3f2c9a7e-5b1d-4c8e-9f0a-1b2c3d4e5f60/content \
-H "Authorization: Bearer $SURSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"content_type": "markdown", "body": "# Refund policy\n\nRefunds are processed within 10 days."}'- Opětovně odeslaný stejný obsah vrátí
"status": "skipped"s"reason": "unchanged". - Karta, která se právě indexuje, vrátí
409s kódemcards.indexing_in_progress. Zopakujte požadavek za několik sekund. - Karta, která pochází ze zdroje, například z konektoru nebo vlastního zdroje, se mění jen ve svém zdroji:
cards.managed_by_source. - Klíč musí smět vidět celou kartu; částečně viditelná karta vrátí
cards.content_whole_access.
Import mnoha dokumentů
Smyčka přes vaše záznamy s PUT /v1/cards-by-external-id/… je nejjednodušší hromadný import a lze ji kdykoli
zastavit a spustit znovu. Aby byla rychlá a šetrná k limitu četnosti:
- Odesílejte
"async": true, aby se každý požadavek vrátil, jakmile se karta zařadí do fronty. - Spouštějte několik požadavků paralelně (4 až 8) a zpomalte, když hlavička
RateLimitukazuje, že zbývá málo požadavků. Viz Limity četnosti a kvóty. - Při
429počkejte podleRetry-After; při chybě sítě nebo5xxzopakujte stejný požadavek. Opakování nic nepokazí. - Zaznamenejte
external_idkaždého záznamu, který skončí chybou, a ty na konci zopakujte.
import { api } from "./sursa.mjs";
async function importAll(records, concurrency = 6) {
const failed = [];
const queue = [...records];
async function worker() {
for (let record = queue.shift(); record; record = queue.shift()) {
try {
await api("PUT", `/v1/cards-by-external-id/${encodeURIComponent(record.id)}`, {
collection_id: 3,
title: record.title,
content_type: "html",
body: record.html,
metadata: { source: "helpdesk" },
async: true,
});
} catch (error) {
failed.push({ id: record.id, error: String(error) });
}
}
}
await Promise.all(Array.from({ length: concurrency }, worker));
return failed;
}U archivu ZIP se soubory vytvoří POST /v1/cards/archive jedním
požadavkem kartu z každého podporovaného souboru uvnitř. Odpoví okamžitě plánem (které soubory se stanou kartami,
které se přeskočí a proč) a úlohou; výsledek hlásí GET /v1/archives/{job_id}.
Vyhledání a odstranění importovaných karet
- Kartu podle svého identifikátoru přečtete pomocí
GET /v1/cards-by-external-id/{external_id}. - Karty jednoho importu vypíšete pomocí filtru metadat:
GET /v1/cards?metadata[source]=helpdesk. Viz Metadata. - Kartu smažete pomocí
DELETE /v1/cards/{card_id}.
Časté chyby
| Kód | Příčina | Co dělat |
|---|---|---|
collections.not_found | Klíč nevidí žádnou kolekci s tímto ID nebo názvem. | Zkontrolujte collection_id pomocí GET /v1/collections. |
collections.no_write_access | Klíč nesmí do této kolekce zapisovat. | Použijte klíč s rolí editor a přístupem ke kolekci. |
cards.external_id_taken | POST s external_id, které už má jiná karta. | K nahrazení použijte PUT /v1/cards-by-external-id/…. |
cards.managed_by_source | Karta patří zdroji. | Změňte dokument v jeho zdroji. |
files.type_mismatch | Název, typ a obsah souboru si neodpovídají. | Odešlete soubor s jeho skutečnou příponou. |
files.too_large | Soubor přesahuje limit nahrávání nebo úložiště organizace. | Použijte nahrávání po částech, nebo uvolněte úložiště. |
limits.cards | Organizace dosáhla limitu karet svého tarifu. | Smažte karty, které už nejsou potřeba, nebo změňte tarif. |
api.metadata_invalid | metadata porušuje limit. | Viz Metadata. |