İçeriğe geç
Sursa Developers

Belgeleri içe aktarma

Bu kılavuz, belgelerinizi kart API’siyle Sursa’ya nasıl koyacağınızı gösterir: bir betikten birkaç belge ya da düzenli çalışan bir işle bir sistemin tüm belgeleri. Her belge bir koleksiyonda bir kart olur. Kişiler onu aramada bulur, asistan yanıtlarını ona dayanarak verir ve diğer tüm kartlar gibi bir sorumlusu, etiketleri, doğrulaması ve izinleri olur.

Sisteminizde hangi belgelerin silindiğini Sursa’nın kendisinin belirlemesini istiyorsanız ya da belgeleri bir entegrasyon platformundan gönderiyorsanız bunun yerine bir özel kaynak kullanın. Özel kaynak, tam ve artımlı senkronizasyonlar için tasarlanmıştır. Bu kılavuz bir koleksiyona doğrudan yazmayı anlatır.

cards:write kapsamına ve hedef koleksiyona yazabilen bir role (editor ya da admin) sahip bir API anahtarına ihtiyacınız vardır. Örnekler Hızlı başlangıç kılavuzundaki yardımcıyı kullanır.

Doğru uç noktayı seçme

ElinizdekiKullanın
Sisteminizde değişmeyen bir kimliği olan kayıtPUT /v1/cards-by-external-id/{external_id}: kimliğinize göre oluşturma ya da değiştirme.
Kendinize ait bir kimliği olmayan, bir kez eklenecek metinPOST /v1/cards/text
Bir kez eklenecek dosyaPOST /v1/cards
Çok sayıda dosya içeren ZIP arşiviPOST /v1/cards/archive
Tek istek sınırından büyük bir dosyaParçalar hâlinde yükleme, ardından yukarıdaki uç noktalardan herhangi biri.
Zaten var olan bir kart için yeni içerikPUT /v1/cards/{card_id}/content

Birden fazla kez içe aktardığınız her şey için external_id kullanın. Böylece her içe aktarma tekrarlanabilir olur: içe aktarmayı yeniden çalıştırmak kopya eklemek yerine daha önce oluşturduğu kartları günceller.

Kendi kimliğinizle kart oluşturma ya da değiştirme

PUT /v1/cards-by-external-id/{external_id} sisteminizdeki kaydın kimliğini alır. Bu external_id değerine sahip bir kart yoksa bir kart oluşturur (201). Böyle bir kart varsa kartın içeriğini ve ayrıntılarını değiştirir (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"}
  }'

Tekrarda ne olur:

  • İçerik değişmediyse: yeni sürüm oluşturulmaz. Yanıt "status": "skipped" ve "reason": "unchanged" ile 200 olur. İsteği tekrarlamak, Idempotency-Key olmadan bile her zaman güvenlidir.
  • İçerik değiştiyse: kart yeni bir sürüm alır ve yeniden dizinlenir. Başlığı, etiketleri, sorumlusu, kategorisi ve metadata alanı gönderdiğiniz değerleri alır; metadata bir bütün olarak değiştirilir.
  • Koleksiyon ve klasör yalnızca kart oluşturulurken uygulanır. Bir kartı daha sonra taşımak için onu PATCH /v1/cards/{card_id} ile değiştirin.

Yeni bir sürüm, içerikteki her değişiklik gibi kartın doğrulamasını kaldırır: bir doğrulayıcının kartı yeniden onaylaması gerekir.

Metin biçimleri

content_typeGövde
markdown (varsayılan)Markdown.
htmlHTML. Basit bir işaretlemeye indirgenerek temizlenir: başlıklar, paragraflar, listeler, tablolar ve http, https ve mailto bağlantıları. Betikler, stiller, çerçeveler, formlar ve görseller içerikleriyle birlikte kaldırılır.
textDüz metin. Paragraflar boş satırlarla ayrılır.

Kartı bekleme ya da beklememe

Varsayılan olarak istek, kart bulunmaya hazır olduğunda "status": "ready" değeri ve card alanındaki kartla birlikte yanıt döner. Bu, kısa bir metin için saniyenin bir kesrinden uzun bir dosya için bir dakika ya da daha fazlasına kadar sürer.

Toplu içe aktarmalarda "async": true gönderin. Yanıt hemen, "status": "queued" değeri ve job alanındaki dizinleme işiyle (job_id değeriyle birlikte) gelir. İşi GET /v1/jobs/{job_id} ile kontrol edin ya da tüm işleri GET /v1/jobs/stream ile izleyin. Bir iş, status değeri done, error ya da canceled olarak sona erer.

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

Dosya yükleme

Dosyalar bir multipart/form-data isteğinde, file alanında gönderilir. Sursa PDF, Word, Excel, PowerPoint, OpenDocument elektronik tabloları, CSV, Markdown, HTML, AsciiDoc, e-posta (.eml), düz metin ve yaygın görsel biçimlerini okur. Dosyanın adının, bildirilen türünün ve içeriğinin uyuştuğunu kontrol eder ve uyuşmazlığı 415 ile reddeder.

Kendi kimliğinizle bir dosya kartı oluşturmak ya da değiştirmek için dosyayı aynı PUT /v1/cards-by-external-id/{external_id} uç noktasına gönderin:

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"}'

Formda tags virgülle ayrılmış bir dizedir, metadata ise dize olarak yazılmış bir JSON nesnesidir. title olmadan oluşturulan yeni bir kart başlık olarak dosyanın adını alır.

Bir dosyayı kendi kimliğiniz olmadan bir kez eklemek için aynı formla ve bir Idempotency-Key ile POST /v1/cards kullanın. Koleksiyonda zaten bulunan bir dosyayı yüklemek, bir external_id göndermediğiniz sürece "duplicate": true ve mevcut card_id ile birlikte "status": "skipped" döndürür.

Tek bir dosyanın boyutu kurulum tarafından sınırlanır (varsayılan olarak 200 MB). Daha büyük dosyalar için ya da güvenilir olmayan ağlarda dosyayı önce parçalar hâlinde yükleyin.

Bir kartın içeriğini değiştirme

Bir kartın Sursa kimliği zaten elinizdeyse PUT /v1/cards/{card_id}/content kartın metnini ya da dosyasını değiştirir ve geri kalan her şeyi korur: sorumlu, etiketler, doğrulayıcılar, doğrulama aralığı ve elle belirlenmiş 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."}'
  • Aynı içerik yeniden gönderildiğinde "status": "skipped" ve "reason": "unchanged" döner.
  • Şu anda dizinlenmekte olan bir kart cards.indexing_in_progress koduyla 409 döndürür. Birkaç saniye sonra yeniden deneyin.
  • Bağlayıcı ya da özel kaynak gibi bir kaynaktan gelen bir kart yalnızca kendi kaynağında değiştirilir: cards.managed_by_source.
  • Anahtar kartın tamamına erişebilmelidir; kısmen erişilebilen bir kart cards.content_whole_access döndürür.

Çok sayıda belgeyi içe aktarma

Kayıtlarınız üzerinde PUT /v1/cards-by-external-id/… ile dönen bir döngü en basit toplu içe aktarmadır ve her noktada durdurulup yeniden çalıştırılabilir. Onu hızlı ve hız sınırıyla uyumlu hâle getirmek için:

  1. Her istek kart kuyruğa alınır alınmaz yanıt dönsün diye "async": true gönderin.
  2. Birkaç isteği paralel çalıştırın (4–8) ve RateLimit başlığı az istek kaldığını gösterdiğinde yavaşlayın. Hız sınırları ve kotalar sayfasına bakın.
  3. 429 yanıtında Retry-After süresi kadar bekleyin; ağ hatasında ya da 5xx yanıtında aynı isteği yeniden deneyin. Tekrarlar zararsızdır.
  4. Hatayla sonuçlanan her kaydın external_id değerini not edin ve bunları en sonda yeniden deneyin.
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;
}

Dosyalardan oluşan bir ZIP arşivi için POST /v1/cards/archive, içindeki desteklenen her dosyayı tek bir istekle karta dönüştürür. Plan (hangi dosyaların karta dönüşeceği, hangilerinin atlanacağı ve neden) ve bir işle hemen yanıt verir; GET /v1/archives/{job_id} sonucu bildirir.

İçe aktarılan kartları bulma ve kaldırma

Sık karşılaşılan hatalar

KodNedenNe yapmalı
collections.not_foundAnahtarın erişebildiği, bu kimliğe ya da ada sahip bir koleksiyon yok.collection_id değerini GET /v1/collections ile kontrol edin.
collections.no_write_accessAnahtar bu koleksiyona yazamaz.editor rolüne ve koleksiyona erişime sahip bir anahtar kullanın.
cards.external_id_takenBaşka bir kartın zaten sahip olduğu bir external_id ile POST isteği.Kartı değiştirmek için PUT /v1/cards-by-external-id/… kullanın.
cards.managed_by_sourceKart bir kaynağa ait.Belgeyi kendi kaynağında değiştirin.
files.type_mismatchDosyanın adı, türü ve içeriği uyuşmuyor.Dosyayı gerçek uzantısıyla gönderin.
files.too_largeDosya yükleme sınırını ya da kuruluşun depolama alanını aşıyor.Parçalar hâlinde yükleme kullanın ya da depolama alanında yer açın.
limits.cardsKuruluş, planının kart sınırına ulaştı.Artık gerekmeyen kartları silin ya da planı değiştirin.
api.metadata_invalidmetadata bir sınırı aşıyor.Meta veriler sayfasına bakın.