Hopp til innholdet
Sursa Developers

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 harBruk
En post med en stabil ID i systemet dittPUT /v1/cards-by-external-id/{external_id}: Opprett eller erstatt med din ID.
Tekst som skal legges til én gang, uten egen IDPOST /v1/cards/text
En fil som skal legges til én gangPOST /v1/cards
Et ZIP-arkiv med mange filerPOST /v1/cards/archive
En fil som er større enn grensen for én forespørselEn opplasting i deler, deretter en av operasjonene ovenfor.
Nytt innhold for et kort du allerede harPUT /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 200 med "status": "skipped" og "reason": "unchanged". Det er alltid trygt å gjenta forespørselen, selv uten en Idempotency-Key.
  • Innholdet er endret: Kortet får en ny versjon og indekseres på nytt. Tittelen, taggene, den ansvarlige, kategorien og metadata får verdiene du sendte; metadata erstattes 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_typeBrødteksten er
markdown (standard)Markdown.
htmlHTML. 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.
textRen 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 409 med koden cards.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:

  1. Send "async": true, slik at hver forespørsel returnerer så snart kortet er lagt i kø.
  2. Kjør noen forespørsler parallelt (4 til 8), og senk tempoet når headeren RateLimit viser at det er få forespørsler igjen. Se Hastighetsgrenser og kvoter.
  3. Vent i Retry-After sekunder ved 429; prøv den samme forespørselen på nytt ved en nettverksfeil eller 5xx. Gjentakelser gjør ingen skade.
  4. Noter external_id for 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

Vanlige feil

KodeÅrsakHva du gjør
collections.not_foundIngen samling med denne ID-en eller dette navnet er synlig for nøkkelen.Kontroller collection_id med GET /v1/collections.
collections.no_write_accessNøkkelen har ikke lov til å skrive til denne samlingen.Bruk en nøkkel med rollen editor og tilgang til samlingen.
cards.external_id_takenPOST med en external_id som et annet kort allerede har.Bruk PUT /v1/cards-by-external-id/… for å erstatte kortet.
cards.managed_by_sourceKortet tilhører en kilde.Endre dokumentet i kilden.
files.type_mismatchFilens navn, type og innhold stemmer ikke overens.Send filen med den riktige filtypen.
files.too_largeFilen er over grensen for opplasting eller organisasjonens lagringsplass.Bruk en opplasting i deler, eller frigjør lagringsplass.
limits.cardsOrganisasjonen har nådd grensen for antall kort i prisplanen sin.Slett kort som ikke lenger trengs, eller bytt prisplan.
api.metadata_invalidmetadata bryter en grense.Se Metadata.