Heppu APIv2.heppu.ai/api

Batch sources

Up to 50 sources in one call. The normal way to sync a catalogue.

POST/api/v1/kb/sources/batch

Same per-source fields as the single endpoint, minus collectionId which moves to the top.

{
  "collectionId": "col_…",
  "sources": [
    { "externalId": "VIN-1", "title": "…", "content": "…" },
    { "externalId": "VIN-2", "title": "…", "content": "…", "contentRole": "historical" }
  ]
}

1 to 50 sources. One failing source doesn't stop the others.

Always 200, even if every source failed. Read summary:

{
  "data": {
    "results": [
      { "externalId": "VIN-1", "documentId": "1f0a…", "status": "created" },
      { "externalId": "VIN-2", "documentId": "2b7c…", "status": "updated" },
      { "externalId": "VIN-3", "documentId": "3d1e…", "status": "unchanged" },
      { "externalId": "VIN-4", "documentId": "", "status": "failed", "error": "…" }
    ],
    "summary": { "total": 4, "created": 1, "updated": 1, "unchanged": 1, "failed": 1 },
    "message": "Processed 4 sources: 1 created, 1 updated, 1 unchanged, 1 failed"
  },
  "meta": { "timestamp": "…" }
}

Validation is all-or-nothing though. One bad field anywhere and the whole batch is a 400 naming the path, like sources.3.content: content too long (max 500KB).

Sync recipe

Nightly catalogue sync, in pseudo code:

for chunk in chunks(catalogue, 50):
    POST /v1/kb/sources/batch { collectionId, sources: chunk }
stale = GET /v1/kb/sources?collectionId=…  minus ids in catalogue
for chunk in chunks(stale, 100):
    DELETE /v1/kb/sources { collectionId, externalIds: chunk }

Unchanged sources are free, so re-posting the full catalogue every night is fine. Don't put the same externalId twice in one batch, the second one creates a duplicate.

On this page