Skip to main content

Introduction

The newly released Knowledge Bases API offers users the ability to create, manage and enrich Knowledge Base using the orq.ai API. In this guide we will see how to manipulate the different entities while building a Knowledge Base.

Prerequisite

API Key

To get started using the API, an API key is needed to use within SDKs or HTTP API.
To get an API key ready, see Authentication.

SDKs

Creating a Knowledge Base

To create a Knowledge Base, we’ll be using the Create a Knowledge API. The necessary inputs to create a knowledge base are:
  • key to define its name
  • embedding_model choose here a model to create embedding.
To find an embedding model, head to the Model Garden and filter models with Model Type =Embedding . The value should be formatted as follow: supplier/model_name, example: cohere/embed-english-v3.0 .
  • path is the Project and folder the Knowledge Base will created in, formatted as follow project/path, example Default/Production
The resulting call looks as follow:
curl --request POST \
     --url https://api.orq.ai/v2/knowledge \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --header 'authorization: Bearer <API_KEY>' \
     --data '
{
  "key": "<key>",
  "embedding_model": "<model>",
  "path": "<path>",
  "type": "internal"
}
'
Once the Knowledge Base is created, save the knowledge_base id returned from the API call.

(Optional) Uploading a File

The most common use case when building a knowledge base is uploading a file (e.g. a pdf) containing the data that you want models to search into. Before integrating your source file into the Knowledge Base, you need this file to be created and uploaded, for that, we’ll use the Create file API. To upload a file, simply point the API to the path of your file and set a name to it.
The maximum file size is 10MB.
The resulting call looks as follow:
curl --request POST \
     --url https://api.orq.ai/v2/files \
     --header 'accept: application/json' \
     --header 'authorization: Bearer <API_KEY>' \
     --header 'content-type: multipart/form-data' \
     --form file='@file_path'
Once this file is created, save the resulting file id returned from the api call.

Creating a Datasource

A Datasource is the integral part of the Knowledge Base, it holds chunks of data within which a model can search and make retrievals returned within a RAG use case. A Knowledge base can hold any number of Datasources. To create a data source, we’ll be using the Create a datasource API. The following fields are needed:
  • knowledge_id, corresponding to the previously created knowledge
  • (optional) file_id, from the previously created file, if you want to prepopulate the data source with your file.
  • name, a name for the datasource.
The resulting call looks as follow:
curl --request POST \
     --url https://api.orq.ai/v2/knowledge/knowledge_id/datasources \
     --header 'accept: application/json' \
     --header 'authorization: Bearer <API_KEY>' \
     --header 'content-type: application/json' \
     --data '
{
  "display_name": "name",
  "file_id": "file_id"
}
'
The created datasource will be returned, it is important to store its datasource id.

Viewing Datasource Chunks

Once a Datasource is populated with a file or manually, it holds Chunks for each parts of data that can be searched and retrieved. To view chunks we are using the List all chunks for a datasource API. The only needed data is the previously acquired datasource id and knowledge id. The resulting call looks as follow:
curl --request GET \
     --url https://api.orq.ai/v2/knowledge/<knowledge_id>/datasources/<datasource_id>/chunks \
     --header 'accept: application/json' \
     --header 'authorization: Bearer <API_KEY>'
The result contains lists of chunks containing the data for each chunk.

Chunking Data

Before adding Chunks to a Datasource, prepare the content by chunking the data to best fit the need of the Knowledge Base. orq exposes a Chunking text API that prepares data for Datasource ingestion.

Common Parameters

All chunking strategies support these parameters:
  • text (required): The text content to be chunked
  • strategy (required): The chunking strategy to use (token, sentence, recursive, semantic, or agentic)
  • metadata (optional, default: true): Whether to include metadata for each chunk (start_index, end_index, token_count)
  • return_type (optional, default: "chunks"): Return format - "chunks" (with metadata) or "texts" (plain strings)

Chunking Strategies

Choose which chunking strategy to use for the source data:

Token Chunker

Splits your text based on token count. Great for keeping chunks small enough for LLMs and for consistent embedding sizes. Additional Parameters:
  • chunk_size (optional, default: 512): Maximum tokens per chunk
  • chunk_overlap (optional, default: 0): Number of tokens to overlap between chunks
{
  "strategy": "token",
  "text": "The quick brown fox jumps over the lazy dog. This is a sample text that will be chunked into smaller pieces. Each chunk will maintain context while respecting the maximum chunk size.",
  "chunk_size": 512,
  "chunk_overlap": 0
}

Sentence Chunker

Breaks your text at sentence boundaries, so each chunk stays readable and sentences remain intact. Additional Parameters:
  • chunk_size (optional, default: 512): Maximum tokens per chunk
  • chunk_overlap (optional, default: 0): Number of overlapping tokens between chunks
  • min_sentences_per_chunk (optional, default: 1): Minimum number of sentences per chunk
{
  "strategy": "sentence",
  "text": "The quick brown fox jumps over the lazy dog. This is a sample text that will be chunked into smaller pieces. Each chunk will maintain context while respecting the maximum chunk size.",
  "chunk_size": 512,
  "min_sentences_per_chunk": 3
}

Recursive Chunker

Chunks text by working down a hierarchy (paragraphs, then sentences, then words) to maintain document structure. Additional Parameters:
  • chunk_size (optional, default: 512): Maximum tokens per chunk
  • separators (optional, default: ["\n\n", "\n", " ", ""]): Hierarchy of separators to use for splitting
  • min_characters_per_chunk (optional, default: 24): Minimum characters allowed per chunk
{
  "strategy": "recursive",
  "text": "The quick brown fox jumps over the lazy dog. This is a sample text that will be chunked into smaller pieces. Each chunk will maintain context while respecting the maximum chunk size.",
  "chunk_size": 512,
  "min_characters_per_chunk": 256
}

Semantic Chunker

Groups together sentences that are topically related, so each chunk makes sense on its own. Additional Parameters:
  • embedding_model (required): Embedding model to use for semantic similarity (e.g., "openai/text-embedding-3-small")
  • chunk_size (optional, default: 512): Maximum tokens per chunk
  • threshold (optional, default: "auto"): Similarity threshold for grouping (0-1) or “auto” for automatic detection
  • mode (optional, default: "window"): Chunking mode - "window" or "sentence"
  • similarity_window (optional, default: 1): Window size for similarity comparison
  • dimensions (optional): Number of dimensions for embedding output (required for text-embedding-3 models, range: 256-3072)
  • max_tokens (optional, default: 8191): Maximum number of tokens per embedding request
{
  "strategy": "semantic",
  "text": "The quick brown fox jumps over the lazy dog. This is a sample text that will be chunked into smaller pieces. Each chunk will maintain context while respecting the maximum chunk size.",
  "embedding_model": "openai/text-embedding-3-small",
  "chunk_size": 512,
  "threshold": 0.8,
  "mode": "window",
  "similarity_window": 1,
  "dimensions": 512
}

Agentic Chunker

Uses an LLM to determine the best split points, ideal for complex documents that need intelligent segmentation. Additional Parameters:
  • model (required): Model to use for chunking (e.g., "openai/gpt-4.1")
  • chunk_size (optional, default: 1024): Maximum tokens per chunk
  • candidate_size (optional, default: 128): Size of candidate splits for LLM evaluation
  • min_characters_per_chunk (optional, default: 24): Minimum characters allowed per chunk
{
  "strategy": "agentic",
  "text": "The quick brown fox jumps over the lazy dog. This is a sample text that will be chunked into smaller pieces. Each chunk will maintain context while respecting the maximum chunk size.",
  "model": "openai/gpt-4.1",
  "chunk_size": 1024,
  "candidate_size": 128,
  "min_characters_per_chunk": 24
}

Example API Call

Here is an example call using the semantic chunking strategy
curl --request POST \
     --url https://api.orq.ai/v2/chunking \
     --header 'accept: application/json' \
     --header 'authorization: Bearer ORQ_API_KEY' \
     --header 'content-type: application/json' \
     --data '
{
  "strategy": "semantic",
  "text": "The quick brown fox jumps over the lazy dog. This is a sample text that will be chunked into smaller pieces. Each chunk will maintain context while respecting the maximum chunk size.The quick brown fox jumps over the lazy dog. This is a sample text that will be chunked into smaller pieces. Each chunk will maintain context while respecting the maximum chunk size.The quick brown fox jumps over the lazy dog. This is a sample text that will be chunked into smaller pieces. Each chunk will maintain context while respecting the maximum chunk size.The quick brown fox jumps over the lazy dog. This is a sample text that will be chunked into smaller pieces. Each chunk will maintain context while respecting the maximum chunk size.The quick brown fox jumps over the lazy dog. This is a sample text that will be chunked into smaller pieces. Each chunk will maintain context while respecting the maximum chunk size.The quick brown fox jumps over the lazy dog. This is a sample text that will be chunked into smaller pieces. Each chunk will maintain context while respecting the maximum chunk size.",
  "chunk_size": 55,
  "embedding_model": "openai/text-embedding-3-small"
}
'

Response Format

The API returns a JSON object with a chunks array. Each chunk contains:
  • id: Unique identifier for the chunk (ULID format)
  • text: The actual text content of the chunk
  • index: The position index of this chunk in the sequence (0-based)
  • metadata (when metadata: true):
    • start_index: Starting character position in the original text
    • end_index: Ending character position in the original text
    • token_count: Number of tokens in this chunk
{
  "chunks": [
    {
      "id": "01JZVV3NM2X9RNC1FR3CJ89GGT",
      "text": "The quick brown fox jumps over the lazy dog. This is a sample text that will be chunked into smaller pieces.",
      "index": 0,
      "metadata": {
        "start_index": 0,
        "end_index": 109,
        "token_count": 26
      }
    },
    {
      "id": "01JZVV3NM2KWE7A1HS7XHE0N5W",
      "text": "Each chunk will maintain context while respecting the maximum chunk size.The quick brown fox jumps over the lazy dog.",
      "index": 1,
      "metadata": {
        "start_index": 109,
        "end_index": 227,
        "token_count": 22
      }
    }
  ]
}

Adding Chunk to a Datasource

It is possible to manually add a Chunk into a Datasource, to do so, we use the Create chunk API. The needed input data are:
  • The previously fetched knowledge_id.
  • The desired Datasource to add data to.
  • The Text to add to the chunk.
  • Optional Metadata to enrich the chunk.
Metadata are used to further classify the chunk with additional information that can then be used to search more precisely through the knowledge base.To learn more about search, see Searching a Knowledge Base
The resulting call looks as follow:
curl --request POST \
   --url https://api.orq.ai/v2/knowledge/<knowledge_id>/datasources/<datasource_id>/chunks \
   --header 'accept: application/json' \
   --header 'authorization: Bearer <API_KEY>' \
   --header 'content-type: application/json' \
   --data '
[
{
  "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
  "metadata": {
    "page_id": "page_1xadko1",
    "premium_information": false
  }
}
]
'
To learn how you can use a knowledge base inside a project check the how to build a customer support with AI Gateway tutorial
Once a Knowledge Base is created, it can be used within a Prompt to Retrieve Chunk data during model generation. To learn more, see Using a Knowledge Base in a Prompt.
Knowledge Base search in Orq.ai allows you to query your uploaded documents and data using vector similarity search. You can perform semantic searches across your content and apply metadata filters to narrow results to specific subsets of your data. This enables you to build powerful RAG (Retrieval Augmented Generation) applications that can find relevant information from your knowledge base to enhance LLM responses. You can search knowledge bases using the dedicated Search Knowledge Base API, which provides programmatic access to perform queries with optional metadata filtering and search options. A basic search queries your knowledge base using semantic similarity to find the most relevant chunks for your query:
curl --location 'https://api.orq.ai/v2/knowledge/KNOWLEDGE_BASE_ID/search' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer $ORQ_API_KEY' \
--data '{
    "query": "What are the benefits of machine learning?"
}'
The API returns chunks matching your query from the Knowledge Base.
{
  "matches": [
    {
      "id": "01K2XYMZB25NC01T4BKWARQG5M",
      "text": "Machine learning algorithms excel at identifying complex patterns within vast datasets, enabling computers to make predictions and decisions without explicit programming. From recommendation systems that suggest your next favorite movie to autonomous vehicles navigating city streets, ML transforms raw data into actionable insights. Deep neural networks mimic brain structures, while ensemble methods combine multiple models for enhanced accuracy and robustness across diverse applications."
    },
    {
      "id": "01K2XYMZB25NC01T4BKWARQG5V",
      "text": "The neural network's gradient descent algorithm struggled to converge during training, prompting Sarah to adjust the learning rate from 0.01 to 0.001. Her convolutional layers were overfitting on the image classification dataset, so she implemented dropout regularization and data augmentation techniques. After 50 epochs, the validation accuracy plateaued at 87%, suggesting she needed more diverse training samples or perhaps a deeper architecture with residual connections to break through the performance barrier."
    }
...
}

Filter by metadata

In every chunk in the knowledge base, you can include metadata key-value pairs to store additional information. This metadata can be added via de Chunks API or via the Studio. When searching the knowledge base, you can include a metadata filter to limit the search to chunks matching a filter expression.
A search without metadata filters omits metadata and performs a search on the entire Knowledge Base.

Metadata types

Metadata payloads must be key-value pairs in a JSON object. Keys must be strings, and values can be one of the following data types:
  • String
  • Number
  • Boolean
For example, the following would be valid metadata payloads:
{
    "page_id": "page_x1i2j3",
    "edition": 2020,
}

{
    "color": "blue",
    "is_premium_info": true
}

Metadata constraints

  • Use metadata for concise, discrete filter attributes to maximize search performance.
  • Avoid placing large text blobs in metadata, long strings will result in slower queries.
  • Keep each field’s data type consistent. Our system attempts to coerce mismatched values during ingestion, non-coercible values are discarded and omitted from the chunk.

Metadata filter expressions

orq.ai Knowledge Base filtering is based on MongoDB’s query and projection operators. We currently supports a subset of those selectors:
FilterDescriptionExampleSupported types
$eqSearch chunks with metadata values that are equal to a specified value.{"page_id": {"eq": "page_x1i2j3"}}Number, string, boolean
$neSearch chunks with metadata values that are not equal to a specified value.{"page_id": {"ne": "page_x1i2j3"}}Number, string, boolean
$gtSearch chunks with metadata values that are greater than a specified value.{"edition": {"gt": 2019}}Number
$gteSearch chunks with metadata values that are greater than or equal to a specified value.{"edition": {"gte": 2020}}Number
$ltSearch chunks with metadata values that are less than a specified value.{"edition": {"lt": 2022}}Number
$lteSearch chunks with metadata values that are less than or equal to a specified value.{"edition": {"lte": 2020}}Number
$inSearch chunks with metadata values that are in a specified array.{"page_id": {"in": ["page_x1i2j3", "page_y1xiijas"]}}String, number, boolean
$ninSearch chunks with metadata values that are not in a specified array.{"page_id": {"nin": ["comedy", "documentary"]}}String, number, boolean
$andJoins query clauses with a logical AND.{"$and": [{"page_id": {"eq": "page_x1i2j3"}}, {"edition": {"gte": 2020}}]}Object (array of filter expressions)
$orJoins query clauses with a logical OR.{"$or": [{"page_id": {"eq": "page_x1i2j3"}}, {"edition": {"gte": 2020}}]}Object (array of filter expressions)

Search examples

curl --location 'http://api.orq.ai/v2/knowledge/01J58RKRX4AWMSBMJVPYY1N2CG/search' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer $ORQ_API_KEY' \
--data '{
    "query": "What we the top editions of science fiction books",
    "filter_by": {
        "edition": {
            "gte": 2020
        }
    },
    "search_options":{
        "include_metadata": true,
        "include_vectors": true,
        "include_scores": true
    }
}'