API REFERENCE

The Knowledge API

Give one user their own private documents. Uploads run through the same pgvector hybrid retrieval as your shared knowledge base, but the chunks stay scoped to that user.

These endpoints manage the private documents that belong to a single end user. Every call carries a signed user_context, so the file is indexed under the audience user:<id> and never leaks into another user's retrieval. To seed the shared pool that everyone in a project can see, upload from Settings instead.

All three endpoints require signed identity mode. The request must include a valid _ts and _sig on the user_context, or you get SIGNED_IDENTITY_REQUIRED. See the signed identity guide for the HMAC recipe.

Upload a document

POST/v1/knowledge

A multipart/form-data request with two parts: the file itself and a user_context field holding the signed identity as JSON. The file is queued for embedding and the call returns immediately with a job id. Indexing runs in the background (chunk, embed with BAAI/bge-m3, write to pgvector), so a fresh upload becomes retrievable a few seconds later.

FieldTypeDescription
filerequiredfileThe document. PDF, TXT, or MD. Up to 50 MB.
user_contextrequiredstring (JSON)The signed identity for the owning user, serialized as JSON. Must include _ts and _sig.

Limits enforced on upload:

FieldTypeDescription
file typeenumPDF, TXT, or MD only. Anything else returns UNSUPPORTED_TYPE.
file sizebytesHard cap of 50 MB. A larger file returns FILE_TOO_LARGE.
docs per userintUp to 20 documents per user. The 21st returns DOC_CAP_REACHED until one is deleted.
bash
curl -X POST https://eerraa.online/v1/knowledge \
  -H "Authorization: Bearer era_your_project_key" \
  -F "file=@handbook.pdf" \
  -F 'user_context={"id":"u_42","name":"Sara","_ts":1735689600,"_sig":"a1b2c3..."}'

Response:

json
{
  "job_id": "kb_9f3c1e7a",
  "status": "processing",
  "filename": "handbook.pdf"
}
FieldTypeDescription
job_idstringHandle for the background indexing job.
statusstringAlways "processing" on accept. The document is embedded asynchronously.
filenamestringThe original filename, echoed back.
There is no polling endpoint for the job. Retrieval simply starts including the document once indexing finishes, usually within a few seconds. If you need to confirm it landed, list the user's documents.

List a user's documents

GET/v1/knowledge

Returns the documents owned by the user in the request identity. Because the audience is derived from the signed user_context, a user only ever sees their own uploads, never the shared project pool and never another user's files.

bash
# The signed user_context goes in the X-Era-User header, URL-encoded.
curl https://eerraa.online/v1/knowledge \
  -H "Authorization: Bearer era_your_project_key" \
  -H "X-Era-User: %7B%22id%22%3A%22u_42%22%2C%22_ts%22%3A1735689600%2C%22_sig%22%3A%22a1b2c3...%22%7D"

Response:

json
{
  "documents": [
    { "id": "kb_9f3c1e7a", "filename": "handbook.pdf", "status": "ready", "chunks": 128 },
    { "id": "kb_2b8d40f1", "filename": "notes.md", "status": "processing", "chunks": 0 }
  ]
}

Delete a document

DELETE/v1/knowledge

Removes one of the user's own documents and drops its chunks from the index. Pass the document id you got back from the list call. A user can only delete a file they own, which frees a slot against the 20-document cap.

bash
curl -X DELETE "https://eerraa.online/v1/knowledge?id=kb_9f3c1e7a" \
  -H "Authorization: Bearer era_your_project_key" \
  -H "X-Era-User: %7B%22id%22%3A%22u_42%22%2C%22_ts%22%3A1735689600%2C%22_sig%22%3A%22a1b2c3...%22%7D"

Response:

json
{ "deleted": true, "id": "kb_9f3c1e7a" }