Hoppa till innehållet
Sursa Developers

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 harAnvänd
En post med ett stabilt id i ditt systemPUT /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 idPOST /v1/cards/text
En fil som ska läggas till en gångPOST /v1/cards
Ett ZIP-arkiv med många filerPOST /v1/cards/archive
En fil som är större än gränsen för ett enda anropEn uppladdning i delar, och sedan någon av slutpunkterna ovan.
Nytt innehåll för ett kort som du redan harPUT /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 200 med "status": "skipped" och "reason": "unchanged". Det är alltid säkert att upprepa anropet, även utan en Idempotency-Key.
  • Innehållet har ändrats: kortet får en ny version och indexeras igen. Dess rubrik, taggar, ansvarig, kategori och metadata får de värden som du skickade; metadata ersä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_typeBrödtexten är
markdown (standard)Markdown.
htmlHTML. 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.
textVanlig 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 409 med koden cards.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:

  1. Skicka "async": true, så att varje anrop returnerar så snart kortet har köats.
  2. Kör några anrop parallellt (4–8) och sakta ned när huvudet RateLimit visar att få anrop återstår. Se Hastighetsbegränsningar och kvoter.
  3. Vid 429 väntar du på Retry-After; vid ett nätverksfel eller 5xx försöker du igen med samma anrop. Upprepningar gör ingen skada.
  4. Anteckna external_id fö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

Vanliga fel

KodOrsakVad du gör
collections.not_foundIngen samling med det här id:t eller namnet är synlig för nyckeln.Kontrollera collection_id med GET /v1/collections.
collections.no_write_accessNyckeln får inte skriva till den här samlingen.Använd en nyckel med rollen editor och åtkomst till samlingen.
cards.external_id_takenPOST 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_sourceKortet hör till en källa.Ändra dokumentet i dess källa.
files.type_mismatchFilens namn, typ och innehåll stämmer inte överens.Skicka filen med dess riktiga filändelse.
files.too_largeFilen är större än gränsen för uppladdningar eller organisationens lagringsutrymme.Använd en uppladdning i delar eller frigör lagringsutrymme.
limits.cardsOrganisationen har nått prisplanens gräns för antalet kort.Ta bort kort som inte längre behövs eller byt prisplan.
api.metadata_invalidmetadata bryter mot en gräns.Se Metadata.