मुख्य कंटेंट पर जाएँ
Sursa Developers

दस्तावेज़ों का इम्पोर्ट

यह गाइड बताती है कि कार्ड API से अपने दस्तावेज़ Sursa में कैसे डालें: किसी स्क्रिप्ट से कुछ दस्तावेज़, या नियमित जॉब के ज़रिए किसी सिस्टम का हर दस्तावेज़। हर दस्तावेज़ किसी कलेक्शन में एक कार्ड बन जाता है। लोग उसे खोज में पाते हैं, असिस्टेंट उससे जवाब देता है, और किसी भी दूसरे कार्ड की तरह उसका ज़िम्मेदार व्यक्ति, टैग, सत्यापन और अनुमतियाँ होती हैं।

अगर आप चाहते हैं कि Sursa ख़ुद पता लगाए कि आपके सिस्टम में कौन-से दस्तावेज़ हटाए गए, या आप दस्तावेज़ किसी इंटीग्रेशन प्लैटफ़ॉर्म से भेजते हैं, तो इसके बजाय कस्टम स्रोत इस्तेमाल करें। वह पूरे और इंक्रीमेंटल सिंक के लिए बना है। यह गाइड सीधे कलेक्शन में लिखने के बारे में है।

आपको cards:write स्कोप वाली API कुंजी चाहिए और ऐसा रोल, जो लक्ष्य कलेक्शन में लिख सकता हो (editor या admin)। उदाहरण क्विकस्टार्ट का हेल्पर इस्तेमाल करते हैं।

सही एंडपॉइंट चुनें

आपके पास हैइस्तेमाल करें
आपके सिस्टम में स्थिर ID वाला रिकॉर्डPUT /v1/cards-by-external-id/{external_id}: अपनी ID से बनाएँ या बदलें।
एक बार जोड़ने वाला टेक्स्ट, आपकी अपनी ID के बिनाPOST /v1/cards/text
एक बार जोड़ने वाली फ़ाइलPOST /v1/cards
कई फ़ाइलों का ZIP आर्काइवPOST /v1/cards/archive
एक रिक्वेस्ट की सीमा से बड़ी फ़ाइलहिस्सों में अपलोड, फिर ऊपर का कोई भी एंडपॉइंट।
पहले से मौजूद कार्ड का नया कंटेंटPUT /v1/cards/{card_id}/content

जो कुछ भी आप एक से ज़्यादा बार इम्पोर्ट करते हैं, उसके लिए external_id इस्तेमाल करें। इससे हर इम्पोर्ट दोहराया जा सकता है: फिर से चलाने पर वह कॉपी जोड़ने के बजाय अपने बनाए कार्ड अपडेट करता है।

अपनी ID से कार्ड बनाएँ या बदलें

PUT /v1/cards-by-external-id/{external_id} आपके सिस्टम में रिकॉर्ड की ID लेता है। अगर किसी कार्ड का यह external_id नहीं है, तो वह नया कार्ड बनाता है (201)। अगर किसी कार्ड का है, तो वह कार्ड का कंटेंट और विवरण बदल देता है (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"}
  }'

दोहराने पर क्या होता है:

  • कंटेंट नहीं बदला: कोई नया वर्शन नहीं बनता। रिस्पॉन्स "status": "skipped" और "reason": "unchanged" के साथ 200 होता है। रिक्वेस्ट दोहराना हमेशा सुरक्षित है, Idempotency-Key के बिना भी।
  • कंटेंट बदला: कार्ड का नया वर्शन बनता है और वह दोबारा इंडेक्स होता है। उसका शीर्षक, टैग, ज़िम्मेदार व्यक्ति, कैटेगरी और metadata आपके भेजे मान ले लेते हैं; metadata पूरा का पूरा बदल दिया जाता है।
  • कलेक्शन और फ़ोल्डर सिर्फ़ कार्ड बनते समय लागू होते हैं। बाद में कार्ड को दूसरी जगह ले जाने के लिए उसे PATCH /v1/cards/{card_id} से बदलें।

नया वर्शन कार्ड का सत्यापन हटा देता है, जैसे कंटेंट का कोई भी बदलाव हटाता है: वेरिफ़ायर उसे फिर से सत्यापित करता है।

टेक्स्ट फ़ॉर्मेट

content_typeबॉडी है
markdown (डिफ़ॉल्ट)Markdown।
htmlHTML। इसे साफ़ करके सरल मार्कअप तक लाया जाता है: शीर्षक, पैराग्राफ़, सूचियाँ, टेबल और http, https और mailto लिंक। स्क्रिप्ट, स्टाइल, फ़्रेम, फ़ॉर्म और इमेज अपने कंटेंट समेत हटा दिए जाते हैं।
textसादा टेक्स्ट। पैराग्राफ़ ख़ाली लाइनों से अलग होते हैं।

कार्ड का इंतज़ार करें, या नहीं

डिफ़ॉल्ट रूप से रिक्वेस्ट तब लौटती है, जब कार्ड खोज में मिलने के लिए तैयार हो जाता है, "status": "ready" और card में कार्ड के साथ। इसमें छोटे टेक्स्ट के लिए सेकंड के एक हिस्से से लेकर लंबी फ़ाइल के लिए एक मिनट या उससे ज़्यादा समय लगता है।

बड़े इम्पोर्ट के लिए "async": true भेजें। रिस्पॉन्स तुरंत "status": "queued" और job में इंडेक्सिंग जॉब (उसके job_id के साथ) लेकर आता है। जॉब को GET /v1/jobs/{job_id} से जाँचें, या सभी जॉब GET /v1/jobs/stream में देखें। जॉब status done, error या canceled के साथ ख़त्म होता है।

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

फ़ाइल अपलोड करें

फ़ाइलें multipart/form-data रिक्वेस्ट में, file फ़ील्ड में जाती हैं। Sursa PDF, Word, Excel, PowerPoint, OpenDocument स्प्रेडशीट, CSV, Markdown, HTML, AsciiDoc, ई-मेल (.eml), सादा टेक्स्ट और आम इमेज फ़ॉर्मेट पढ़ता है। वह जाँचता है कि फ़ाइल का नाम, बताया गया टाइप और कंटेंट आपस में मेल खाते हैं, और मेल न खाने पर 415 के साथ अस्वीकार करता है।

अपनी ID से फ़ाइल वाला कार्ड बनाने या बदलने के लिए फ़ाइल उसी 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"}'

फ़ॉर्म में tags कॉमा से अलग की गई स्ट्रिंग है और metadata स्ट्रिंग के रूप में लिखा JSON ऑब्जेक्ट है। title के बिना नए कार्ड को शीर्षक के रूप में फ़ाइल का नाम मिलता है।

अपनी ID के बिना कोई फ़ाइल एक बार जोड़ने के लिए उसी फ़ॉर्म और Idempotency-Key के साथ POST /v1/cards इस्तेमाल करें। ऐसी फ़ाइल अपलोड करने पर, जो कलेक्शन में पहले से है, "duplicate": true और मौजूदा card_id के साथ "status": "skipped" लौटता है, जब तक आप external_id नहीं भेजते।

एक फ़ाइल का आकार इंस्टॉलेशन से सीमित होता है (डिफ़ॉल्ट रूप से 200 MB)। बड़ी फ़ाइलों के लिए, या अस्थिर नेटवर्क के लिए, पहले फ़ाइल को हिस्सों में अपलोड करें।

कार्ड का कंटेंट बदलें

जब आपके पास कार्ड की Sursa ID पहले से हो, तो PUT /v1/cards/{card_id}/content उसका टेक्स्ट या फ़ाइल बदल देता है और बाक़ी सब वैसा ही रखता है: ज़िम्मेदार व्यक्ति, टैग, वेरिफ़ायर, सत्यापन का अंतराल और हाथ से सेट की गई कैटेगरी।

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."}'
  • वही कंटेंट फिर से भेजने पर "reason": "unchanged" के साथ "status": "skipped" लौटता है।
  • जो कार्ड अभी इंडेक्स हो रहा है, वह कोड cards.indexing_in_progress के साथ 409 लौटाता है। कुछ सेकंड में रीट्राई करें।
  • जो कार्ड किसी स्रोत से आता है, जैसे कनेक्टर या कस्टम स्रोत, वह सिर्फ़ अपने स्रोत में बदला जाता है: cards.managed_by_source।
  • कुंजी को पूरा कार्ड देखने की अनुमति होनी चाहिए; आंशिक रूप से दिखने वाला कार्ड cards.content_whole_access लौटाता है।

कई दस्तावेज़ इम्पोर्ट करें

आपके रिकॉर्ड पर PUT /v1/cards-by-external-id/… वाला लूप सबसे सरल बल्क इम्पोर्ट है, और इसे किसी भी पल रोककर फिर से चलाना सुरक्षित है। इसे तेज़ और रेट लिमिट के अनुकूल बनाने के लिए:

  1. "async": true भेजें, ताकि हर रिक्वेस्ट कार्ड के कतार में लगते ही लौट आए।
  2. कुछ रिक्वेस्ट समानांतर चलाएँ (4 से 8), और जब RateLimit हेडर दिखाए कि कुछ ही रिक्वेस्ट बाक़ी हैं, तो रफ़्तार धीमी करें। देखें रेट लिमिट और कोटा।
  3. 429 पर Retry-After तक इंतज़ार करें; नेटवर्क एरर या 5xx पर वही रिक्वेस्ट रीट्राई करें। दोहराना नुक़सान नहीं करता।
  4. एरर पर ख़त्म होने वाले हर रिकॉर्ड का external_id नोट करें, और आख़िर में उन्हें रीट्राई करें।
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;
}

फ़ाइलों के ZIP आर्काइव के लिए POST /v1/cards/archive एक रिक्वेस्ट में अंदर की हर सपोर्टेड फ़ाइल को कार्ड बना देता है। यह तुरंत योजना (कौन-सी फ़ाइलें कार्ड बनेंगी और कौन-सी छोड़ी जाएँगी, और क्यों) और एक जॉब के साथ जवाब देता है; GET /v1/archives/{job_id} नतीजा बताता है।

इम्पोर्ट किए गए कार्ड ढूँढें और हटाएँ

आम एरर

कोडकारणक्या करें
collections.not_foundइस ID या नाम वाला कोई कलेक्शन कुंजी को नहीं दिखता।GET /v1/collections से collection_id जाँचें।
collections.no_write_accessकुंजी इस कलेक्शन में नहीं लिख सकती।editor रोल और कलेक्शन के ऐक्सेस वाली कुंजी इस्तेमाल करें।
cards.external_id_takenऐसे external_id के साथ POST, जो किसी दूसरे कार्ड का पहले से है।उसे बदलने के लिए PUT /v1/cards-by-external-id/… इस्तेमाल करें।
cards.managed_by_sourceकार्ड किसी स्रोत का है।दस्तावेज़ उसके स्रोत में बदलें।
files.type_mismatchफ़ाइल का नाम, टाइप और कंटेंट आपस में मेल नहीं खाते।फ़ाइल उसके असली एक्सटेंशन के साथ भेजें।
files.too_largeफ़ाइल अपलोड की सीमा या संगठन के स्टोरेज से बड़ी है।हिस्सों में अपलोड इस्तेमाल करें, या स्टोरेज ख़ाली करें।
limits.cardsसंगठन अपने प्लान की कार्ड सीमा तक पहुँच गया है।जिन कार्ड की अब ज़रूरत नहीं, उन्हें हटाएँ, या प्लान बदलें।
api.metadata_invalidmetadata कोई सीमा तोड़ता है।देखें मेटाडेटा।