Gå til indholdet
Sursa Developers

Importér dokumenter

Denne vejledning viser, hvordan du lægger dine dokumenter ind i Sursa med kort-API’et: nogle få dokumenter fra et script eller alle dokumenter fra et system via et fast job. Hvert dokument bliver til et kort i en samling. Folk finder det i søgningen, assistenten svarer ud fra det, og det har en ejer, tags, verificering og tilladelser som ethvert andet kort.

Vil du have Sursa til at finde ud af, hvilke dokumenter der er slettet i dit system, eller sender du dokumenter fra en integrationsplatform, så brug i stedet en brugerdefineret kilde. Den er bygget til fulde og inkrementelle synkroniseringer. Denne vejledning dækker direkte skrivning i en samling.

Du skal bruge en API-nøgle med scopet cards:write og en rolle, der kan skrive i målsamlingen (editor eller admin). Eksemplerne bruger hjælpefunktionen fra Hurtig start.

Vælg den rigtige operation

Du harBrug
En post med et stabilt id i dit systemPUT /v1/cards-by-external-id/{external_id}: opret eller erstat efter dit id.
Tekst, der skal tilføjes én gang, uden dit eget idPOST /v1/cards/text
En fil, der skal tilføjes én gangPOST /v1/cards
Et ZIP-arkiv med mange filerPOST /v1/cards/archive
En fil, der er større end grænsen for én anmodningEn upload i dele og derefter en af operationerne ovenfor.
Nyt indhold til et kort, du allerede harPUT /v1/cards/{card_id}/content

Brug external_id til alt, du importerer mere end én gang. Det gør hver import gentagelig: Kører du den igen, opdateres de kort, den oprettede, i stedet for at der tilføjes kopier.

Opret eller erstat et kort efter dit id

PUT /v1/cards-by-external-id/{external_id} tager id’et på posten i dit system. Har intet kort dette external_id, oprettes et nyt (201). Har et kort det, erstattes kortets indhold og detaljer (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 sker ved en gentagelse:

  • Indholdet er ikke ændret: Der laves ingen ny version. Svaret er 200 med "status": "skipped" og "reason": "unchanged". Det er altid sikkert at gentage anmodningen, også uden en Idempotency-Key.
  • Indholdet er ændret: Kortet får en ny version og indekseres igen. Dets titel, tags, ejer, kategori og metadata får de værdier, du sendte; metadata erstattes som en helhed.
  • Samlingen og mappen gælder kun, når kortet oprettes. Vil du flytte et kort senere, så ændr det med PATCH /v1/cards/{card_id}.

En ny version fjerner kortets verificering, som enhver ændring af indholdet gør: En kontrollant bekræfter kortet igen.

Tekstformater

content_typeBrødteksten er
markdown (standard)Markdown.
htmlHTML. Koden renses ned til enkel markup: overskrifter, afsnit, lister, tabeller og links med http, https og mailto. Scripts, styles, frames, formularer og billeder fjernes sammen med deres indhold.
textAlmindelig tekst. Afsnit adskilles af tomme linjer.

Vent på kortet, eller lad være

Som standard returnerer anmodningen, når kortet er klar til at blive fundet, med "status": "ready" og kortet i card. Det tager fra en brøkdel af et sekund for en kort tekst til et minut eller mere for en lang fil.

Ved masseimport sender du "async": true. Svaret kommer med det samme med "status": "queued" og indekseringsjobbet i job (med dets job_id). Kontrollér jobbet med GET /v1/jobs/{job_id}, eller følg alle job i GET /v1/jobs/stream. Et job slutter med status done, error eller canceled.

curl https://api.sursa.com/v1/jobs/48213 \
  -H "Authorization: Bearer $SURSA_API_KEY"

Upload en fil

Filer sendes i en multipart/form-data-anmodning i feltet file. Sursa læser PDF, Word, Excel, PowerPoint, OpenDocument-regneark, CSV, Markdown, HTML, AsciiDoc, e-mail (.eml), almindelig tekst og gængse billedformater. Sursa kontrollerer, at filens navn, angivne type og indhold stemmer overens, og afviser en uoverensstemmelse med 415.

Vil du oprette eller erstatte et filkort efter dit id, så send 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 en formular er tags en kommasepareret streng, og metadata er et JSON-objekt skrevet som en streng. Et nyt kort uden title får filnavnet som titel.

Vil du tilføje en fil én gang uden dit eget id, så brug POST /v1/cards med den samme formular og en Idempotency-Key. Uploader du en fil, som samlingen allerede har, returneres "status": "skipped" med "duplicate": true og det eksisterende card_id, medmindre du angiver et external_id.

Størrelsen på én fil er begrænset af installationen (som standard 200 MB). Ved større filer eller ustabile netværk skal du først uploade filen i dele.

Erstat et korts indhold

Når du allerede har kortets id i Sursa, erstatter PUT /v1/cards/{card_id}/content dets tekst eller fil og bevarer alt andet: ejer, tags, kontrollanter, verificeringsinterval og en manuelt angivet kategori.

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 indhold igen returnerer "status": "skipped" med "reason": "unchanged".
  • Et kort, der er ved at blive indekseret, returnerer 409 med koden cards.indexing_in_progress. Forsøg igen om nogle sekunder.
  • Et kort, der kommer fra en kilde, fx en connector eller en brugerdefineret kilde, ændres kun i sin kilde: cards.managed_by_source.
  • Nøglen skal have lov til at se hele kortet; et delvist synligt kort returnerer cards.content_whole_access.

Importér mange dokumenter

En løkke over dine poster med PUT /v1/cards-by-external-id/… er den enkleste masseimport, og den kan trygt stoppes og køres igen når som helst. Sådan gør du den hurtig og skånsom over for hastighedsgrænsen:

  1. Send "async": true, så hver anmodning returnerer, så snart kortet står i kø.
  2. Kør nogle få anmodninger parallelt (4 til 8), og sænk tempoet, når RateLimit-headeren viser, at der er få anmodninger tilbage. Se Hastighedsgrænser og kvoter.
  3. Vent ved 429 det antal sekunder, der står i Retry-After; forsøg ved en netværksfejl eller 5xx den samme anmodning igen. Gentagelser gør ingen skade.
  4. Registrér external_id for hver post, der ender med en fejl, og forsøg dem igen til sidst.
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;
}

Til et ZIP-arkiv med filer gør POST /v1/cards/archive hver understøttet fil i arkivet til et kort med én anmodning. Operationen svarer med det samme med planen for udpakning (hvilke filer der bliver til kort, og hvilke der springes over og hvorfor) og et job; GET /v1/archives/{job_id} rapporterer resultatet.

Find og fjern importerede kort

Almindelige fejl

KodeÅrsagHvad du gør
collections.not_foundIngen samling med dette id eller navn er synlig for nøglen.Kontrollér collection_id med GET /v1/collections.
collections.no_write_accessNøglen må ikke skrive i denne samling.Brug en nøgle med rollen editor og adgang til samlingen.
cards.external_id_takenPOST med et external_id, som et andet kort allerede har.Brug PUT /v1/cards-by-external-id/… til at erstatte kortet.
cards.managed_by_sourceKortet hører til en kilde.Ændr dokumentet i dets kilde.
files.type_mismatchFilens navn, type og indhold stemmer ikke overens.Send filen med dens rigtige filtypenavn.
files.too_largeFilen overskrider grænsen for uploads eller organisationens lagerplads.Brug en upload i dele, eller frigør lagerplads.
limits.cardsOrganisationen har nået grænsen for kort i sin prisplan.Slet kort, der ikke længere er brug for, eller skift prisplan.
api.metadata_invalidmetadata overskrider en grænse.Se Metadata.