Salt la conținut
Sursa Developers

Importați documente

Acest ghid arată cum puneți documentele în Sursa cu API-ul fișelor: câteva documente dintr-un script sau toate documentele unui sistem printr-un job regulat. Fiecare document devine o fișă într-o colecție. Utilizatorii o găsesc prin căutare, asistentul răspunde pe baza ei, iar ea are un responsabil, etichete, verificare și permisiuni, ca orice altă fișă.

Dacă vreți ca Sursa să deducă ce documente au fost șterse în sistemul dumneavoastră sau trimiteți documente dintr-o platformă de integrare, folosiți în schimb o sursă personalizată. Ea este construită pentru sincronizări complete și incrementale. Acest ghid tratează scrierile directe într-o colecție.

Aveți nevoie de o cheie API cu domeniul cards:write și de un rol care poate scrie în colecția țintă (editor sau admin). Exemplele folosesc funcția ajutătoare din Pornire rapidă.

Alegeți endpointul potrivit

AvețiFolosiți
O înregistrare cu un identificator stabil în sistemul propriuPUT /v1/cards-by-external-id/{external_id}: creare sau înlocuire după identificatorul propriu.
Un text de adăugat o singură dată, fără identificator propriuPOST /v1/cards/text
Un fișier de adăugat o singură datăPOST /v1/cards
O arhivă ZIP cu multe fișierePOST /v1/cards/archive
Un fișier mai mare decât limita unei singure cereriO încărcare în părți, apoi oricare dintre endpointurile de mai sus.
Conținut nou pentru o fișă existentăPUT /v1/cards/{card_id}/content

Pentru tot ce importați de mai multe ori, folosiți external_id. Astfel, fiecare import poate fi repetat: o nouă rulare actualizează fișele create anterior, în loc să adauge copii.

Crearea sau înlocuirea unei fișe după identificatorul propriu

PUT /v1/cards-by-external-id/{external_id} primește identificatorul înregistrării din sistemul propriu. Dacă nicio fișă nu are acest external_id, creează una (201). Dacă o fișă îl are, îi înlocuiește conținutul și detaliile (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"}
  }'

Ce se întâmplă la o repetare:

  • Conținutul nu s-a schimbat: nu se creează o versiune nouă. Răspunsul este 200 cu "status": "skipped" și "reason": "unchanged". Repetarea cererii este întotdeauna sigură, chiar și fără un Idempotency-Key.
  • Conținutul s-a schimbat: fișa primește o versiune nouă și este indexată din nou. Titlul, etichetele, responsabilul, categoria și metadata primesc valorile trimise; metadata este înlocuit în întregime.
  • Colecția și dosarul se aplică doar la crearea fișei. Pentru a muta o fișă mai târziu, modificați-o cu PATCH /v1/cards/{card_id}.

O versiune nouă elimină verificarea fișei, ca orice modificare a conținutului: un verificator o confirmă din nou.

Formate de text

content_typeCorpul este
markdown (implicit)Markdown.
htmlHTML. Este curățat până la un marcaj simplu: titluri, paragrafe, liste, tabele și linkuri http, https și mailto. Scripturile, stilurile, cadrele, formularele și imaginile sunt eliminate împreună cu conținutul lor.
textText simplu. Paragrafele sunt separate prin rânduri goale.

Așteptați fișa sau nu

În mod implicit, cererea se încheie când fișa este gata să fie găsită, cu "status": "ready" și fișa în card. Aceasta durează de la o fracțiune de secundă pentru un text scurt până la un minut sau mai mult pentru un fișier lung.

Pentru importurile în volum mare, trimiteți "async": true. Răspunsul vine imediat, cu "status": "queued" și jobul de indexare în job (cu job_id al lui). Verificați jobul cu GET /v1/jobs/{job_id} sau urmăriți toate joburile în GET /v1/jobs/stream. Un job se încheie cu status done, error sau canceled.

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

Încărcarea unui fișier

Fișierele se trimit într-o cerere multipart/form-data, în câmpul file. Sursa citește PDF, Word, Excel, PowerPoint, foi de calcul OpenDocument, CSV, Markdown, HTML, AsciiDoc, e-mailuri (.eml), text simplu și formatele de imagine uzuale. Verifică dacă numele fișierului, tipul declarat și conținutul se potrivesc și respinge o nepotrivire cu 415.

Pentru a crea sau a înlocui o fișă de tip fișier după identificatorul propriu, trimiteți fișierul la același 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"}'

Într-un formular, tags este un șir separat prin virgule, iar metadata este un obiect JSON scris ca șir. O fișă nouă fără title primește ca titlu numele fișierului.

Pentru a adăuga un fișier o singură dată, fără identificator propriu, folosiți POST /v1/cards cu același formular și un Idempotency-Key. Încărcarea unui fișier pe care colecția îl are deja returnează "status": "skipped" cu "duplicate": true și card_id al fișei existente, dacă nu transmiteți un external_id.

Dimensiunea unui fișier este limitată de instalare (implicit 200 MB). Pentru fișiere mai mari sau pentru rețele nesigure, încărcați mai întâi fișierul în părți.

Înlocuirea conținutului unei fișe

Când aveți deja identificatorul Sursa al unei fișe, PUT /v1/cards/{card_id}/content îi înlocuiește textul sau fișierul și păstrează tot restul: responsabilul, etichetele, verificatorii, intervalul de verificare și o categorie setată manual.

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."}'
  • Același conținut trimis din nou returnează "status": "skipped" cu "reason": "unchanged".
  • O fișă care este indexată chiar acum returnează 409 cu codul cards.indexing_in_progress. Reîncercați peste câteva secunde.
  • O fișă care provine dintr-o sursă, de exemplu un conector sau o sursă personalizată, se modifică doar în sursa ei: cards.managed_by_source.
  • Cheia trebuie să aibă voie să vadă întreaga fișă; o fișă vizibilă doar parțial returnează cards.content_whole_access.

Importul multor documente

O buclă peste înregistrări cu PUT /v1/cards-by-external-id/… este cel mai simplu import în volum mare și poate fi oprită și rulată din nou în orice moment. Pentru a o face rapidă și prietenoasă cu limita de frecvență:

  1. Trimiteți "async": true, ca fiecare cerere să se încheie imediat ce fișa a intrat în coadă.
  2. Rulați câteva cereri în paralel (între 4 și 8) și încetiniți când antetul RateLimit arată că au rămas puține cereri. Vedeți Limite de frecvență și cote.
  3. La 429, așteptați cât indică Retry-After; la o eroare de rețea sau la 5xx, reîncercați aceeași cerere. Repetările nu fac rău.
  4. Notați external_id al fiecărei înregistrări care se încheie cu eroare și reîncercați-le la sfârșit.
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;
}

Pentru o arhivă ZIP cu fișiere, POST /v1/cards/archive transformă fiecare fișier acceptat din ea într-o fișă, cu o singură cerere. Răspunde imediat cu planul (ce fișiere devin fișe și care sunt sărite, și de ce) și cu un job; GET /v1/archives/{job_id} raportează rezultatul.

Găsirea și eliminarea fișelor importate

Erori frecvente

CodCauzăCe trebuie făcut
collections.not_foundNicio colecție cu acest identificator sau nume nu este vizibilă pentru cheie.Verificați collection_id cu GET /v1/collections.
collections.no_write_accessCheia nu are voie să scrie în această colecție.Folosiți o cheie cu rolul editor și cu acces la colecție.
cards.external_id_takenPOST cu un external_id pe care îl are deja altă fișă.Folosiți PUT /v1/cards-by-external-id/… pentru a o înlocui.
cards.managed_by_sourceFișa aparține unei surse.Modificați documentul în sursa lui.
files.type_mismatchNumele, tipul și conținutul fișierului nu se potrivesc.Trimiteți fișierul cu extensia lui reală.
files.too_largeFișierul depășește limita de încărcare sau spațiul de stocare al organizației.Folosiți o încărcare în părți sau eliberați spațiu de stocare.
limits.cardsOrganizația a atins limita de fișe a planului.Ștergeți fișele care nu mai sunt necesare sau schimbați planul.
api.metadata_invalidmetadata încalcă o limită.Vedeți Metadate.