Importer dokumenter
Denne veiledningen viser hvordan du legger dokumentene dine inn i Sursa med kort-API-et: noen få dokumenter fra et skript, eller alle dokumentene i et system gjennom en fast jobb. Hvert dokument blir et kort i en samling. Folk finner det i søket, assistenten svarer ut fra det, og det har en ansvarlig, tagger, verifisering og tillatelser som alle andre kort.
Hvis du vil at Sursa skal finne ut hvilke dokumenter som er slettet i systemet ditt, eller hvis du sender dokumenter fra en integrasjonsplattform, bruker du en egendefinert kilde i stedet. Den er laget for fulle og inkrementelle synkroniseringer. Denne veiledningen handler om å skrive direkte til en samling.
Du trenger en API-nøkkel med scopet cards:write og en rolle som kan skrive til målsamlingen (editor eller
admin). Eksemplene bruker hjelpefunksjonen fra Hurtigstart.
Velg riktig operasjon
| Du har | Bruk |
|---|---|
| En post med en stabil ID i systemet ditt | PUT /v1/cards-by-external-id/{external_id}: Opprett eller erstatt med din ID. |
| Tekst som skal legges til én gang, uten egen ID | POST /v1/cards/text |
| En fil som skal legges til én gang | POST /v1/cards |
| Et ZIP-arkiv med mange filer | POST /v1/cards/archive |
| En fil som er større enn grensen for én forespørsel | En opplasting i deler, deretter en av operasjonene ovenfor. |
| Nytt innhold for et kort du allerede har | PUT /v1/cards/{card_id}/content |
For alt du importerer mer enn én gang, bruker du external_id. Den gjør hver import gjentakbar: Kjører du den på
nytt, oppdateres kortene den opprettet, i stedet for at det legges til kopier.
Opprett eller erstatt et kort med din ID
PUT /v1/cards-by-external-id/{external_id} tar ID-en til posten i systemet ditt. Hvis ingen kort har denne
external_id, opprettes et kort (201). Hvis et kort har den, erstattes innholdet og detaljene til kortet (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"}
}'Dette skjer ved en gjentakelse:
- Innholdet er ikke endret: Ingen ny versjon lages. Svaret er
200med"status": "skipped"og"reason": "unchanged". Det er alltid trygt å gjenta forespørselen, selv uten enIdempotency-Key. - Innholdet er endret: Kortet får en ny versjon og indekseres på nytt. Tittelen, taggene, den ansvarlige,
kategorien og
metadatafår verdiene du sendte;metadataerstattes under ett. - Samlingen og mappen gjelder bare når kortet opprettes. For å flytte et kort senere endrer du det med
PATCH /v1/cards/{card_id}.
En ny versjon fjerner verifiseringen av kortet, slik enhver endring av innholdet gjør: En kontrollør bekrefter det på nytt.
Tekstformater
content_type | Brødteksten er |
|---|---|
markdown (standard) | Markdown. |
html | HTML. Den renses ned til enkel markering: overskrifter, avsnitt, lister, tabeller og lenker med http, https og mailto. Skript, stiler, rammer, skjemaer og bilder fjernes sammen med innholdet sitt. |
text | Ren tekst. Avsnitt skilles med tomme linjer. |
Vent på kortet, eller la være
Som standard returnerer forespørselen når kortet er klart til å bli funnet, med "status": "ready" og kortet i
card. Det tar fra en brøkdel av et sekund for en kort tekst til ett minutt eller mer for en lang fil.
For masseimport sender du "async": true. Svaret kommer med en gang med "status": "queued" og indekseringsjobben
i job (med job_id). Kontroller jobben med GET /v1/jobs/{job_id}, eller følg alle
jobber i GET /v1/jobs/stream. En jobb avsluttes med status done, error eller canceled.
curl https://api.sursa.com/v1/jobs/48213 \
-H "Authorization: Bearer $SURSA_API_KEY"Last opp en fil
Filer sendes i en multipart/form-data-forespørsel, i feltet file. Sursa leser PDF, Word, Excel, PowerPoint,
OpenDocument-regneark, CSV, Markdown, HTML, AsciiDoc, e-post (.eml), ren tekst og vanlige bildeformater. Sursa
kontrollerer at filens navn, oppgitte type og innhold stemmer overens, og avviser et avvik med 415.
For å opprette eller erstatte et filkort med din ID sender du filen til den samme
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 et skjema er tags en kommaseparert streng, og metadata er et JSON-objekt skrevet som en streng. Et nytt kort
uten title får filnavnet som tittel.
For å legge til en fil én gang, uten egen ID, bruker du POST /v1/cards med det samme
skjemaet og en Idempotency-Key. Laster du opp en fil som samlingen allerede har, returneres "status": "skipped"
med "duplicate": true og den eksisterende card_id, med mindre du sender en external_id.
Størrelsen på én fil er begrenset av installasjonen (200 MB som standard). For større filer, eller på ustabile nettverk, laster du først opp filen i deler.
Erstatt innholdet i et kort
Når du allerede har Sursa-ID-en til et kort, erstatter PUT /v1/cards/{card_id}/content
teksten eller filen og beholder alt annet: den ansvarlige, taggene, kontrollørene, verifiseringsintervallet og en
kategori som er satt manuelt.
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."}'- Det samme innholdet på nytt returnerer
"status": "skipped"med"reason": "unchanged". - Et kort som indekseres akkurat nå, returnerer
409med kodencards.indexing_in_progress. Prøv på nytt om noen sekunder. - Et kort som kommer fra en kilde, for eksempel en kobling eller en egendefinert kilde, endres bare i kilden:
cards.managed_by_source. - Nøkkelen må ha lov til å se hele kortet; et kort som bare er delvis synlig, returnerer
cards.content_whole_access.
Importer mange dokumenter
En løkke over postene dine med PUT /v1/cards-by-external-id/… er den enkleste masseimporten, og det er trygt å
stoppe den og kjøre den på nytt når som helst. Slik gjør du den rask og skånsom mot hastighetsgrensen:
- Send
"async": true, slik at hver forespørsel returnerer så snart kortet er lagt i kø. - Kjør noen forespørsler parallelt (4 til 8), og senk tempoet når headeren
RateLimitviser at det er få forespørsler igjen. Se Hastighetsgrenser og kvoter. - Vent i
Retry-Aftersekunder ved429; prøv den samme forespørselen på nytt ved en nettverksfeil eller5xx. Gjentakelser gjør ingen skade. - Noter
external_idfor hver post som ender med en feil, og prøv dem på nytt til slutt.
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;
}For et ZIP-arkiv med filer gjør POST /v1/cards/archive hver støttet fil i
arkivet om til et kort med én forespørsel. Den svarer med en gang med planen for utpakking (hvilke filer som blir
kort, hvilke som hoppes over, og hvorfor) og en jobb; GET /v1/archives/{job_id}
rapporterer resultatet.
Finn og fjern importerte kort
- Les et kort etter din ID med
GET /v1/cards-by-external-id/{external_id}. - Vis kortene fra én import med et metadatafilter:
GET /v1/cards?metadata[source]=helpdesk. Se Metadata. - Slett et kort med
DELETE /v1/cards/{card_id}.
Vanlige feil
| Kode | Årsak | Hva du gjør |
|---|---|---|
collections.not_found | Ingen samling med denne ID-en eller dette navnet er synlig for nøkkelen. | Kontroller collection_id med GET /v1/collections. |
collections.no_write_access | Nøkkelen har ikke lov til å skrive til denne samlingen. | Bruk en nøkkel med rollen editor og tilgang til samlingen. |
cards.external_id_taken | POST med en external_id som et annet kort allerede har. | Bruk PUT /v1/cards-by-external-id/… for å erstatte kortet. |
cards.managed_by_source | Kortet tilhører en kilde. | Endre dokumentet i kilden. |
files.type_mismatch | Filens navn, type og innhold stemmer ikke overens. | Send filen med den riktige filtypen. |
files.too_large | Filen er over grensen for opplasting eller organisasjonens lagringsplass. | Bruk en opplasting i deler, eller frigjør lagringsplass. |
limits.cards | Organisasjonen har nådd grensen for antall kort i prisplanen sin. | Slett kort som ikke lenger trengs, eller bytt prisplan. |
api.metadata_invalid | metadata bryter en grense. | Se Metadata. |