Knowledge
Knowledge sync
Load the products and files a persona answers from, over REST. Authenticate every request with that persona's API key (the X-Api-Key header).
https://api.personaizer.com/v1/knowledge/docsProducts
Create or update products, matched by id.
Body — each product
Requirements & limits
Per-field requirements
attributes — supported types
| The object | ≤100 keys · each key name ≤100 chars |
string | ≤500 chars |
number | |n| ≤ 1e15 (1×1015) |
boolean | true or false (JSON literal, never "true"/"yes" strings) |
string[] | ≤50 items · each item ≤100 chars |
date | ISO-8601 string, e.g. "2026-03-01" (JSON has no date literal) |
Reserved keys
attributes holds your own custom fields. These eight names are already first-class product fields, so they can't be reused as attribute keys — a custom field would shadow the real one, so the request is rejected. Put the value on the top-level field instead (e.g. price, not attributes.price).
priceoriginal_pricein_stockcurrencyimageslinkstitledescriptionhttps://api.personaizer.com/v1/knowledge/docs{
"items": [
{
"id": "sku-002",
"source": "my-shop.ge",
"category": "footwear",
"title": "Red trail runners",
"description": "Lightweight trail shoe with a grippy outsole.",
"attributes": {
"brand": "acme",
"weight_kg": 0.5,
"waterproof": true,
"sizes": [
"8",
"9",
"10"
],
"released_at": "2026-03-01"
},
"images": [
{
"url": "https://cdn.example.com/red-runners.jpg",
"description": "Red trail runners",
"is_primary": true
}
],
"links": [
{
"url": "https://my-shop.ge/p/sku-002",
"is_primary": true
}
],
"price": 109.99,
"original_price": 129.99,
"currency": "USD",
"in_stock": true
},
{
"source": "my-shop.ge",
"category": "footwear",
"title": "Blue running shoes"
}
]
}{ "created": 2, "updated": 0, "no_op": 0 }Validation
All-or-nothing: if any product is invalid, nothing is written and the call returns 422 (see the response tab) with one entry per problem.
Each errors[] entry
Request-level failures use their own status (the console's response tabs): 401 (missing or invalid key), 403 (Persona ID used — needs the API key), 402 (over quota), or 429 (rate limited).
https://api.personaizer.com/v1/knowledge/docs/uploadFile
Upload non-product knowledge — FAQs, Q&A, manuals, policies, troubleshooting, company info, glossaries. Structured products go through the PUT above.
Validate large files first with POST /v1/knowledge/docs/upload/preflight (name, size, page count) before transferring bytes. The response includes the document's id — poll GET /v1/knowledge/docs/{id} until status.state is ready. File docs come back with kind: "file" and original_file_name / content_type / pages.
Form fields
images and links are independent lanes: omit a field and the server auto-discovers that lane from the document; send [] to suppress it; send entries to use them verbatim. There is no category on files — that's for structured products only.
https://api.personaizer.com/v1/knowledge/docs/upload{
"id": "manuals-v3",
"kind": "file",
"source": "my-shop.ge",
"title": "Manuals",
"original_file_name": "product-manuals.pdf",
"content_type": "pdf",
"pages": 12,
"status": { "state": "pending", "created_at": "...", "processed_at": null }
}https://api.personaizer.com/v1/knowledge/docs/upload/preflightPreflight an upload
Validate a file's metadata before transferring the bytes — cheap guard against an upload that would be rejected. Returns { ok: true }, or 400 with the reason.
Send the file_name, content_length (bytes), and page_count (for PDF / DOCX / PPTX). The same size and page limits as the upload apply.
https://api.personaizer.com/v1/knowledge/docs/upload/preflight{
"file_name": "product-manuals.pdf",
"content_length": 5242880,
"page_count": 12
}{ "ok": true }Scoping & activation
The API key determines the persona; reads only see that persona's knowledge.
Every document you write is automatically activated on the key's persona. Documents won't surface in conversations until processing completes. To share one document across personas, upload it with the same id using each persona's key — the content is stored once and activated per persona.
https://api.personaizer.com/v1/knowledge/docsDelete
Two-phase: documents leave this persona immediately (deactivated); any that no other persona still references are queued for permanent deletion.
- ids not in the persona's knowledge are silently skipped.
- job_id is present only when queued_for_deletion > 0 — poll the jobs endpoint until completed.
https://api.personaizer.com/v1/knowledge/docs{ "deactivated": 2, "queued_for_deletion": 1, "job_id": "0197a1b2-..." }https://api.personaizer.com/v1/knowledge/docsRead endpoints
Read the persona's catalog back. A document comes back exactly as you sent it, plus a status block (state, processing accounting).
Endpoints
List query params
https://api.personaizer.com/v1/knowledge/docs{
"items": [
{
"id": "sku-002", "kind": "item",
"source": "my-shop.ge", "category": "footwear",
"title": "Red trail runners",
"price": 109.99, "original_price": 129.99, "currency": "USD", "in_stock": true,
"status": { "state": "ready", "knowledge_units": 1.0, "active_persona_count": 1 }
}
],
"total_count": 1
}https://api.personaizer.com/v1/knowledge/docs/{id}Read one document
Full detail for a single document — the same typed shape as a list row, including its status block. 404 if the id isn't on this persona.
https://api.personaizer.com/v1/knowledge/docs/{id}{
"id": "sku-002", "kind": "item",
"source": "my-shop.ge", "category": "footwear",
"title": "Red trail runners",
"description": "Lightweight trail shoe with a grippy outsole.",
"price": 109.99, "original_price": 129.99, "currency": "USD", "in_stock": true,
"status": { "state": "ready", "knowledge_units": 1.0, "active_persona_count": 1 }
}https://api.personaizer.com/v1/knowledge/jobs/{job_id}Job status
Status of an async job — the job_id comes back from a delete that queued documents for permanent removal. Poll until status is completed or failed; processed / total track progress.
https://api.personaizer.com/v1/knowledge/jobs/{job_id}{ "job_id": "0197a1b2-...", "status": "completed", "processed": 1, "total": 1 }https://core.personaizer.com/api/subscription/limitsChecking your limits
Check remaining quota before large uploads. Knowledge Units (Ku) measure your searchable content; Storage Units (Su) measure raw file storage in MB.
Note the host — this is served from core.personaizer.com, the one /api route that accepts API keys. Uploading beyond your limit returns 402 limits.quota_exceeded (Credit quota exceeded).
https://core.personaizer.com/api/subscription/limits{
"usage": {
"knowledgeUnitsUsed": 12480, "knowledgeUnitsLimit": 100000,
"storageUnitsUsed": 4.2, "storageUnitsLimit": 512
}
}