Ihr System mit einer benutzerdefinierten Quelle synchronisieren
Eine benutzerdefinierte Quelle bindet ein System an, für das es keinen eingebauten Connector gibt: Ihr Wiki, Ihr Ticketsystem, eine Datenbank, einen Export von irgendwoher. Ihr Code sendet Dokumente an Sursa, und Sursa macht daraus Karten in der Sammlung und den Ordnern, für die die Quelle eingerichtet ist – mit derselben Suche, denselben Antworten, derselben Prüfung und denselben Berechtigungen wie bei Karten aus jeder anderen Quelle.
Anders als beim direkten Schreiben von Karten merkt sich eine benutzerdefinierte Quelle, was Sie gesendet haben. Am Ende einer vollständigen Synchronisierung archiviert Sursa jedes Dokument, das Sie nicht gesendet haben. So kommen Löschungen in Ihrem System ohne Zusatzaufwand bei Sursa an.
Quelle einrichten
Die Quelle legen Administratorinnen und Administratoren in Sursa unter Sources → New source → Custom source an und wählen dabei:
- die Sammlung und optional einen Ordner für ihre Karten;
- den Ordnermodus: alle Karten im gewählten Ordner oder Unterordner, die den
pathjedes Dokuments abbilden; - die Berechtigungen: die Berechtigungen der Sammlung oder „wie in der Quelle“, wobei jedes Dokument angibt, wer es sehen darf.
Die Seite der Quelle zeigt ihre ID; die Beispiele verwenden 42.
Schlüssel wählen
| Schlüssel | Beginnt mit | Darf |
|---|---|---|
| Quellschlüssel | kbsrc_ | Dokumente in genau diese Quelle schreiben. Sonst nichts: Er kann weder lesen noch suchen. Erstellen Sie ihn auf der Seite der Quelle unter API keys. |
Schlüssel der Organisation mit dem Scope import:write | kb_ | In jede benutzerdefinierte Quelle der Organisation schreiben und ihren Zustand lesen. Das Anlegen einer Quelle und ihrer Schlüssel erfordert den Scope admin. |
Der Quellschlüssel ist die sicherste Wahl für eine einzelne Integration, besonders für eine, die auf einer Plattform
eines Drittanbieters läuft. Ein Schlüssel der Organisation mit import:write eignet sich für einen Dienst, der mehrere
Quellen befüllt.
Beide Schlüssel werden auf dieselbe Weise gesendet, und jeder Push-Endpunkt liegt unter /v1/push/sources/{source_id}.
Prüfen Sie den Schlüssel und den Zustand der Quelle mit
GET /v1/push/sources/{source_id}:
curl https://api.sursa.com/v1/push/sources/42 \
-H "Authorization: Bearer $SURSA_SOURCE_KEY"{"source_id": 42, "name": "Helpdesk articles", "documents": 1840, "open_sync": null}
Das Dokument
| Feld | Pflicht | Beschreibung |
|---|---|---|
external_id | ja | Ihre stabile ID des Dokuments, bis zu 512 Zeichen. Wird dieselbe ID erneut gesendet, wird das Dokument ersetzt. |
title | ja | Titel der Karte, bis zu 500 Zeichen. Bei einer Datei standardmäßig der Dateiname. |
content | ja, außer bei einer Datei | Bis zu 5 MB. |
content_type | nein | html (Standard), markdown oder text. HTML wird von Skripten, Styles, Formularen und eingebetteten Objekten bereinigt. |
url | nein | Link auf das Dokument in Ihrem System, wird auf der Karte angezeigt. |
path | nein | Ordner als Array (["Support", "Billing"]) oder als Zeichenkette ("Support/Billing"), bis zu 10 Ebenen. |
permissions | nein | {"everyone": true} oder {"emails": [...], "groups": [...]}. Wird verwendet, wenn die Berechtigungen der Quelle auf „wie in der Quelle“ stehen. |
tags | nein | Bis zu 50 Tags, zusätzlich zu den Tags der Quelle. |
author_email | nein | Ist dies ein Benutzer der Organisation, wird diese Person für die Karte verantwortlich. |
updated_at | nein | Wann sich das Dokument in Ihrem System geändert hat (RFC 3339). |
metadata | nein | Ihre Schlüssel-Wert-Paare an der Karte. Siehe Metadaten. |
category | nein | Kategorie der Karte: der Schlüssel einer Kategorie der Organisation. |
verifiers, verify_interval_days | nein | Wer die Karte prüft (Benutzer per E-Mail und Gruppen) und wie oft, in Tagen. |
upload_id | nein | Die Datei des Dokuments aus einem Upload in Teilen, statt content. |
attachments | nein | Bis zu 20 weitere Dateien des Dokuments als Liste von upload_id. Jede davon wird zu einer eigenen Karte der Quelle. |
Statt content kann ein einzelnes Dokument in einer Anfrage mit multipart/form-data eine Datei von bis zu 100 MB
mitbringen: die Datei im Teil file, die obigen Felder als JSON im Teil document. Uploads in Teilen für upload_id
und attachments werden mit einem Schlüssel der Organisation erstellt, der den Scope import:write hat, und mit dem
Zweck import_attachment; ein Quellschlüssel kann sie nicht erstellen.
Zwei Arten zu senden
Direkte Aktualisierungen eignen sich für Systeme, die Sie über jede Änderung informieren, etwa ein Webhook aus Ihrem Helpdesk oder ein Schritt in Zapier. Senden Sie ein Dokument, wenn es erstellt oder geändert wird, und löschen Sie es, wenn es entfernt wird:
| Anfrage | Bewirkt |
|---|---|
POST /v1/push/sources/{source_id}/documents | Erstellt oder ersetzt ein Dokument. |
POST /v1/push/sources/{source_id}/documents/batch | Erstellt oder ersetzt viele Dokumente auf einmal. |
DELETE /v1/push/sources/{source_id}/documents/{external_id} | Entfernt ein Dokument. Kodieren Sie die ID für die URL. |
Änderungen werden innerhalb von etwa einer Minute zu Karten; mehrere aufeinanderfolgende Änderungen werden gemeinsam verarbeitet.
Synchronisierungen eignen sich für regelmäßige Exporte: Sie senden alles oder alles Geänderte, und Sursa gleicht ab. Der Rest dieser Anleitung behandelt Synchronisierungen.
Vollständige Synchronisierung ausführen
Eine Synchronisierung hat drei Schritte: öffnen, senden, schließen.
1. Öffnen
POST /v1/push/sources/{source_id}/syncs öffnet eine Synchronisierung und gibt
ihre Nummer zurück:
curl -X POST https://api.sursa.com/v1/push/sources/42/syncs \
-H "Authorization: Bearer $SURSA_SOURCE_KEY" \
-H "Idempotency-Key: sync-2026-10-24" \
-H "Content-Type: application/json" \
-d '{"type": "initial", "max_minutes": 180}'{"sync_number": 7, "type": "initial", "status": "open", "opened_at": "2026-10-24T02:00:00Z",
"expires_at": "2026-10-24T05:00:00Z", "pushed": 0, "removed": 0}
typeistinitialfür die erste Synchronisierung der Quelle undincremental, sobald eine Synchronisierung abgeschlossen ist. Eineincremental-Synchronisierung vor der ersten abgeschlossenen ergibtsources.push_initial_required.- Es kann immer nur eine Synchronisierung offen sein: Eine zweite ergibt
409sources.push_sync_open. - Eine Synchronisierung bleibt
max_minuteslang offen (standardmäßig 60, bis zu 1440). Danach läuft sie ab: Nichts wird archiviert, und ihre Nummer wird nicht mehr akzeptiert. Wählen Sie eine Zeit, die deutlich länger ist, als Ihr Export dauert.
2. Dokumente senden
Senden Sie die Dokumente in Batches von bis zu 500 zusammen mit der Synchronisierungsnummer. Der Body eines Batches
umfasst bis zu 50 MiB; Dateien innerhalb eines Batches werden als upload_id übergeben.
curl -X POST https://api.sursa.com/v1/push/sources/42/documents/batch \
-H "Authorization: Bearer $SURSA_SOURCE_KEY" \
-H "Idempotency-Key: sync-7-batch-1" \
-H "Content-Type: application/json" \
-d '{
"sync_number": 7,
"documents": [
{"external_id": "faq-shipping", "title": "Shipping", "content_type": "markdown",
"content": "# Shipping\n\nWe ship worldwide within 5 days.", "path": ["Support"]},
{"external_id": "faq-refunds", "title": "Refunds", "content_type": "html",
"content": "<p>Refunds take 14 days.</p>", "path": ["Support", "Billing"],
"permissions": {"groups": ["Support"]}, "metadata": {"article_id": "1042"}}
]
}'Die Antwort enthält für jedes Dokument ein Ergebnis, in der Reihenfolge, in der Sie sie gesendet haben:
{
"results": [
{"external_id": "faq-shipping", "result": "unchanged", "status": "indexed", "card_id": "8c1d…", "version": "5e0f…"},
{"external_id": "faq-refunds", "result": "updated", "status": "pending", "card_id": "3f2c…", "version": "a91b…"}
]
}
| Feld | Bedeutung |
|---|---|
result | Was jetzt mit dem Dokument geschehen ist: created, updated, unchanged, deleted, not_found, error oder skipped (in einem atomaren Batch, der nicht angewendet wurde). |
status | Wo sich das Dokument auf dem Weg zur Karte befindet: pending, processing (die Karte ist geschrieben und wird indexiert), indexed, failed oder removed. |
card_id | Die Karte des Dokuments, sobald sie existiert. |
version | Ein Hash des Inhalts und der Felder. Dasselbe Dokument, erneut gesendet, hat dieselbe Version und ist unchanged. |
error, reason | Warum das Dokument fehlgeschlagen ist. reason ist ein stabiler Code: content_invalid, file_rejected, too_large, limit_reached, index_failed oder batch_rejected (ein anderes Dokument eines atomaren Batches ist fehlgeschlagen). |
Standardmäßig wird jedes Dokument eines Batches für sich angewendet: Ein fehlerhaftes Dokument hält die anderen nicht auf.
Dokumente, die sich seit der letzten Synchronisierung nicht geändert haben, müssen Sie nicht erneut senden. Bestätigen
Sie sie über ihre ID mit
POST /v1/push/sources/{source_id}/syncs/{sync_number}/touch, bis zu
1000 IDs pro Anfrage, damit der vollständige Abgleich sie behält:
curl -X POST https://api.sursa.com/v1/push/sources/42/syncs/7/touch \
-H "Authorization: Bearer $SURSA_SOURCE_KEY" \
-H "Content-Type: application/json" \
-d '{"external_ids": ["faq-contact", "faq-hours"]}'3. Schließen
POST /v1/push/sources/{source_id}/syncs/{sync_number}/close beendet die
Synchronisierung:
curl -X POST https://api.sursa.com/v1/push/sources/42/syncs/7/close \
-H "Authorization: Bearer $SURSA_SOURCE_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "complete"}'status | Wirkung |
|---|---|
complete | Vollständiger Abgleich. Jedes Dokument der Quelle, das in dieser Synchronisierung weder gesendet noch bestätigt wurde, wird archiviert. Verwenden Sie dies nur, wenn Sie alles gesendet haben. |
complete_incremental | Übernimmt, was Sie gesendet haben, und archiviert nichts. |
failed | Archiviert nichts und behält, was bereits gesendet wurde. Fügen Sie reason (zum Beispiel API_ERROR) und error_details für das Protokoll hinzu. |
Schließen Sie mit failed, wann immer Ihr Export auf halbem Weg abbricht: Ein complete nach einem unvollständigen
Export würde jedes Dokument archivieren, zu dem Sie nicht mehr gekommen sind. Dasselbe Schließen erneut auszuführen
ergibt dasselbe Ergebnis.
Nach dem Schließen macht Sursa innerhalb von etwa einer Minute Karten aus den Dokumenten. Die Seite der Quelle zeigt
jede Synchronisierung mit der Anzahl der gesendeten und archivierten Dokumente, und
GET /v1/push/sources/{source_id}/syncs/{sync_number} gibt dieselben Zähler
zurück.
Inkrementelle Synchronisierungen
Senden Sie zwischen vollständigen Synchronisierungen nur, was sich geändert hat:
- Öffnen Sie mit
"type": "incremental". - Senden Sie die geänderten Dokumente und tragen Sie die IDs entfernter Dokumente in
deletesein (siehe unten). - Schließen Sie mit
complete_incremental.
Führen Sie von Zeit zu Zeit eine vollständige Synchronisierung aus, zum Beispiel wöchentlich, um alles zu erfassen, was ein inkrementeller Lauf verpasst hat.
Dokumente in einem Batch löschen
Ein Batch kann zusammen mit den Dokumenten, die er schreibt, auch Dokumente entfernen. Führen Sie deren IDs in
deletes auf:
{
"sync_number": 8,
"documents": [{"external_id": "faq-shipping", "title": "Shipping", "content": "…"}],
"deletes": ["faq-old-returns", "faq-fax"]
}
Jede gelöschte ID erhält einen eigenen Eintrag in results, mit result gleich deleted oder not_found, wenn die
Quelle kein solches Dokument hat. Dieselbe ID erneut zu löschen schadet nicht.
Atomare Batches
Manche Änderungen ergeben nur zusammen einen Sinn, zum Beispiel ein Dokument und das Dokument, das es ersetzt. Senden
Sie "atomic": true, dann wird der Batch ganz oder gar nicht angewendet: Besteht ein Dokument seine Prüfungen nicht,
wird nichts aus dem Batch übernommen, und die Antwort ist 422 mit dem Code sources.push_batch_rejected und dem
Ergebnis jedes Dokuments in error.details.results: Die fehlgeschlagenen Dokumente haben error, die anderen
skipped.
{"sync_number": 8, "atomic": true, "documents": […], "deletes": ["faq-old-returns"]}
Ohne atomic wird ein Batch Dokument für Dokument angewendet. Verwenden Sie atomare Batches für zusammengehörige
Änderungen und normale Batches für Massenladungen, bei denen ein fehlerhaftes Dokument den Rest nicht aufhalten soll.
Ergebnis jedes Dokuments prüfen
Die Antwort auf einen Batch sagt Ihnen, wie jedes Dokument geschrieben wurde. Die Umwandlung in eine Karte geschieht
danach, daher kann status noch pending sein. So finden Sie die Dokumente einer Synchronisierung, die nicht zu
Karten geworden sind:
curl "https://api.sursa.com/v1/push/sources/42/syncs/7/documents?status=failed" \
-H "Authorization: Bearer $SURSA_SOURCE_KEY"Jeder Eintrag hat external_id, title, status, card_id, version und reason, und die Liste wird mit cursor
paginiert. status akzeptiert auch pending, processing, indexed und removed.
Sie können sich auch benachrichtigen lassen, statt nachzufragen: Die Ereignisse import.sync_completed (eine
Synchronisierung ist geschlossen und verarbeitet, mit ihren Summen) und import.document_failed (ein Dokument ist
nicht zur Karte geworden, mit seinem reason) kommen per Webhook und im
Ereignis-Feed an.
Wiederholungen
- Senden Sie bei jedem
POSTeinenIdempotency-Key. Ein wiederholter Batch mit demselben Schlüssel gibt das erste Ergebnis zurück. - Auch ohne den Schlüssel wird ein Dokument mit derselben
external_idnie zu einer zweiten Karte: Es istunchangedoderupdated. - Bricht der Prozess mitten in einer Synchronisierung ab, öffnen Sie eine neue, nachdem die alte abgelaufen ist, oder
schließen Sie die alte mit
failed, wenn Sie ihre Nummer noch haben, und führen Sie die Synchronisierung erneut aus.
Limits
| Limit | Wert |
|---|---|
| Inhalt eines Dokuments | 5 MB |
| Datei in einer Anfrage mit einem einzelnen Dokument | 100 MB |
| Dokumente pro Batch | 500 |
| Body einer Batch-Anfrage | 50 MiB |
IDs pro touch-Anfrage | 1000 |
| Dokumente pro Quelle | Abhängig vom Tarif: ab 100.000 |
| Offene Synchronisierung | Standardmäßig 60 Minuten, bis zu 24 Stunden |
Ein Dokument über dem Dokumentenlimit der Quelle schlägt in einem Batch mit dem Grund limit_reached fehl; eine
Anfrage mit einem einzelnen Dokument ergibt 409 mit dem Code
sources.push_too_many_documents. Ratenlimits gelten wie für jede andere
Anfrage; siehe Ratenlimits und Kontingente.
Häufige Fehler
| Antwort | Ursache | Was zu tun ist |
|---|---|---|
401 sources.push_key_invalid | Der Schlüssel ist falsch, widerrufen oder gehört zu einer anderen Quelle. | Prüfen Sie den Schlüssel und die Quell-ID im Pfad. |
400 sources.push_document_invalid | Ein Pflichtfeld fehlt oder ein Limit ist überschritten. | Korrigieren Sie das Dokument; in einem normalen Batch schlägt nur dieses Dokument fehl. |
409 sources.push_sync_open | Eine andere Synchronisierung ist noch offen. | Schließen Sie sie oder warten Sie, bis sie abläuft. |
409 sources.push_sync_closed | Die Synchronisierung ist geschlossen oder abgelaufen. | Öffnen Sie eine neue Synchronisierung; erhöhen Sie max_minutes für lange Exporte. |
403 sources.feature_disabled | Quellen sind nicht Teil des Tarifs der Organisation. | Wenden Sie sich an die Administration. |
429 | Zu viele Anfragen. | Warten Sie die Zeit aus Retry-After ab; senden Sie weniger, dafür größere Batches. |