Sources
Push one source, list them, delete them.
Upsert one
/api/v1/kb/sourcescollectionIduuidrequiredexternalIdstringrequiredtitlestringrequiredcontentstringrequiredvalidFromRFC3339 | null2026-09-01T00:00:00+03:00.validUntilRFC3339 | nullvalidFrom.contentRolecurrent | historical | nullmetadataobjectapi_created_at / api_updated_at to it.curl -X POST https://v2.heppu.ai/api/v1/kb/sources \
-H "x-api-key: hep_..." -H "Content-Type: application/json" \
-d '{
"collectionId": "col_…",
"externalId": "VIN-123",
"title": "2021 Volvo XC60",
"content": "# 2021 Volvo XC60\n\nPrice 34 900 €. 61 000 km. …",
"validUntil": "2026-12-31T23:59:59+02:00"
}'201 new, 200 updated or unchanged:
{
"data": {
"documentId": "1f0a…",
"externalId": "VIN-123",
"status": "processing",
"message": "Source queued for processing"
},
"meta": { "timestamp": "…" }
}status is processing or unchanged. Note that on unchanged we still update the validity fields and contentRole, but not title or metadata. Change the content if you need those to move.
404 if the collection isn't yours. 400 with all validation issues joined. 409 if the collection is an AI employee's Corrections collection, which takes Corrections filed in Heppu only.
List
/api/v1/kb/sourcesOnly sources created through the API. Uploads and crawls don't show here.
collectionIduuidrequiredexternalIdstringstatuspending | processing | completed | failedlimitintoffsetint{
"data": {
"sources": [
{
"id": "1f0a…",
"externalId": "VIN-123",
"title": "2021 Volvo XC60",
"status": "completed",
"chunkCount": 7,
"fileSize": 4211,
"error": null,
"validFrom": null,
"validUntil": "2026-12-31T21:59:59.000Z",
"contentRole": "current",
"metadata": { "api_created_at": "…" },
"createdAt": "…",
"updatedAt": "…"
}
],
"pagination": { "total": 128, "limit": 50, "offset": 0, "hasMore": true }
},
"meta": { "timestamp": "…" }
}error is the processing error text when status is failed. Ordered by updatedAt desc.
Delete
/api/v1/kb/sourcesYes, a DELETE with a body.
{ "collectionId": "col_…", "externalIds": ["VIN-123", "VIN-124"] }Max 100 ids. Removes them from this collection. If a source is also in another collection it survives there, otherwise the document, its chunks and its file go too.
{
"data": {
"deleted": 2,
"documentsDeleted": 1,
"deletedExternalIds": ["VIN-123", "VIN-124"],
"notFound": ["VIN-999"],
"message": "Removed 2 source(s) from collection col_…; 1 deleted entirely, 1 kept for other collections"
},
"meta": { "timestamp": "…" }
}notFound is omitted when empty. Always 200, even if nothing matched.
