Skip to content

Items: single, batch, snapshot, deletes & tombstones

The staging set of a source is the full desired state of its content. You mutate it with four operations; a run later reads it.

Item shape

{
"externalItemId": "faq-1", // REQUIRED — stable id you own (≤ 1024 chars)
"title": "Refund policy", // REQUIRED (≤ 2048 chars)
"content": "Refunds take 14 days.", // REQUIRED — markdown or plain text
"externalParentId": "section-billing", // optional
"externalVersion": "v3", // optional, your version marker
"contentType": "text/markdown", // optional (default text/markdown)
"sourceUrl": "https://help.example.com/refunds", // optional
"metadata": { "lang": "en" }, // optional, free-form JSON
"visibility": "public", // public | internal | restricted | disabled
"publishTarget": "public_widget" // public_widget | internal_assistant
}

visibility and publishTarget default to the source’s defaults when omitted.

Short content is fully supported: even a single sentence (well under the internal chunking minimum) is indexed as one searchable chunk — it is never silently dropped. Empty or whitespace/heading-only content contributes no searchable chunk. A publish that would turn real content into zero searchable chunks fails closed rather than publishing an empty result.

1. Single upsert

Re-using an externalItemId updates the same item (naturally idempotent).

Terminal window
curl -X POST "$CHATBOT_API/v1/sources/$SID/items" \
-H "Authorization: Bearer $CHATBOT_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"externalItemId":"faq-1","title":"Refunds","content":"Refunds take 14 days."}'

201 when created, 200 when updated.

2. Batch upsert (atomic, rolling)

Validates every item before writing — either the whole batch lands or none of it does, so a partial batch can never look like a deletion. A batch is a rolling upsert: items it does not name are left untouched. Max 1000 items, 8 MiB body.

Terminal window
curl -X POST "$CHATBOT_API/v1/sources/$SID/items/batch" \
-H "Authorization: Bearer $CHATBOT_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: import-7" \
-d '{"items":[
{"externalItemId":"faq-1","title":"Refunds","content":"…"},
{"externalItemId":"faq-2","title":"Shipping","content":"…"}
]}'
# → { "batch": { "count": 2, "created": 1, "updated": 1 } }

3. Full snapshot (replace the whole set)

PUT replaces the entire staging set atomically. Items present before but absent now are tombstoned — a subsequent run with complete discovery turns those tombstones into removals (subject to the source’s graceDays). Use this when your system can produce the complete current state.

Terminal window
curl -X PUT "$CHATBOT_API/v1/sources/$SID/items" \
-H "Authorization: Bearer $CHATBOT_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: snapshot-2024-06-01" \
-d '{"items":[ …the complete current set… ]}'
# → { "snapshot": { "count": 42 } }

4. Delete / tombstone

Soft-delete one or many items. Deleted items become tombstones; a run propagates the removal to the published generation (after the grace window).

Terminal window
# single
curl -X POST "$CHATBOT_API/v1/sources/$SID/items/delete" \
-H "Authorization: Bearer $CHATBOT_KEY" -H "Content-Type: application/json" \
-d '{"externalItemId":"faq-1"}'
# many
curl -X POST "$CHATBOT_API/v1/sources/$SID/items/delete" \
-H "Authorization: Bearer $CHATBOT_KEY" -H "Content-Type: application/json" \
-d '{"externalItemIds":["faq-1","faq-2"]}'
# → { "delete": { "requested": 2, "deleted": 2 } }

Listing

Terminal window
curl "$CHATBOT_API/v1/sources/$SID/items" # active items
curl "$CHATBOT_API/v1/sources/$SID/items?includeDeleted=true" # + tombstones

Choosing rolling vs snapshot

Use…When
Single / batch upsert + deleteYou receive incremental changes (webhooks, CDC) and know exactly what changed.
Full snapshot (PUT)You can re-export the complete current state and want removals handled automatically.

Both are safe and atomic; pick whichever matches how your source system emits changes.