Getting Started—Using JSON Format
If you want to write more complex filter conditions, use JSON format to specify by ID at each level (e.g., knowledge base, individual document)
Query Metadata Control Item Descriptions
Knowledge Base
knowledge_base
The knowledge base referenced by the AI assistant when generating conversations
Wrap in an Array→[...] named knowledge_bases, pass in knowledge base IDs to enable multiple knowledge bases
Knowledge Base File Document
Chatbot_file
File documents available for reference within the knowledge base specified by knowledge_base
Define within the Object→{...} passed in knowledge_base
FAQ Dataset
FAQ
FAQ sets available for reference within the knowledge base specified by knowledge_base
Same as above
Knowledge Base File Document Label
label
Labels on file documents. Even without specifying Chatbot_file, you can still specify labels to restrict references to only documents matching those labels, supporting more granular document permission controls
Pass in using an object named label_relations, define applicable document label conditions with "OR"/"AND", defined within an Array→[...] named conditions
Structure Format Example and Description
{
"query_metadata": {
"knowledge_bases": [
{
"knowledge_base_id": "123e4567-e89b-12d3-a456-426614174000",
"chatbot_file_ids": ["9f7a9f7b-2b2b-4c4c-9d9d-8e8e8e8e8e8e"],
"faq_ids": ["a1b2c3d4-e5f6-7890-abcd-1234567890ab"],
"has_user_selected_all": false
},
{
"knowledge_base_id": "223e4567-e89b-12d3-a456-426614174001",
"has_user_selected_all": true
}
],
"label_relations": {
"operator": "OR",
"conditions": [
{ "label_id": "11111111-2222-3333-4444-555555555555" },
{
"operator": "AND",
"conditions": [
{ "label_id": "66666666-7777-8888-9999-000000000000" },
{ "label_id": "aaaaaaa1-bbbb-cccc-dddd-eeeeeeeeeeee" }
]
}
]
}
}
}Example description:
knowledge_basesaccepts multiple objects, allowing you to configure referenced documents and FAQs across multiple knowledge bases at once.The first knowledge base with
has_user_selected_all: false= only the explicitly listed documents and FAQs are accessible; the second withhas_user_selected_all: true= all content in that knowledge base is accessible.label_relations.operatorcombines conditions using"OR"(match any label) or"AND"(must match all labels), and supports nested definitions for complex conditions.The above example is valid JSON that can be copied and used directly (JSON does not support
//comments).
Semantics of Empty Sets vs. Unset (Important)
"Empty set" and "unset" have different meanings. Incorrect configuration can result in permissions being fully open or fully closed:
Not provided or null
Unset → continues searching the next level down; if all three levels are unset = no restriction, all knowledge bases attached to the AI assistant can be queried
{} (empty object)
Treated as no restriction (select all), and because a setting "exists," it stops searching further levels — to set "no permissions," use "knowledge_bases": []
"knowledge_bases": [] (empty array)
All knowledge bases are inaccessible — use this setting for "no permissions"
"label_relations": {"operator": "OR", "conditions": []} (empty conditions)
No label filtering = all content in selected knowledge bases is accessible, this is not the same as no permissions
Has values
Filters by conditions: Knowledge Base → Files/FAQs → Labels, narrowing scope level by level
label_relations must be provided together with knowledge_bases: when label_relations is provided alone (without knowledge_bases), knowledge base retrieval will not apply label filtering (equivalent to no restriction).
Field Names Must Be Exactly Correct
Each condition inside
conditionsonly accepts two forms:{"label_id": "..."}, or a nested group{"operator": ..., "conditions": [...]}. Using other key names such aslabel,labelid, etc. will cause the API to return 400 with the incorrect field name indicated.Objects inside
knowledge_basesonly accept five fields:knowledge_base_id,chatbot_file_ids,knowledge_base_file_ids,faq_ids, andhas_user_selected_all. Any other field will also return 400.You may add your own identifier fields at the
query_metadatatop level (e.g.,_user_id); these fields are ignored and do not affect the query scope.
Level Priority Order
query_metadata can be set at three levels: Message / Conversation / Contact. The system uses the first level that "has a setting," from top to bottom: Message > Conversation > Contact. Upper-level settings override lower-level ones.
How to Obtain IDs at Each Level?
You can find the ID field within each level's content in the left-side menu (using knowledge base as an example, click the copy icon to directly copy all ID content).
Key Logic Descriptions
1. label_relations Logic
ORoperation: access is granted if any label matchesANDoperation: access is granted only if all labels matchNested logic: supports multi-level, nested permission combinations
2. knowledge_bases Configuration
has_user_selected_all = true: access all content in the knowledge base (excluding items listed in the exclusion list)has_user_selected_all = false: access only the specified documents and FAQsUsing JSON booleans (
true/false) is recommended; string values"True"/"False"are also accepted by the system (for backward compatibility with existing integrations)
Contact Settings
You can write query_metadata settings in JSON format directly in the contact editing interface:
The system automatically validates the format and applies the permission settings.
Web Chat Initialization Settings
If you want to restrict conversation content before contact registration (e.g., providing Web Chat service to customers without registered contact accounts), you can provide Query Metadata during embedding. The system will enable the Message-level knowledge base document filtering mechanism by default.
Code Example
hasUserSelectedAll Parameter Description
This parameter controls the exclude/include behavior for items within a single knowledge base. Label filtering conditions are applied on top of the documents you have made accessible.
true
The system selects all content in the knowledge base, excluding items listed in chatbotFileIds and faqIds
Using 98 out of 100 documents, with the 2 documents listed in the parameter indicating exclusion
false
The system selects only the items explicitly listed in chatbotFileIds and faqIds
Using only 2 out of 100 documents
Code Example
Priority Order of queryMetadata and contactId
When neither queryMetadata nor contactId is set: The system searches the entire knowledge base scope without any exclusions
You can set queryMetadata or contactId independently
When both are set: The system only uses the Query Metadata settings from the contact (identified by contactId)
Conversation API (completions) Per-Request Inclusion
In addition to contact and Web Chat embedding settings, you can also pass Query Metadata with each call to the conversation API, allowing the same AI assistant to apply different knowledge scopes for different requests. This is ideal for integration scenarios where the backend dynamically assembles conditions based on the current user's identity, for example:
Finance/Securities: Determine accessible plan documents based on membership tier — regular members and VIP customers asking the same question receive responses from different scopes
Technology/Electronics Manufacturing: Restrict references to specification sheets and technical documents for the customer's specific product line
Educational Institutions: Provide different levels of admissions and academic information based on whether the user is a current student, alumni, or general visitor
Healthcare/Health Industry: Restrict health education materials by department to prevent cross-department content interference
Endpoint: POST https://api.maiagent.ai/api/v1/chatbots/{chatbotId}/completions/
queryMetadata must be placed inside the message object, not at the top level of the request body. Placing it in the wrong location will not produce an error, but the conditions will not take effect, resulting in behavior equivalent to having no filters set.
Full Example
The above example means: only within the 123e4567… knowledge base, reference documents and FAQs that match the 186a3012… label (e.g., "Regular Member"). When switching to a VIP customer, the backend only needs to pass the corresponding label ID — there is no need to duplicate the AI assistant.
The syntax for nested conditions is the same as Web Chat. You can directly reuse the labelRelations structure from the previous section:
Differences Between the Three Setting Locations
Contact
All conversations for that contact
Long-term permission binding based on identity
Web Chat Embedding
Conversations generated from that embedded page
Restricting scope for visitors without registered contacts
Conversation API (message.queryMetadata)
Only that specific request
Backend assembles conditions per request; one assistant serves multiple permission levels
Field Naming: Both camelCase and snake_case Are Accepted
The API automatically converts naming styles, so the following two formats are equivalent:
camelCase:
queryMetadata,knowledgeBases,knowledgeBaseId,labelRelations,labelId,hasUserSelectedAllsnake_case:
query_metadata,knowledge_bases,knowledge_base_id,label_relations,label_id,has_user_selected_all
It is recommended to use a consistent naming style throughout the entire request to avoid confusion during maintenance.
Default Value When hasUserSelectedAll Is Omitted
When hasUserSelectedAll is not provided, it defaults to true, meaning all content in the knowledge base is included, with label conditions applied as filters afterward.
Therefore, when you only want to "restrict an entire knowledge base by labels," knowledgeBases only needs to include knowledgeBaseId:
Label Filtering Scope
Label conditions apply to both file documents and FAQs in the knowledge base.
Attachments directly uploaded by the user during the conversation are not restricted by label conditions and can still be referenced; labels only constrain content within the knowledge base.
Labels are created independently for each knowledge base. The
label_idmust use the label ID from that specific knowledge base and cannot be reused from other knowledge bases.Labels must be actually assigned to files/FAQs to take effect: simply creating label options in "Label Management" without assigning them to content will have no filtering effect.
When a specific file is requested by name in the query, label conditions still apply: if the file does not meet the conditions, the AI assistant will respond that the file cannot be found in the knowledge base.
Last updated
Was this helpful?
