Knowledge
Operations tagged Knowledge in the public API.
About Knowledge
A knowledge dataset is one source a chatbot answers from: text you send, an uploaded file, a web page, a cloud document or a page a crawler collected. The platform extracts its text, cuts it into chunks and embeds them; the chatbot then retrieves those chunks to answer.
Lifecycle. POST /knowledge creates a dataset and emits knowledge.dataset.created; with a chatbot_id (and auto_train, on by default) it is queued for training as soon as its content is in — at once for text and files, after the fetch for a web page. Training runs in the background: embedding_status moves not_started → pending → processing → completed or failed, and the moment it reaches completed or failed the platform emits knowledge.dataset.trained or knowledge.dataset.failed, whatever started it — a create, a retry, an edit, a file replacement, a re-fetch or a crawl. Subscribe to those two events rather than polling GET /knowledge/{id}/status. DELETE /knowledge/{id} emits knowledge.dataset.deleted and removes the dataset in the background: until that finishes it stays readable with is_deleting: true, and every change to it is 409 DATASET_DELETING.
Limits. Text sent inline is at most 1,000,000 characters and a file at most 10 MB (both by default). The plan caps how much knowledge a chatbot holds, counted in extracted characters: a create whose text would pass the cap is 402 KNOWLEDGE_PLAN_SIZE_EXCEEDED, and content that only turns out too large once fetched fails training. GET /knowledge/usage shows where the account stands.
Duplicates. A dataset name is unique among the account's active datasets (409 KNOWLEDGE_NAME_TAKEN). Training skips a passage another trained dataset of the same collection already holds, so a dataset that only repeats others completes with total_chunks: 0. To refresh a source, update it — PATCH /knowledge/{id} for text, replace_file for a file, recrawl for a web page — rather than adding a second dataset.
IDs you will meet.
id— the dataset id, an integer, in every/knowledge/{id}path; elsewheredataset_id,knowledge_idsor a file'sknowledge_dataset_id.chatbot_id— the chatbot the dataset trains.GET /chatbots/{id}/knowledge,GET /chatbots/{id}/knowledge/status,POST /knowledge/{id}/retry_failedandPOST /knowledge/{id}/train_collectedtake a chatbot id as{id}.collection_id— the knowledge collection the dataset is filed in.
IDs on this page
- Knowledge collection id
<COLLECTION_ID> - Integer.
Get it from
- POST /v1/knowledge/collections returns it as
id - GET /v1/knowledge/collections returns it as
data[].id - POST /v1/knowledge/collections/auto_create returns it as
id - GET /v1/knowledge/{id} returns it as
collection_id - Webhook knowledge.collection.created carries it as
data.object.id - Adding knowledge or a crawl with only
chatbot_idfiles it in the chatbot's default collection, created on first use: read its id ascollection_idon any of the chatbot's datasets.
- POST /v1/knowledge/collections returns it as
- Chatbot id
<CHATBOT_ID> - Integer.
Get it from
- GET /v1/chatbots returns it as
data[].id - POST /v1/chatbots returns it as
id - GET /v1/chatbots/by_handle/{handle} returns it as
id - Webhook chatbot.created carries it as
data.object.id - In the dashboard, it is the number in a chatbot's address:
/dashboard/chatbots/{id}.
- GET /v1/chatbots returns it as
- File id
<FILE_ID> - Integer: the file's
id. The UUID in itsfile_idfield is not accepted here.Get it from
- POST /v1/files returns it as
id - POST /v1/files returns it as
data[].id - GET /v1/files returns it as
data[].id - Webhook file.created carries it as
data.object.id
- POST /v1/files returns it as
- Knowledge dataset id
<DATASET_ID> - Integer.
Get it from
- POST /v1/knowledge returns it as
id - GET /v1/knowledge returns it as
data[].id - GET /v1/chatbots/{id}/knowledge returns it as
data[].id - GET /v1/knowledge/collections/{id}/datasets returns it as
data[].id - POST /v1/knowledge/import/cloud returns it as
data[].id - GET /v1/files/{id} returns it as
knowledge_dataset_id - POST /v1/search returns it as
data[].dataset_id - Webhook knowledge.dataset.created carries it as
data.object.id - A crawler creates one dataset per page it collects; list them with
GET /chatbots/{id}/knowledge.
- POST /v1/knowledge returns it as
- Knowledge dataset ids
<DATASET_IDS> - Array of 1–100 integer dataset ids. A repeated id counts once.
Get it from
- POST /v1/knowledge returns it as
id - GET /v1/knowledge returns it as
data[].id - GET /v1/chatbots/{id}/knowledge returns it as
data[].id - GET /v1/knowledge/collections/{id}/datasets returns it as
data[].id - POST /v1/knowledge/import/cloud returns it as
data[].id - GET /v1/files/{id} returns it as
knowledge_dataset_id - POST /v1/search returns it as
data[].dataset_id - Webhook knowledge.dataset.created carries it as
data.object.id - A crawler creates one dataset per page it collects; list them with
GET /chatbots/{id}/knowledge.
- POST /v1/knowledge returns it as
List knowledge collections
chatbot_id) and the account-level ones bound to no chatbot. List one collection's datasets with GET /knowledge/collections/{id}/datasets.- Required scope
- knowledge:read
- Idempotency
- Read-only
- Rate limits
Query parameters
limitintegerOptionalPage size, clamped to 1–100.Default:
20Minimum:1Maximum:100starting_afterstringOptionalCursor from a previous page'snext_cursor: returns the page after it. A cursor minted for another list,sortororderis 422INVALID_CURSOR.ending_beforestringOptionalCursor from a previous page'sprevious_cursor: returns the page before it. Wins when both cursors are sent.created[gte]stringOptionalOnly rows created on or after this instant:YYYY-MM-DD(whole UTC day) or an RFC 3339 timestamp with a zone. Anything else is 422INVALID_PARAMETER.created[lte]stringOptionalOnly rows created on or before this instant:YYYY-MM-DD(whole UTC day) or an RFC 3339 timestamp with a zone. Anything else is 422INVALID_PARAMETER.
Responses
- 200Success.
objectstringRequiredAlways
listdataarray of KnowledgeCollectionResourceRequiredhas_morebooleanRequirednext_cursorstringnullableRequiredprevious_cursorstringnullableRequiredurlstringRequiredAlways
/v1/knowledge/collections
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither.Error codesACCOUNT_SELECTOR_NOT_SUPPORTED
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 422Validation failed. See
error.details.Error codesINVALID_CURSORINVALID_PARAMETER
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X GET 'https://api.agentency.com/v1/knowledge/collections' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "list",
"data": [
{
"object": "knowledge_collection",
"id": 1,
"name": "Help centre",
"description": "Articles from the public help centre.",
"chatbot_id": 1,
"created_at": "2026-01-01T00:00:00+00:00",
"updated_at": "2026-01-01T00:00:00+00:00"
}
],
"has_more": false,
"next_cursor": null,
"previous_cursor": null,
"url": "/v1/knowledge/collections"
}Retrieve a knowledge collection
chatbot_id, null for an account-level collection). A collection of another account, or of a chatbot the key cannot reach, is 404 NOT_FOUND.- Required scope
- knowledge:read
- Idempotency
- Read-only
- Rate limits
Integer.id(path)Knowledge collection idPlaceholder in the samples:
<COLLECTION_ID>Get it from
- POST /v1/knowledge/collections returns it as
id - GET /v1/knowledge/collections returns it as
data[].id - POST /v1/knowledge/collections/auto_create returns it as
id - GET /v1/knowledge/{id} returns it as
collection_id - Webhook knowledge.collection.created carries it as
data.object.id - Adding knowledge or a crawl with only
chatbot_idfiles it in the chatbot's default collection, created on first use: read its id ascollection_idon any of the chatbot's datasets.
- POST /v1/knowledge/collections returns it as
Path parameters
idintegerRequiredThe knowledge collection id.
Responses
- 200
KnowledgeCollectionResourceobjectstringRequiredAlways
knowledge_collectionidintegerRequiredThe collection id.namestringRequiredDisplay name, unique among the chatbot's collections (among the account's unbound ones whenchatbot_idisnull).descriptionstringnullableRequiredYour longer description;nullwhen none.chatbot_idintegernullableRequiredThe chatbot the collection belongs to; datasets filed in it are that chatbot's knowledge.nullfor an account-level collection bound to no chatbot.created_atstringnullableRequiredWhen the collection was created (ISO 8601, UTC).updated_atstringnullableRequiredWhen the collection last changed (ISO 8601, UTC).
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither.Error codesACCOUNT_SELECTOR_NOT_SUPPORTED
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesNOT_FOUND
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X GET 'https://api.agentency.com/v1/knowledge/collections/<COLLECTION_ID>' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "knowledge_collection",
"id": 1,
"name": "Help centre",
"description": "Articles from the public help centre.",
"chatbot_id": 1,
"created_at": "2026-01-01T00:00:00+00:00",
"updated_at": "2026-01-01T00:00:00+00:00"
}Retrieve the account's knowledge usage
per_agent_limit is what each chatbot may hold on its own, (null on a plan without a cap), and the account-wide pool (pool_limit, from the extra_packs bought) covers what chatbots hold beyond it, pool_used of it already taken. A create that would pass a chatbot's allowance is 402 KNOWLEDGE_PLAN_SIZE_EXCEEDED.- Required scope
- knowledge:read
- Idempotency
- Read-only
- Rate limits
Responses
- 200Success.
objectstringRequiredAlways
knowledge_usageidintegerRequiredThe account owner's user id.per_agent_limitintegernullableRequiredKnowledge characters each chatbot may hold on its own plan allowance;nullwhen the plan sets no cap.pool_limitintegerRequiredKnowledge characters of the account-wide shared pool, which covers what chatbots hold beyondper_agent_limit.pool_usedintegerRequiredCharacters of the account-wide shared knowledge pool in use (1 character = 1 byte), capped atpool_limit.extra_packsintegerRequiredExtra knowledge packs bought; each adds topool_limit.
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither.Error codesACCOUNT_SELECTOR_NOT_SUPPORTED
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X GET 'https://api.agentency.com/v1/knowledge/usage' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "knowledge_usage",
"id": 1,
"per_agent_limit": 409600,
"pool_limit": 0,
"pool_used": 0,
"extra_packs": 0
}Retrieve knowledge totals
GET /knowledge/usage. Datasets being removed are not counted.- Required scope
- knowledge:read
- Idempotency
- Read-only
- Rate limits
Responses
- 200Success.
objectstringRequiredAlways
knowledge_statsidintegerRequiredThe account owner's user id.datasetsintegerRequiredActive datasets the API key reaches.Minimum:
0collectionsintegerRequiredKnowledge collections the API key reaches.Minimum:
0per_agent_limitintegernullableRequiredKnowledge characters each chatbot may hold on its own plan allowance;nullwhen the plan sets no cap.pool_limitintegerRequiredKnowledge characters of the account-wide shared pool, which covers what chatbots hold beyondper_agent_limit.pool_usedintegerRequiredCharacters of the account-wide shared knowledge pool in use (1 character = 1 byte), capped atpool_limit.extra_packsintegerRequiredExtra knowledge packs bought; each adds topool_limit.
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither.Error codesACCOUNT_SELECTOR_NOT_SUPPORTED
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X GET 'https://api.agentency.com/v1/knowledge/stats' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "knowledge_stats",
"id": 1,
"datasets": 1,
"collections": 1,
"per_agent_limit": 409600,
"pool_limit": 0,
"pool_used": 0,
"extra_packs": 0
}List knowledge datasets
chatbot_id narrows the list to one chatbot's. A dataset whose removal is still running in the background is listed with is_deleting: true until it is gone. A chatbot_id the key cannot reach is 404 NOT_FOUND; a malformed one is 422 VALIDATION_FAILED.
Each item reports its own training state in embedding_status; for one chatbot's totals use GET /chatbots/{id}/knowledge/status.- Required scope
- knowledge:read
- Idempotency
- Read-only
- Rate limits
Integer.chatbot_id(query)Chatbot idPlaceholder in the samples:
<CHATBOT_ID>Get it from
- GET /v1/chatbots returns it as
data[].id - POST /v1/chatbots returns it as
id - GET /v1/chatbots/by_handle/{handle} returns it as
id - Webhook chatbot.created carries it as
data.object.id - In the dashboard, it is the number in a chatbot's address:
/dashboard/chatbots/{id}.
- GET /v1/chatbots returns it as
Query parameters
chatbot_idintegernullableOptionalOnly the datasets of this chatbot. Omit it to list every dataset the API key reaches. A chatbot the key cannot reach is 404NOT_FOUND.Minimum:
1limitintegerOptionalPage size, clamped to 1–100.Default:
20Minimum:1Maximum:100starting_afterstringOptionalCursor from a previous page'snext_cursor: returns the page after it. A cursor minted for another list,sortororderis 422INVALID_CURSOR.ending_beforestringOptionalCursor from a previous page'sprevious_cursor: returns the page before it. Wins when both cursors are sent.created[gte]stringOptionalOnly rows created on or after this instant:YYYY-MM-DD(whole UTC day) or an RFC 3339 timestamp with a zone. Anything else is 422INVALID_PARAMETER.created[lte]stringOptionalOnly rows created on or before this instant:YYYY-MM-DD(whole UTC day) or an RFC 3339 timestamp with a zone. Anything else is 422INVALID_PARAMETER.
Responses
- 200Success.
objectstringRequiredAlways
listdataarray of KnowledgeDatasetResourceRequiredhas_morebooleanRequirednext_cursorstringnullableRequiredprevious_cursorstringnullableRequiredurlstringRequiredAlways
/v1/knowledge
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither.Error codesACCOUNT_SELECTOR_NOT_SUPPORTED
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesNOT_FOUND
- 422Validation failed. See
error.details. - 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X GET 'https://api.agentency.com/v1/knowledge' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "list",
"data": [
{
"object": "knowledge_dataset",
"id": 1,
"name": "Refund policy",
"description": "How and when refunds are issued.",
"type": "Text",
"source_type": "text",
"source_url": null,
"status": "processed",
"embedding_status": "completed",
"embedding_processed_at": "2026-01-01T00:00:00+00:00",
"total_chunks": 1,
"total_words": 13,
"collection_id": 1,
"chatbot_id": 1,
"is_deleting": false,
"created_at": "2026-01-01T00:00:00+00:00",
"updated_at": "2026-01-01T00:00:00+00:00"
}
],
"has_more": false,
"next_cursor": null,
"previous_cursor": null,
"url": "/v1/knowledge"
}Create a knowledge dataset
201, then trains it in the background. Send one of:
Source
Body
Text
name, type: Text, source_type: text, content
A web page
name, type: URL, source_type: url, source_url — fetched in the background; refresh it later with POST /knowledge/{id}/recrawl
An uploaded file
name, file_id from POST /files — its text is extracted now (scanned PDFs and images by OCR, in the background)
With chatbot_id the dataset is filed in knowledge_collection_id or the chatbot's default collection and, with auto_train (default true), trained: text and readable files are queued at once (embedding_status: pending in the response), a web page once it has been fetched. Without chatbot_id it is stored in its collection and not trained. Training finishes with knowledge.dataset.trained or knowledge.dataset.failed; GET /knowledge/{id}/status polls the same state.
A name another active dataset uses is 409 KNOWLEDGE_NAME_TAKEN. A create whose text would pass the chatbot's plan allowance is 402 KNOWLEDGE_PLAN_SIZE_EXCEEDED, with nothing created. A retry with the same Idempotency-Key returns the dataset the first request created.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- knowledge.dataset.created
- Rate limits
Integer.knowledge_collection_id(body)Knowledge collection idPlaceholder in the samples:
<COLLECTION_ID>Get it from
- POST /v1/knowledge/collections returns it as
id - GET /v1/knowledge/collections returns it as
data[].id - POST /v1/knowledge/collections/auto_create returns it as
id - GET /v1/knowledge/{id} returns it as
collection_id - Webhook knowledge.collection.created carries it as
data.object.id - Adding knowledge or a crawl with only
chatbot_idfiles it in the chatbot's default collection, created on first use: read its id ascollection_idon any of the chatbot's datasets.
- POST /v1/knowledge/collections returns it as
Integer.chatbot_id(body)Chatbot idPlaceholder in the samples:
<CHATBOT_ID>Get it from
- GET /v1/chatbots returns it as
data[].id - POST /v1/chatbots returns it as
id - GET /v1/chatbots/by_handle/{handle} returns it as
id - Webhook chatbot.created carries it as
data.object.id - In the dashboard, it is the number in a chatbot's address:
/dashboard/chatbots/{id}.
- GET /v1/chatbots returns it as
Integer: the file'sfile_id(body)File idid. The UUID in itsfile_idfield is not accepted here.Placeholder in the samples:
<FILE_ID>Get it from
- POST /v1/files returns it as
id - POST /v1/files returns it as
data[].id - GET /v1/files returns it as
data[].id - Webhook file.created carries it as
data.object.id
- POST /v1/files returns it as
Header parameters
Idempotency-KeystringOptionalMakes a retry safe. The first 2xx answer is stored for 24 h and replayed for the same key withIdempotency-Replayed: true; a retry while the first request runs is 409IDEMPOTENCY_IN_FLIGHT; the same key with a different payload is 422IDEMPOTENCY_KEY_REUSED; a malformed key is 400INVALID_IDEMPOTENCY_KEY.Min length:
16Max length:128Pattern:^[A-Za-z0-9_-]+$
Request body
namestringRequiredDisplay name, at most 255 characters, unique among the account's active datasets: a taken name is 409KNOWLEDGE_NAME_TAKEN.Max length:
255descriptionstringnullableOptionalOptional longer description, at most 1000 characters.Max length:
1000typestringRequiredContent format label:Textwithsource_type: text,URLwithsource_type: url. Not read withfile_id: the file's extension sets it.Possible values
TextPDFWordExcelURLVideoAudioImagesource_typestringRequiredHow the content arrives:text(incontent) orurl(fetched in the background fromsource_url).upload,integrationandapicreate a dataset with no content; to create one from an uploaded file sendfile_idinstead, which needs nosource_type.Possible values
textuploadurlintegrationapicontentstringOptionalThe text to train on. Required withsource_type: text; at most 1,000,000 characters by default.Max length:
1000000source_urlstringnullableOptionalThe publichttp(s)page to fetch. Required withsource_type: url. Checked before it is ever fetched: a private, loopback, link-local or otherwise blocked address is 422VALIDATION_FAILEDon this field.Format:
uriMax length:2048categorystringnullableOptionalFree-form category label, at most 100 characters.Max length:
100tagsarray of stringnullableOptionalList of tags, each at most 50 characters.is_publicbooleanOptionalVisibility flag stored with the dataset and mirrored into its search payload.knowledge_collection_idintegernullableOptionalThe collection to file the dataset in. Optional withchatbot_id, when the chatbot's default collection is used (created on first use); required without it. A collection of another chatbot is 422COLLECTION_NOT_OWNED_BY_CHATBOT; a chatbot's collection withoutchatbot_idis 422CHATBOT_REQUIRED.chatbot_idintegernullableOptionalThe chatbot the dataset trains. Without it the dataset is stored in its collection but never trained.auto_trainbooleannullableOptionalStart training as soon as the dataset is created (defaulttrue; needschatbot_id). Withfalseit staysnot_starteduntilPOST /knowledge/{id}/train_collected, called with the chatbot id, trains the chatbot's untrained datasets.idempotency_keystringnullableOptionalNot read on/v1: send theIdempotency-Keyheader instead.Max length:
255file_idintegerOptionalCreate the dataset from a file uploaded withPOST /files: its integerid, not its UUID. Withfile_idonlyname,description,chatbot_id,knowledge_collection_idandauto_trainare read —typefollows the file's extension andsource_typeisupload, so neither is required. A file whose text cannot be read is 422TEXT_EXTRACTION_FAILEDand creates nothing; a file already behind a dataset is 409FILE_ALREADY_ATTACHED(details.dataset_id).
Responses
- 201
KnowledgeDatasetResourceobjectstringRequiredAlways
knowledge_datasetidintegerRequiredThe dataset id.namestringRequiredDisplay name, unique among the account's active datasets.descriptionstringnullableRequiredYour longer description;nullwhen none.typestringRequiredContent format. An uploaded file's type follows its extension;URL_LINKSis the list of links a website crawler found.Possible values
PDFWordExcelTextURLURL_LINKSVideoAudioImagesource_typestringnullableRequiredWhere the content came from:text(sent inline),upload(a file),url(a web page, alone or collected by a website crawler),url_links,sitemap(a page a sitemap crawler collected),google_driveordropbox(cloud import),site_info(the site summary a crawler builds),apiorintegration.source_urlstringnullableRequiredThe page the content is fetched from, for URL-sourced datasets;nullotherwise.statusstringRequiredContent processing, separate from training:uploaded(stored),processing(text extraction, OCR or training running),processed,failed(no text could be extracted) orarchived.Possible values
uploadedprocessingprocessedfailedarchivedembedding_statusstringRequiredTraining:not_started(training not requested),pending(queued),processing(chunking and embedding),completed(the chatbot answers from it) orfailed. Reachingcompletedorfailedemitsknowledge.dataset.trainedorknowledge.dataset.failed.Possible values
not_startedpendingprocessingcompletedfailedembedding_processed_atstringnullableRequiredWhen training last completed (ISO 8601, UTC);nullbefore the first completed run.total_chunksintegerRequiredChunks stored for the dataset.0on acompleteddataset means every passage repeated knowledge its collection already holds.total_wordsintegerRequiredWords in the extracted text.collection_idintegernullableRequiredThe knowledge collection the dataset is filed in;nullwhen none.chatbot_idintegernullableRequiredThe chatbot the dataset trains;nullwhen it is attached to none.is_deletingbooleanRequiredtruewhile the dataset is being removed in the background. It stays readable until the removal finishes; every change to it is 409DATASET_DELETING.created_atstringnullableRequiredWhen the dataset was created (ISO 8601, UTC).updated_atstringnullableRequiredWhen the dataset last changed (ISO 8601, UTC).
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither. A mutation that honoursIdempotency-Keyalso returnsINVALID_IDEMPOTENCY_KEYwhen that header is not 16–128[A-Za-z0-9_-]characters.Error codesACCOUNT_SELECTOR_NOT_SUPPORTEDINVALID_IDEMPOTENCY_KEY
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 402A billing gate refused the request (plan limit, monthly AI budget or message credits). See
error.code.Error codesKNOWLEDGE_PLAN_SIZE_EXCEEDED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesNOT_FOUND
- 409The request conflicts with the current resource state.
Error codesIDEMPOTENCY_IN_FLIGHTKNOWLEDGE_NAME_TAKEN
- 422Validation failed. See
error.details.Error codesCHATBOT_REQUIREDCOLLECTION_NOT_OWNED_BY_CHATBOTIDEMPOTENCY_KEY_REUSEDVALIDATION_FAILED
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X POST 'https://api.agentency.com/v1/knowledge' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"
-d '{
"name": "name",
"description": "description",
"type": "type",
"source_type": "source_type",
"content": "content",
"source_url": "source_url",
"category": "category",
"tags": "tags"
}'Response
Example 201 response
{
"object": "knowledge_dataset",
"id": 1,
"name": "Shipping FAQ",
"description": null,
"type": "Text",
"source_type": "text",
"source_url": null,
"status": "uploaded",
"embedding_status": "pending",
"embedding_processed_at": null,
"total_chunks": 0,
"total_words": 0,
"collection_id": 1,
"chatbot_id": 1,
"is_deleting": false,
"created_at": "2026-01-01T00:00:00+00:00",
"updated_at": "2026-01-01T00:00:00+00:00"
}Retrieve a knowledge dataset
source_type, source_url), how processing and training went (status, embedding_status, total_chunks) and which chatbot and collection it belongs to. The text itself is not returned; read it chunk by chunk with GET /knowledge/{id}/chunks. A dataset being removed is still returned, with is_deleting: true.- Required scope
- knowledge:read
- Idempotency
- Read-only
- Rate limits
Integer.id(path)Knowledge dataset idPlaceholder in the samples:
<DATASET_ID>Get it from
- POST /v1/knowledge returns it as
id - GET /v1/knowledge returns it as
data[].id - GET /v1/chatbots/{id}/knowledge returns it as
data[].id - GET /v1/knowledge/collections/{id}/datasets returns it as
data[].id - POST /v1/knowledge/import/cloud returns it as
data[].id - GET /v1/files/{id} returns it as
knowledge_dataset_id - POST /v1/search returns it as
data[].dataset_id - Webhook knowledge.dataset.created carries it as
data.object.id - A crawler creates one dataset per page it collects; list them with
GET /chatbots/{id}/knowledge.
- POST /v1/knowledge returns it as
Path parameters
idintegerRequiredThe knowledge dataset id.
Responses
- 200
KnowledgeDatasetResourceobjectstringRequiredAlways
knowledge_datasetidintegerRequiredThe dataset id.namestringRequiredDisplay name, unique among the account's active datasets.descriptionstringnullableRequiredYour longer description;nullwhen none.typestringRequiredContent format. An uploaded file's type follows its extension;URL_LINKSis the list of links a website crawler found.Possible values
PDFWordExcelTextURLURL_LINKSVideoAudioImagesource_typestringnullableRequiredWhere the content came from:text(sent inline),upload(a file),url(a web page, alone or collected by a website crawler),url_links,sitemap(a page a sitemap crawler collected),google_driveordropbox(cloud import),site_info(the site summary a crawler builds),apiorintegration.source_urlstringnullableRequiredThe page the content is fetched from, for URL-sourced datasets;nullotherwise.statusstringRequiredContent processing, separate from training:uploaded(stored),processing(text extraction, OCR or training running),processed,failed(no text could be extracted) orarchived.Possible values
uploadedprocessingprocessedfailedarchivedembedding_statusstringRequiredTraining:not_started(training not requested),pending(queued),processing(chunking and embedding),completed(the chatbot answers from it) orfailed. Reachingcompletedorfailedemitsknowledge.dataset.trainedorknowledge.dataset.failed.Possible values
not_startedpendingprocessingcompletedfailedembedding_processed_atstringnullableRequiredWhen training last completed (ISO 8601, UTC);nullbefore the first completed run.total_chunksintegerRequiredChunks stored for the dataset.0on acompleteddataset means every passage repeated knowledge its collection already holds.total_wordsintegerRequiredWords in the extracted text.collection_idintegernullableRequiredThe knowledge collection the dataset is filed in;nullwhen none.chatbot_idintegernullableRequiredThe chatbot the dataset trains;nullwhen it is attached to none.is_deletingbooleanRequiredtruewhile the dataset is being removed in the background. It stays readable until the removal finishes; every change to it is 409DATASET_DELETING.created_atstringnullableRequiredWhen the dataset was created (ISO 8601, UTC).updated_atstringnullableRequiredWhen the dataset last changed (ISO 8601, UTC).
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither.Error codesACCOUNT_SELECTOR_NOT_SUPPORTED
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesNOT_FOUND
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X GET 'https://api.agentency.com/v1/knowledge/<DATASET_ID>' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "knowledge_dataset",
"id": 1,
"name": "Refund policy",
"description": "How and when refunds are issued.",
"type": "Text",
"source_type": "text",
"source_url": null,
"status": "processed",
"embedding_status": "completed",
"embedding_processed_at": "2026-01-01T00:00:00+00:00",
"total_chunks": 1,
"total_words": 13,
"collection_id": 1,
"chatbot_id": 1,
"is_deleting": false,
"created_at": "2026-01-01T00:00:00+00:00",
"updated_at": "2026-01-01T00:00:00+00:00"
}Update a knowledge dataset
name, description, category, tags and is_public are metadata and never retrain anything. Renaming to a name another active dataset already uses is 409 KNOWLEDGE_NAME_TAKEN.
content replaces the text of a text-sourced dataset (any other source is 422 VALIDATION_FAILED; replace a file with POST /knowledge/{id}/replace_file, refresh a page with POST /knowledge/{id}/recrawl). When the dataset is already trained, retrain (default true) re-embeds it for every chatbot that uses it — ending in knowledge.dataset.trained or knowledge.dataset.failed — and false saves the text but keeps answering from the old chunks until the next training. A dataset being removed is 409 DATASET_DELETING.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- None
- Rate limits
Integer.id(path)Knowledge dataset idPlaceholder in the samples:
<DATASET_ID>Get it from
- POST /v1/knowledge returns it as
id - GET /v1/knowledge returns it as
data[].id - GET /v1/chatbots/{id}/knowledge returns it as
data[].id - GET /v1/knowledge/collections/{id}/datasets returns it as
data[].id - POST /v1/knowledge/import/cloud returns it as
data[].id - GET /v1/files/{id} returns it as
knowledge_dataset_id - POST /v1/search returns it as
data[].dataset_id - Webhook knowledge.dataset.created carries it as
data.object.id - A crawler creates one dataset per page it collects; list them with
GET /chatbots/{id}/knowledge.
- POST /v1/knowledge returns it as
Path parameters
idintegerRequiredThe knowledge dataset id.
Header parameters
Idempotency-KeystringOptionalMakes a retry safe. The first 2xx answer is stored for 24 h and replayed for the same key withIdempotency-Replayed: true; a retry while the first request runs is 409IDEMPOTENCY_IN_FLIGHT; the same key with a different payload is 422IDEMPOTENCY_KEY_REUSED; a malformed key is 400INVALID_IDEMPOTENCY_KEY.Min length:
16Max length:128Pattern:^[A-Za-z0-9_-]+$
Request body
PATCH /v1/knowledge/{id}.
Send only the fields you want to change; at least one is required. content
and retrain apply to text-sourced datasets and control whether the edited
text is re-embedded immediately.namestringOptionalDisplay name. Max 255 characters; must stay unique among the account's active datasets.Max length:
255descriptionstringnullableOptionalOptional longer description. Max 1000 characters.Max length:
1000categorystringnullableOptionalFree-form category label. Max 100 characters.Max length:
100tagsarray of stringnullableOptionalList of tags: at most 50 tags of at most 50 characters each.Max items:
50is_publicbooleanOptionalVisibility flag mirrored into the vector payload.contentstringOptionalReplacement inline text. Only valid when source_type istext; any other source answers 422 VALIDATION_FAILED.Max length:
1000000retrainbooleanOptionalWhencontentchanges an already-trained dataset: re-embed now (default true) or save the text and keep the current vectors (false).
Responses
- 200
KnowledgeDatasetResourceobjectstringRequiredAlways
knowledge_datasetidintegerRequiredThe dataset id.namestringRequiredDisplay name, unique among the account's active datasets.descriptionstringnullableRequiredYour longer description;nullwhen none.typestringRequiredContent format. An uploaded file's type follows its extension;URL_LINKSis the list of links a website crawler found.Possible values
PDFWordExcelTextURLURL_LINKSVideoAudioImagesource_typestringnullableRequiredWhere the content came from:text(sent inline),upload(a file),url(a web page, alone or collected by a website crawler),url_links,sitemap(a page a sitemap crawler collected),google_driveordropbox(cloud import),site_info(the site summary a crawler builds),apiorintegration.source_urlstringnullableRequiredThe page the content is fetched from, for URL-sourced datasets;nullotherwise.statusstringRequiredContent processing, separate from training:uploaded(stored),processing(text extraction, OCR or training running),processed,failed(no text could be extracted) orarchived.Possible values
uploadedprocessingprocessedfailedarchivedembedding_statusstringRequiredTraining:not_started(training not requested),pending(queued),processing(chunking and embedding),completed(the chatbot answers from it) orfailed. Reachingcompletedorfailedemitsknowledge.dataset.trainedorknowledge.dataset.failed.Possible values
not_startedpendingprocessingcompletedfailedembedding_processed_atstringnullableRequiredWhen training last completed (ISO 8601, UTC);nullbefore the first completed run.total_chunksintegerRequiredChunks stored for the dataset.0on acompleteddataset means every passage repeated knowledge its collection already holds.total_wordsintegerRequiredWords in the extracted text.collection_idintegernullableRequiredThe knowledge collection the dataset is filed in;nullwhen none.chatbot_idintegernullableRequiredThe chatbot the dataset trains;nullwhen it is attached to none.is_deletingbooleanRequiredtruewhile the dataset is being removed in the background. It stays readable until the removal finishes; every change to it is 409DATASET_DELETING.created_atstringnullableRequiredWhen the dataset was created (ISO 8601, UTC).updated_atstringnullableRequiredWhen the dataset last changed (ISO 8601, UTC).
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither. A mutation that honoursIdempotency-Keyalso returnsINVALID_IDEMPOTENCY_KEYwhen that header is not 16–128[A-Za-z0-9_-]characters.Error codesACCOUNT_SELECTOR_NOT_SUPPORTEDINVALID_IDEMPOTENCY_KEY
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesNOT_FOUND
- 409The request conflicts with the current resource state.
Error codesDATASET_DELETINGIDEMPOTENCY_IN_FLIGHTINGESTION_IN_PROGRESSKNOWLEDGE_NAME_TAKEN
- 422Validation failed. See
error.details.Error codesIDEMPOTENCY_KEY_REUSEDVALIDATION_FAILED
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X PATCH 'https://api.agentency.com/v1/knowledge/<DATASET_ID>' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"
-d '{
"name": "name",
"description": "description",
"category": "category",
"tags": "tags",
"is_public": true,
"content": "content",
"retrain": true
}'Response
Example 200 response
{
"object": "knowledge_dataset",
"id": 1,
"name": "Delivery times",
"description": "Delivery times by region.",
"type": "Text",
"source_type": "text",
"source_url": null,
"status": "uploaded",
"embedding_status": "completed",
"embedding_processed_at": null,
"total_chunks": 0,
"total_words": 100,
"collection_id": null,
"chatbot_id": 1,
"is_deleting": false,
"created_at": "2026-01-01T00:00:00+00:00",
"updated_at": "2026-01-01T00:00:00+00:00"
}Delete a knowledge dataset
status: processing and knowledge.dataset.deleted is emitted; the removal itself runs in the background. Until it finishes the dataset stays readable with is_deleting: true, chatbots stop answering from it as its vectors are deleted, and every change to it — this call included — is 409 DATASET_DELETING.
To stop one chatbot answering from it but keep the dataset, use POST /knowledge/remove_from_chatbot.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- knowledge.dataset.deleted
- Rate limits
Integer.id(path)Knowledge dataset idPlaceholder in the samples:
<DATASET_ID>Get it from
- POST /v1/knowledge returns it as
id - GET /v1/knowledge returns it as
data[].id - GET /v1/chatbots/{id}/knowledge returns it as
data[].id - GET /v1/knowledge/collections/{id}/datasets returns it as
data[].id - POST /v1/knowledge/import/cloud returns it as
data[].id - GET /v1/files/{id} returns it as
knowledge_dataset_id - POST /v1/search returns it as
data[].dataset_id - Webhook knowledge.dataset.created carries it as
data.object.id - A crawler creates one dataset per page it collects; list them with
GET /chatbots/{id}/knowledge.
- POST /v1/knowledge returns it as
Path parameters
idintegerRequiredThe knowledge dataset id.
Header parameters
Idempotency-KeystringOptionalMakes a retry safe. The first 2xx answer is stored for 24 h and replayed for the same key withIdempotency-Replayed: true; a retry while the first request runs is 409IDEMPOTENCY_IN_FLIGHT; the same key with a different payload is 422IDEMPOTENCY_KEY_REUSED; a malformed key is 400INVALID_IDEMPOTENCY_KEY.Min length:
16Max length:128Pattern:^[A-Za-z0-9_-]+$
Responses
- 200Success.
objectstringRequiredAlways
knowledge_datasetidintegerRequiredThe dataset id.deletedbooleanRequiredAlwaystrue: the removal is queued and cannot be undone.statusstringRequiredAlwaysprocessing: the removal runs in the background.Always
processing
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither. A mutation that honoursIdempotency-Keyalso returnsINVALID_IDEMPOTENCY_KEYwhen that header is not 16–128[A-Za-z0-9_-]characters.Error codesACCOUNT_SELECTOR_NOT_SUPPORTEDINVALID_IDEMPOTENCY_KEY
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesNOT_FOUND
- 409The request conflicts with the current resource state.
Error codesDATASET_DELETINGIDEMPOTENCY_IN_FLIGHT
- 422Validation failed. See
error.details.Error codesIDEMPOTENCY_KEY_REUSED
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X DELETE 'https://api.agentency.com/v1/knowledge/<DATASET_ID>' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "knowledge_dataset",
"id": 1,
"deleted": true,
"status": "processing"
}List a dataset's chunks
chunk_index order and cursor-paginated: exactly the text the chatbot retrieves from. The list is empty before training has run, and stays empty for a dataset whose every passage repeated knowledge its collection already holds (completed with total_chunks: 0).- Required scope
- knowledge:read
- Idempotency
- Read-only
- Rate limits
Integer.id(path)Knowledge dataset idPlaceholder in the samples:
<DATASET_ID>Get it from
- POST /v1/knowledge returns it as
id - GET /v1/knowledge returns it as
data[].id - GET /v1/chatbots/{id}/knowledge returns it as
data[].id - GET /v1/knowledge/collections/{id}/datasets returns it as
data[].id - POST /v1/knowledge/import/cloud returns it as
data[].id - GET /v1/files/{id} returns it as
knowledge_dataset_id - POST /v1/search returns it as
data[].dataset_id - Webhook knowledge.dataset.created carries it as
data.object.id - A crawler creates one dataset per page it collects; list them with
GET /chatbots/{id}/knowledge.
- POST /v1/knowledge returns it as
Path parameters
idintegerRequiredThe knowledge dataset id.
Query parameters
limitintegerOptionalPage size, clamped to 1–100.Default:
20Minimum:1Maximum:100starting_afterstringOptionalCursor from a previous page'snext_cursor: returns the page after it. A cursor minted for another list,sortororderis 422INVALID_CURSOR.ending_beforestringOptionalCursor from a previous page'sprevious_cursor: returns the page before it. Wins when both cursors are sent.created[gte]stringOptionalOnly rows created on or after this instant:YYYY-MM-DD(whole UTC day) or an RFC 3339 timestamp with a zone. Anything else is 422INVALID_PARAMETER.created[lte]stringOptionalOnly rows created on or before this instant:YYYY-MM-DD(whole UTC day) or an RFC 3339 timestamp with a zone. Anything else is 422INVALID_PARAMETER.
Responses
- 200Success.
objectstringRequiredAlways
listdataarray of KnowledgeChunkResourceRequiredhas_morebooleanRequirednext_cursorstringnullableRequiredprevious_cursorstringnullableRequiredurlstringRequired
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither.Error codesACCOUNT_SELECTOR_NOT_SUPPORTED
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesNOT_FOUND
- 422Validation failed. See
error.details.Error codesINVALID_CURSORINVALID_PARAMETER
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X GET 'https://api.agentency.com/v1/knowledge/<DATASET_ID>/chunks' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "list",
"data": [
{
"object": "knowledge_chunk",
"id": 1,
"dataset_id": 1,
"chunk_index": 0,
"text": "Refunds are issued to the original payment method within 5 business days.",
"metadata": {
"word_count": 13
},
"embedded_at": "2026-01-01T00:00:00+00:00"
}
],
"has_more": false,
"next_cursor": null,
"previous_cursor": null,
"url": "/v1/knowledge/1/chunks"
}Check a dataset's training status
embedding_status is completed or failed once training has finished. Poll every few seconds at most — or subscribe to knowledge.dataset.trained and knowledge.dataset.failed, which fire the moment it finishes. failed stays failed until you retry, edit or replace the dataset.- Required scope
- knowledge:read
- Idempotency
- Read-only
- Rate limits
Integer.id(path)Knowledge dataset idPlaceholder in the samples:
<DATASET_ID>Get it from
- POST /v1/knowledge returns it as
id - GET /v1/knowledge returns it as
data[].id - GET /v1/chatbots/{id}/knowledge returns it as
data[].id - GET /v1/knowledge/collections/{id}/datasets returns it as
data[].id - POST /v1/knowledge/import/cloud returns it as
data[].id - GET /v1/files/{id} returns it as
knowledge_dataset_id - POST /v1/search returns it as
data[].dataset_id - Webhook knowledge.dataset.created carries it as
data.object.id - A crawler creates one dataset per page it collects; list them with
GET /chatbots/{id}/knowledge.
- POST /v1/knowledge returns it as
Path parameters
idintegerRequiredThe knowledge dataset id.
Responses
- 200Success.
objectstringRequiredAlways
knowledge_statusidintegerRequiredThe dataset id.statusstringRequiredContent processing:uploaded,processing,processed,failed(no text could be extracted) orarchived.embedding_statusstringRequiredTraining:not_started,pending,processing,completedorfailed.total_chunksintegerRequiredChunks stored so far.is_deletingbooleanRequiredtruewhile the dataset is being removed in the background.
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither.Error codesACCOUNT_SELECTOR_NOT_SUPPORTED
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesNOT_FOUND
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X GET 'https://api.agentency.com/v1/knowledge/<DATASET_ID>/status' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "knowledge_status",
"id": 1,
"status": "processed",
"embedding_status": "completed",
"total_chunks": 1,
"is_deleting": false
}List a chatbot's knowledge
is_deleting: true). It is the same list as GET /knowledge?chatbot_id=.- Required scope
- knowledge:read
- Idempotency
- Read-only
- Rate limits
Integer.id(path)Chatbot idPlaceholder in the samples:
<CHATBOT_ID>Get it from
- GET /v1/chatbots returns it as
data[].id - POST /v1/chatbots returns it as
id - GET /v1/chatbots/by_handle/{handle} returns it as
id - Webhook chatbot.created carries it as
data.object.id - In the dashboard, it is the number in a chatbot's address:
/dashboard/chatbots/{id}.
- GET /v1/chatbots returns it as
Path parameters
idintegerRequiredThe chatbot id.
Query parameters
limitintegerOptionalPage size, clamped to 1–100.Default:
20Minimum:1Maximum:100starting_afterstringOptionalCursor from a previous page'snext_cursor: returns the page after it. A cursor minted for another list,sortororderis 422INVALID_CURSOR.ending_beforestringOptionalCursor from a previous page'sprevious_cursor: returns the page before it. Wins when both cursors are sent.created[gte]stringOptionalOnly rows created on or after this instant:YYYY-MM-DD(whole UTC day) or an RFC 3339 timestamp with a zone. Anything else is 422INVALID_PARAMETER.created[lte]stringOptionalOnly rows created on or before this instant:YYYY-MM-DD(whole UTC day) or an RFC 3339 timestamp with a zone. Anything else is 422INVALID_PARAMETER.
Responses
- 200Success.
objectstringRequiredAlways
listdataarray of KnowledgeDatasetResourceRequiredhas_morebooleanRequirednext_cursorstringnullableRequiredprevious_cursorstringnullableRequiredurlstringRequired
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither.Error codesACCOUNT_SELECTOR_NOT_SUPPORTED
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesNOT_FOUND
- 422Validation failed. See
error.details.Error codesINVALID_CURSORINVALID_PARAMETER
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X GET 'https://api.agentency.com/v1/chatbots/<CHATBOT_ID>/knowledge' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "list",
"data": [
{
"object": "knowledge_dataset",
"id": 1,
"name": "Refund policy",
"description": "How and when refunds are issued.",
"type": "Text",
"source_type": "text",
"source_url": null,
"status": "processed",
"embedding_status": "completed",
"embedding_processed_at": "2026-01-01T00:00:00+00:00",
"total_chunks": 1,
"total_words": 13,
"collection_id": 1,
"chatbot_id": 1,
"is_deleting": false,
"created_at": "2026-01-01T00:00:00+00:00",
"updated_at": "2026-01-01T00:00:00+00:00"
}
],
"has_more": false,
"next_cursor": null,
"previous_cursor": null,
"url": "/v1/chatbots/1/knowledge"
}Summarise a chatbot's training
processing and removing are both 0. failed datasets can be retrained in one call with POST /knowledge/{id}/retry_failed, queued ones trained with POST /knowledge/{id}/train_collected (both with the chatbot id).- Required scope
- knowledge:read
- Idempotency
- Read-only
- Rate limits
Integer.id(path)Chatbot idPlaceholder in the samples:
<CHATBOT_ID>Get it from
- GET /v1/chatbots returns it as
data[].id - POST /v1/chatbots returns it as
id - GET /v1/chatbots/by_handle/{handle} returns it as
id - Webhook chatbot.created carries it as
data.object.id - In the dashboard, it is the number in a chatbot's address:
/dashboard/chatbots/{id}.
- GET /v1/chatbots returns it as
Path parameters
idintegerRequiredThe chatbot id.
Responses
- 200Success.
objectstringRequiredAlways
knowledge_statusidintegerRequiredThe chatbot id.countsobjectRequiredThe chatbot's datasets by training state.
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither.Error codesACCOUNT_SELECTOR_NOT_SUPPORTED
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesNOT_FOUND
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X GET 'https://api.agentency.com/v1/chatbots/<CHATBOT_ID>/knowledge/status' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "knowledge_status",
"id": 1,
"counts": {
"total": 1,
"processing": 0,
"failed": 0,
"completed": 1,
"queued": 0,
"removing": 0
}
}Preview a knowledge removal
POST /knowledge/remove_from_chatbot or POST /knowledge/remove_from_system. It does not list the chatbots that use them. Changes nothing, so a key with only knowledge:read may call it.- Required scope
- knowledge:read
- Webhook events
- None
- Rate limits
Array of 1–100 integer dataset ids. A repeated id counts once.knowledge_ids(body)Knowledge dataset idsPlaceholder in the samples:
<DATASET_IDS>Get it from
- POST /v1/knowledge returns it as
id - GET /v1/knowledge returns it as
data[].id - GET /v1/chatbots/{id}/knowledge returns it as
data[].id - GET /v1/knowledge/collections/{id}/datasets returns it as
data[].id - POST /v1/knowledge/import/cloud returns it as
data[].id - GET /v1/files/{id} returns it as
knowledge_dataset_id - POST /v1/search returns it as
data[].dataset_id - Webhook knowledge.dataset.created carries it as
data.object.id - A crawler creates one dataset per page it collects; list them with
GET /chatbots/{id}/knowledge.
- POST /v1/knowledge returns it as
Integer.chatbot_id(body)Chatbot idPlaceholder in the samples:
<CHATBOT_ID>Get it from
- GET /v1/chatbots returns it as
data[].id - POST /v1/chatbots returns it as
id - GET /v1/chatbots/by_handle/{handle} returns it as
id - Webhook chatbot.created carries it as
data.object.id - In the dashboard, it is the number in a chatbot's address:
/dashboard/chatbots/{id}.
- GET /v1/chatbots returns it as
Request body
knowledge_idsarray of integerRequiredThe datasets to act on: 1 to 100 dataset ids.Min items:
1Max items:100chatbot_idintegerOptionalThe chatbot to detach the datasets from. Required byPOST /knowledge/remove_from_chatbot; the other operations ignore it.confirm_deletionstringOptionalMust betrueforPOST /knowledge/remove_from_system, which deletes the datasets permanently (422VALIDATION_FAILEDwithout it); the other operations ignore it.Possible values
yeson11truetrue
Responses
- 200Success.
objectstringRequiredAlways
knowledge_removal_impactdataset_countintegerRequiredHow many ofidsa removal would act on. Ids you do not have, and datasets already being removed, are not counted.Minimum:
0idsarray of anyRequiredThe ids as you sent them.
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither.Error codesACCOUNT_SELECTOR_NOT_SUPPORTED
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 422Validation failed. See
error.details.Error codesVALIDATION_FAILED
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X POST 'https://api.agentency.com/v1/knowledge/removal_impact' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"
-d '{
"knowledge_ids": [],
"chatbot_id": 1,
"confirm_deletion": "confirm_deletion"
}'Response
Example 200 response
{
"object": "knowledge_removal_impact",
"dataset_count": 1,
"ids": [
12
]
}Retrain a dataset
embedding_status: pending. Use it after a failed run, to train a not_started dataset, or to rebuild a trained one; the run ends in knowledge.dataset.trained or knowledge.dataset.failed. The previous attempt's error and any pending cancellation are cleared.
A dataset that is being trained right now is 409 INGESTION_IN_PROGRESS (cancel it first); one attached to no chatbot is 422 CHATBOT_REQUIRED; one being removed is 409 DATASET_DELETING. For many datasets at once use POST /knowledge/retry.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- None
- Rate limits
Integer.id(path)Knowledge dataset idPlaceholder in the samples:
<DATASET_ID>Get it from
- POST /v1/knowledge returns it as
id - GET /v1/knowledge returns it as
data[].id - GET /v1/chatbots/{id}/knowledge returns it as
data[].id - GET /v1/knowledge/collections/{id}/datasets returns it as
data[].id - POST /v1/knowledge/import/cloud returns it as
data[].id - GET /v1/files/{id} returns it as
knowledge_dataset_id - POST /v1/search returns it as
data[].dataset_id - Webhook knowledge.dataset.created carries it as
data.object.id - A crawler creates one dataset per page it collects; list them with
GET /chatbots/{id}/knowledge.
- POST /v1/knowledge returns it as
Path parameters
idintegerRequiredThe knowledge dataset id.
Header parameters
Idempotency-KeystringOptionalMakes a retry safe. The first 2xx answer is stored for 24 h and replayed for the same key withIdempotency-Replayed: true; a retry while the first request runs is 409IDEMPOTENCY_IN_FLIGHT; the same key with a different payload is 422IDEMPOTENCY_KEY_REUSED; a malformed key is 400INVALID_IDEMPOTENCY_KEY.Min length:
16Max length:128Pattern:^[A-Za-z0-9_-]+$
Responses
- 200
KnowledgeDatasetResourceobjectstringRequiredAlways
knowledge_datasetidintegerRequiredThe dataset id.namestringRequiredDisplay name, unique among the account's active datasets.descriptionstringnullableRequiredYour longer description;nullwhen none.typestringRequiredContent format. An uploaded file's type follows its extension;URL_LINKSis the list of links a website crawler found.Possible values
PDFWordExcelTextURLURL_LINKSVideoAudioImagesource_typestringnullableRequiredWhere the content came from:text(sent inline),upload(a file),url(a web page, alone or collected by a website crawler),url_links,sitemap(a page a sitemap crawler collected),google_driveordropbox(cloud import),site_info(the site summary a crawler builds),apiorintegration.source_urlstringnullableRequiredThe page the content is fetched from, for URL-sourced datasets;nullotherwise.statusstringRequiredContent processing, separate from training:uploaded(stored),processing(text extraction, OCR or training running),processed,failed(no text could be extracted) orarchived.Possible values
uploadedprocessingprocessedfailedarchivedembedding_statusstringRequiredTraining:not_started(training not requested),pending(queued),processing(chunking and embedding),completed(the chatbot answers from it) orfailed. Reachingcompletedorfailedemitsknowledge.dataset.trainedorknowledge.dataset.failed.Possible values
not_startedpendingprocessingcompletedfailedembedding_processed_atstringnullableRequiredWhen training last completed (ISO 8601, UTC);nullbefore the first completed run.total_chunksintegerRequiredChunks stored for the dataset.0on acompleteddataset means every passage repeated knowledge its collection already holds.total_wordsintegerRequiredWords in the extracted text.collection_idintegernullableRequiredThe knowledge collection the dataset is filed in;nullwhen none.chatbot_idintegernullableRequiredThe chatbot the dataset trains;nullwhen it is attached to none.is_deletingbooleanRequiredtruewhile the dataset is being removed in the background. It stays readable until the removal finishes; every change to it is 409DATASET_DELETING.created_atstringnullableRequiredWhen the dataset was created (ISO 8601, UTC).updated_atstringnullableRequiredWhen the dataset last changed (ISO 8601, UTC).
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither. A mutation that honoursIdempotency-Keyalso returnsINVALID_IDEMPOTENCY_KEYwhen that header is not 16–128[A-Za-z0-9_-]characters.Error codesACCOUNT_SELECTOR_NOT_SUPPORTEDINVALID_IDEMPOTENCY_KEY
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesNOT_FOUND
- 409The request conflicts with the current resource state.
Error codesDATASET_DELETINGIDEMPOTENCY_IN_FLIGHTINGESTION_IN_PROGRESS
- 422Validation failed. See
error.details.Error codesCHATBOT_REQUIREDIDEMPOTENCY_KEY_REUSED
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X POST 'https://api.agentency.com/v1/knowledge/<DATASET_ID>/retry' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "knowledge_dataset",
"id": 1,
"name": "Warranty terms",
"description": null,
"type": "Text",
"source_type": "text",
"source_url": null,
"status": "uploaded",
"embedding_status": "pending",
"embedding_processed_at": null,
"total_chunks": 0,
"total_words": 100,
"collection_id": null,
"chatbot_id": 1,
"is_deleting": false,
"created_at": "2026-01-01T00:00:00+00:00",
"updated_at": "2026-01-01T00:00:00+00:00"
}Re-fetch a web page dataset
source_type url, url_links or sitemap, with a source_url) and returns the dataset. When the page changed, the dataset's text is replaced and retrained for every chatbot trained on it, ending in knowledge.dataset.trained or knowledge.dataset.failed; an unchanged page changes nothing, and an empty or failed fetch never overwrites the stored content. The fetch obeys the same URL rules as a crawler.
Any other source is 409 DATASET_NOT_URL_SOURCED. While a fetch is still running, another call is 409 RECRAWL_IN_PROGRESS. A dataset being removed is 409 DATASET_DELETING.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- None
- Rate limits
Integer.id(path)Knowledge dataset idPlaceholder in the samples:
<DATASET_ID>Get it from
- POST /v1/knowledge returns it as
id - GET /v1/knowledge returns it as
data[].id - GET /v1/chatbots/{id}/knowledge returns it as
data[].id - GET /v1/knowledge/collections/{id}/datasets returns it as
data[].id - POST /v1/knowledge/import/cloud returns it as
data[].id - GET /v1/files/{id} returns it as
knowledge_dataset_id - POST /v1/search returns it as
data[].dataset_id - Webhook knowledge.dataset.created carries it as
data.object.id - A crawler creates one dataset per page it collects; list them with
GET /chatbots/{id}/knowledge.
- POST /v1/knowledge returns it as
Path parameters
idintegerRequiredThe knowledge dataset id.
Header parameters
Idempotency-KeystringOptionalMakes a retry safe. The first 2xx answer is stored for 24 h and replayed for the same key withIdempotency-Replayed: true; a retry while the first request runs is 409IDEMPOTENCY_IN_FLIGHT; the same key with a different payload is 422IDEMPOTENCY_KEY_REUSED; a malformed key is 400INVALID_IDEMPOTENCY_KEY.Min length:
16Max length:128Pattern:^[A-Za-z0-9_-]+$
Responses
- 200
KnowledgeDatasetResourceobjectstringRequiredAlways
knowledge_datasetidintegerRequiredThe dataset id.namestringRequiredDisplay name, unique among the account's active datasets.descriptionstringnullableRequiredYour longer description;nullwhen none.typestringRequiredContent format. An uploaded file's type follows its extension;URL_LINKSis the list of links a website crawler found.Possible values
PDFWordExcelTextURLURL_LINKSVideoAudioImagesource_typestringnullableRequiredWhere the content came from:text(sent inline),upload(a file),url(a web page, alone or collected by a website crawler),url_links,sitemap(a page a sitemap crawler collected),google_driveordropbox(cloud import),site_info(the site summary a crawler builds),apiorintegration.source_urlstringnullableRequiredThe page the content is fetched from, for URL-sourced datasets;nullotherwise.statusstringRequiredContent processing, separate from training:uploaded(stored),processing(text extraction, OCR or training running),processed,failed(no text could be extracted) orarchived.Possible values
uploadedprocessingprocessedfailedarchivedembedding_statusstringRequiredTraining:not_started(training not requested),pending(queued),processing(chunking and embedding),completed(the chatbot answers from it) orfailed. Reachingcompletedorfailedemitsknowledge.dataset.trainedorknowledge.dataset.failed.Possible values
not_startedpendingprocessingcompletedfailedembedding_processed_atstringnullableRequiredWhen training last completed (ISO 8601, UTC);nullbefore the first completed run.total_chunksintegerRequiredChunks stored for the dataset.0on acompleteddataset means every passage repeated knowledge its collection already holds.total_wordsintegerRequiredWords in the extracted text.collection_idintegernullableRequiredThe knowledge collection the dataset is filed in;nullwhen none.chatbot_idintegernullableRequiredThe chatbot the dataset trains;nullwhen it is attached to none.is_deletingbooleanRequiredtruewhile the dataset is being removed in the background. It stays readable until the removal finishes; every change to it is 409DATASET_DELETING.created_atstringnullableRequiredWhen the dataset was created (ISO 8601, UTC).updated_atstringnullableRequiredWhen the dataset last changed (ISO 8601, UTC).
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither. A mutation that honoursIdempotency-Keyalso returnsINVALID_IDEMPOTENCY_KEYwhen that header is not 16–128[A-Za-z0-9_-]characters.Error codesACCOUNT_SELECTOR_NOT_SUPPORTEDINVALID_IDEMPOTENCY_KEY
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesNOT_FOUND
- 409The request conflicts with the current resource state.
Error codesDATASET_DELETINGDATASET_NOT_URL_SOURCEDIDEMPOTENCY_IN_FLIGHTRECRAWL_IN_PROGRESS
- 422Validation failed. See
error.details.Error codesIDEMPOTENCY_KEY_REUSED
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X POST 'https://api.agentency.com/v1/knowledge/<DATASET_ID>/recrawl' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "knowledge_dataset",
"id": 1,
"name": "Pricing page",
"description": null,
"type": "URL",
"source_type": "url",
"source_url": "https://example.com/pricing",
"status": "uploaded",
"embedding_status": "completed",
"embedding_processed_at": null,
"total_chunks": 0,
"total_words": 100,
"collection_id": null,
"chatbot_id": 1,
"is_deleting": false,
"created_at": "2026-01-01T00:00:00+00:00",
"updated_at": "2026-01-01T00:00:00+00:00"
}Cancel a dataset's training
pending or processing. A queued run that has not started is dropped at once and the dataset returns to not_started; a running one stops at its next checkpoint, so the response can still read processing. Start again with POST /knowledge/{id}/retry.
A dataset that is not training is 409 NOTHING_TO_CANCEL; one being removed is 409 DATASET_DELETING.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- None
- Rate limits
Integer.id(path)Knowledge dataset idPlaceholder in the samples:
<DATASET_ID>Get it from
- POST /v1/knowledge returns it as
id - GET /v1/knowledge returns it as
data[].id - GET /v1/chatbots/{id}/knowledge returns it as
data[].id - GET /v1/knowledge/collections/{id}/datasets returns it as
data[].id - POST /v1/knowledge/import/cloud returns it as
data[].id - GET /v1/files/{id} returns it as
knowledge_dataset_id - POST /v1/search returns it as
data[].dataset_id - Webhook knowledge.dataset.created carries it as
data.object.id - A crawler creates one dataset per page it collects; list them with
GET /chatbots/{id}/knowledge.
- POST /v1/knowledge returns it as
Path parameters
idintegerRequiredThe knowledge dataset id.
Header parameters
Idempotency-KeystringOptionalMakes a retry safe. The first 2xx answer is stored for 24 h and replayed for the same key withIdempotency-Replayed: true; a retry while the first request runs is 409IDEMPOTENCY_IN_FLIGHT; the same key with a different payload is 422IDEMPOTENCY_KEY_REUSED; a malformed key is 400INVALID_IDEMPOTENCY_KEY.Min length:
16Max length:128Pattern:^[A-Za-z0-9_-]+$
Responses
- 200
KnowledgeDatasetResourceobjectstringRequiredAlways
knowledge_datasetidintegerRequiredThe dataset id.namestringRequiredDisplay name, unique among the account's active datasets.descriptionstringnullableRequiredYour longer description;nullwhen none.typestringRequiredContent format. An uploaded file's type follows its extension;URL_LINKSis the list of links a website crawler found.Possible values
PDFWordExcelTextURLURL_LINKSVideoAudioImagesource_typestringnullableRequiredWhere the content came from:text(sent inline),upload(a file),url(a web page, alone or collected by a website crawler),url_links,sitemap(a page a sitemap crawler collected),google_driveordropbox(cloud import),site_info(the site summary a crawler builds),apiorintegration.source_urlstringnullableRequiredThe page the content is fetched from, for URL-sourced datasets;nullotherwise.statusstringRequiredContent processing, separate from training:uploaded(stored),processing(text extraction, OCR or training running),processed,failed(no text could be extracted) orarchived.Possible values
uploadedprocessingprocessedfailedarchivedembedding_statusstringRequiredTraining:not_started(training not requested),pending(queued),processing(chunking and embedding),completed(the chatbot answers from it) orfailed. Reachingcompletedorfailedemitsknowledge.dataset.trainedorknowledge.dataset.failed.Possible values
not_startedpendingprocessingcompletedfailedembedding_processed_atstringnullableRequiredWhen training last completed (ISO 8601, UTC);nullbefore the first completed run.total_chunksintegerRequiredChunks stored for the dataset.0on acompleteddataset means every passage repeated knowledge its collection already holds.total_wordsintegerRequiredWords in the extracted text.collection_idintegernullableRequiredThe knowledge collection the dataset is filed in;nullwhen none.chatbot_idintegernullableRequiredThe chatbot the dataset trains;nullwhen it is attached to none.is_deletingbooleanRequiredtruewhile the dataset is being removed in the background. It stays readable until the removal finishes; every change to it is 409DATASET_DELETING.created_atstringnullableRequiredWhen the dataset was created (ISO 8601, UTC).updated_atstringnullableRequiredWhen the dataset last changed (ISO 8601, UTC).
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither. A mutation that honoursIdempotency-Keyalso returnsINVALID_IDEMPOTENCY_KEYwhen that header is not 16–128[A-Za-z0-9_-]characters.Error codesACCOUNT_SELECTOR_NOT_SUPPORTEDINVALID_IDEMPOTENCY_KEY
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesNOT_FOUND
- 409The request conflicts with the current resource state.
Error codesDATASET_DELETINGIDEMPOTENCY_IN_FLIGHTNOTHING_TO_CANCEL
- 422Validation failed. See
error.details.Error codesIDEMPOTENCY_KEY_REUSED
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X POST 'https://api.agentency.com/v1/knowledge/<DATASET_ID>/cancel' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "knowledge_dataset",
"id": 1,
"name": "Store locations",
"description": null,
"type": "Text",
"source_type": "text",
"source_url": null,
"status": "uploaded",
"embedding_status": "not_started",
"embedding_processed_at": null,
"total_chunks": 0,
"total_words": 100,
"collection_id": null,
"chatbot_id": 1,
"is_deleting": false,
"created_at": "2026-01-01T00:00:00+00:00",
"updated_at": "2026-01-01T00:00:00+00:00"
}Replace a dataset's file
file. Its text is extracted (a scanned PDF goes to OCR in the background), replaces the dataset's content, and every chatbot trained on the old content is retrained, ending in knowledge.dataset.trained or knowledge.dataset.failed. The old file is kept as archived.
Only source_type: upload datasets qualify (409 DATASET_NOT_UPLOAD_SOURCED). A file with no readable text is 422 TEXT_EXTRACTION_FAILED and leaves the dataset untouched. A dataset being trained right now is 409 INGESTION_IN_PROGRESS; one being removed is 409 DATASET_DELETING.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- None
- Rate limits
Integer.id(path)Knowledge dataset idPlaceholder in the samples:
<DATASET_ID>Get it from
- POST /v1/knowledge returns it as
id - GET /v1/knowledge returns it as
data[].id - GET /v1/chatbots/{id}/knowledge returns it as
data[].id - GET /v1/knowledge/collections/{id}/datasets returns it as
data[].id - POST /v1/knowledge/import/cloud returns it as
data[].id - GET /v1/files/{id} returns it as
knowledge_dataset_id - POST /v1/search returns it as
data[].dataset_id - Webhook knowledge.dataset.created carries it as
data.object.id - A crawler creates one dataset per page it collects; list them with
GET /chatbots/{id}/knowledge.
- POST /v1/knowledge returns it as
Path parameters
idintegerRequiredThe knowledge dataset id.
Header parameters
Idempotency-KeystringOptionalMakes a retry safe. The first 2xx answer is stored for 24 h and replayed for the same key withIdempotency-Replayed: true; a retry while the first request runs is 409IDEMPOTENCY_IN_FLIGHT; the same key with a different payload is 422IDEMPOTENCY_KEY_REUSED; a malformed key is 400INVALID_IDEMPOTENCY_KEY.Min length:
16Max length:128Pattern:^[A-Za-z0-9_-]+$
Request body
POST /v1/knowledge/{id}/replace_file.
Multipart upload of the replacement document. The file must be a supported
document type by both extension and content, within the account's size limit.filestringRequiredThe replacement document:txt,pdf,doc,docx,rtforodt, at most 10 MB by default. Its content must match its extension. Images and spreadsheets are not accepted here.Format:
binary
Responses
- 200
KnowledgeDatasetResourceobjectstringRequiredAlways
knowledge_datasetidintegerRequiredThe dataset id.namestringRequiredDisplay name, unique among the account's active datasets.descriptionstringnullableRequiredYour longer description;nullwhen none.typestringRequiredContent format. An uploaded file's type follows its extension;URL_LINKSis the list of links a website crawler found.Possible values
PDFWordExcelTextURLURL_LINKSVideoAudioImagesource_typestringnullableRequiredWhere the content came from:text(sent inline),upload(a file),url(a web page, alone or collected by a website crawler),url_links,sitemap(a page a sitemap crawler collected),google_driveordropbox(cloud import),site_info(the site summary a crawler builds),apiorintegration.source_urlstringnullableRequiredThe page the content is fetched from, for URL-sourced datasets;nullotherwise.statusstringRequiredContent processing, separate from training:uploaded(stored),processing(text extraction, OCR or training running),processed,failed(no text could be extracted) orarchived.Possible values
uploadedprocessingprocessedfailedarchivedembedding_statusstringRequiredTraining:not_started(training not requested),pending(queued),processing(chunking and embedding),completed(the chatbot answers from it) orfailed. Reachingcompletedorfailedemitsknowledge.dataset.trainedorknowledge.dataset.failed.Possible values
not_startedpendingprocessingcompletedfailedembedding_processed_atstringnullableRequiredWhen training last completed (ISO 8601, UTC);nullbefore the first completed run.total_chunksintegerRequiredChunks stored for the dataset.0on acompleteddataset means every passage repeated knowledge its collection already holds.total_wordsintegerRequiredWords in the extracted text.collection_idintegernullableRequiredThe knowledge collection the dataset is filed in;nullwhen none.chatbot_idintegernullableRequiredThe chatbot the dataset trains;nullwhen it is attached to none.is_deletingbooleanRequiredtruewhile the dataset is being removed in the background. It stays readable until the removal finishes; every change to it is 409DATASET_DELETING.created_atstringnullableRequiredWhen the dataset was created (ISO 8601, UTC).updated_atstringnullableRequiredWhen the dataset last changed (ISO 8601, UTC).
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither. A mutation that honoursIdempotency-Keyalso returnsINVALID_IDEMPOTENCY_KEYwhen that header is not 16–128[A-Za-z0-9_-]characters.Error codesACCOUNT_SELECTOR_NOT_SUPPORTEDINVALID_IDEMPOTENCY_KEY
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesNOT_FOUND
- 409The request conflicts with the current resource state.
Error codesDATASET_DELETINGDATASET_NOT_UPLOAD_SOURCEDIDEMPOTENCY_IN_FLIGHTINGESTION_IN_PROGRESS
- 422Validation failed. See
error.details.Error codesIDEMPOTENCY_KEY_REUSEDTEXT_EXTRACTION_FAILEDVALIDATION_FAILED
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X POST 'https://api.agentency.com/v1/knowledge/<DATASET_ID>/replace_file' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"
-d '{
"file": "file"
}'Response
Example 200 response
{
"object": "knowledge_dataset",
"id": 1,
"name": "Employee handbook",
"description": null,
"type": "Text",
"source_type": "upload",
"source_url": null,
"status": "uploaded",
"embedding_status": "not_started",
"embedding_processed_at": null,
"total_chunks": 0,
"total_words": 7,
"collection_id": null,
"chatbot_id": 1,
"is_deleting": false,
"created_at": "2026-01-01T00:00:00+00:00",
"updated_at": "2026-01-01T00:00:00+00:00"
}Import files from Google Drive or Dropbox
chatbot_id, named after the file, the way an upload is: its text is extracted (scanned PDFs and images by OCR, in the background) and, with auto_train (default true), it is trained. Datasets created this way emit no knowledge.dataset.created; each emits knowledge.dataset.trained or knowledge.dataset.failed when its training finishes. A file whose text cannot be read still becomes a dataset, with status: failed.
Answers 201 with a list of the created datasets (the same objects as GET /knowledge/{id}) plus failures: one {name, reason} entry per file that was not imported. When no file could be imported the call is 422 CLOUD_IMPORT_FAILED with the same entries in error.details.failures. A file whose name an active dataset already uses is skipped without a failures entry; when every file collides the call is 409 KNOWLEDGE_NAME_TAKEN. Once the batch passes its size cap the remaining files are not downloaded and fail as too_large.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- None
- Rate limits
Integer.chatbot_id(body)Chatbot idPlaceholder in the samples:
<CHATBOT_ID>Get it from
- GET /v1/chatbots returns it as
data[].id - POST /v1/chatbots returns it as
id - GET /v1/chatbots/by_handle/{handle} returns it as
id - Webhook chatbot.created carries it as
data.object.id - In the dashboard, it is the number in a chatbot's address:
/dashboard/chatbots/{id}.
- GET /v1/chatbots returns it as
Integer.knowledge_collection_id(body)Knowledge collection idPlaceholder in the samples:
<COLLECTION_ID>Get it from
- POST /v1/knowledge/collections returns it as
id - GET /v1/knowledge/collections returns it as
data[].id - POST /v1/knowledge/collections/auto_create returns it as
id - GET /v1/knowledge/{id} returns it as
collection_id - Webhook knowledge.collection.created carries it as
data.object.id - Adding knowledge or a crawl with only
chatbot_idfiles it in the chatbot's default collection, created on first use: read its id ascollection_idon any of the chatbot's datasets.
- POST /v1/knowledge/collections returns it as
Header parameters
Idempotency-KeystringOptionalMakes a retry safe. The first 2xx answer is stored for 24 h and replayed for the same key withIdempotency-Replayed: true; a retry while the first request runs is 409IDEMPOTENCY_IN_FLIGHT; the same key with a different payload is 422IDEMPOTENCY_KEY_REUSED; a malformed key is 400INVALID_IDEMPOTENCY_KEY.Min length:
16Max length:128Pattern:^[A-Za-z0-9_-]+$
Request body
/v1 import cloud knowledge payload. Field set is pinned on this class so a
dashboard FormRequest tweak cannot silently widen the public contract.providerstringRequiredWhere the files live:google_driveordropbox. A provider switched off on this deployment is 404IMPORT_PROVIDER_UNAVAILABLE.Possible values
google_drivedropboxchatbot_idintegerRequiredThe chatbot the imported files train.knowledge_collection_idintegernullableOptionalThe collection to file the datasets in; omit it for the chatbot's default collection. A collection of another chatbot is 422COLLECTION_NOT_OWNED_BY_CHATBOT.auto_trainbooleannullableOptionalTrain each imported file as soon as its dataset is created (defaulttrue).idempotency_keystringnullableOptionalA durable replay token: a retry with a token that already imported files returns those datasets instead of importing again. TheIdempotency-Keyheader wins when both are sent.Max length:
255access_tokenstringnullableOptionalGoogle Drive only, and required there: the short-lived OAuth token (drive.filescope) the Google Picker gave your page. It is used for these downloads and not stored.Max length:
4096filesarray of objectRequiredThe picked files, 1 to 20 by default, each{name, external_id, download_url, mime_type, size_bytes}:name(required) becomes the dataset name; Google Drive needsexternal_id(the Drive file id), Dropboxdownload_url(the Chooser's direct link, checked like any fetched URL). The typesPOST /filesaccepts are allowed, at most 10 MB per file and 90 MB per batch by default.Min items:
1Max items:20
Responses
- 201Created.
objectstringRequiredAlways
listdataarray of KnowledgeDatasetResourceRequiredhas_morebooleanRequirednext_cursoranynullableRequiredprevious_cursoranynullableRequiredurlstringRequiredAlways
/v1/knowledge/import/cloudfailuresarray of objectRequiredOne entry per picked file that was not imported; empty when all were.
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither. A mutation that honoursIdempotency-Keyalso returnsINVALID_IDEMPOTENCY_KEYwhen that header is not 16–128[A-Za-z0-9_-]characters.Error codesACCOUNT_SELECTOR_NOT_SUPPORTEDINVALID_IDEMPOTENCY_KEY
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesIMPORT_PROVIDER_UNAVAILABLENOT_FOUND
- 409The request conflicts with the current resource state.
Error codesIDEMPOTENCY_IN_FLIGHTKNOWLEDGE_NAME_TAKEN
- 422Validation failed. See
error.details.Error codesCLOUD_IMPORT_FAILEDCOLLECTION_NOT_OWNED_BY_CHATBOTIDEMPOTENCY_KEY_REUSEDVALIDATION_FAILED
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X POST 'https://api.agentency.com/v1/knowledge/import/cloud' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"
-d '{
"provider": "provider",
"chatbot_id": 1,
"knowledge_collection_id": 1,
"auto_train": "auto_train",
"idempotency_key": "idempotency_key",
"access_token": "access_token",
"files": []
}'Response
Example 201 response
{
"object": "list",
"data": [
{
"object": "knowledge_dataset",
"id": 1,
"name": "returns-policy.txt",
"description": null,
"type": "Text",
"source_type": "google_drive",
"source_url": null,
"status": "uploaded",
"embedding_status": "pending",
"embedding_processed_at": null,
"total_chunks": 0,
"total_words": 11,
"collection_id": 1,
"chatbot_id": 1,
"is_deleting": false,
"created_at": "2026-01-01T00:00:00+00:00",
"updated_at": "2026-01-01T00:00:00+00:00"
}
],
"has_more": false,
"next_cursor": null,
"previous_cursor": null,
"url": "/v1/knowledge/import/cloud",
"failures": []
}Retrain several datasets
POST /knowledge/{id}/retry would, and reports how many were queued. A dataset that cannot be retrained is skipped and counted in skipped and skipped_by_reason instead of failing the batch; ids you do not have appear in neither count.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- None
- Rate limits
Array of 1–100 integer dataset ids. A repeated id counts once.knowledge_ids(body)Knowledge dataset idsPlaceholder in the samples:
<DATASET_IDS>Get it from
- POST /v1/knowledge returns it as
id - GET /v1/knowledge returns it as
data[].id - GET /v1/chatbots/{id}/knowledge returns it as
data[].id - GET /v1/knowledge/collections/{id}/datasets returns it as
data[].id - POST /v1/knowledge/import/cloud returns it as
data[].id - GET /v1/files/{id} returns it as
knowledge_dataset_id - POST /v1/search returns it as
data[].dataset_id - Webhook knowledge.dataset.created carries it as
data.object.id - A crawler creates one dataset per page it collects; list them with
GET /chatbots/{id}/knowledge.
- POST /v1/knowledge returns it as
Header parameters
Idempotency-KeystringOptionalMakes a retry safe. The first 2xx answer is stored for 24 h and replayed for the same key withIdempotency-Replayed: true; a retry while the first request runs is 409IDEMPOTENCY_IN_FLIGHT; the same key with a different payload is 422IDEMPOTENCY_KEY_REUSED; a malformed key is 400INVALID_IDEMPOTENCY_KEY.Min length:
16Max length:128Pattern:^[A-Za-z0-9_-]+$
Request body
knowledge_idsarray of integerRequiredThe datasets to retrain: 1 to 100 dataset ids. Ids you do not have are ignored.Min items:
1Max items:100
Responses
- 200Success.
objectstringRequiredAlways
knowledge_bulk_retryqueuedintegerRequiredDatasets queued for training.skippednumberRequiredDatasets left as they were: the sum ofskipped_by_reason.skipped_by_reasonobjectRequiredWhy:processing(being trained right now),deleting(being removed) orno_chatbot(attached to no chatbot).
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither. A mutation that honoursIdempotency-Keyalso returnsINVALID_IDEMPOTENCY_KEYwhen that header is not 16–128[A-Za-z0-9_-]characters.Error codesACCOUNT_SELECTOR_NOT_SUPPORTEDINVALID_IDEMPOTENCY_KEY
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 409The request conflicts with the current resource state.
Error codesIDEMPOTENCY_IN_FLIGHT
- 422Validation failed. See
error.details.Error codesIDEMPOTENCY_KEY_REUSEDVALIDATION_FAILED
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X POST 'https://api.agentency.com/v1/knowledge/retry' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"
-d '{
"knowledge_ids": []
}'Response
Example 200 response
{
"object": "knowledge_bulk_retry",
"queued": 1,
"skipped": 0,
"skipped_by_reason": {
"processing": 0,
"deleting": 0,
"no_chatbot": 0
}
}Retrain a chatbot's failed datasets
failed dataset of the chatbot for training again, up to a fixed batch cap per call, and returns how many it queued; call it again if datasets are still failed after the batch. The datasets are reset and retrained in the background, each ending in knowledge.dataset.trained or knowledge.dataset.failed. {id} is the chatbot id.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- None
- Rate limits
Integer.id(path)Chatbot idPlaceholder in the samples:
<CHATBOT_ID>Get it from
- GET /v1/chatbots returns it as
data[].id - POST /v1/chatbots returns it as
id - GET /v1/chatbots/by_handle/{handle} returns it as
id - Webhook chatbot.created carries it as
data.object.id - In the dashboard, it is the number in a chatbot's address:
/dashboard/chatbots/{id}.
- GET /v1/chatbots returns it as
Path parameters
idintegerRequiredThe chatbot id.
Header parameters
Idempotency-KeystringOptionalMakes a retry safe. The first 2xx answer is stored for 24 h and replayed for the same key withIdempotency-Replayed: true; a retry while the first request runs is 409IDEMPOTENCY_IN_FLIGHT; the same key with a different payload is 422IDEMPOTENCY_KEY_REUSED; a malformed key is 400INVALID_IDEMPOTENCY_KEY.Min length:
16Max length:128Pattern:^[A-Za-z0-9_-]+$
Responses
- 200Success.
objectstringRequiredAlways
knowledge_bulk_retryqueuedintegerRequiredFailed datasets queued for training in this call.
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither. A mutation that honoursIdempotency-Keyalso returnsINVALID_IDEMPOTENCY_KEYwhen that header is not 16–128[A-Za-z0-9_-]characters.Error codesACCOUNT_SELECTOR_NOT_SUPPORTEDINVALID_IDEMPOTENCY_KEY
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesNOT_FOUND
- 409The request conflicts with the current resource state.
Error codesIDEMPOTENCY_IN_FLIGHT
- 422Validation failed. See
error.details.Error codesIDEMPOTENCY_KEY_REUSED
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X POST 'https://api.agentency.com/v1/knowledge/<CHATBOT_ID>/retry_failed' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "knowledge_bulk_retry",
"queued": 1
}Train a chatbot's untrained datasets
not_started dataset (added or collected with auto_train: false) and, like POST /knowledge/{id}/retry_failed, its failed ones. Returns how many datasets were queued; the training runs in the background, each dataset ending in knowledge.dataset.trained or knowledge.dataset.failed. A dataset whose text extraction failed or that is still in OCR is not picked up. {id} is the chatbot id.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- None
- Rate limits
Integer.id(path)Chatbot idPlaceholder in the samples:
<CHATBOT_ID>Get it from
- GET /v1/chatbots returns it as
data[].id - POST /v1/chatbots returns it as
id - GET /v1/chatbots/by_handle/{handle} returns it as
id - Webhook chatbot.created carries it as
data.object.id - In the dashboard, it is the number in a chatbot's address:
/dashboard/chatbots/{id}.
- GET /v1/chatbots returns it as
Path parameters
idintegerRequiredThe chatbot id.
Header parameters
Idempotency-KeystringOptionalMakes a retry safe. The first 2xx answer is stored for 24 h and replayed for the same key withIdempotency-Replayed: true; a retry while the first request runs is 409IDEMPOTENCY_IN_FLIGHT; the same key with a different payload is 422IDEMPOTENCY_KEY_REUSED; a malformed key is 400INVALID_IDEMPOTENCY_KEY.Min length:
16Max length:128Pattern:^[A-Za-z0-9_-]+$
Responses
- 200Success.
objectstringRequiredAlways
knowledge_trainqueuedintegerRequiredDatasets queued for training: thenot_startedones plus the failed ones of this batch.
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither. A mutation that honoursIdempotency-Keyalso returnsINVALID_IDEMPOTENCY_KEYwhen that header is not 16–128[A-Za-z0-9_-]characters.Error codesACCOUNT_SELECTOR_NOT_SUPPORTEDINVALID_IDEMPOTENCY_KEY
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesNOT_FOUND
- 409The request conflicts with the current resource state.
Error codesIDEMPOTENCY_IN_FLIGHT
- 422Validation failed. See
error.details.Error codesIDEMPOTENCY_KEY_REUSED
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X POST 'https://api.agentency.com/v1/knowledge/<CHATBOT_ID>/train_collected' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "knowledge_train",
"queued": 3
}Detach datasets from a chatbot
chatbot_id answering from up to 100 datasets while keeping the datasets themselves — their text, chunks and any other chatbot trained on them stay. The detach is queued and runs in the background; it emits no event. To delete datasets for good use POST /knowledge/remove_from_system.
The batch is all or nothing: one id you do not have is 404 NOT_FOUND for the whole call, and one dataset already being removed is 409 DATASET_DELETING with those ids in details.ids. chatbot_id is required here (422 VALIDATION_FAILED without it).- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- None
- Rate limits
Array of 1–100 integer dataset ids. A repeated id counts once.knowledge_ids(body)Knowledge dataset idsPlaceholder in the samples:
<DATASET_IDS>Get it from
- POST /v1/knowledge returns it as
id - GET /v1/knowledge returns it as
data[].id - GET /v1/chatbots/{id}/knowledge returns it as
data[].id - GET /v1/knowledge/collections/{id}/datasets returns it as
data[].id - POST /v1/knowledge/import/cloud returns it as
data[].id - GET /v1/files/{id} returns it as
knowledge_dataset_id - POST /v1/search returns it as
data[].dataset_id - Webhook knowledge.dataset.created carries it as
data.object.id - A crawler creates one dataset per page it collects; list them with
GET /chatbots/{id}/knowledge.
- POST /v1/knowledge returns it as
Integer.chatbot_id(body)Chatbot idPlaceholder in the samples:
<CHATBOT_ID>Get it from
- GET /v1/chatbots returns it as
data[].id - POST /v1/chatbots returns it as
id - GET /v1/chatbots/by_handle/{handle} returns it as
id - Webhook chatbot.created carries it as
data.object.id - In the dashboard, it is the number in a chatbot's address:
/dashboard/chatbots/{id}.
- GET /v1/chatbots returns it as
Header parameters
Idempotency-KeystringOptionalMakes a retry safe. The first 2xx answer is stored for 24 h and replayed for the same key withIdempotency-Replayed: true; a retry while the first request runs is 409IDEMPOTENCY_IN_FLIGHT; the same key with a different payload is 422IDEMPOTENCY_KEY_REUSED; a malformed key is 400INVALID_IDEMPOTENCY_KEY.Min length:
16Max length:128Pattern:^[A-Za-z0-9_-]+$
Request body
knowledge_idsarray of integerRequiredThe datasets to act on: 1 to 100 dataset ids.Min items:
1Max items:100chatbot_idintegerOptionalThe chatbot to detach the datasets from. Required byPOST /knowledge/remove_from_chatbot; the other operations ignore it.confirm_deletionstringOptionalMust betrueforPOST /knowledge/remove_from_system, which deletes the datasets permanently (422VALIDATION_FAILEDwithout it); the other operations ignore it.Possible values
yeson11truetrue
Responses
- 200Success.
objectstringRequiredAlways
knowledge_removalqueuedintegerRequiredDatasets queued to be detached.
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither. A mutation that honoursIdempotency-Keyalso returnsINVALID_IDEMPOTENCY_KEYwhen that header is not 16–128[A-Za-z0-9_-]characters.Error codesACCOUNT_SELECTOR_NOT_SUPPORTEDINVALID_IDEMPOTENCY_KEY
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesNOT_FOUND
- 409The request conflicts with the current resource state.
Error codesDATASET_DELETINGIDEMPOTENCY_IN_FLIGHT
- 422Validation failed. See
error.details.Error codesIDEMPOTENCY_KEY_REUSEDVALIDATION_FAILED
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X POST 'https://api.agentency.com/v1/knowledge/remove_from_chatbot' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"
-d '{
"knowledge_ids": [],
"chatbot_id": 1,
"confirm_deletion": "confirm_deletion"
}'Response
Example 200 response
{
"object": "knowledge_removal",
"queued": 1
}Delete several datasets
DELETE /knowledge/{id} does for one: each emits knowledge.dataset.deleted, stays readable with is_deleting: true while the removal runs in the background, and refuses every change meanwhile. Send confirm_deletion: true; without it the call is 422 VALIDATION_FAILED.
The batch is all or nothing: one id you do not have is 404 NOT_FOUND for the whole call, and one dataset already being removed is 409 DATASET_DELETING with those ids in details.ids. POST /knowledge/removal_impact previews the count first.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- knowledge.dataset.deleted
- Rate limits
Array of 1–100 integer dataset ids. A repeated id counts once.knowledge_ids(body)Knowledge dataset idsPlaceholder in the samples:
<DATASET_IDS>Get it from
- POST /v1/knowledge returns it as
id - GET /v1/knowledge returns it as
data[].id - GET /v1/chatbots/{id}/knowledge returns it as
data[].id - GET /v1/knowledge/collections/{id}/datasets returns it as
data[].id - POST /v1/knowledge/import/cloud returns it as
data[].id - GET /v1/files/{id} returns it as
knowledge_dataset_id - POST /v1/search returns it as
data[].dataset_id - Webhook knowledge.dataset.created carries it as
data.object.id - A crawler creates one dataset per page it collects; list them with
GET /chatbots/{id}/knowledge.
- POST /v1/knowledge returns it as
Integer.chatbot_id(body)Chatbot idPlaceholder in the samples:
<CHATBOT_ID>Get it from
- GET /v1/chatbots returns it as
data[].id - POST /v1/chatbots returns it as
id - GET /v1/chatbots/by_handle/{handle} returns it as
id - Webhook chatbot.created carries it as
data.object.id - In the dashboard, it is the number in a chatbot's address:
/dashboard/chatbots/{id}.
- GET /v1/chatbots returns it as
Header parameters
Idempotency-KeystringOptionalMakes a retry safe. The first 2xx answer is stored for 24 h and replayed for the same key withIdempotency-Replayed: true; a retry while the first request runs is 409IDEMPOTENCY_IN_FLIGHT; the same key with a different payload is 422IDEMPOTENCY_KEY_REUSED; a malformed key is 400INVALID_IDEMPOTENCY_KEY.Min length:
16Max length:128Pattern:^[A-Za-z0-9_-]+$
Request body
knowledge_idsarray of integerRequiredThe datasets to act on: 1 to 100 dataset ids.Min items:
1Max items:100chatbot_idintegerOptionalThe chatbot to detach the datasets from. Required byPOST /knowledge/remove_from_chatbot; the other operations ignore it.confirm_deletionstringOptionalMust betrueforPOST /knowledge/remove_from_system, which deletes the datasets permanently (422VALIDATION_FAILEDwithout it); the other operations ignore it.Possible values
yeson11truetrue
Responses
- 200Success.
objectstringRequiredAlways
knowledge_removalqueuedintegerRequiredDatasets queued for removal.Minimum:
0statusstringRequiredAlwaysprocessing: the removal runs in the background.Always
processing
- 400A tenant selector header named a tenant other than the API key's own (
ACCOUNT_SELECTOR_NOT_SUPPORTED): an all-digitX-Account-Idother than the key owner's id or, whileworkspaces.context_enabledis on, anX-Workspace-Idother than the key's workspace (ws_prefix optional, case-insensitive). A header naming the key's own tenant, or a non-numericX-Account-Id, is ignored; a key cannot switch tenants, so send neither. A mutation that honoursIdempotency-Keyalso returnsINVALID_IDEMPOTENCY_KEYwhen that header is not 16–128[A-Za-z0-9_-]characters.Error codesACCOUNT_SELECTOR_NOT_SUPPORTEDINVALID_IDEMPOTENCY_KEY
- 401Missing or invalid API key.
Error codesUNAUTHENTICATED
- 403The API key is missing a required scope.
Error codesACCOUNT_SUSPENDEDINSUFFICIENT_SCOPE
- 404The resource does not exist on this account.
Error codesNOT_FOUND
- 409The request conflicts with the current resource state.
Error codesDATASET_DELETINGIDEMPOTENCY_IN_FLIGHT
- 422Validation failed. See
error.details.Error codesIDEMPOTENCY_KEY_REUSEDVALIDATION_FAILED
- 429Rate limited. Honour the Retry-After header before retrying.
Error codesRATE_LIMITED
- 500Unexpected server error. Retry with the same Idempotency-Key.
Error codesSERVER_ERROR
Request
curl -X POST 'https://api.agentency.com/v1/knowledge/remove_from_system' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"
-d '{
"knowledge_ids": [],
"chatbot_id": 1,
"confirm_deletion": "confirm_deletion"
}'Response
Example 200 response
{
"object": "knowledge_removal",
"queued": 1,
"status": "processing"
}