curl --request POST \
--url https://api.example.com/v0/search \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"query": "<string>",
"corpus_ids": [
"<string>"
],
"mode": "hybrid",
"profile": "default",
"limit": 10,
"filter": {
"source_namespaces": [
"<string>"
]
}
}
'import requests
url = "https://api.example.com/v0/search"
payload = {
"query": "<string>",
"corpus_ids": ["<string>"],
"mode": "hybrid",
"profile": "default",
"limit": 10,
"filter": { "source_namespaces": ["<string>"] }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
query: '<string>',
corpus_ids: ['<string>'],
mode: 'hybrid',
profile: 'default',
limit: 10,
filter: {source_namespaces: ['<string>']}
})
};
fetch('https://api.example.com/v0/search', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v0/search",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'query' => '<string>',
'corpus_ids' => [
'<string>'
],
'mode' => 'hybrid',
'profile' => 'default',
'limit' => 10,
'filter' => [
'source_namespaces' => [
'<string>'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v0/search"
payload := strings.NewReader("{\n \"query\": \"<string>\",\n \"corpus_ids\": [\n \"<string>\"\n ],\n \"mode\": \"hybrid\",\n \"profile\": \"default\",\n \"limit\": 10,\n \"filter\": {\n \"source_namespaces\": [\n \"<string>\"\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/v0/search")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"query\": \"<string>\",\n \"corpus_ids\": [\n \"<string>\"\n ],\n \"mode\": \"hybrid\",\n \"profile\": \"default\",\n \"limit\": 10,\n \"filter\": {\n \"source_namespaces\": [\n \"<string>\"\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v0/search")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"query\": \"<string>\",\n \"corpus_ids\": [\n \"<string>\"\n ],\n \"mode\": \"hybrid\",\n \"profile\": \"default\",\n \"limit\": 10,\n \"filter\": {\n \"source_namespaces\": [\n \"<string>\"\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"items": [
{
"record_id": "<string>",
"version_id": "<string>",
"part_key": "<string>",
"segment_id": "<string>",
"segmentation_id": "<string>",
"projection_generation_id": "<string>",
"rank": 2,
"excerpt": {
"text": "<string>",
"start": 1,
"end": 1,
"coordinate_system": "unicode_codepoint"
},
"availability": {
"state": "materialized",
"is_current": true,
"searchable": true
},
"embedding_artifact_id": "<string>",
"vector_space_id": "<string>",
"explanation": "<string>"
}
],
"retrieval_profile": {
"name": "<string>",
"version": "<string>"
},
"usage": {
"rounds": 2,
"elapsed_ms": 1,
"paid_calls": 1,
"cost_cents": 1
}
}{
"code": "<string>",
"message": "<string>",
"retryable": true,
"field": "<string>",
"resync_url": "<string>"
}Search records
Resolve the requested profile, compile mandatory Corpus/Organization prefilters and any requested filter, obtain candidates, then canonically hydrate and reauthorize every returned segment. Lexical-first records remain eligible without embeddings; semantic-only queries require vector coverage. Profile selection does not change access/currentness rules. When a retrieval plugin is pinned, it ranks. It asks the engine for candidates in up to three rounds and returns its ranking, which may hold only candidates the engine served in this search, each already authorized and hydrated.
curl --request POST \
--url https://api.example.com/v0/search \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"query": "<string>",
"corpus_ids": [
"<string>"
],
"mode": "hybrid",
"profile": "default",
"limit": 10,
"filter": {
"source_namespaces": [
"<string>"
]
}
}
'import requests
url = "https://api.example.com/v0/search"
payload = {
"query": "<string>",
"corpus_ids": ["<string>"],
"mode": "hybrid",
"profile": "default",
"limit": 10,
"filter": { "source_namespaces": ["<string>"] }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
query: '<string>',
corpus_ids: ['<string>'],
mode: 'hybrid',
profile: 'default',
limit: 10,
filter: {source_namespaces: ['<string>']}
})
};
fetch('https://api.example.com/v0/search', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/v0/search",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'query' => '<string>',
'corpus_ids' => [
'<string>'
],
'mode' => 'hybrid',
'profile' => 'default',
'limit' => 10,
'filter' => [
'source_namespaces' => [
'<string>'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/v0/search"
payload := strings.NewReader("{\n \"query\": \"<string>\",\n \"corpus_ids\": [\n \"<string>\"\n ],\n \"mode\": \"hybrid\",\n \"profile\": \"default\",\n \"limit\": 10,\n \"filter\": {\n \"source_namespaces\": [\n \"<string>\"\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/v0/search")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"query\": \"<string>\",\n \"corpus_ids\": [\n \"<string>\"\n ],\n \"mode\": \"hybrid\",\n \"profile\": \"default\",\n \"limit\": 10,\n \"filter\": {\n \"source_namespaces\": [\n \"<string>\"\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v0/search")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"query\": \"<string>\",\n \"corpus_ids\": [\n \"<string>\"\n ],\n \"mode\": \"hybrid\",\n \"profile\": \"default\",\n \"limit\": 10,\n \"filter\": {\n \"source_namespaces\": [\n \"<string>\"\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"items": [
{
"record_id": "<string>",
"version_id": "<string>",
"part_key": "<string>",
"segment_id": "<string>",
"segmentation_id": "<string>",
"projection_generation_id": "<string>",
"rank": 2,
"excerpt": {
"text": "<string>",
"start": 1,
"end": 1,
"coordinate_system": "unicode_codepoint"
},
"availability": {
"state": "materialized",
"is_current": true,
"searchable": true
},
"embedding_artifact_id": "<string>",
"vector_space_id": "<string>",
"explanation": "<string>"
}
],
"retrieval_profile": {
"name": "<string>",
"version": "<string>"
},
"usage": {
"rounds": 2,
"elapsed_ms": 1,
"paid_calls": 1,
"cost_cents": 1
}
}{
"code": "<string>",
"message": "<string>",
"retryable": true,
"field": "<string>",
"resync_url": "<string>"
}Authorizations
API key, not necessarily a JWT. Server derives Organization, permitted actions and Corpus scope; every resource access is authorized.
Body
Text-only top-k query. Resolve all Corpora in the authenticated Organization and require read/search permission for every requested Corpus before querying. Never silently drop an unauthorized Corpus. Unknown/unsupported profile or mode returns 422; a dependency outage is an error, not an empty successful result. Query token limits are checked against the resolved profile; no silent truncation. An optional filter narrows candidates inside the engine query, before ranking and the limit, in every mode. Other metadata filters and pagination are outside this surface.
At most 8192 code points on the wire. A semantic or hybrid query is also limited by the owner of the searched vector space (the first-party core.ingest plugin accepts at most 256 tokens of its model's tokenizer); a longer query is refused with 422 query_too_long, whose message names the limit, never truncated.
1 - 81921 - 16 elements1lexical, semantic, hybrid A search profile this deployment answers (listSearchProfiles). The built-in path answers default only; a pinned retrieval plugin answers the profiles it declares, default among them. balanced is a deprecated alias of default, accepted through engine 0.1.x and removed in engine 0.2.0. An unknown profile returns 422 unsupported_profile.
^[a-z][a-z0-9_]{0,31}$1 <= x <= 50Candidate filter applied before ranking. Every present condition must hold. A requested Corpus served by a Projection Generation built before source filtering existed returns 422 source_filter_unavailable; rebuild that Corpus once (rebuildCorpusProjection) to enable it. Unfiltered search is unaffected.
Show child attributes
Show child attributes
Response
Successful response
Bounded top-k results after canonical rechecks. May contain fewer hits than requested; no total count, completeness promise or stable pagination snapshot. Empty results still name the resolved profile.
50Show child attributes
Show child attributes
Resolved retrieval profile identity. Name is the profile that answered (default when the request named none or the deprecated balanced). Version identifies what ranked; the built-in path's immutable profile version, or plugin:@/ for a retrieval plugin.
Show child attributes
Show child attributes
What a search answered by a retrieval plugin spent; rounds of the plugin, elapsed time, and the paid calls and cost the plugin reported.
Show child attributes
Show child attributes