> 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/en/authorization-integration/zhi-shi-guan-li-quan-xian-query-metadata-cha-xun-yuan-zi-liao-zong-lan/json-interfaces.md).

# Get Started—Using JSON

To create more complex filter conditions, use JSON to specify IDs directly at each level, such as a knowledge base or individual document

## Query Metadata Controls <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 Type</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 that the AI assistant references when generating conversations</td><td>Pass knowledge base IDs in the <code>Array→[...]</code> named knowledge_bases to allow multiple knowledge bases</td></tr><tr><td>Knowledge base file</td><td><code>Chatbot_file</code></td><td>Files that may be referenced within the knowledge base specified by knowledge_base</td><td>Define them in the <code>object→{...}</code> passed within knowledge_base</td></tr><tr><td>FAQ dataset</td><td><code>FAQ</code></td><td>FAQs that may be referenced within the knowledge base specified by knowledge_base</td><td>Same as above</td></tr><tr><td>Knowledge base file label</td><td><code>label</code></td><td>Labels on files. You can specify a label even without specifying Chatbot_file, restricting references to documents that match the label and enabling more granular document permissions</td><td>Pass an object named label_relations, use <code>"OR"/"AND"</code> to define applicable document label conditions, and define them in the <code>Array→[...]</code> named conditions</td></tr></tbody></table>

### Structure Example and Explanation

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

* `knowledge_bases` can accept multiple objects, configuring the referenceable documents and FAQs in multiple knowledge bases at once.
* For the first knowledge base, `has_user_selected_all: false` allows only the explicitly listed documents and FAQs. For the second, `has_user_selected_all: true` allows all content in that knowledge base.
* `label_relations.operator` combines conditions with `"OR"` (match any label) or `"AND"` (match all labels), and supports nested definitions for complex conditions.
* The example above is valid JSON that can be copied and used directly (JSON does not support `//` comments).

## Semantics of Empty Collections and Unset Values (Important) <a href="#empty-vs-unset" id="empty-vs-unset"></a>

An "empty collection" and an "unset value" have different meanings. Incorrect settings may grant access to everything or deny all access:

| Setting                                                                      | Effect                                                                                                                                                                 |
| ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Omitted or `null`                                                            | Unset → continue searching at the next level; if all three levels are unset, no restrictions apply and all knowledge bases attached to the AI assistant can be queried |
| `{}` (empty object)                                                          | **Treated as unrestricted (select all)**, and because a setting is present, lookup at lower levels stops. To configure "no access," always use `"knowledge_bases": []` |
| `"knowledge_bases": []` (empty array)                                        | No knowledge bases can be queried—**use this setting for "no access"**                                                                                                 |
| `"label_relations": {"operator": "OR", "conditions": []}` (empty conditions) | No label filtering—all content in the selected knowledge bases can be queried; this does **not** mean no access                                                        |
| Has a value                                                                  | Filter by the conditions, narrowing the scope at each level: knowledge base → file/FAQ → label                                                                         |

{% hint style="warning" %}
`label_relations` must be provided together with `knowledge_bases`. If `label_relations` is provided alone (without `knowledge_bases`), label filtering is not applied to knowledge base retrieval (equivalent to no restriction).
{% endhint %}

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

* Each condition in `conditions` accepts only one of two forms: `{"label_id": "..."}` or a nested group `{"operator": ..., "conditions": [...]}`. If you use another key name such as `label` or `labelid`, the API returns 400 and identifies the invalid field name.
* Objects in `knowledge_bases` accept only these five fields: `knowledge_base_id`, `chatbot_file_ids`, `knowledge_base_file_ids`, `faq_ids`, and `has_user_selected_all`. The API likewise returns 400 if any other field is present.
* At the top level of `query_metadata`, you may add your own identifying fields (such as `_user_id`). These fields are ignored and do not affect the query scope.

{% hint style="info" %}
All formatting errors are rejected with a 400 response at the API boundary (fail-closed), so broader permissions than intended are never silently applied. After configuring the settings, we still recommend testing them once to confirm that the scope meets your expectations.
{% endhint %}

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

query\_metadata can be configured at the Message, Conversation, or Contact level. The first configured level is used from top to bottom: **Message > Conversation > Contact**. A higher-level setting overrides a lower-level setting.

## How Do I Get the ID for Each Level? <a href="#ru-he-huo-qu-ge-ceng-ji-id" id="ru-he-huo-qu-ge-ceng-ji-id"></a>

Open the content for each level from the menu on the left to view its ID field. For example, in a knowledge base, click the copy icon to copy the entire ID.

<figure><img src="https://3415477754-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNBTi475lqozGpB7xObpE%2Fuploads%2Fgit-blob-ac377b11864763f6d3b96811593f2262b28eba95%2F%E8%9E%A2%E5%B9%95%E6%93%B7%E5%8F%96%E7%95%AB%E9%9D%A2%202025-08-08%20101733.png?alt=media" alt=""><figcaption><p>Location of IDs at each level</p></figcaption></figure>

## Key Logic <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 allowed when any label matches
* `AND` operation: all labels must match for access to be allowed
* Nested logic: supports multilevel, nested permission combinations

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

* `has_user_selected_all = true`: allows access to all content in the knowledge base (excluding items listed in the exclusion list)
* `has_user_selected_all = false`: allows access only to the specified documents and FAQs
* We recommend using JSON booleans (`true` / `false`). The strings `"True"` / `"False"` are also accepted by the system for compatibility with existing integrations.

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

You can enter query\_metadata settings directly in JSON format when editing a contact:

<figure><img src="https://3415477754-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNBTi475lqozGpB7xObpE%2Fuploads%2Fgit-blob-948b74fac65e94e770db5ec15e7f148c07f242c2%2F%E8%9E%A2%E5%B9%95%E6%93%B7%E5%8F%96%E7%95%AB%E9%9D%A2%202025-08-07%20163545.png?alt=media" alt=""><figcaption><p>Contact JSON editing interface</p></figcaption></figure>

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 an introduction to embedding Web Chat, see [Web Chat Embedding and SDK](/tech/en/api-integration/web-chat-sdk.md).
{% endhint %}

To restrict conversation content before a contact is available (for example, when providing Web Chat to customers without registered contact accounts), provide Query Metadata when embedding. The system enables message-level knowledge base document filtering by default.

### Code Example <a href="#cheng-shi-ma-fan-li" id="cheng-shi-ma-fan-li"></a>

```javascript
<script>
  window.maiagentChatbotConfig = {
    // Configure basic Web Chat parameters
    webChatId: 'Web Chat ID obtained from the Admin embed window',
    baseUrl: 'https://chat.maiagent.ai/web-chats',
    primaryColor: '#3854d8',
    
    // Configure the search scope for Web Chat knowledge base documents
    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
          ],
          faqIds: [
            'a1b2c3d4-e5f6-7890-abcd-1234567890ab' // FAQ
          ],
          hasUserSelectedAll: false // Select only the explicitly specified files and FAQs listed above
        }
      ]
    },
    
    // Configure Contact
    contactId: '60f81de6-a4b6-4d86-9781-5430783ef0b6'
  };
</script>
<script
  src="https://chat.maiagent.ai/js/embed.min.js"
  defer>
</script>
```

### hasUserSelectedAll Parameter

This parameter controls whether to exclude or use a small number of items within a single knowledge base. Label filters are applied only after the document scope has been established.

<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 except the items listed in <code>chatbotFileIds</code> and <code>faqIds</code></td><td>Use 98 out of 100 documents; list the 2 documents to exclude in the parameters</td></tr><tr><td><code>false</code></td><td>The system selects the items explicitly listed in <code>chatbotFileIds</code> and <code>faqIds</code></td><td>Use only 2 out of 100 documents</td></tr></tbody></table>

### Code Example

```js
// hasUserSelectedAll: true; list the document IDs to exclude
{
  "knowledgeBaseId": "123e4567-e89b-12d3-a456-426614174000",
  "chatbotFileIds": ["unwanted-document-ID-1", "unwanted-document-ID-2"],
  "faqIds": ["unwanted-FAQ_ID-1"],
  "hasUserSelectedAll": true
}

// hasUserSelectedAll: false; list the document IDs to use
{
  "knowledgeBaseId": "123e4567-e89b-12d3-a456-426614174000",
  "chatbotFileIds": ["desired-document-ID-1", "desired-document-ID-2"],
  "faqIds": ["desired-FAQ_ID-1"],
  "hasUserSelectedAll": false
}
```

### Precedence of queryMetadata and contactId

* **When neither queryMetadata nor contactId is configured**: The system searches all knowledge bases without exclusions
* **You can configure queryMetadata or contactId independently**
* **When both are configured**: The system uses only the Query Metadata settings for the contact identified by contactId

## Passing Query Metadata with Each Conversation API (completions) Call <a href="#completions-api" id="completions-api"></a>

In addition to contact and Web Chat embedding settings, you can pass Query Metadata with each Conversation API call so the same AI assistant applies a different knowledge scope to different requests. This is suitable for integrations where the backend assembles conditions in real time based on the current user's identity, for example:

* **Financial services/securities**: Determine which plan documents can be referenced based on membership level, so regular members and VIP customers receive responses drawn from different scopes when asking the same question
* **Technology/electronics manufacturing**: Limit references to specifications and technical documents for the customer's product line
* **Educational institutions**: Provide different levels of admissions and administrative information to current students, alumni, and general visitors
* **Healthcare**: Limit the scope of educational materials by specialty to prevent content from different specialties from interfering with one another

Endpoint: `POST https://api.maiagent.ai/api/v1/chatbots/{chatbotId}/completions/`

{% hint style="warning" %}
Place `queryMetadata` **inside the `message` object**, not at the top level of the request body. An incorrect location does not produce an error, but the conditions do not take effect, making the result equivalent to having no filters configured.
{% endhint %}

### Complete 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": "Which offers are available for my membership level?",
        "queryMetadata": {
            "knowledgeBases": [
                {
                    "knowledgeBaseId": "123e4567-e89b-12d3-a456-426614174000"
                }
            ],
            "labelRelations": {
                "operator": "AND",
                "conditions": [
                    { "labelId": "186a3012-44ac-4cd2-a132-a76bfda5bcae" }
                ]
            }
        }
    },
    "isStreaming": false
}'
```

{% endcode %}

The example means: within the `123e4567…` knowledge base, reference only documents and FAQs that also match the `186a3012…` label (for example, "regular member"). For a VIP customer, the backend only needs to pass the corresponding label ID instead; there is no need to duplicate the AI assistant.

Nested conditions use the same format as Web Chat, so you can reuse the `labelRelations` structure from the previous section directly:

```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 Configuration Locations <a href="#three-entry-points" id="three-entry-points"></a>

<table><thead><tr><th width="150">Configuration 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>Bind permissions to an identity over the long term</td></tr><tr><td>Web Chat embedding</td><td>Conversations created from the embedded page</td><td>Restrict the scope for visitors without registered contacts</td></tr><tr><td>Conversation API (<code>message.queryMetadata</code>)</td><td>That request only</td><td>Let the backend assemble conditions for each request so the same assistant can serve multiple permission levels</td></tr></tbody></table>

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

The API automatically converts naming styles, so the following two forms 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`

We recommend using one consistent style throughout the 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 omitted, it defaults to `true`, meaning **all content in that knowledge base**, after which label conditions are applied.

Therefore, when you only want to restrict an entire knowledge base by label, `knowledgeBases` only needs a `knowledgeBaseId`:

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

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

* Label conditions apply to **both** knowledge base files and FAQs.
* Attachments uploaded **directly** by a user in that conversation are not restricted by label conditions and can still be referenced. Labels constrain only content within knowledge bases.
* Labels are **created independently for each knowledge base**. A `label_id` must belong to the knowledge base in question and cannot be reused from another knowledge base.
* A label takes effect only when it is **actually attached to a file/FAQ**. Merely creating a label option in Label Management without attaching it to content has no filtering effect.
* Requests for a specific file by name are still subject to label conditions. If the file does not match the conditions, the AI assistant responds that the file could not 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/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.
