Αναφορά API / Knowledge base

Knowledge base

Τα endpoints της ομάδας Knowledge base του Voiceland AI API, με παραμέτρους, σχήματα και παραδείγματα curl.

Τελευταία ενημέρωση:

Οι περιγραφές των endpoints και των πεδίων εμφανίζονται στα αγγλικά, όπως ακριβώς τις δημοσιεύει το API. Είναι επιλογή μας, ώστε να διαβάζετε εδώ ό,τι θα δείτε και στις αποκρίσεις.

GET /v1/kb/collections#

List collections. Every collection on your account, with its document and chunk counts.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl "https://api.voiceland.ai/v1/kb/collections" \
  -H "Authorization: Bearer VL_API_KEY"

Παράδειγμα απόκρισης

{
  "items": [
    {
      "doc_count": 12,
      "id": "col_9f2a1c7d",
      "name": "Τιμοκατάλογος",
      "vector_count": 143
    }
  ]
}

POST /v1/kb/collections#

Create a collection. Creates a collection, a named set of documents your agents can answer from. Collections belong to your account, not to one agent: any number of agents may attach the same collection, and attaching never changes it. Supply id to make the call repeatable (a second create with the same id returns 409), or omit it for a generated one.

Σώμα αιτήματος

application/json Σχήμα: KbCollectionRequest

Πεδίο Τύπος Απαιτείται Περιγραφή
default_lang string
description string
id string
name string Ναι

Αποκρίσεις

Κωδικός Περιγραφή
201 Created.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
409 The collection id is already taken (collection_exists), or your plan's collection allowance is used up (kb_collection_limit).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X POST "https://api.voiceland.ai/v1/kb/collections" \
  -H "Authorization: Bearer VL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "default_lang": "el",
  "description": "Price list and billing rules.",
  "name": "Τιμοκατάλογος"
}'

Η επιτυχής απόκριση επιστρέφει ένα KnowledgeCollection.

Παράδειγμα απόκρισης

{
  "default_lang": "el",
  "doc_count": 0,
  "id": "col_9f2a1c7d",
  "name": "Τιμοκατάλογος",
  "vector_count": 0
}

DELETE /v1/kb/collections/{id}#

Delete a collection. Deletes an empty collection. A collection that still holds documents returns 409, pass ?cascade=true to delete its documents and remove them from the search index in the same call.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
id path string Ναι Collection id.
cascade query boolean Also delete every document in the collection.

Αποκρίσεις

Κωδικός Περιγραφή
204 Deleted.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
409 The collection still holds documents and cascade was not set (collection_not_empty).
4XX Request error (validation, not-found, etc.).
501 The collection holds indexed documents and this deployment has no search index, so the cascade cannot remove their passages (vector_store_unavailable).
502 The search index could not be reached (vector_store_error), or passages could not be removed from it (kb_purge_failed). The request made no change; retry the call.
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X DELETE "https://api.voiceland.ai/v1/kb/collections/{id}" \
  -H "Authorization: Bearer VL_API_KEY"

GET /v1/kb/collections/{id}#

Get a collection. Returns one collection by id.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
id path string Ναι Collection id.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl "https://api.voiceland.ai/v1/kb/collections/{id}" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KnowledgeCollection.

Παράδειγμα απόκρισης

{
  "doc_count": 12,
  "id": "col_9f2a1c7d",
  "name": "Τιμοκατάλογος"
}

PATCH /v1/kb/collections/{id}#

Update a collection. Changes the name, description, or default language. Omitted fields are left alone; the documents inside are untouched.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
id path string Ναι Collection id.

Σώμα αιτήματος

application/json Σχήμα: KbCollectionPatchRequest

Πεδίο Τύπος Απαιτείται Περιγραφή
default_lang string
description string
name string

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X PATCH "https://api.voiceland.ai/v1/kb/collections/{id}" \
  -H "Authorization: Bearer VL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "description": "Τιμές και εκπτώσεις 2026"
}'

Η επιτυχής απόκριση επιστρέφει ένα KnowledgeCollection.

Παράδειγμα απόκρισης

{
  "description": "Τιμές και εκπτώσεις 2026",
  "id": "col_9f2a1c7d"
}

GET /v1/kb/collections/{id}/documents#

List documents. One page of the documents in a collection, in id order. The response omits each document's body, fetch a single document for its text. **Paging.** Pass the next_cursor from the previous response back as ?cursor= to get the page after it. **An empty next_cursor is the only signal that you have seen everything**, a short page, including an empty one, is normal and means "ask again": status is applied after each read, so a page can legitimately match nothing and still have more behind it. Follow the cursor until it comes back empty and your account's whole collection is covered, however large it is. Ordering is by document id within the collection, not by when a document was last edited: a page cannot sort documents it has not read, and a listing that claimed an order it could not keep across pages would repeat and skip documents.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
id path string Ναι Collection id.
status query string Filter by lifecycle state: draft, in_review, published, archived.
audience query string Only documents that declare this audience. Matched against the stored, lower-cased value, so the case you send does not matter. A document that declares no audience is not returned, absent is not "every audience".
source_authority query string Only documents with this authority: official, verified, community or unverified. A document that declares none is not returned. Anything outside the four is a 400 rather than an empty page, so a typo cannot read as "you have no official documents".
limit query integer Documents per page, 1 to 100 (default 50). Larger values are capped rather than refused, keep following next_cursor for the rest.
cursor query string The next_cursor from the previous page. Omit for the first page. A cursor belongs to the collection that issued it.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
400 status is not one of the four lifecycle states, source_authority is not one of the four authority levels, or limit is not a positive whole number (bad_request); or cursor was not issued by this listing for this collection (invalid_cursor), start again without it.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
404 No such collection on your account (collection_not_found).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl "https://api.voiceland.ai/v1/kb/collections/{id}/documents" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KbDocumentsResponse.

Παράδειγμα απόκρισης

{
  "items": [
    {
      "chunk_count": 7,
      "id": "doc_4b1e77a0",
      "status": "published",
      "title": "Τιμολόγηση 2026",
      "version": "1.1.0"
    }
  ],
  "next_cursor": "Y29sXzlmMmExYzdkI2RvY180YjFlNzdhMA"
}

POST /v1/kb/collections/{id}/documents#

Add a document. Adds a document to the collection. Five shapes are accepted on this one route: - **inline text**, JSON with title + body. Indexed synchronously; responds **201** with the document. - **file upload**, multipart/form-data with a file part (PDF, DOCX, HTML, Markdown, TXT, CSV) plus optional title, lang, tags, categories, audience, source_authority fields. Send the fields BEFORE the file. - **a web page**, JSON {"url": "https://example.com"}. The page is fetched, extracted and indexed. - **your website**, JSON {"website": "https://example.com"}, and the one to reach for. You do not have to know where your sitemap lives: we read your robots.txt, then try the conventional paths, and crawl the sitemap we find. A site that publishes none is crawled by FOLLOWING ITS LINKS instead, same result, one document made of many pages. A deep link is reduced to the site it belongs to, so pasting the page you had open works. The **202** carries a discovery block saying which sitemap was found and where it was declared, or, when there was none, which addresses were tried and that links will be followed. Takes the same optional scope as a sitemap. - **a sitemap**, JSON {"sitemap": "https://example.com/sitemap.xml"} with an optional scope (allow/deny path prefixes, max_pages). **Leave max_pages out and you get every page**, there is no default cap; a limit applies when you state one or when your plan sets one, and the job says when it stopped short and why. The whole crawl becomes ONE document made of many pages, so each answer still links to the exact page it came from. Add scope.recrawl_interval ("24h", between 1h and 8760h, one hour to one year) to have the source re-fetched on a timer, the re-fetch is conditional, so a page that has not changed costs you nothing, and the schedule only runs while the document is published. It applies to a single url as well as to a sitemap. You send it as a duration string; the document reports it back as a number of nanoseconds. Everything except inline text responds **202** with the draft document AND an ingestion job, poll GET /kb/jobs/{jobID} for progress. Every shape starts as a draft at version 1.0.0 and is NOT searchable until you publish it. **Standardised taxonomy.** Beside the free-form tags and categories, every shape accepts two typed fields that search and the document listing can narrow by: - audience, who the document is written for (["customers", "partners"], «συνεργάτες»). Your own vocabulary, in any language, but it is stored lower-cased with runs of spaces collapsed and matched EXACTLY, so pick the words once and reuse them. At most 8 values, 64 characters each. Nothing is enforced; if you have no opinion of your own, these are the words we suggest so that two collections agree: customers, prospects, partners, employees, agents, public, internal. - source_authority, how much weight the document carries: official (your own published position), verified (third-party material somebody checked), community (written by users), unverified (explicitly not checked). Nothing else is accepted. **Leaving either one out is not a value.** A document with no source_authority has made no claim, and unverified says the opposite, that somebody looked. Filters honour the difference: narrowing a search to unverified returns the documents marked so, never the ones nobody has labelled. Nothing on the platform fills these in for you. If you have been keeping the same information in metadata (metadata.audience and the like), it stays exactly where it is and keeps working, it is not read as a fallback and nothing was migrated, because a value nobody validated should not silently become a retrieval filter. Move it across when you are ready, one document at a time.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
id path string Ναι Collection id.

Σώμα αιτήματος

application/json Σχήμα: KbDocumentRequest

Πεδίο Τύπος Απαιτείται Περιγραφή
audience array of string
body string
categories array of string
effective_from string
effective_until string
id string
lang string
metadata map of string
scope KbCrawlScope
sitemap string
source_authority string
tags array of string
title string Ναι
url string
website string

Σώμα αιτήματος

multipart/form-data

Αποκρίσεις

Κωδικός Περιγραφή
201 Created as a draft (inline text).
202 Accepted for ingestion (upload, url or sitemap).
400 The address could not be parsed or is not http(s) (invalid_url); the address resolves somewhere we will not fetch from (url_not_allowed); scope.recrawl_interval is not a duration or is outside the 1h, 8760h range (recrawl_interval_out_of_range); effective_from/effective_until could not be parsed as RFC3339 or does not close after it opens (bad_request); or a platform-managed metadata key was set, anything starting crawl_ or vl_, plus filename and content_type (reserved_metadata_key).
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
409 A quota was reached, documents on the account (kb_document_limit), upload size (kb_upload_limit), or pages per crawl (kb_crawl_page_limit), the document id is already taken by another document anywhere on your account (document_exists), or that document already has an ingestion job in flight (kb_job_in_flight), so wait for it to finish or cancel it.
413 The request body exceeds the accepted size (body_too_large).
415 The uploaded file is not one of the supported document types (unsupported_document_type).
4XX Request error (validation, not-found, etc.).
501 This deployment has no document storage (document_storage_unavailable) or no search index (vector_store_unavailable) configured; inline documents still work.
502 The stored copy of your file or crawled pages could not be read or written (document_storage_error). The request made no change; retry the call.
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X POST "https://api.voiceland.ai/v1/kb/collections/{id}/documents" \
  -H "Authorization: Bearer VL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "body": "# Τιμολόγηση\n\nΗ χρέωση γίνεται ανά λεπτό ομιλίας…",
  "categories": [
    "Τιμολόγηση/Εκπτώσεις"
  ],
  "lang": "el",
  "tags": [
    "pricing"
  ],
  "title": "Τιμολόγηση 2026"
}'

Η επιτυχής απόκριση επιστρέφει ένα KnowledgeDocument.

Παράδειγμα απόκρισης

{
  "collection_id": "col_9f2a1c7d",
  "id": "doc_4b1e77a0",
  "status": "draft",
  "version": "1.0.0"
}

DELETE /v1/kb/documents/{docID}#

Delete a document. Deletes the document and everything derived from it, in order: any ingestion still running is cancelled, its passages are removed from the search index, the stored copy of your file or crawled pages is erased, and then the document itself. Permanent, archive instead if you may want the text back.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
docID path string Ναι Document id.
collection_id query string The document's collection. Optional: document ids are unique across your whole knowledge base, so we can always find the document without it. Supplying it, every listing and every create response gives it to you, saves one lookup.

Αποκρίσεις

Κωδικός Περιγραφή
204 Deleted.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
404 No such document on your account (document_not_found).
4XX Request error (validation, not-found, etc.).
501 The document has passages in search and this deployment has no search index, so they cannot be removed (vector_store_unavailable). Deleting a never-indexed document is unaffected.
502 The search index could not be reached (vector_store_error), or passages could not be removed from it (kb_purge_failed). The stored copy of your file or crawled pages could not be read or written (document_storage_error). The request made no change; retry the call.
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X DELETE "https://api.voiceland.ai/v1/kb/documents/{docID}" \
  -H "Authorization: Bearer VL_API_KEY"

GET /v1/kb/documents/{docID}#

Get a document. Returns one document including its full text. A document with a re-crawl schedule also carries recrawl_state: last_crawled_at and next_due_at. Read the ABSENCE of next_due_at beside a non-zero recrawl_interval as meaningful rather than as an error, only a published document is ever re-fetched, so that combination is the usual answer to "I set a schedule and nothing is happening". The listing does not carry it; ask for the document.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
docID path string Ναι Document id.
collection_id query string The document's collection. Optional: document ids are unique across your whole knowledge base, so we can always find the document without it. Supplying it, every listing and every create response gives it to you, saves one lookup.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
404 No such document on your account (document_not_found).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl "https://api.voiceland.ai/v1/kb/documents/{docID}" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KnowledgeDocument.

Παράδειγμα απόκρισης

{
  "id": "doc_4b1e77a0",
  "status": "published",
  "title": "Τιμολόγηση 2026",
  "version": "1.1.0"
}

PATCH /v1/kb/documents/{docID}#

Update a document. Edits the title, text, language, tags, categories, audience, source authority, metadata, validity window or re-crawl schedule. **Sending body is a redaction, and it is destructive.** The text you send becomes the whole content of the document, and everything derived from the old text is destroyed rather than left to reappear: - the passages already in search are removed, so the old text stops being answerable the moment you save; - a published document drops back to draft, publish again to make the new text live. A draft stays a draft, and editing anything other than body leaves a published document published; - **on an uploaded or crawled document, the stored copy of your file or crawled pages is erased, any ingestion still running on it is cancelled, and the document's source becomes inline.** From then on the text on the row is the only content of record: re-index and publish rebuild from what you sent, never from the file you originally uploaded or the page we crawled. source.url is kept as provenance for citations, but nothing re-fetches it. That last point is the difference between an edit and a redaction, and it is one-way. If you need the original bytes back, upload them again as a new document. If you only meant to correct a typo in a file you still want us to hold, edit the file and re-upload it instead. **Moving the validity window also takes a published document out of search**, and for the same reason a text edit does: the window is stamped into every passage when you publish, so a row whose dates moved while its passages still carry the old ones is a document that answers on a day it should not. It is a NARROWER action than a body edit, nothing stored is destroyed and the source is not flipped to inline, the document simply drops back to draft, and publishing again re-stamps the passages. Send "" on either side to clear it. recrawl_interval sets or clears the schedule (a Go duration, "24h", between 1h and 8760h, one hour to one year; "" stops it). It applies to documents whose source is a url or a sitemap, and only a published one is ever re-fetched. audience and source_authority are the standardised taxonomy, see the create call for what the values mean. Send "audience": [] or "source_authority": "" to take a claim back off a document; there is no word in the vocabulary for "we have not said", so clearing is how you say it. **Re-labelling does NOT take a published document out of search**, it is a label, not content, and the same is true of tags and categories. The passages already in search keep the labels they were published with until you publish again, so a search narrowed by the new label finds the document only after the next publish. metadata replaces the map you own. Keys the platform manages, anything starting crawl_ or vl_, plus filename and content_type, cannot be set and are preserved across the replacement (400 reserved_metadata_key if you send one). The same rule applies when you CREATE a document. metadata.audience and friends are NOT reserved and are NOT read as a fallback for the typed fields: if you have been keeping this information there it keeps working untouched.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
docID path string Ναι Document id.
collection_id query string The document's collection. Optional: document ids are unique across your whole knowledge base, so we can always find the document without it. Supplying it, every listing and every create response gives it to you, saves one lookup.

Σώμα αιτήματος

application/json Σχήμα: KbDocumentPatchRequest

Πεδίο Τύπος Απαιτείται Περιγραφή
audience array of string
body string
categories array of string
effective_from string
effective_until string
lang string
metadata map of string
recrawl_interval string
source_authority string
tags array of string
title string

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
400 A platform-managed metadata key was supplied (reserved_metadata_key); effective_from/effective_until could not be parsed as RFC3339 or from is not before until (bad_request); or recrawl_interval is not a duration, is outside 1h, 8760h (recrawl_interval_out_of_range), or names a document with no address to fetch again (recrawl_not_applicable); or the new primary lang is already held by one of the document's translations (primary_language_conflict), delete that variant first, or the row would carry the same language twice.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
404 No such document on your account, or it was deleted while the edit was in flight (document_not_found). The edit is discarded rather than recreating the document.
4XX Request error (validation, not-found, etc.).
501 The edit takes a published document out of search and this deployment has no search index, so its passages cannot be removed (vector_store_unavailable); or it redacts an uploaded document and this deployment has no document storage, so the stored bytes cannot be erased (document_storage_unavailable). Editing an unpublished inline document is unaffected.
502 The search index could not be reached (vector_store_error), or passages could not be removed from it (kb_purge_failed). The stored copy of your file or crawled pages could not be read or written (document_storage_error). The request made no change; retry the call.
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X PATCH "https://api.voiceland.ai/v1/kb/documents/{docID}" \
  -H "Authorization: Bearer VL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "body": "# Τιμολόγηση\n\nΑναθεωρημένες τιμές…"
}'

Η επιτυχής απόκριση επιστρέφει ένα KnowledgeDocument.

Παράδειγμα απόκρισης

{
  "id": "doc_4b1e77a0",
  "source": {
    "kind": "inline"
  },
  "status": "draft",
  "version": "1.1.0"
}

POST /v1/kb/documents/{docID}/archive#

Archive a document. Takes the document out of search while keeping the text and its history. Safe to repeat. Publish again to bring it back. The passages are removed from the index before the document is marked archived, and the removal is attempted whether or not the document is recorded as indexed, so an archive can only ever end with less in search than it started with, never more.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
docID path string Ναι Document id.
collection_id query string The document's collection. Optional: document ids are unique across your whole knowledge base, so we can always find the document without it. Supplying it, every listing and every create response gives it to you, saves one lookup.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
403 Signed in as a console user without the account_admin role (role_required). API keys are unaffected.
404 No such document on your account, or it was deleted while the archive was in flight (document_not_found).
4XX Request error (validation, not-found, etc.).
501 The document has passages in search and this deployment has no search index, so they cannot be removed (vector_store_unavailable). Archiving a never-indexed document is unaffected.
502 The search index could not be reached (vector_store_error), or passages could not be removed from it (kb_purge_failed). The request made no change; retry the call.
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X POST "https://api.voiceland.ai/v1/kb/documents/{docID}/archive" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KnowledgeDocument.

Παράδειγμα απόκρισης

{
  "chunk_count": 0,
  "id": "doc_4b1e77a0",
  "status": "archived"
}

GET /v1/kb/documents/{docID}/chunks#

Preview passages. Shows how the document splits into retrievable passages, with the heading each one sits under. count is what the current text would produce; indexed_count is what search actually holds, they differ when the text was edited after the last publish.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
docID path string Ναι Document id.
collection_id query string The document's collection. Optional: document ids are unique across your whole knowledge base, so we can always find the document without it. Supplying it, every listing and every create response gives it to you, saves one lookup.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
404 No such document on your account (document_not_found).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl "https://api.voiceland.ai/v1/kb/documents/{docID}/chunks" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KbChunksResponse.

Παράδειγμα απόκρισης

{
  "count": 7,
  "document_id": "doc_4b1e77a0",
  "indexed_count": 7,
  "items": [
    {
      "chunk_id": "doc_4b1e77a0#0",
      "index": 0,
      "section": "Τιμολόγηση",
      "text": "Η χρέωση γίνεται ανά λεπτό ομιλίας…"
    }
  ],
  "status": "published",
  "version": "1.1.0"
}

POST /v1/kb/documents/{docID}/publish#

Publish a document. Makes the document answerable: the text is split into passages, indexed for search, and the version's minor number is bumped so an answer can name the exact revision it used. Safe to repeat, republishing replaces the previous passages rather than duplicating them. Publishable from any state: a draft, a document **in review** (this is the approval step), a published one you are re-indexing, or an archived one you are bringing back. An inline document is indexed inside the call (**200**). An uploaded or crawled one cannot be, its content is not on the row, so publishing it responds **202** with {document, job} and the passages appear once the job reports indexed.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
docID path string Ναι Document id.
collection_id query string The document's collection. Optional: document ids are unique across your whole knowledge base, so we can always find the document without it. Supplying it, every listing and every create response gives it to you, saves one lookup.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
202 Queued for indexing (uploaded or crawled document).
400 The text produces no retrievable passages (document_empty), or it splits into more passages than one document may hold (document_too_large), split it into several documents.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
403 Signed in as a console user without the account_admin role (role_required). API keys are unaffected.
404 No such document on your account, or it was deleted while the publish was in flight (document_not_found). Any passages already written are taken back out, so a deleted document is never resurrected by a publish that raced it.
409 That document already has an ingestion job in flight (kb_job_in_flight), wait for it to finish or cancel it.
4XX Request error (validation, not-found, etc.).
501 Publishing needs a search index and this deployment has none configured (vector_store_unavailable).
502 The text could not be turned into vectors by the embedding provider (embed_failed). The search index could not be reached (vector_store_error), or passages could not be removed from it (kb_purge_failed). The request made no change; retry the call.
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X POST "https://api.voiceland.ai/v1/kb/documents/{docID}/publish" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KnowledgeDocument.

Παράδειγμα απόκρισης

{
  "chunk_count": 7,
  "id": "doc_4b1e77a0",
  "status": "published",
  "version": "1.1.0"
}

POST /v1/kb/documents/{docID}/recrawl#

Fetch this document's source again. Goes back to the address this document came from and reads it again, because the PAGE changed, not because we did. **This is the other half of re-index, and the difference matters.** /reindex rebuilds passages from the copy we already keep, so it is right when our chunking or embedding model improved and useless when your website changed. /recrawl is the opposite: it re-fetches, and the fetch is conditional, a page that has not changed costs you nothing. The kind of walk is the document's own: a document built from a sitemap re-walks that sitemap, one built by following links walks them again, and a single page re-fetches that page. You do not choose, and cannot: it is what the document is made of. Refused with **400** not_a_remote_document when there is no address to go back to, text you typed, a file you uploaded, a bucket import. One job at a time per document, because this one reaches out to somebody's web server.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
docID path string Ναι Document id.
collection_id query string The document's collection. Optional: document ids are unique across your whole knowledge base, so we can always find the document without it. Supplying it, every listing and every create response gives it to you, saves one lookup.

Αποκρίσεις

Κωδικός Περιγραφή
202 Queued.
400 This document has no address to fetch again (not_a_remote_document).
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
404 No such document on your account (document_not_found).
409 An ingestion job is already running on it (kb_job_in_flight).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X POST "https://api.voiceland.ai/v1/kb/documents/{docID}/recrawl" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KbIngestResponse.

Παράδειγμα απόκρισης

{
  "document": {
    "id": "doc_4b1e77a0",
    "status": "published"
  },
  "job": {
    "id": "job_1c4f9ab2",
    "kind": "sitemap",
    "status": "queued"
  }
}

POST /v1/kb/documents/{docID}/reindex#

Re-index a document. Queues the document to be extracted, split and embedded again, after the platform's chunking improves, or once you have corrected the collection's language. It re-reads the copy we already keep of your file or crawled pages, so re-indexing never hits your website again, which is exactly why it will NOT see a page you have edited. Use /recrawl for that.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
docID path string Ναι Document id.
collection_id query string The document's collection. Optional: document ids are unique across your whole knowledge base, so we can always find the document without it. Supplying it, every listing and every create response gives it to you, saves one lookup.

Αποκρίσεις

Κωδικός Περιγραφή
202 Queued.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
404 No such document on your account (document_not_found).
409 That document already has an ingestion job in flight (kb_job_in_flight), wait for it to finish or cancel it.
4XX Request error (validation, not-found, etc.).
501 This deployment has no search index configured, so nothing can be re-indexed (vector_store_unavailable).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X POST "https://api.voiceland.ai/v1/kb/documents/{docID}/reindex" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KbIngestResponse.

Παράδειγμα απόκρισης

{
  "document": {
    "id": "doc_4b1e77a0",
    "status": "published"
  },
  "job": {
    "id": "job_1c4f9ab2",
    "kind": "reindex",
    "status": "queued"
  }
}

POST /v1/kb/documents/{docID}/review-flag/dismiss#

Dismiss a review flag. Closes a review flag by saying the document was not at fault. **A reason is required**: the flag exists because a human confirmed an answer was wrong, so a dismissal is a claim that the cause was somewhere else, and one with no reason attached is indistinguishable from clearing the queue. The other way out is to publish the document again, which closes the flag as resolved with no extra call: republishing states its case by changing the content. A decision is one-shot. What reopens a closed flag is a NEW confirmed-wrong report naming the same document.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
docID path string Ναι Document id.
collection_id query string The document's collection. Optional: document ids are unique across your whole knowledge base, so we can always find the document without it. Supplying it, every listing and every create response gives it to you, saves one lookup.

Σώμα αιτήματος

application/json Σχήμα: KbReviewDismissRequest

Πεδίο Τύπος Απαιτείται Περιγραφή
dismissed_by string
reason string Ναι

Αποκρίσεις

Κωδικός Περιγραφή
200 The closed flag.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
403 Signed in as a console user without the account_admin role (role_required). API keys are unaffected.
404 No such document on your account (document_not_found), or it carries no review flag (review_flag_not_found).
409 The flag is already closed (review_flag_closed).
422 No reason was given (reason_required).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X POST "https://api.voiceland.ai/v1/kb/documents/{docID}/review-flag/dismiss" \
  -H "Authorization: Bearer VL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "dismissed_by": "maria@acme.example",
  "reason": "The document is correct; the agent quoted the wrong section."
}'

Η επιτυχής απόκριση επιστρέφει ένα KnowledgeReviewFlag.

Παράδειγμα απόκρισης

{
  "collection_id": "col_9f2a1c7d",
  "document_id": "doc_4b1e77a0",
  "report_count": 3,
  "resolution_note": "The document is correct; the agent quoted the wrong section.",
  "resolved_by": "maria@acme.example",
  "state": "dismissed"
}

POST /v1/kb/documents/{docID}/submit#

Submit a document for review. Marks a draft as ready for somebody to check before it goes live: the status becomes in_review. Nothing about search changes, a document in review is no more answerable than a draft, so this is a hand-off, not a publish. Only a **draft** can be submitted. Repeating the call on a document already in review succeeds and changes nothing. A **published** document cannot be sent back for review by this call: its passages are live in search, and a status change alone would leave them answering. Edit its text, that takes it out of search and returns it to draft, then submit. Archiving is not a route back: an archived document cannot be submitted either, and the only way out of archived is to publish it.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
docID path string Ναι Document id.
collection_id query string The document's collection. Optional: document ids are unique across your whole knowledge base, so we can always find the document without it. Supplying it, every listing and every create response gives it to you, saves one lookup.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
403 Signed in as a console user without the account_admin role (role_required). API keys are unaffected.
404 No such document on your account (document_not_found).
409 The document is not in a state that can be submitted for review (invalid_transition), the message names the state it is in and the way out of it; or an ingestion job is still running on it (kb_job_in_flight), in which case the move would make that job throw its own work away, so wait for it to finish or cancel it. Repeating a move the document has already made is never refused, job or no job.
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X POST "https://api.voiceland.ai/v1/kb/documents/{docID}/submit" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KnowledgeDocument.

Παράδειγμα απόκρισης

{
  "id": "doc_4b1e77a0",
  "status": "in_review",
  "version": "1.0.0"
}

GET /v1/kb/documents/{docID}/variants#

List a document's languages. Every language the document holds, the primary one first. The primary is in the list because search falls back to it, a language picker built from this list offers exactly the choices search can honour.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
docID path string Ναι Document id.
collection_id query string The document's collection. Optional: document ids are unique across your whole knowledge base, so we can always find the document without it. Supplying it, every listing and every create response gives it to you, saves one lookup.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
404 No such document on your account (document_not_found).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl "https://api.voiceland.ai/v1/kb/documents/{docID}/variants" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KbVariantsResponse.

Παράδειγμα απόκρισης

{
  "document_id": "doc_4b1e77a0",
  "items": [
    {
      "chunk_count": 7,
      "lang": "el",
      "primary": true
    },
    {
      "chunk_count": 6,
      "lang": "en",
      "primary": false
    }
  ],
  "primary_lang": "el"
}

POST /v1/kb/documents/{docID}/variants#

Add or replace a language version. Stores another language of the same document. A variant carries content only, the status, version, tags, categories and validity window stay on the document, so there is one thing to review and publish rather than one per language. Search prefers the language the person is searching in and falls back to the document's own, so a document with no Greek version still answers a Greek question, in the language it has. Adding a language to a **published** document takes it out of search until you publish again, exactly as editing its text does: what search holds is stamped when you publish, and quietly re-indexing inside this call would spend an embedding batch you did not ask for. Available for documents with inline text. A document ingested from a file, a page or a sitemap gets its language from its source.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
docID path string Ναι Document id.
collection_id query string The document's collection. Optional: document ids are unique across your whole knowledge base, so we can always find the document without it. Supplying it, every listing and every create response gives it to you, saves one lookup.

Σώμα αιτήματος

application/json Σχήμα: KbVariantRequest

Πεδίο Τύπος Απαιτείται Περιγραφή
body string Ναι
lang string Ναι Language tag for this version. It may not repeat the document's primary language.
title string

Αποκρίσεις

Κωδικός Περιγραφή
200 Replaced an existing language.
201 Added.
400 lang is missing or is not a language tag, body is empty, the document is not an inline one (variants_not_supported), or this language's text splits into more passages than one document may hold (document_too_large), the cap is a TOTAL across every language, because the languages share one document.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
404 No such document on your account (document_not_found).
409 The document already carries the maximum number of languages, or this one repeats its primary language (variant_conflict).
413 This language's text is too large (body_too_large), the languages share one document.
4XX Request error (validation, not-found, etc.).
502 The search index could not be reached (vector_store_error), or passages could not be removed from it (kb_purge_failed). The request made no change; retry the call.
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X POST "https://api.voiceland.ai/v1/kb/documents/{docID}/variants" \
  -H "Authorization: Bearer VL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "body": "# Pricing\n\nBilling is per minute of speech…",
  "lang": "en",
  "title": "Pricing 2026"
}'

Η επιτυχής απόκριση επιστρέφει ένα KbVariantResponse.

DELETE /v1/kb/documents/{docID}/variants/{lang}#

Delete one language. Removes that language and its passages from search. The other languages are untouched, the removal names this language only. The primary language cannot be deleted this way; deleting the document removes it.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
docID path string Ναι Document id.
lang path string Ναι Language tag.
collection_id query string The document's collection. Optional: document ids are unique across your whole knowledge base, so we can always find the document without it. Supplying it, every listing and every create response gives it to you, saves one lookup.

Αποκρίσεις

Κωδικός Περιγραφή
204 Deleted.
400 That language is the document's primary one (primary_language).
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
404 No such document (document_not_found), or it has no version in that language (variant_not_found).
4XX Request error (validation, not-found, etc.).
502 The search index could not be reached (vector_store_error), or passages could not be removed from it (kb_purge_failed). The request made no change; retry the call.
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X DELETE "https://api.voiceland.ai/v1/kb/documents/{docID}/variants/{lang}" \
  -H "Authorization: Bearer VL_API_KEY"

GET /v1/kb/documents/{docID}/variants/{lang}#

Get one language. Returns that language's title and text, or 404 if the document does not have it. It does NOT fall back to the primary, a console asking "is there a Greek version" has to be able to get a no.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
docID path string Ναι Document id.
lang path string Ναι Language tag.
collection_id query string The document's collection. Optional: document ids are unique across your whole knowledge base, so we can always find the document without it. Supplying it, every listing and every create response gives it to you, saves one lookup.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
404 No such document (document_not_found), or it has no version in that language (variant_not_found).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl "https://api.voiceland.ai/v1/kb/documents/{docID}/variants/{lang}" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KbVariantResponse.

Παράδειγμα απόκρισης

{
  "body": "# Pricing…",
  "chunk_count": 6,
  "lang": "en",
  "primary": false,
  "title": "Pricing 2026"
}

PATCH /v1/kb/documents/{docID}/variants/{lang}#

Update one language. Changes that language's title or text. The language itself cannot be changed, delete it and add the other one. Editing the primary language goes through PATCH /kb/documents/{docID} instead, which is the call that also removes the old text from search and from storage.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
docID path string Ναι Document id.
lang path string Ναι Language tag.
collection_id query string The document's collection. Optional: document ids are unique across your whole knowledge base, so we can always find the document without it. Supplying it, every listing and every create response gives it to you, saves one lookup.

Σώμα αιτήματος

application/json Σχήμα: KbVariantPatchRequest

Πεδίο Τύπος Απαιτείται Περιγραφή
body string
title string

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
400 That language is the document's primary one (primary_language), the document is not an inline one (variants_not_supported), or the new text splits into more passages than the document may hold across all its languages (document_too_large).
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
404 No such document (document_not_found), or it has no version in that language (variant_not_found).
4XX Request error (validation, not-found, etc.).
502 The search index could not be reached (vector_store_error), or passages could not be removed from it (kb_purge_failed). The request made no change; retry the call.
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X PATCH "https://api.voiceland.ai/v1/kb/documents/{docID}/variants/{lang}" \
  -H "Authorization: Bearer VL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "body": "# Pricing\n\nBilling is per minute…"
}'

Η επιτυχής απόκριση επιστρέφει ένα KbVariantResponse.

Παράδειγμα απόκρισης

{
  "chunk_count": 0,
  "lang": "en",
  "primary": false
}

POST /v1/kb/documents/{docID}/withdraw#

Take a document out of review. Returns a document in review to draft, the same call whether the author is withdrawing it or a reviewer is sending it back. Nothing about search changes. Only a document **in review** can be withdrawn. Repeating the call on a draft succeeds and changes nothing. A published document is not withdrawn but archived.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
docID path string Ναι Document id.
collection_id query string The document's collection. Optional: document ids are unique across your whole knowledge base, so we can always find the document without it. Supplying it, every listing and every create response gives it to you, saves one lookup.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
403 Signed in as a console user without the account_admin role (role_required). API keys are unaffected.
404 No such document on your account (document_not_found).
409 The document is not in a state that can be withdrawn from review (invalid_transition), the message names the state it is in and the way out of it; or an ingestion job is still running on it (kb_job_in_flight), in which case the move would make that job throw its own work away, so wait for it to finish or cancel it. Repeating a move the document has already made is never refused, job or no job.
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X POST "https://api.voiceland.ai/v1/kb/documents/{docID}/withdraw" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KnowledgeDocument.

Παράδειγμα απόκρισης

{
  "id": "doc_4b1e77a0",
  "status": "draft",
  "version": "1.0.0"
}

POST /v1/kb/import-inline#

Import an agent's inline knowledge. Turns the free-text knowledge you gave an agent into a knowledge-base document, so it can be searched, versioned, cited and shared with other agents instead of being re-sent to the model on every single turn. **Your agent is not changed.** The inline text stays exactly where it is and keeps working, so you can import, publish, attach, listen to the agent answer from search, and only then remove the inline copy by hand. **Safe to repeat.** The document id is derived from the agent name, so calling it again updates the same document, and if the text has not changed, nothing at all is written (changed: false). Set attach: true to also add the collection to the agent's knowledge sources. audience and source_authority set the standardised taxonomy (see the create call). Changing either one counts as a change, so a re-import that only re-labels the document is written, and, since it changes a label rather than the text, it does not take a published document out of search.

Σώμα αιτήματος

application/json Σχήμα: KbImportInlineRequest

Πεδίο Τύπος Απαιτείται Περιγραφή
agent string Ναι The agent whose inline knowledge is read. The agent is NOT modified.
attach boolean Also add the collection to the agent's knowledge sources. Default false: attaching changes what a LIVE agent retrieves from.
audience array of string
categories array of string
collection_id string Ναι
document_id string Overrides the id derived from the agent name, how you deliberately import one agent's knowledge into more than one document.
knowledge string Text to import instead of reading the agent's prompt. For a console that has the text before it has ever been saved, and for agents whose prompt was not composed here.
lang string
source_authority string
tags array of string
title string

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
400 The agent has no inline knowledge to import (no_inline_knowledge), agent or collection_id is missing, or the document_id you supplied is not a valid id (bad_request); or the import would change the primary language of an existing document to one its translations already hold (primary_language_conflict).
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
404 No such agent (agent_not_found) or collection (collection_not_found).
409 Your plan's document allowance is used up (kb_document_limit), or the derived document id is taken by another collection (document_exists).
413 The inline text is larger than one document may be (body_too_large).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X POST "https://api.voiceland.ai/v1/kb/import-inline" \
  -H "Authorization: Bearer VL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "agent": "front-desk",
  "attach": true,
  "collection_id": "col_9f2a1c7d"
}'

Η επιτυχής απόκριση επιστρέφει ένα KbImportInlineResponse.

Παράδειγμα απόκρισης

{
  "agent": "front-desk",
  "attached": true,
  "changed": true,
  "created": true,
  "document": {
    "id": "inline_front-desk",
    "status": "draft",
    "version": "1.0.0"
  },
  "source": "system_prompt"
}

GET /v1/kb/jobs#

List ingestion jobs. One page of your ingestion jobs, what is queued, running, indexed or failed. A failed job carries a one-line reason. Jobs are kept for 30 days; the document row is the lasting record. **Paging.** Pass the next_cursor from the previous response back as ?cursor= to get the page after it. **An empty next_cursor is the only signal that you have seen everything**, a short page, including an empty one, is normal and means "ask again": status is applied after each read, so a page can legitimately match nothing and still have more behind it. On this listing that is the ordinary case rather than the edge one, because asking for the failed jobs filters a history that is mostly queued ones. Follow the cursor until it comes back empty and your whole job history is covered, however much you have ingested. Ordering is by key, collection, then document, then job id, not by when a job was created: a page cannot sort jobs it has not read, and a listing that claimed an order it could not keep across pages would repeat and skip jobs. Sort a page yourself for an activity feed, or narrow to one document_id, whose whole history is a handful of rows.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
status query string Filter by status: queued, processing, indexed, failed, cancelled.
collection_id query string Only jobs for documents in this collection.
document_id query string Only jobs for this document. Requires collection_id, a job is filed under its document's collection, so jobs are listed within one collection rather than across your account. Every 202 that starts a job returns both ids.
limit query integer Jobs per page, 1 to 100 (default 50). Larger values are capped rather than refused, keep following next_cursor for the rest.
cursor query string The next_cursor from the previous page. Omit for the first page. A cursor belongs to the scope that issued it, one taken from a collection- or document-scoped listing is not valid on a wider one.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
400 status is not one of the five job states, document_id was sent without collection_id, or limit is not a positive whole number (bad_request); or cursor was not issued by this listing for this scope (invalid_cursor), start again without it.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl "https://api.voiceland.ai/v1/kb/jobs" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KbJobsResponse.

Παράδειγμα απόκρισης

{
  "items": [
    {
      "attempts": 1,
      "document_id": "doc_4b1e77a0",
      "id": "job_1c4f9ab2",
      "kind": "sitemap",
      "progress": {
        "chunks_written": 96,
        "pages_done": 17,
        "pages_found": 42
      },
      "status": "processing"
    }
  ],
  "next_cursor": "Y29sXzlmMmExYzdkI2RvY180YjFlNzdhMCNqb2JfMWM0ZjlhYjI"
}

DELETE /v1/kb/jobs/{jobID}#

Cancel an ingestion job. Asks a queued or running job to stop. Best-effort: a job already writing its last passages may still finish, so the response returns the job so you can see which happened. A job that has already finished returns 409.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
jobID path string Ναι Job id.
collection_id query string The job's collection. Give it together with document_id for a direct lookup.
document_id query string The job's document id.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
404 No such job on your account (job_not_found).
409 The job has already finished and cannot be cancelled (job_already_finished).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X DELETE "https://api.voiceland.ai/v1/kb/jobs/{jobID}" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KnowledgeJob.

Παράδειγμα απόκρισης

{
  "id": "job_1c4f9ab2",
  "status": "cancelled"
}

GET /v1/kb/jobs/{jobID}#

Get an ingestion job. One job with its live progress counters. Pass collection_id and document_id together when you have them (the 202 that created the job returned both) to make this a direct lookup instead of a walk.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
jobID path string Ναι Job id.
collection_id query string The job's collection. Give it together with document_id for a direct lookup.
document_id query string The job's document id.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
404 No such job on your account (job_not_found).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl "https://api.voiceland.ai/v1/kb/jobs/{jobID}" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KnowledgeJob.

Παράδειγμα απόκρισης

{
  "document_id": "doc_4b1e77a0",
  "id": "job_1c4f9ab2",
  "kind": "upload",
  "progress": {
    "chunks_written": 12,
    "pages_done": 1,
    "pages_found": 1
  },
  "status": "indexed"
}

GET /v1/kb/object-sources#

List your object-storage sources. Every bucket you have registered. Secrets are never included, has_secret says one is stored, nothing returns its value.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl "https://api.voiceland.ai/v1/kb/object-sources" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KbObjectSourcesResponse.

Παράδειγμα απόκρισης

{
  "items": [
    {
      "access_key_id": "AKIA…",
      "bucket": "acme-docs",
      "endpoint": "s3.eu-central-1.amazonaws.com",
      "has_secret": true,
      "id": "objsrc_a1b2c3d4",
      "prefix": "handbook/"
    }
  ]
}

POST /v1/kb/object-sources#

Register your own object storage. Registers a bucket of yours, AWS S3 or anything that speaks the S3 API, so you can import documents straight out of it instead of uploading them one at a time. **`secret_access_key` is write-only.** It is stored encrypted and is never returned by this call, by the list, by the GET, or by the secrets API, there is no request that reads it back. `has_secret` is how you confirm one is stored. To change it, PATCH this source with a new `secret_access_key`; that is the only way to rotate it. **`endpoint` is a host, not a URL** (`s3.eu-central-1.amazonaws.com`, `objects.example.gr`). We always connect over https on port 443, because anything else would put your access key on the wire in the clear. An `https://example.com prefix is accepted and stripped; a path, a port we do not reach, credentials in the endpoint, or an address on a private network are refused (`endpoint_not_allowed`), and the same check runs again, against the address we actually connect to, every time an import runs. **Give us the narrowest credentials that work.** A read-only key scoped to `prefix` is all an import needs: we only ever LIST and GET. `prefix` is also a boundary, an import may narrow it, never widen it, so a source registered at `handbook/` can never be made to read the rest of the bucket.

Σώμα αιτήματος

application/json Σχήμα: KbObjectSourceRequest

Πεδίο Τύπος Απαιτείται Περιγραφή
access_key_id string Ναι
bucket string Ναι
endpoint string Ναι
id string
name string
prefix string
region string
secret_access_key string Ναι

Αποκρίσεις

Κωδικός Περιγραφή
201 Registered.
400 bucket, access_key_id or secret_access_key is missing, or the id is not a valid id (bad_request); or the endpoint is not one we will connect to (endpoint_not_allowed), a private or link-local address, an internal-only name, a non-https scheme, a port other than 443, or the platform's own storage.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
409 A source with that id already exists (object_source_exists).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X POST "https://api.voiceland.ai/v1/kb/object-sources" \
  -H "Authorization: Bearer VL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "access_key_id": "AKIA…",
  "bucket": "acme-docs",
  "endpoint": "s3.eu-central-1.amazonaws.com",
  "name": "Handbook bucket",
  "prefix": "handbook/",
  "region": "eu-central-1",
  "secret_access_key": "…"
}'

Η επιτυχής απόκριση επιστρέφει ένα KbObjectSourceView.

Παράδειγμα απόκρισης

{
  "access_key_id": "AKIA…",
  "bucket": "acme-docs",
  "endpoint": "s3.eu-central-1.amazonaws.com",
  "has_secret": true,
  "id": "objsrc_a1b2c3d4",
  "name": "Handbook bucket",
  "prefix": "handbook/",
  "region": "eu-central-1"
}

DELETE /v1/kb/object-sources/{sourceID}#

Remove an object-storage source. Removes the registration and erases the stored credential. **It refuses while documents imported from this source still exist** (409 object_source_in_use, naming one of them). That is deliberate: those documents are your indexed content, and deleting a piece of configuration must not destroy them. Delete the documents you no longer want first, deleting a document removes its passages and the copies of your files we kept, and then remove the source. Nothing in your own bucket is touched, ever. We only ever read from it.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
sourceID path string Ναι Source id.

Αποκρίσεις

Κωδικός Περιγραφή
204 Removed.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
404 No such source on your account (object_source_not_found).
409 A document imported from this source still exists (object_source_in_use).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X DELETE "https://api.voiceland.ai/v1/kb/object-sources/{sourceID}" \
  -H "Authorization: Bearer VL_API_KEY"

GET /v1/kb/object-sources/{sourceID}#

Get one object-storage source. The registration as stored. has_secret is checked against the stored credential on this call, so it is the honest answer to "is this source usable"; the secret itself is never returned.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
sourceID path string Ναι Source id.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
404 No such source on your account (object_source_not_found).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl "https://api.voiceland.ai/v1/kb/object-sources/{sourceID}" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KbObjectSourceView.

Παράδειγμα απόκρισης

{
  "bucket": "acme-docs",
  "has_secret": true,
  "id": "objsrc_a1b2c3d4"
}

PATCH /v1/kb/object-sources/{sourceID}#

Update an object-storage source. Changes what is registered. Omitted fields are left alone. **This is how you rotate the credential**: send a new secret_access_key and it replaces the stored one. There is no way to clear it, a source with no credential cannot be imported from, and no way to read the old one back. Documents already imported from this source keep their content. The next import (or re-index that has to re-read the bucket) uses the new settings, so changing the endpoint or bucket redirects future reads without touching what is already indexed.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
sourceID path string Ναι Source id.

Σώμα αιτήματος

application/json Σχήμα: KbObjectSourcePatchRequest

Πεδίο Τύπος Απαιτείται Περιγραφή
access_key_id string
bucket string
endpoint string
name string
prefix string
region string
secret_access_key string

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
400 The new endpoint is not one we will connect to (endpoint_not_allowed), or access_key_id was sent empty (bad_request).
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
404 No such source on your account (object_source_not_found).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X PATCH "https://api.voiceland.ai/v1/kb/object-sources/{sourceID}" \
  -H "Authorization: Bearer VL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "secret_access_key": "…"
}'

Η επιτυχής απόκριση επιστρέφει ένα KbObjectSourceView.

Παράδειγμα απόκρισης

{
  "bucket": "acme-docs",
  "has_secret": true,
  "id": "objsrc_a1b2c3d4"
}

POST /v1/kb/object-sources/{sourceID}/import#

Import from your object storage. Reads every object under the prefix and indexes them, through exactly the same extraction and chunking an upload goes through, PDFs, Word files, Markdown, HTML, CSV and plain text. **One import is one document**, made of every file under the prefix, the same way a sitemap crawl produces one document made of many pages. Each passage still carries the file it came from (s3://bucket/key) so an answer cites the exact file. If you want one document per file, import a narrower prefix per document. Responds **202** with {document, job}: the document exists immediately as a draft, and the files become searchable once the job reports indexed and you publish. Poll GET /kb/jobs/{id}. **Re-importing is cheap and safe, and it is how you pick up changes.** Call this again with the id of a document this same source already produced and it REFRESHES that document rather than making a new one: every file whose ETag has not changed is served from the copy we kept, not downloaded from your bucket, and not re-embedded, and when nothing under the prefix has changed at all the job finishes having written nothing. A refresh is not an edit: the title, the labels and the published status you set are left alone, and the prefix stays whatever that document was imported at (the request's prefix is ignored). Poll or schedule this as often as you like. POST /kb/documents/{id}/reindex is a different thing, it rebuilds passages from the copies we already hold and never looks at your bucket, so it will not see a new or edited file. Your plan's limits are the upload limits: the same per-file size cap, and a per-import ceiling on how many files one import reads. Hitting the ceiling is reported as a warning on the job rather than a failure, narrow the prefix and import the rest separately. audience and source_authority are the standardised taxonomy and mean exactly what they mean on the create call, a bucket of files is one document, so the labels are the document's, not the files'.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
sourceID path string Ναι Source id.

Σώμα αιτήματος

application/json Σχήμα: KbObjectImportRequest

Πεδίο Τύπος Απαιτείται Περιγραφή
audience array of string
categories array of string
collection_id string Ναι
id string
lang string
metadata map of string
prefix string
source_authority string
tags array of string
title string

Αποκρίσεις

Κωδικός Περιγραφή
202 Accepted, the document exists as a draft and the job will fill it.
400 collection_id is missing or the document id is not a valid id (bad_request); the prefix is outside the source's own prefix (prefix_outside_source); a platform-managed metadata key was supplied (reserved_metadata_key); or the source's endpoint is no longer one we will connect to (endpoint_not_allowed).
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
403 Signed in as a console user without the account_admin role (role_required). API keys are unaffected.
404 No such source (object_source_not_found) or collection (collection_not_found).
409 Your plan's document allowance is used up (kb_document_limit); the document id belongs to something this source did not produce, another source's import, or a document you wrote or uploaded (document_exists), and re-importing would overwrite it; or that document already has an ingestion job in flight (kb_job_in_flight).
4XX Request error (validation, not-found, etc.).
501 Importing needs a search index and this deployment has none configured (vector_store_unavailable).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X POST "https://api.voiceland.ai/v1/kb/object-sources/{sourceID}/import" \
  -H "Authorization: Bearer VL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "collection_id": "col_9f2a1c7d",
  "prefix": "handbook/policies/",
  "tags": [
    "hr"
  ],
  "title": "Employee handbook"
}'

Η επιτυχής απόκριση επιστρέφει ένα KbIngestResponse.

Παράδειγμα απόκρισης

{
  "document": {
    "id": "doc_4b1e77a0",
    "source": {
      "kind": "object",
      "object_prefix": "handbook/policies/",
      "object_source_id": "objsrc_a1b2c3d4",
      "url": "s3://acme-docs/handbook/policies/"
    },
    "status": "draft"
  },
  "job": {
    "id": "job_7c1d",
    "kind": "object",
    "status": "queued"
  }
}

GET /v1/kb/review-flags#

List documents flagged for review. One page of the review queue: documents a human traced a wrong answer back to. A flag is raised when somebody resolves an inaccuracy report as confirmed_wrong and names the document that caused it (POST /feedback/reports/{id}/resolve), and it carries the ids of the reports behind it so an author can read why the document is suspect. **Ordering is by how many reports point at each document**, most first, then by collection and document id. That is a ranking rather than a key order, so the read is bounded: truncated: true means the ranking is over the flags examined and not over every flag on your account. Use collection_id to narrow it, or the analytics route for the whole picture. **Paging.** Pass the next_cursor from the previous response back as ?cursor=. **An empty next_cursor is the only signal that you have seen everything**: state is applied after each read, so a short page, including an empty one, is normal and means "ask again". A flag leaves the queue in one of two ways: publish the document again (the fix speaks for itself, and the flag closes as resolved), or dismiss it with a reason. A new confirmed-wrong report on a closed flag reopens it.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
state query string Filter by review state: open, resolved or dismissed. Anything else is a 400 rather than an empty page, so a typo cannot read as "nothing to review".
collection_id query string Only flags on documents in this collection. Also narrows the read, so a collection-scoped queue gets much further before it truncates.
limit query integer Flags per page, 1 to 100 (default 50). Larger values are capped rather than refused.
cursor query string The next_cursor from the previous page. Omit for the first page.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
400 state is not one of open/resolved/dismissed or limit is not a positive whole number (bad_request); or the cursor was not issued by this listing (invalid_cursor).
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl "https://api.voiceland.ai/v1/kb/review-flags" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KbReviewFlagsResponse.

Παράδειγμα απόκρισης

{
  "items": [
    {
      "agent_name": "front-desk",
      "collection_id": "col_9f2a1c7d",
      "document_id": "doc_4b1e77a0",
      "reason": "confirmed_wrong_answer",
      "report_count": 3,
      "report_ids": [
        "fbr_9d8c7b6a",
        "fbr_5e4d3c2b",
        "fbr_1a2b3c4d"
      ],
      "state": "open"
    }
  ],
  "next_cursor": "",
  "truncated": false
}

GET /v1/kb/review-flags/analytics#

Which documents cause wrong answers. Ranks your documents by how many answers a human confirmed wrong and traced back to them. This is the number that says where your knowledge is actually wrong, as opposed to where the agent is. knowledge_fault_rate is the share of confirmed-wrong answers a reviewer traced to a document at all; linked_to_document beside confirmed_wrong is what makes that honest: a rate of zero means "nobody filled in which document", not "your knowledge is fine". It counts REPORTS, not open flags: a document you fixed last week still shows the answers it broke, because it broke them. The definition field ships the exact arithmetic. The read is bounded; truncated: true means there were more confirmed-wrong reports than one request folds.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl "https://api.voiceland.ai/v1/kb/review-flags/analytics" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KbReviewAnalyticsResponse.

Παράδειγμα απόκρισης

{
  "confirmed_wrong": 7,
  "documents": 2,
  "items": [
    {
      "agents": [
        "front-desk"
      ],
      "categories": [
        "outdated"
      ],
      "confirmed_wrong": 3,
      "document_id": "doc_4b1e77a0",
      "share": 0.6
    }
  ],
  "knowledge_fault_rate": 0.7142857142857143,
  "linked_to_document": 5,
  "scanned": 7,
  "truncated": false
}

POST /v1/kb/search#

Search your knowledge base. Searches your **published** documents and returns ranked passages with the matched words marked in a snippet. Natural-language questions work, the query is matched both by meaning and by word, so a Greek question finds a Greek document written with or without accents. filters.lang is the language of the person searching, not a hard filter: a document with no version in that language still answers, in the language it has. filters.collections, filters.tags, filters.categories, filters.audience and filters.source_authority narrow; nothing here can widen a search beyond your own published content, and a document outside its validity window never appears. filters.audience and filters.source_authority are the standardised taxonomy (see the create call). Both are lists and both match ANY of the values you send, so "source_authority": ["official", "verified"] is "trustworthy material only". **A document that declares neither is not returned by either filter**, absence is not a wildcard, and "nobody labelled this" must not be answerable as "this is official". An authority outside the four is a 400, not an empty result set. One thing to know about timing: the labels are stamped onto a document's passages when you PUBLISH it. Re-labelling an already-published document does not take it out of search, and it does not change what these filters match until you publish again. **This call is rate limited**, it embeds your query, which is a per-request cost, and the allowance comes from your plan. A refusal is 429 with retry-after; the current allowance is on every response as x-ratelimit-limit. A search that matches nothing is a normal 200 with outcome: "zero" and no results. Those queries are what the zero-result list in GET /me/search-stats is built from, they are the questions your customers asked that your content does not answer yet.

Σώμα αιτήματος

application/json Σχήμα: KbSearchRequest

Πεδίο Τύπος Απαιτείται Περιγραφή
filters KbSearchFilters
limit integer How many passages to return.
query string Ναι What to search for. Natural-language questions work, the query is matched both by meaning and by word.
snippet_runes integer How long each snippet may be, in characters.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
400 query is empty, filters.source_authority names something outside official / verified / community / unverified (bad_request), or a filter list is longer than we accept.
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
413 The query is longer than we accept (query_too_large).
429 Too many searches for your plan's per-minute allowance (search_rate_limit). Wait retry-after seconds; the allowance itself is on every response as x-ratelimit-limit.
4XX Request error (validation, not-found, etc.).
501 This deployment has no search index configured (vector_store_unavailable).
502 The text could not be turned into vectors by the embedding provider (embed_failed). The search index could not be reached (vector_store_error). The request made no change; retry the call.
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X POST "https://api.voiceland.ai/v1/kb/search" \
  -H "Authorization: Bearer VL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "filters": {
    "audience": [
      "customers"
    ],
    "collections": [
      "col_9f2a1c7d"
    ],
    "lang": "el",
    "source_authority": [
      "official",
      "verified"
    ]
  },
  "limit": 5,
  "query": "πόσο κοστίζει το λεπτό ομιλίας;"
}'

Η επιτυχής απόκριση επιστρέφει ένα KbSearchResponse.

Παράδειγμα απόκρισης

{
  "count": 1,
  "outcome": "hit",
  "query": "πόσο κοστίζει το λεπτό ομιλίας;",
  "results": [
    {
      "chunk_id": "doc_4b1e77a0#0",
      "collection_id": "col_9f2a1c7d",
      "document_id": "doc_4b1e77a0",
      "highlights": [
        {
          "end": 51,
          "start": 41
        },
        {
          "end": 66,
          "start": 52
        }
      ],
      "lang": "el",
      "rank": 1,
      "score": 0.0328,
      "section": "Τιμολόγηση",
      "snippet": "…Η χρέωση γίνεται ανά λεπτό ομιλίας…",
      "title": "Τιμολόγηση 2026"
    }
  ],
  "took_ms": 41
}

POST /v1/kb/search/selection#

Record that a result was opened. Counts a search result the person actually opened. It is what turns the search report's selection rate into a real number, without it, "how often does a search lead anywhere" cannot be answered. Send the query exactly as it was searched; we key the count by the query, not by the document.

Σώμα αιτήματος

application/json Σχήμα: KbSelectionRequest

Πεδίο Τύπος Απαιτείται Περιγραφή
document_id string The result that was opened. Recorded for context; the selection rate is per query.
query string Ναι The query exactly as it was searched. The count is keyed by the query, not by the document.

Αποκρίσεις

Κωδικός Περιγραφή
204 Counted.
400 query is empty (bad_request).
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
429 Too many calls for your plan's per-minute allowance (search_rate_limit). Wait retry-after seconds; the allowance itself is on every response as x-ratelimit-limit.
4XX Request error (validation, not-found, etc.).
501 This deployment has no search index configured (vector_store_unavailable).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl -X POST "https://api.voiceland.ai/v1/kb/search/selection" \
  -H "Authorization: Bearer VL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "document_id": "doc_4b1e77a0",
  "query": "πόσο κοστίζει το λεπτό ομιλίας;"
}'

GET /v1/kb/suggest#

Autocomplete and did-you-mean. Completions for what someone is typing, drawn from your own documents' titles and headings, your tags and categories, and the searches that actually found something. When nothing completes the prefix, did_you_mean offers the nearest known word, accent-insensitive, in Greek and English. It answers from memory and never searches, so it is safe to call as the user types. The first call after a deployment can legitimately have nothing to say: ready: false means the word list for your account is still being built, and it is not an error.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
q query string What the user has typed so far.
lang query string The language they are typing in.
limit query integer How many suggestions to return.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
400 limit is not a positive whole number (bad_request).
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
413 q is longer than we accept (query_too_large).
429 Too many calls for your plan's per-minute allowance (search_rate_limit). Wait retry-after seconds; the allowance itself is on every response as x-ratelimit-limit.
4XX Request error (validation, not-found, etc.).
501 This deployment has no search index configured (vector_store_unavailable), or suggestions are switched off (suggest_unavailable).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl "https://api.voiceland.ai/v1/kb/suggest" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KbSuggestResponse.

Παράδειγμα απόκρισης

{
  "ready": true,
  "suggestions": [
    {
      "kind": "title",
      "score": 3,
      "text": "τιμοκατάλογος 2026"
    }
  ]
}

GET /v1/me/search-stats#

Search report. What people searched for, whether they found anything, and whether they opened it, per day, plus the top queries and the **zero-result list**. The zero-result list is the content-gap report: every question your customers asked that your published content could not answer. It is the shortest route from "the agent said it doesn't know" to knowing what to write next. Defaults to the last 30 days. truncated is true when the window held more distinct queries than one request reads, narrow the window rather than raising the limit.

Παράμετροι

Όνομα Θέση Τύπος Απαιτείται Περιγραφή
from query string Start of the window (2026-01-31, or RFC3339). Defaults to 30 days ago.
to query string End of the window. Defaults to now.
limit query integer How many queries to return in each list.

Αποκρίσεις

Κωδικός Περιγραφή
200 Success.
400 from/to could not be parsed as a date or an RFC3339 instant, from is after to, or limit is not a positive whole number (bad_request); or the window is longer than we report on (window_too_large).
401 Missing or invalid API key.
402 Your plan does not include the knowledge base (feature_not_entitled).
4XX Request error (validation, not-found, etc.).
5XX Server or upstream error.

Παράδειγμα αιτήματος

curl "https://api.voiceland.ai/v1/me/search-stats" \
  -H "Authorization: Bearer VL_API_KEY"

Η επιτυχής απόκριση επιστρέφει ένα KbSearchStatsResponse.

Παράδειγμα απόκρισης

{
  "from": "2026-07-01",
  "to": "2026-07-31",
  "totals": {
    "hits": 1102,
    "queries": 1284,
    "selection_rate": 0.498,
    "selections": 640,
    "zero": 182,
    "zero_rate": 0.142
  },
  "zero_results": [
    {
      "count": 37,
      "outcome": "zero",
      "query": "επιστροφη χρηματων"
    }
  ]
}

Σχήματα#

Error#

Error envelope returned for non-2xx responses.

Πεδίο Τύπος Απαιτείται Περιγραφή
error object Ναι

KbChunkPreview#

Πεδίο Τύπος Απαιτείται Περιγραφή
chunk_id string Ναι
index integer Ναι
section string
text string Ναι

KbChunksResponse#

Πεδίο Τύπος Απαιτείται Περιγραφή
count integer Ναι Passages the CURRENT text would produce.
document_id string Ναι
indexed_count integer Ναι Passages the search index actually holds. The two disagree exactly when the text was edited after the last publish.
items array of KbChunkPreview Ναι
status string Ναι
version string

KbCollectionPatchRequest#

Πεδίο Τύπος Απαιτείται Περιγραφή
default_lang string
description string
name string

KbCollectionRequest#

Πεδίο Τύπος Απαιτείται Περιγραφή
default_lang string
description string
id string
name string Ναι

KbCrawlScope#

Πεδίο Τύπος Απαιτείται Περιγραφή
allow array of string
deny array of string
max_pages integer
recrawl_interval string
respect_robots boolean

KbDiscoveryResult#

Πεδίο Τύπος Απαιτείται Περιγραφή
checked array of string
sitemap string
strategy string Ναι
via string

KbDocumentPatchRequest#

Πεδίο Τύπος Απαιτείται Περιγραφή
audience array of string
body string
categories array of string
effective_from string
effective_until string
lang string
metadata map of string
recrawl_interval string
source_authority string
tags array of string
title string

KbDocumentRequest#

Πεδίο Τύπος Απαιτείται Περιγραφή
audience array of string
body string
categories array of string
effective_from string
effective_until string
id string
lang string
metadata map of string
scope KbCrawlScope
sitemap string
source_authority string
tags array of string
title string Ναι
url string
website string

KbDocumentsResponse#

Πεδίο Τύπος Απαιτείται Περιγραφή
items array of KnowledgeDocument Ναι
next_cursor string Ναι

KbImportInlineRequest#

Πεδίο Τύπος Απαιτείται Περιγραφή
agent string Ναι The agent whose inline knowledge is read. The agent is NOT modified.
attach boolean Also add the collection to the agent's knowledge sources. Default false: attaching changes what a LIVE agent retrieves from.
audience array of string
categories array of string
collection_id string Ναι
document_id string Overrides the id derived from the agent name, how you deliberately import one agent's knowledge into more than one document.
knowledge string Text to import instead of reading the agent's prompt. For a console that has the text before it has ever been saved, and for agents whose prompt was not composed here.
lang string
source_authority string
tags array of string
title string

KbImportInlineResponse#

Πεδίο Τύπος Απαιτείται Περιγραφή
agent string Ναι
attached boolean Ναι
changed boolean Ναι False when the text was identical to what the document already held, in which case nothing was written at all, so polling this endpoint cannot take a published document offline.
created boolean Ναι
document KnowledgeDocument One piece of knowledge. Only a published document inside its validity window is searchable.
source string Ναι Where the text came from: the agent's system prompt, or the request.

KbIngestResponse#

Πεδίο Τύπος Απαιτείται Περιγραφή
discovery KbDiscoveryResult
document KnowledgeDocument One piece of knowledge. Only a published document inside its validity window is searchable.
job KnowledgeJob

KbJobsResponse#

Πεδίο Τύπος Απαιτείται Περιγραφή
items array of KnowledgeJob Ναι
next_cursor string Ναι

KbObjectImportRequest#

Πεδίο Τύπος Απαιτείται Περιγραφή
audience array of string
categories array of string
collection_id string Ναι
id string
lang string
metadata map of string
prefix string
source_authority string
tags array of string
title string

KbObjectSourcePatchRequest#

Πεδίο Τύπος Απαιτείται Περιγραφή
access_key_id string
bucket string
endpoint string
name string
prefix string
region string
secret_access_key string

KbObjectSourceRequest#

Πεδίο Τύπος Απαιτείται Περιγραφή
access_key_id string Ναι
bucket string Ναι
endpoint string Ναι
id string
name string
prefix string
region string
secret_access_key string Ναι

KbObjectSourceView#

Πεδίο Τύπος Απαιτείται Περιγραφή
access_key_id string Ναι
bucket string Ναι
created_at string
endpoint string Ναι
has_secret boolean Ναι
id string Ναι
name string
prefix string
region string
updated_at string
updated_by string

KbObjectSourcesResponse#

Πεδίο Τύπος Απαιτείται Περιγραφή
items array of KbObjectSourceView Ναι

KbReviewAnalyticsResponse#

Πεδίο Τύπος Απαιτείται Περιγραφή
confirmed_wrong integer Ναι
definition string Ναι
documents integer Ναι
items array of KnowledgeDocumentFaultRow Ναι
knowledge_fault_rate number Ναι
linked_to_document integer Ναι
scanned integer Ναι
truncated boolean Ναι

KbReviewDismissRequest#

Πεδίο Τύπος Απαιτείται Περιγραφή
dismissed_by string
reason string Ναι

KbReviewFlagsResponse#

Πεδίο Τύπος Απαιτείται Περιγραφή
items array of KnowledgeReviewFlag Ναι
next_cursor string Ναι
truncated boolean Ναι

KbSearchFilters#

Πεδίο Τύπος Απαιτείται Περιγραφή
audience array of string
categories array of string
collections array of string Narrow to these collections. Empty searches everything published on your account.
lang string The language of the person searching. NOT a hard filter: a document with no version in that language still answers, in the language it has. Omitting it means no preference.
source_authority array of string
tags array of string

KbSearchHighlight#

Πεδίο Τύπος Απαιτείται Περιγραφή
end integer Ναι
start integer Ναι

KbSearchRequest#

Search your published knowledge.

Πεδίο Τύπος Απαιτείται Περιγραφή
filters KbSearchFilters
limit integer How many passages to return.
query string Ναι What to search for. Natural-language questions work, the query is matched both by meaning and by word.
snippet_runes integer How long each snippet may be, in characters.

KbSearchResponse#

Πεδίο Τύπος Απαιτείται Περιγραφή
count integer Ναι
outcome string Ναι hit when something matched, zero when nothing did. A zero is a normal 200, those queries are what the zero-result report is built from.
query string Ναι
results array of KbSearchResult Ναι
took_ms integer Ναι Server-side time for the search, in milliseconds.

KbSearchResult#

Πεδίο Τύπος Απαιτείται Περιγραφή
chunk_id string Ναι
collection_id string Ναι
document_id string Ναι
highlights array of KbSearchHighlight Byte ranges into snippet (not into text) where the query matched.
lang string
rank integer Ναι
score number Ναι Fused relevance. Comparable WITHIN one response and not across responses, do not build a threshold on it.
section string
snippet string Ναι The passage trimmed around the match, for display.
text string The whole passage, as the model would see it.
title string
url string
version string The document revision this passage was indexed from.

KbSearchStatsDay#

Πεδίο Τύπος Απαιτείται Περιγραφή
day string Ναι
hits integer Ναι
queries integer Ναι
results integer Ναι
selection_rate number Ναι Selections divided by queries, for that day. Zero when nothing reports selections.
selections integer Ναι
zero integer Ναι
zero_rate number Ναι

KbSearchStatsQuery#

Πεδίο Τύπος Απαιτείται Περιγραφή
count integer Ναι
last_seen_at string (date-time)
outcome string Ναι
query string Ναι
selections integer Ναι

KbSearchStatsResponse#

Πεδίο Τύπος Απαιτείται Περιγραφή
days array of KbSearchStatsDay Ναι
from string Ναι
to string Ναι
top_queries array of KbSearchStatsQuery Ναι
totals KbSearchStatsDay Ναι The whole window summed.
truncated boolean Ναι True when the window held more distinct queries than one request reads. Narrow the window rather than raising the limit.
zero_results array of KbSearchStatsQuery Ναι The content-gap report: questions your customers asked that your published content could not answer.

KbSelectionRequest#

Πεδίο Τύπος Απαιτείται Περιγραφή
document_id string The result that was opened. Recorded for context; the selection rate is per query.
query string Ναι The query exactly as it was searched. The count is keyed by the query, not by the document.

KbSuggestResponse#

Πεδίο Τύπος Απαιτείται Περιγραφή
built_at string (date-time)
did_you_mean string The nearest known word when nothing completed the prefix.
partial boolean True when the word list was built from a bounded scan rather than your whole corpus.
ready boolean Ναι False while the word list for your account is still being built. Not an error, call again shortly.
stale boolean True when the word list is past its refresh age and a rebuild is under way.
suggestions array of Suggestion Ναι

KbVariantPatchRequest#

Πεδίο Τύπος Απαιτείται Περιγραφή
body string
title string

KbVariantRequest#

Πεδίο Τύπος Απαιτείται Περιγραφή
body string Ναι
lang string Ναι Language tag for this version. It may not repeat the document's primary language.
title string

KbVariantResponse#

Πεδίο Τύπος Απαιτείται Περιγραφή
body string
chunk_count integer Ναι
lang string Ναι
primary boolean Ναι True for the document's own language, which lives on the document rather than in the variant map.
title string

KbVariantsResponse#

Πεδίο Τύπος Απαιτείται Περιγραφή
document_id string Ναι
items array of KbVariantResponse Ναι
primary_lang string

KnowledgeCollection#

A shared container of documents. Agents attach collections by id; many agents may hold the same one, and attaching never writes to it.

Πεδίο Τύπος Απαιτείται Περιγραφή
created_at string (date-time)
default_lang string Language assumed for documents in this collection that do not state one.
description string
doc_count integer Ναι Documents in the collection, all lifecycle states included.
id string Ναι
name string Ναι
tenant_slug string Ναι
updated_at string (date-time)
vector_count integer Ναι Passages currently in the search index for this collection. It trails a publish or an archive by the length of that operation and is recounted on success, so a value that disagrees with the documents' chunk counts means the last write did not finish.

KnowledgeDocument#

One piece of knowledge. Only a published document inside its validity window is searchable.

Πεδίο Τύπος Απαιτείται Περιγραφή
audience array of string
body string The text, for a document typed in directly. Empty for uploaded and crawled documents, their content of record is the stored file or the crawled pages, not this field.
categories array of string
chunk_count integer Ναι Passages the last successful index wrote for the PRIMARY language. A multilingual document's total is the sum of this and each variant's own count.
collection_id string Ναι
created_at string (date-time)
effective_from string (date-time) The document is not searchable before this instant, even while published. Absent means no lower bound.
effective_until string (date-time) The document stops being searchable at this instant, even while published, a price list that expires, a policy that lapses. Absent means no upper bound. Nothing writes when the moment arrives; every search checks the window, so an expired document simply stops appearing.
id string Ναι
lang string
metadata map of string Your own key/value map. Keys the platform manages, anything starting crawl_ or vl_, plus filename and content_type, cannot be written and survive a replacement that omits them.
recrawl_interval integer How often the source is re-fetched, in NANOSECONDS. You set it as a duration string ("24h") and read it back as a number, 86400000000000 is one day. Zero means no schedule. Only a published document with an address is ever re-fetched, the re-fetch is conditional, and a source that has not changed costs nothing.
recrawl_state KnowledgeRecrawlState
review_flag KnowledgeReviewFlag
source KnowledgeSource Ναι Where the content came from: typed in (inline), uploaded (upload) or fetched (url). Kept as provenance for citations after a redaction, even though nothing re-fetches it then.
source_authority string
stats KnowledgeUsageStats Retrieval counters for this document. Read-only, and present only where it was asked for: single-document reads and the document listing hydrate it, everything else leaves it out. Absent therefore means "not requested", never "never retrieved".
status string Ναι draft, in_review, published or archived. Publishing indexes the text; archiving removes it from search while keeping it.
tags array of string
tenant_slug string Ναι
title string Ναι
updated_at string (date-time)
updated_by string
variants map of KnowledgeDocumentVariant Other languages of the same document, keyed by language tag. A variant carries content only, status, version, tags, categories and the validity window stay here on the document, so there is one thing to review and publish rather than one per language.
version string Semantic version, bumped on each publish so an answer can name the exact revision it used.

KnowledgeDocumentFaultRow#

Πεδίο Τύπος Απαιτείται Περιγραφή
agents array of string
categories array of string
confirmed_wrong integer Ναι
document_id string Ναι
first_reported_at string (date-time)
last_reported_at string (date-time)
share number Ναι

KnowledgeDocumentVariant#

One language of a document: title and text only.

Πεδίο Τύπος Απαιτείται Περιγραφή
body string
chunk_count integer Ναι Passages the last index wrote for THIS language.
lang string Ναι
source KnowledgeSource Where the content came from: typed in (inline), uploaded (upload) or fetched (url). Kept as provenance for citations after a redaction, even though nothing re-fetches it then.
title string

KnowledgeJob#

Πεδίο Τύπος Απαιτείται Περιγραφή
attempts integer Ναι How many times this job has been picked up. A retryable failure schedules another attempt; the ladder is what bounds total work, not the page cap.
collection_id string Ναι
created_at string (date-time)
document_id string
error string
finished_at string (date-time)
id string Ναι
kind string Ναι
lang string
lease_until string (date-time)
next_attempt_at string (date-time)
progress KnowledgeJobProgress Ναι Live counters, pages found, pages done, pages skipped, passages written. They only move forward within one attempt and reset when an attempt restarts.
requested_by string
source KnowledgeSource Ναι Where the content came from: typed in (inline), uploaded (upload) or fetched (url). Kept as provenance for citations after a redaction, even though nothing re-fetches it then.
started_at string (date-time)
status string Ναι
tenant_slug string Ναι

KnowledgeJobProgress#

Πεδίο Τύπος Απαιτείται Περιγραφή
chunks_written integer Ναι
pages_done integer Ναι
pages_found integer Ναι
pages_skipped integer Ναι

KnowledgeRecrawlState#

Πεδίο Τύπος Απαιτείται Περιγραφή
last_crawled_at string (date-time)
next_due_at string (date-time)

KnowledgeReviewFlag#

Πεδίο Τύπος Απαιτείται Περιγραφή
agent_name string
collection_id string Ναι
created_at string (date-time)
document_id string Ναι
first_flagged_at string (date-time)
last_flagged_at string (date-time)
reason string Ναι
reopened_at string (date-time)
report_count integer Ναι
report_ids array of string
resolution_note string
resolved_at string (date-time)
resolved_by string
state string Ναι
tenant_slug string Ναι
updated_at string (date-time)

KnowledgeSource#

Where the content came from: typed in (inline), uploaded (upload) or fetched (url). Kept as provenance for citations after a redaction, even though nothing re-fetches it then.

Πεδίο Τύπος Απαιτείται Περιγραφή
kind string Ναι
object_prefix string
object_source_id string
s3_key string
url string

KnowledgeUsageStats#

Πεδίο Τύπος Απαιτείται Περιγραφή
cited_count integer Ναι How many answers actually cited it. Retrieved but never cited, over a long window, is a document search keeps finding and the model keeps not using.
cited_wrong_count integer Ναι Reserved for explicit negative feedback. Nothing writes it yet, so it is always zero.
collection_id string Ναι
document_id string
last_cited_at string (date-time)
last_retrieved_at string (date-time)
retrieved_count integer Ναι How many searches and agent turns this document's passages were returned for.
tenant_slug string Ναι
updated_at string (date-time)

Suggestion#

Πεδίο Τύπος Απαιτείται Περιγραφή
kind string Ναι
score number Ναι
text string Ναι

Η κονσόλα

Οι σελίδες αυτές είναι μόνο για ανάγνωση. Η δοκιμαστική κλήση, τα κλειδιά API και η ζωντανή αναφορά API βρίσκονται στην κονσόλα, όπου ο λογαριασμός σας είναι συνδεδεμένος.

Άνοιγμα κονσόλας