Collections
Operations tagged Collections in the public API.
About Collections
A knowledge collection groups datasets. A collection bound to a chatbot (chatbot_id) holds that chatbot's knowledge: the datasets filed in it belong to that chatbot. A collection with chatbot_id: null is an account-level folder bound to no chatbot.
Default collection. Adding knowledge or a crawler with only chatbot_id files it in the chatbot's default collection, created on first use. POST /knowledge/collections/auto_create returns a chatbot's first collection, creating one when it has none.
Moving datasets. POST /knowledge/collections/{id}/datasets files a dataset in a collection and DELETE /knowledge/collections/{id}/datasets/{datasetId} takes it out; both change which chatbots answer from the dataset. A dataset never moves between chatbots: one that belongs to another chatbot than the collection is 422 COLLECTION_NOT_OWNED_BY_CHATBOT. A collection that still holds datasets cannot be deleted (409 COLLECTION_HAS_DATASETS, with details.dataset_count). Collection names are unique per chatbot (409 COLLECTION_NAME_TAKEN).
IDs you will meet.
id— the collection id, an integer, in every/knowledge/collections/{id}path. A dataset carries it ascollection_id;POST /knowledgeand the crawlers take it asknowledge_collection_id,POST /searchascollection_id.datasetId— a knowledge dataset id.
IDs on this page
- 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
- 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
- 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
Create a knowledge collection
201. With chatbot_id it belongs to that chatbot, and datasets you file in it (POST /knowledge with knowledge_collection_id, POST /knowledge/collections/{id}/datasets) become the chatbot's knowledge; without it it is an account-level collection bound to no chatbot.
A name already used among the chatbot's collections (or the account's unbound ones) is 409 COLLECTION_NAME_TAKEN. A retry with the same Idempotency-Key returns the collection the first request created.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- knowledge.collection.created
- 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
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 chatbot's collections (among the account's unbound collections withoutchatbot_id): a taken name is 409COLLECTION_NAME_TAKEN.Max length:
255chatbot_idintegernullableOptionalThe chatbot the collection belongs to; datasets filed in it become that chatbot's knowledge. Omit it for an account-level collection bound to no chatbot.descriptionstringnullableOptionalOptional longer description, at most 1000 characters.Max length:
1000
Responses
- 201
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. 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_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/collections' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"
-d '{
"name": "name",
"chatbot_id": 1,
"description": "description"
}'Response
Example 201 response
{
"object": "knowledge_collection",
"id": 1,
"name": "Returns",
"description": "Return and exchange policies.",
"chatbot_id": 1,
"created_at": "2026-01-01T00:00:00+00:00",
"updated_at": "2026-01-01T00:00:00+00:00"
}Update a knowledge collection
name, description or status — and returns the collection. The chatbot a collection belongs to cannot be changed. Renaming to a name a sibling collection already uses is 409 COLLECTION_NAME_TAKEN.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- knowledge.collection.updated
- 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.
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
namestringOptionalDisplay name, at most 255 characters. Renaming to a name a sibling collection uses is 409COLLECTION_NAME_TAKEN.Max length:
255descriptionstringnullableOptionalLonger description, at most 1000 characters;nullclears it.Max length:
1000statusstringOptionalStored collection status:active,inactiveorarchived. The collection object does not return it. To stop a chatbot answering from the collection's datasets, usePOST /knowledge/remove_from_chatbot.Possible values
activeinactivearchived
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. 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_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/collections/<COLLECTION_ID>' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"
-d '{
"name": "name",
"description": "description",
"status": "status"
}'Response
Example 200 response
{
"object": "knowledge_collection",
"id": 1,
"name": "Returns and exchanges",
"description": "Return and exchange policies.",
"chatbot_id": 1,
"created_at": "2026-01-01T00:00:00+00:00",
"updated_at": "2026-01-01T00:00:00+00:00"
}Delete a knowledge collection
COLLECTION_HAS_DATASETS with their number in details.dataset_count, and nothing changes: move the datasets out (DELETE /knowledge/collections/{id}/datasets/{datasetId}) or delete them first, then send the same request again.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- knowledge.collection.deleted
- 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.
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_collectionidintegerRequiredThe collection id.deletedbooleanRequiredAlwaystrue.
- 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 codesCOLLECTION_HAS_DATASETSIDEMPOTENCY_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/collections/<COLLECTION_ID>' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "knowledge_collection",
"id": 1,
"deleted": true
}List a collection's datasets
- 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.
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/knowledge/collections/<COLLECTION_ID>/datasets' \
-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/collections/1/datasets"
}File a dataset in a collection
dataset_id into this collection and returns the dataset. The chatbots that answer from it follow the move: a chatbot that only had it through its old collection stops answering from it, and an already-trained dataset starts serving the collection's chatbot in the background without being retrained. A dataset never trained stays untrained until you train it. A dataset of no chatbot joins the collection's chatbot, and its size then counts against that chatbot's plan allowance (402 KNOWLEDGE_PLAN_SIZE_EXCEEDED when it does not fit, with nothing moved). A dataset never moves between chatbots: one of another chatbot than the collection's is 422 COLLECTION_NOT_OWNED_BY_CHATBOT.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- None
- 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
Integer.dataset_id(body)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 collection 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
dataset_idintegerRequiredThe dataset to file in this collection, from your account. A dataset of another chatbot than the collection's is 422COLLECTION_NOT_OWNED_BY_CHATBOT; a dataset of no chatbot joins the collection's chatbot, and its size then counts against that chatbot's plan quota (402KNOWLEDGE_PLAN_SIZE_EXCEEDEDwhen it does not fit).
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
- 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_FLIGHT
- 422Validation failed. See
error.details.Error codesCOLLECTION_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/collections/<COLLECTION_ID>/datasets' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"
-d '{
"dataset_id": 1
}'Response
Example 200 response
{
"object": "knowledge_dataset",
"id": 1,
"name": "Exchange policy",
"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": 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"
}Duplicate a knowledge collection
name you give, and returns it with 201. The original's datasets are not copied. A name already used among that chatbot's collections is 409 COLLECTION_NAME_TAKEN.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- knowledge.collection.created
- 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 id of the knowledge collection to copy.
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
namestringRequiredName of the copy, at most 255 characters. It must be free among the collections of the original's chatbot (or the account's unbound collections, when the original has no chatbot): a taken name is 409COLLECTION_NAME_TAKEN.Max length:
255
Responses
- 201
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. 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_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/collections/<COLLECTION_ID>/duplicate' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"
-d '{
"name": "name"
}'Response
Example 201 response
{
"object": "knowledge_collection",
"id": 1,
"name": "Returns (draft)",
"description": "Return and exchange policies.",
"chatbot_id": 1,
"created_at": "2026-01-01T00:00:00+00:00",
"updated_at": "2026-01-01T00:00:00+00:00"
}Get or create a chatbot's collection
200, or — when it has none — creates one named chatbot_name and returns it with 201 (emitting knowledge.collection.created). Safe to call before every import: concurrent calls never create two. The collection returned is the chatbot's oldest, not necessarily the default collection POST /knowledge and the crawlers use when sent only chatbot_id: pass its id as knowledge_collection_id to file into it.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- knowledge.collection.created
- 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
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
chatbot_idintegerRequiredThe chatbot whose collection you want.chatbot_namestringRequiredThe name to give the collection when one is created, at most 255 characters (usually the chatbot's name). Ignored when the chatbot already has a collection.Max length:
255
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).
- 201
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. 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_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/collections/auto_create' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"
-d '{
"chatbot_id": 1,
"chatbot_name": "chatbot_name"
}'Response
Example 200 response
{
"object": "knowledge_collection",
"id": 0,
"name": "string",
"description": "string",
"chatbot_id": 0,
"created_at": "string",
"updated_at": "string"
}Built from the response schema, not recorded from a live call.
Take a dataset out of a collection
collection_id: null. The dataset itself is kept, but every chatbot that answered from it through this collection stops doing so. To delete it instead use DELETE /knowledge/{id}. A dataset that is not in this collection is 404 NOT_FOUND.- Required scope
- knowledge:write
- Idempotency
- Accepts Idempotency-Key
- Webhook events
- None
- 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
Integer.datasetId(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 collection id.datasetIdintegerRequiredThe 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 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 DELETE 'https://api.agentency.com/v1/knowledge/collections/<COLLECTION_ID>/datasets/<DATASET_ID>' \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json"Response
Example 200 response
{
"object": "knowledge_dataset",
"id": 1,
"name": "Exchange policy",
"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"
}