> For the complete documentation index, see [llms.txt](https://docs.maiagent.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.maiagent.ai/tech/maiagent-tech-en/authorization-integration/zhi-shi-guan-li-quan-xian-query-metadata-cha-xun-yuan-zi-liao-zong-lan/json-interfaces.md).

# Getting Started—Using JSON Format

## Query Metadata Control Item Descriptions <a href="#querymetadata-kong-zhi-xiang-mu-shuo-ming" id="querymetadata-kong-zhi-xiang-mu-shuo-ming"></a>

<table><thead><tr><th width="108.66668701171875">Item Category</th><th width="140.66668701171875">Key Name</th><th>Description</th><th>Usage</th></tr></thead><tbody><tr><td>Knowledge Base</td><td><code>knowledge_base</code></td><td>The knowledge base referenced by the AI assistant when generating conversations</td><td>Wrap in an <code>Array→[...]</code> named knowledge_bases, pass in knowledge base IDs to enable multiple knowledge bases</td></tr><tr><td>Knowledge Base File Document</td><td><code>Chatbot_file</code></td><td>File documents available for reference within the knowledge base specified by knowledge_base</td><td>Define within the <code>Object→{...}</code> passed in knowledge_base</td></tr><tr><td>FAQ Dataset</td><td><code>FAQ</code></td><td>FAQ sets available for reference within the knowledge base specified by knowledge_base</td><td>Same as above</td></tr><tr><td>Knowledge Base File Document Label</td><td><code>label</code></td><td>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</td><td>Pass in using an object named label_relations, define applicable document label conditions with <code>"OR"/"AND"</code>, defined within an <code>Array→[...]</code> named conditions</td></tr></tbody></table>

### Structure Format Example and Description

```json
{
  "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_bases` accepts 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 with `has_user_selected_all: true` = all content in that knowledge base is accessible.
* `label_relations.operator` combines 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) <a href="#empty-vs-unset" id="empty-vs-unset"></a>

"Empty set" and "unset" have different meanings. Incorrect configuration can result in permissions being fully open or fully closed:

| Setting                                                                      | Effect                                                                                                                                                               |
| ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 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                                                                          |

{% hint style="warning" %}
`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).
{% endhint %}

### Field Names Must Be Exactly Correct <a href="#exact-field-names" id="exact-field-names"></a>

* Each condition inside `conditions` only accepts two forms: `{"label_id": "..."}`, or a nested group `{"operator": ..., "conditions": [...]}`. Using other key names such as `label`, `labelid`, etc. will cause the API to return 400 with the incorrect field name indicated.
* Objects inside `knowledge_bases` only accept five fields: `knowledge_base_id`, `chatbot_file_ids`, `knowledge_base_file_ids`, `faq_ids`, and `has_user_selected_all`. Any other field will also return 400.
* You may add your own identifier fields at the `query_metadata` top level (e.g., `_user_id`); these fields are ignored and do not affect the query scope.

{% hint style="info" %}
Format errors are all blocked at the API boundary with 400 (fail-closed) and will not silently take effect with broader permissions than intended. After configuration, it is recommended to test once to confirm the scope matches expectations.
{% endhint %}

### Level Priority Order <a href="#metadata-hierarchy" id="metadata-hierarchy"></a>

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? <a href="#ru-he-huo-qu-ge-ceng-ji-id" id="ru-he-huo-qu-ge-ceng-ji-id"></a>

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 <a href="#guan-jian-luo-ji-shuo-ming" id="guan-jian-luo-ji-shuo-ming"></a>

### 1. label\_relations Logic <a href="#id-1labelrelations-luo-ji" id="id-1labelrelations-luo-ji"></a>

* `OR` operation: access is granted if any label matches
* `AND` operation: access is granted only if all labels match
* Nested logic: supports multi-level, nested permission combinations

### 2. knowledge\_bases Configuration <a href="#id-2knowledgebases-she-ding" id="id-2knowledgebases-she-ding"></a>

* `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 FAQs
* Using JSON booleans (`true` / `false`) is recommended; string values `"True"` / `"False"` are also accepted by the system (for backward compatibility with existing integrations)

## Contact Settings <a href="#lian-luo-ren-contact-she-ding" id="lian-luo-ren-contact-she-ding"></a>

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 <a href="#webchat-chu-shi-hua-she-ding" id="webchat-chu-shi-hua-she-ding"></a>

{% hint style="info" %}
For Web Chat embedding introduction, refer to [Web Chat Embedding and SDK](/tech/maiagent-tech-en/api-integration/web-chat-sdk.md)
{% endhint %}

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 <a href="#cheng-shi-ma-fan-li" id="cheng-shi-ma-fan-li"></a>

```javascript
<script>
  window.maiagentChatbotConfig = {
    // Set Web Chat basic parameters
    webChatId: 'Web Chat ID obtained from the Admin embed window',
    baseUrl: 'https://chat.maiagent.ai/web-chats',
    primaryColor: '#3854d8',
    
    // Set Web Chat knowledge base document search scope
    queryMetadata: {
      labelRelations: { // Labels
        operator: 'OR',
        conditions: [
          { labelId: '186a3012-44ac-4cd2-a132-a76bfda5bcae' },
          {
            operator: 'AND',
            conditions: [
              { labelId: '0267c405-cc26-4497-b17f-180aedf8b0eb' }, 
              { labelId: '60f81de6-a4b6-4d86-9781-5430783ef0b6' }
            ]
          }
        ]
      },
      knowledgeBases: [
        {
          knowledgeBaseId: '123e4567-e89b-12d3-a456-426614174000',
          chatbotFileIds: [
            '9f7a9f7b-2b2b-4c4c-9d9d-8e8e8e8e8e8e' // File document
          ],
          faqIds: [
            'a1b2c3d4-e5f6-7890-abcd-1234567890ab' // FAQ
          ],
          hasUserSelectedAll: false // Only select the explicitly specified files and FAQs listed above
        }
      ]
    },
    
    // Set Contact
    contactId: '60f81de6-a4b6-4d86-9781-5430783ef0b6'
  };
</script>
<script
  src="https://chat.maiagent.ai/js/embed.min.js"
  defer>
</script>
```

### 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.

<table><thead><tr><th width="82">Value</th><th>Behavior</th><th>Use Case</th></tr></thead><tbody><tr><td><code>true</code></td><td>The system selects all content in the knowledge base, excluding items listed in <code>chatbotFileIds</code> and <code>faqIds</code></td><td>Using 98 out of 100 documents, with the 2 documents listed in the parameter indicating exclusion</td></tr><tr><td><code>false</code></td><td>The system selects only the items explicitly listed in <code>chatbotFileIds</code> and <code>faqIds</code></td><td>Using only 2 out of 100 documents</td></tr></tbody></table>

### Code Example

```js
// hasUserSelectedAll: true, list document IDs to exclude
{
  "knowledgeBaseId": "123e4567-e89b-12d3-a456-426614174000",
  "chatbotFileIds": ["document_ID_to_exclude_1", "document_ID_to_exclude_2"],
  "faqIds": ["FAQ_ID_to_exclude_1"],
  "hasUserSelectedAll": true
}

// hasUserSelectedAll: false, list document IDs to include
{
  "knowledgeBaseId": "123e4567-e89b-12d3-a456-426614174000",
  "chatbotFileIds": ["document_ID_to_include_1", "document_ID_to_include_2"],
  "faqIds": ["FAQ_ID_to_include_1"],
  "hasUserSelectedAll": false
}
```

### 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 <a href="#completions-api" id="completions-api"></a>

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/`

{% hint style="warning" %}
`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.
{% endhint %}

### Full Example <a href="#completions-full-example" id="completions-full-example"></a>

{% code title="completions + queryMetadata" overflow="wrap" %}

```bash
curl --location 'https://api.maiagent.ai/api/v1/chatbots/550e8400-e29b-41d4-a716-446655440000/completions/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Api-Key YOUR_API_KEY' \
--data '{
    "conversation": null,
    "message": {
        "content": "What promotional plans are available for my membership tier?",
        "queryMetadata": {
            "knowledgeBases": [
                {
                    "knowledgeBaseId": "123e4567-e89b-12d3-a456-426614174000"
                }
            ],
            "labelRelations": {
                "operator": "AND",
                "conditions": [
                    { "labelId": "186a3012-44ac-4cd2-a132-a76bfda5bcae" }
                ]
            }
        }
    },
    "isStreaming": false
}'
```

{% endcode %}

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:

```json
"labelRelations": {
    "operator": "OR",
    "conditions": [
        { "labelId": "186a3012-44ac-4cd2-a132-a76bfda5bcae" },
        {
            "operator": "AND",
            "conditions": [
                { "labelId": "0267c405-cc26-4497-b17f-180aedf8b0eb" },
                { "labelId": "60f81de6-a4b6-4d86-9781-5430783ef0b6" }
            ]
        }
    ]
}
```

### Differences Between the Three Setting Locations <a href="#three-entry-points" id="three-entry-points"></a>

<table><thead><tr><th width="150">Setting Location</th><th>Effective Scope</th><th>Use Case</th></tr></thead><tbody><tr><td>Contact</td><td>All conversations for that contact</td><td>Long-term permission binding based on identity</td></tr><tr><td>Web Chat Embedding</td><td>Conversations generated from that embedded page</td><td>Restricting scope for visitors without registered contacts</td></tr><tr><td>Conversation API (<code>message.queryMetadata</code>)</td><td>Only that specific request</td><td>Backend assembles conditions per request; one assistant serves multiple permission levels</td></tr></tbody></table>

### Field Naming: Both camelCase and snake\_case Are Accepted <a href="#field-naming" id="field-naming"></a>

The API automatically converts naming styles, so the following two formats are equivalent:

* camelCase: `queryMetadata`, `knowledgeBases`, `knowledgeBaseId`, `labelRelations`, `labelId`, `hasUserSelectedAll`
* snake\_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 <a href="#default-has-user-selected-all" id="default-has-user-selected-all"></a>

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`:

```json
"knowledgeBases": [
    { "knowledgeBaseId": "123e4567-e89b-12d3-a456-426614174000" }
]
```

### Label Filtering Scope <a href="#label-filter-scope" id="label-filter-scope"></a>

* 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_id` must 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.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.maiagent.ai/tech/maiagent-tech-en/authorization-integration/zhi-shi-guan-li-quan-xian-query-metadata-cha-xun-yuan-zi-liao-zong-lan/json-interfaces.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
