Importera dokument
Den här guiden visar hur du lägger in dina dokument i Sursa med API:et för kort: några dokument från ett skript, eller alla dokument i ett system genom ett regelbundet jobb. Varje dokument blir ett kort i en samling. Folk hittar det i sökningen, assistenten svarar utifrån det, och det har en ansvarig, taggar, verifiering och behörigheter som alla andra kort.
Om du vill att Sursa ska räkna ut vilka dokument som har tagits bort i ditt system, eller om du skickar dokument från en integrationsplattform, använder du i stället en egen källa. Den är byggd för fullständiga och inkrementella synkningar. Den här guiden tar upp direkta skrivningar till en samling.
Du behöver en API-nyckel med omfånget cards:write och en roll som får skriva till målsamlingen (editor eller
admin). Exemplen använder hjälpfunktionen från Snabbstart.
Välj rätt slutpunkt
| Du har | Använd |
|---|---|
| En post med ett stabilt id i ditt system | PUT /v1/cards-by-external-id/{external_id}: skapa eller ersätt med ditt id. |
| Text som ska läggas till en gång, utan eget id | POST /v1/cards/text |
| En fil som ska läggas till en gång | POST /v1/cards |
| Ett ZIP-arkiv med många filer | POST /v1/cards/archive |
| En fil som är större än gränsen för ett enda anrop | En uppladdning i delar, och sedan någon av slutpunkterna ovan. |
| Nytt innehåll för ett kort som du redan har | PUT /v1/cards/{card_id}/content |
För allt som du importerar mer än en gång använder du external_id. Det gör varje import upprepbar: kör du den igen
uppdateras korten som den skapade i stället för att kopior läggs till.
Skapa eller ersätt ett kort med ditt id
PUT /v1/cards-by-external-id/{external_id} tar id:t för posten i ditt system. Om inget kort har detta external_id
skapas ett (201). Om ett kort har det ersätts kortets innehåll och uppgifter (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"}
}'Det här händer vid en upprepning:
- Innehållet har inte ändrats: ingen ny version skapas. Svaret är
200med"status": "skipped"och"reason": "unchanged". Det är alltid säkert att upprepa anropet, även utan enIdempotency-Key. - Innehållet har ändrats: kortet får en ny version och indexeras igen. Dess rubrik, taggar, ansvarig, kategori och
metadatafår de värden som du skickade;metadataersätts i sin helhet. - Samlingen och mappen gäller bara när kortet skapas. För att flytta ett kort senare ändrar du det med
PATCH /v1/cards/{card_id}.
En ny version tar bort kortets verifiering, som varje ändring av innehållet gör: en granskare bekräftar det igen.
Textformat
content_type | Brödtexten är |
|---|---|
markdown (standard) | Markdown. |
html | HTML. Den rensas ned till enkel märkning: rubriker, stycken, listor, tabeller och länkar av typen http, https och mailto. Skript, stilar, ramar, formulär och bilder tas bort tillsammans med sitt innehåll. |
text | Vanlig text. Stycken skiljs åt med tomma rader. |
Vänta på kortet, eller inte
Som standard returnerar anropet när kortet är klart att hittas, med "status": "ready" och kortet i card. Det tar
allt från en bråkdel av en sekund för en kort text till en minut eller mer för en lång fil.
För massimporter skickar du "async": true. Svaret kommer genast med "status": "queued" och indexeringsjobbet i job
(med dess job_id). Kontrollera jobbet med GET /v1/jobs/{job_id}, eller följ alla jobb i
GET /v1/jobs/stream. Ett jobb slutar med status done, error eller canceled.
curl https://api.sursa.com/v1/jobs/48213 \
-H "Authorization: Bearer $SURSA_API_KEY"Ladda upp en fil
Filer skickas i ett multipart/form-data-anrop, i fältet file. Sursa läser PDF, Word, Excel, PowerPoint,
OpenDocument-kalkylblad, CSV, Markdown, HTML, AsciiDoc, e-post (.eml), vanlig text och vanliga bildformat. Sursa
kontrollerar att filens namn, angivna typ och innehåll stämmer överens, och avvisar en avvikelse med 415.
För att skapa eller ersätta ett filkort med ditt id skickar du filen till samma 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"}'I ett formulär är tags en kommaseparerad sträng och metadata ett JSON-objekt som skrivs som en sträng. Ett nytt
kort utan title får filnamnet som rubrik.
För att lägga till en fil en gång, utan eget id, använder du POST /v1/cards med samma
formulär och en Idempotency-Key. Laddar du upp en fil som samlingen redan har returneras "status": "skipped" med
"duplicate": true och det befintliga card_id, om du inte skickar ett external_id.
Storleken på en enskild fil begränsas av installationen (200 MB som standard). För större filer, eller för opålitliga nätverk, laddar du först upp filen i delar.
Ersätt innehållet i ett kort
När du redan har ett korts id i Sursa ersätter PUT /v1/cards/{card_id}/content
dess text eller fil och behåller allt annat: ansvarig, taggar, granskare, verifieringsintervall och en kategori som har
angetts för hand.
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."}'- Samma innehåll igen returnerar
"status": "skipped"med"reason": "unchanged". - Ett kort som indexeras just nu returnerar
409med kodencards.indexing_in_progress. Försök igen om några sekunder. - Ett kort som kommer från en källa, till exempel en connector eller en egen källa, ändras bara i sin källa:
cards.managed_by_source. - Nyckeln måste få se hela kortet; ett delvis synligt kort returnerar
cards.content_whole_access.
Importera många dokument
En loop över dina poster med PUT /v1/cards-by-external-id/… är den enklaste massimporten, och den är säker att
stoppa och köra igen när som helst. Så gör du den snabb och skonsam mot hastighetsbegränsningen:
- Skicka
"async": true, så att varje anrop returnerar så snart kortet har köats. - Kör några anrop parallellt (4–8) och sakta ned när huvudet
RateLimitvisar att få anrop återstår. Se Hastighetsbegränsningar och kvoter. - Vid
429väntar du påRetry-After; vid ett nätverksfel eller5xxförsöker du igen med samma anrop. Upprepningar gör ingen skada. - Anteckna
external_idför varje post som slutar med ett fel och försök igen med dem i slutet.
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;
}För ett ZIP-arkiv med filer gör POST /v1/cards/archive varje fil som stöds
i arkivet till ett kort med ett enda anrop. Den svarar genast med planen (vilka filer som blir kort och vilka som hoppas
över, och varför) och ett jobb; GET /v1/archives/{job_id} rapporterar
resultatet.
Hitta och ta bort importerade kort
- Läs ett kort med ditt id med
GET /v1/cards-by-external-id/{external_id}. - Lista korten från en import med ett metadatafilter:
GET /v1/cards?metadata[source]=helpdesk. Se Metadata. - Ta bort ett kort med
DELETE /v1/cards/{card_id}.
Vanliga fel
| Kod | Orsak | Vad du gör |
|---|---|---|
collections.not_found | Ingen samling med det här id:t eller namnet är synlig för nyckeln. | Kontrollera collection_id med GET /v1/collections. |
collections.no_write_access | Nyckeln får inte skriva till den här samlingen. | Använd en nyckel med rollen editor och åtkomst till samlingen. |
cards.external_id_taken | POST med ett external_id som ett annat kort redan har. | Använd PUT /v1/cards-by-external-id/… för att ersätta det. |
cards.managed_by_source | Kortet hör till en källa. | Ändra dokumentet i dess källa. |
files.type_mismatch | Filens namn, typ och innehåll stämmer inte överens. | Skicka filen med dess riktiga filändelse. |
files.too_large | Filen är större än gränsen för uppladdningar eller organisationens lagringsutrymme. | Använd en uppladdning i delar eller frigör lagringsutrymme. |
limits.cards | Organisationen har nått prisplanens gräns för antalet kort. | Ta bort kort som inte längre behövs eller byt prisplan. |
api.metadata_invalid | metadata bryter mot en gräns. | Se Metadata. |