Search
Method: POST /{api_prefix}/{folder_path}/_search
Auth: Flux API Key
_search is the most flexible Flux endpoint. Use it when you need structured filters, joins across folders, population, localization, full-text search, or semantic vector search in a single request.
URL Pattern
POST https://{environment_key}.fxns.io/{api_prefix}/{folder_path}/_search
Example: POST https://7c9h4pwu.fxns.io/blog/articles/_search
Make sure the folder path is connected to your Flux API through Connect Folder to API.
Query Parameters
These parameters live in the query string alongside the POST body.
- Name
limit- Type
- integer
- Default
- default:100
- Description
Results per page (1–100). Body
limittakes precedence if provided.
- Name
next- Type
- string
- Description
Cursor for the next page. Mutually exclusive with
previous.
- Name
previous- Type
- string
- Description
Cursor for the previous page. Mutually exclusive with
next.
- Name
component- Type
- string
- Description
Component key required when querying composite folders with filters/search clauses.
- Name
search_locale- Type
- string
- Description
Locale for text search and sorting. Defaults to the environment default.
- Name
return_locales- Type
- string
- Description
Comma-separated locales returned in
data. Defaults to all enabled locales.
- Name
fallback_locales- Type
- boolean
- Default
- default:false
- Description
Apply the workspace fallback chain for missing translations.
- Name
populate- Type
- string
- Description
Comma-separated field paths to populate (dot notation enabled).
- Name
raw- Type
- boolean
- Default
- default:false
- Description
Return raw stored values (skip locale/formatting logic). Intended for tooling.
Request Body
| Field | Type | Description |
|---|---|---|
where | object | Structured filters using all_of / any_of. |
find_text | object | Text search (query, optional fields, threshold). |
find_phrase | object | Phrase search (query, optional fields). Cannot be combined with find_text. |
sort | array of strings | Sort fields (use -field for descending). |
join | object | Join definition (see Joins). |
limit | integer | Body-level limit (overrides query limit). |
search_mode | "text" | "vector" | "vector_boosted" | "hybrid" | Controls whether vector search is active. Defaults to "text". |
vector_search | object | Semantic vector payload for search_mode="vector", "vector_boosted", or "hybrid". Required for hybrid, optional in vector/vector_boosted when vector_field_search is used instead. |
vector_field_search | object | Search using a user-provided embedding vector against a vector field. Supported in search_mode="vector" and "vector_boosted" only. Mutually exclusive with vector_search. See Vector Field Search. |
vector_boost_config | object | Extra boost controls when search_mode="vector_boosted". |
hybrid_config | object | Weight and rerank options when search_mode="hybrid". |
ignore_unknown_fields | boolean | Skip validation errors for unknown fields in where. |
Filtering with where
Use where to combine AND/OR logic:
{
"where": {
"$": {
"all_of": [
{"status__eq": "published"},
{
"any_of": [
{"category__in": ["tech", "science"]},
{"tags__includes": "ml"}
]
}
]
}
}
}
Supported operators:
| Operator | Description | Example |
|---|---|---|
eq, ieq | Equals (case-sensitive / insensitive) | {"status__ieq": "Published"} |
gt, gte, lt, lte | Numeric/date comparisons | {"rating__gte": 4.0} |
in, iin | Value in list | {"category__iin": ["tech", "Science"]} |
between | Inclusive range (array of two values) | {"price__between": [50, 200]} |
contains, icontains | Substring search | {"title__icontains": "api"} |
startswith, istartswith | Prefix match | {"slug__startswith": "flux"} |
endswith, iendswith | Suffix match | {"email__iendswith": "@example.com"} |
includes, iincludes | Array contains value | {"tags__includes": "ai"} |
exists | Field exists | {"summary__exists": true} |
null | Field is null | {"summary__null": true} |
Prefix any operator with not_ to negate it (e.g., {"status__not_in": ["archived", "deleted"]}).
Per-Field Locale Override
By default, filters on localized fields use the search_locale parameter. You can override the locale for a specific field by appending [locale] to the field name:
{
"where": {
"$": {
"all_of": [
{"title[fr]__eq": "Bonjour"},
{"description[de]__icontains": "hallo"}
]
}
}
}
This is useful when you need to filter on multiple locales in the same query or when the filter locale differs from the search/sort locale.
Text & Phrase Search
find_text
"find_text": {
"query": "machine learning",
"fields": ["title", "summary"],
"threshold": 0.85
}
queryis required (1–1000 characters).fieldsis optional; omit it to search all text-searchable fields.thresholdranges from 0 to 1 (defaults to 1.0). Lower values behave like typo tolerance.
find_phrase
"find_phrase": {
"query": "artificial intelligence",
"fields": ["title"]
}
Phrase search looks for exact matches. Do not include find_text in the same request.
Vector Search Modes
Set search_mode to unlock semantic search:
| search_mode | When to use | Requirements |
|---|---|---|
text | Default full-text mode | No vector_search or vector_field_search payload allowed. |
vector | Pure semantic search | vector_search or vector_field_search required. find_text/find_phrase are not allowed. |
vector_boosted | Text search ranked first, vector scores boost matches | Requires (vector_search or vector_field_search) and either find_text or find_phrase. Optional vector_boost_config. |
hybrid | Merges text + vector results with weighting | Requires vector_search and either find_text or find_phrase. Optional hybrid_config. Not available with vector_field_search — hybrid scoring assumes both scores measure textual relevance, which does not hold for arbitrary user-provided embeddings. |
vector_search
"vector_search": {
"query": "modern living room inspiration",
"fields": ["body"],
"top_k": 50,
"similarity_threshold": 0.5
}
query is required (min length 3). top_k ≤ 100 (default 10). fields and similarity_threshold are optional (default 0.4).
Boost & Hybrid Settings
vector_boost_config:{ "boost_factor": 1.2, "similarity_threshold": 0.8, "max_boost_results": 20 }hybrid_config:{ "vector_weight": 0.6, "text_weight": 0.4, "rerank_results": true }
Flux calculates embeddings behind the scenes and includes metadata in the response when vector modes are active. For a full walkthrough (prerequisites, examples, best practices), see the Vector Search guide.
vector_field_search
If you manage your own embeddings, use vector_field_search instead of vector_search to query a vector field directly:
"vector_field_search": {
"field": "custom_embedding",
"query_vector": [0.012, -0.034, 0.056, ...],
"top_k": 20,
"similarity_threshold": 0.6
}
This sends your own embedding vector and compares it against stored vectors using cosine similarity. Cannot be combined with vector_search or search_mode="hybrid". See Vector Field Search for details.
Sorting
Provide an array of fields or a comma-separated string.
"sort": ["-_sys.created_at", "title"]
Sorting respects search_locale for localized strings.
Joins
join lets you enrich the primary folder (the collection in your _search URL) with up to three additional collections. Think of it as instructing Flux how to look up related records during the SQL query.
"join": {
"as": {
"articles": "blog.articles",
"authors": "people.authors",
"companies": "orgs.companies"
},
"relations": [
{
"source": "articles",
"target": "authors",
"relation_type": "inner",
"source_field": "author"
},
{
"source": "authors",
"target": "companies",
"relation_type": "left",
"source_field": "company"
}
]
}
1. Map folder aliases
- Add every collection you want to use inside
join.as. - The primary folder (the one you’re querying) is implicitly
$; you do not add it tojoin.as.
2. Describe relationships
| Field | Description |
|---|---|
source | Alias that owns the reference field; omit or set to $ to reference the primary folder. |
target | Alias you want to join into the query. |
source_field | Reference field in the source that stores the target’s key. Must be a reference field. |
relation_type | "inner" (require a match) or "left" (return root rows even if the join fails). |
3. Filter joined folders
You can add alias-specific filters inside where. Use the alias name (with or without $) as a key at the top level:
"where": {
"$": {
"all_of": [{"status__eq": "published"}]
},
"authors": {
"all_of": [{"country__eq": "FR"}]
}
}
Flux applies the root filters to the primary folder and the alias filters to the joined folder before assembling the result set.
Constraints & validation
- Maximum joined folders (excluding the primary folder): 3. Exceeding this returns
too_many_join_folders. - Joined folders must be collections; composite folders are not supported in joins.
- Every alias referenced in
relationsor alias-specific filters must be declared injoin.as. - If a folder path cannot be resolved, Flux returns
failed_join(check thedetail.routevalue). - Joined data follows the same localization and population rules as the primary folder (e.g., populated references still count toward the response-size limit).
Population & Localization
Population
- Pass
populate=field1,field2.nestedin the query string to replace reference/relation IDs with their full documents. - Use dot notation to walk nested references (e.g.,
author.company). - Flux follows references up to three levels deep. Exceeding this depth silently stops population for deeper paths.
- Population increases response size; heavy use may trigger
max_response_size_exceeded.
Example:
POST https://7c9h4pwu.fxns.io/blog/articles/_search?populate=author.company,category.parent
Populated excerpt
{
"_sys": {...},
"data": {
"title": "Introduction to AI",
"author": {
"_sys": {...},
"data": {
"name": "John Smith",
"company": {
"_sys": {...},
"data": {"name": "Tech Corp"}
}
}
}
}
}
Localization
search_localecontrols which locale Flux uses for sorting, text search, and case-insensitive comparisons. If omitted, Flux uses the environment default.return_localeslimits the locales returned indata. Provide a comma-separated list (return_locales=en,fr).fallback_locales=truetells Flux to pull translations from the fallback chain when a requested locale is missing. If no fallback exists, the field is returned asnull.- These parameters apply to both the root resources and any populated documents.
Example:
POST https://7c9h4pwu.fxns.io/blog/articles/_search?return_locales=en,fr&fallback_locales=true
Localized excerpt
{
"_sys": {...},
"data": {
"title": {
"en": "Introduction to AI",
"fr": "Introduction à l'IA"
},
"summary": {
"en": "Guide to AI...",
"fr": "Guide de l'IA..."
}
}
}
Pagination
Flux uses cursor-based pagination for _search. Each response returns fully qualified next/previous URLs that already include the cursor token and any query parameters you supplied (e.g., populate, return_locales).
{
"limit": 50,
"next": "https://7c9h4pwu.fxns.io/blog/articles/_search?limit=50&next=eyJjcmVh...NDJ9",
"previous": null,
"results": [...]
}
Usage tips:
- First page – Omit
next/previous. - Next page – Call the
nextURL as-is with the same headers/body. - Previous page – Call the
previousURL if it’s notnull. - Cursor exclusivity – Only one of
nextorpreviouscan be provided per request; violating this returns422 invalid_request. - Limit overrides – Body
limitoverrides the querylimit. Both are clamped to 100.
For code samples in multiple languages, see the dedicated Pagination guide.
Response Schema
- Name
limit- Type
- integer
- Description
Effective limit applied to the query.
- Name
next- Type
- string | null
- Description
Absolute URL for the next page.
- Name
previous- Type
- string | null
- Description
Absolute URL for the previous page.
- Name
results- Type
- array
- Description
Array of resources, each following the _sys/data schema.
- Name
metadata- Type
- object
- Description
Always present. Contains the effective parameters that were used to execute the search, including any server-side defaults. Useful for debugging unexpected results.
Errors
| Status | error_code | When it occurs |
|---|---|---|
| 401 | authentication_required | Missing credentials, invalid signature, or stale timestamp. |
| 403 | access_denied | Authenticated key lacks access to this API prefix or folder. |
| 404 | route_not_found | Folder path is not connected to the Flux API. |
| 405 | action_not_allowed | Folder does not allow _search. |
| 408 | request_timeout | Query exceeded the 60‑second timeout. |
| 413 | max_response_size_exceeded | Populated payload exceeds the size cap. |
| 422 | validation_error | Invalid JSON body or parameter schema. |
| 422 | invalid_request | Generic validation issues (invalid limit, both cursors, malformed join, conflicting search settings). |
| 422 | unknown_locale | search_locale or return_locales includes an unsupported locale. |
| 422 | failed_join | Join references missing folders or unsupported relationships. |
| 422 | too_many_join_folders | Join includes more than three folders. |
| 422 | missed_component | Composite folder filters/search used without component. |
| 404 | component_not_found | Provided component key does not exist. |
For additional error payloads, see Flux Errors.
Complete Example
POST https://7c9h4pwu.fxns.io/blog/articles/_search?populate=author&return_locales=en,fr&fallback_locales=true
Authorization: Secure <access_key>:<signature>
Content-Type: application/json
Request Body
{
"where": {
"$": {
"all_of": [
{"status__eq": "published"},
{"published_at__gte": "2024-01-01"}
]
}
},
"find_text": {
"query": "machine learning",
"fields": ["title", "summary"],
"threshold": 0.85
},
"sort": ["-_sys.created_at"],
"limit": 25,
"ignore_unknown_fields": false
}
Response (trimmed)
{
"limit": 25,
"next": "https://7c9h4pwu.fxns.io/blog/articles/_search?limit=25&next=eyJjcmVh...MjV9",
"previous": null,
"results": [
{
"_sys": {
"key": "hG9tL4nRmXwP",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
"folder": "blog_articles"
},
"data": {
"title": {
"en": "Advanced Machine Learning Techniques",
"fr": "Techniques avancées d'apprentissage automatique"
},
"status": "published",
"author": {
"_sys": {...},
"data": {"name": "Dr. John Smith"}
}
}
}
],
"metadata": {
"search_mode": "text",
"limit": 25,
"text_threshold": 0.85
}
}