Search API
Search across modules with full-text search, filters, and faceted results
The Search API enables powerful full-text search across your workspace data. Search multiple modules simultaneously, filter results, get relevance scores, and retrieve faceted counts.
Overview
Coherence provides two search approaches:
| Approach | Endpoint | Use Case |
|---|---|---|
| Global Search | POST /search | Search across multiple modules at once |
| Module Search | GET /modules/{module}/search | Search within a single module |
Both endpoints support full-text search, filtering, pagination, and result highlighting.
Global Search
Endpoint
POST https://api.getcoherence.io/v1/search
Request Structure
{
"query": "john smith",
"modules": ["contacts", "accounts"],
"filters": {
"status": "active",
"created_at": { "$gte": "2024-01-01" }
},
"limit": 20,
"offset": 0,
"highlight": true,
"facets": ["module", "status"]
}Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Search query text |
modules | string[] | No | Module slugs to search (defaults to all) |
filters | object | No | Additional filter conditions |
limit | number | No | Max results to return (default: 20, max: 100) |
offset | number | No | Results to skip for pagination |
highlight | boolean | No | Include highlighted matches (default: false) |
facets | string[] | No | Fields to get faceted counts for |
Example Request
curl -X POST "https://api.getcoherence.io/v1/search" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "john smith",
"modules": ["contacts", "accounts"],
"filters": {
"status": "active"
},
"limit": 20,
"highlight": true
}'Response Structure
{
"data": [
{
"id": "rec_abc123",
"module": "contacts",
"score": 0.95,
"record": {
"id": "rec_abc123",
"name": "John Smith",
"email": "[email protected]",
"company": "Acme Corp",
"status": "active"
},
"highlights": {
"name": "<em>John</em> <em>Smith</em>",
"email": "<em>john</em>.<em>smith</em>@acme.com"
}
},
{
"id": "rec_def456",
"module": "accounts",
"score": 0.72,
"record": {
"id": "rec_def456",
"name": "Smith & Associates",
"industry": "Consulting"
},
"highlights": {
"name": "<em>Smith</em> & Associates"
}
}
],
"meta": {
"total": 47,
"limit": 20,
"offset": 0,
"query": "john smith",
"took_ms": 23
},
"facets": {
"module": {
"contacts": 32,
"accounts": 15
},
"status": {
"active": 40,
"inactive": 7
}
}
}Response Fields
| Field | Description |
|---|---|
data[].id | Record ID |
data[].module | Module slug the record belongs to |
data[].score | Relevance score (0-1, higher is more relevant) |
data[].record | Full record data |
data[].highlights | Matching text with <em> tags around matches |
meta.total | Total matching records across all modules |
meta.took_ms | Query execution time in milliseconds |
facets | Count of records grouped by facet field values |
Full-Text Search
How It Works
Coherence uses full-text indexing to enable fast, relevant search across your data. The search engine:
- Tokenizes your query into individual terms
- Matches terms against indexed fields
- Ranks results by relevance using TF-IDF scoring
- Returns results sorted by score (highest first)
Indexed Fields
By default, text-based fields are automatically indexed:
| Field Type | Indexed | Notes |
|---|---|---|
| Text | Yes | Full-text indexed |
| Long Text | Yes | Full-text indexed |
| Yes | Indexed as text | |
| URL | Yes | Indexed as text |
| Number | No | Use filters instead |
| Date | No | Use filters instead |
| Reference | Partial | Display value indexed |
Reference fields index the display value of the linked record, so searching "Acme" will find contacts linked to an account named "Acme Corp".
Search Syntax
| Syntax | Example | Description |
|---|---|---|
| Simple terms | john smith | Match records containing both terms |
| Quoted phrase | "john smith" | Match exact phrase |
| OR operator | john OR jane | Match either term |
| Prefix match | john* | Match terms starting with "john" |
| Exclude term | -inactive | Exclude records matching term |
Example Queries
// Simple multi-term search
{ "query": "acme consulting" }
// Exact phrase match
{ "query": "\"senior developer\"" }
// OR search
{ "query": "CEO OR CTO OR founder" }
// Prefix matching
{ "query": "market*" }
// Exclude results
{ "query": "developer -junior" }Filtering Search Results
Combine full-text search with filters to narrow results. Filters apply exact matching on specific fields.
Filter Syntax
{
"query": "john",
"filters": {
"status": "active",
"industry": ["Technology", "Finance"],
"created_at": {
"$gte": "2024-01-01",
"$lt": "2024-07-01"
},
"deal_value": {
"$gte": 10000
}
}
}Filter Operators
| Operator | Description | Example |
|---|---|---|
| (none) | Equals | "status": "active" |
| (array) | In list | "status": ["active", "pending"] |
$gte | Greater than or equal | "value": { "$gte": 1000 } |
$gt | Greater than | "value": { "$gt": 1000 } |
$lte | Less than or equal | "value": { "$lte": 5000 } |
$lt | Less than | "value": { "$lt": 5000 } |
$ne | Not equal | "status": { "$ne": "closed" } |
$exists | Field exists | "phone": { "$exists": true } |
Filtering by Reference
Filter by linked record IDs:
{
"query": "urgent",
"filters": {
"account_id": "rec_abc123"
}
}Module-Specific Search
Search within a single module using the module search endpoint.
Endpoint
GET https://api.getcoherence.io/v1/modules/{module}/search
Query Parameters
| Parameter | Description | Example |
|---|---|---|
q | Search query | ?q=john+smith |
filter[field] | Filter by field | ?filter[status]=active |
limit | Max results | ?limit=50 |
offset | Pagination offset | ?offset=20 |
highlight | Enable highlighting | ?highlight=true |
Example Request
curl -X GET "https://api.getcoherence.io/v1/modules/contacts/search?q=john&filter[status]=active&limit=25" \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"data": [
{
"id": "rec_abc123",
"score": 0.95,
"record": {
"id": "rec_abc123",
"name": "John Smith",
"email": "[email protected]",
"status": "active"
}
}
],
"meta": {
"total": 12,
"limit": 25,
"offset": 0
}
}Faceted Search
Facets provide counts of records grouped by field values. Use facets to build filter UIs showing available options and counts.
Requesting Facets
{
"query": "developer",
"facets": ["module", "status", "industry", "location"]
}Facet Response
{
"data": [...],
"facets": {
"module": {
"contacts": 45,
"accounts": 12,
"deals": 8
},
"status": {
"active": 52,
"inactive": 10,
"pending": 3
},
"industry": {
"Technology": 28,
"Finance": 15,
"Healthcare": 12,
"Other": 10
},
"location": {
"San Francisco": 20,
"New York": 18,
"Austin": 12,
"Remote": 15
}
}
}Facet counts reflect the current search query and filters. As users refine their search, facet counts update to show remaining options.
Facet Limits
By default, facets return the top 10 values. To get more:
{
"query": "developer",
"facets": ["industry"],
"facet_limit": 25
}Highlighting Matched Terms
Enable highlighting to show which parts of the text matched the query.
Enabling Highlights
{
"query": "john smith",
"highlight": true
}Highlight Response
{
"data": [
{
"id": "rec_abc123",
"record": {
"name": "John Smith",
"email": "[email protected]"
},
"highlights": {
"name": "<em>John</em> <em>Smith</em>",
"email": "<em>john</em>.<em>smith</em>@example.com"
}
}
]
}Custom Highlight Tags
Specify custom tags for highlighting:
{
"query": "john",
"highlight": true,
"highlight_pre": "<mark>",
"highlight_post": "</mark>"
}Search Suggestions / Autocomplete
Get search suggestions as users type for autocomplete functionality.
Endpoint
GET https://api.getcoherence.io/v1/search/suggest
Request
curl -X GET "https://api.getcoherence.io/v1/search/suggest?q=joh&modules=contacts,accounts" \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"suggestions": [
{
"text": "John Smith",
"module": "contacts",
"record_id": "rec_abc123",
"field": "name"
},
{
"text": "Johnson & Co",
"module": "accounts",
"record_id": "rec_def456",
"field": "name"
},
{
"text": "[email protected]",
"module": "contacts",
"record_id": "rec_ghi789",
"field": "email"
}
],
"meta": {
"query": "joh",
"took_ms": 8
}
}Suggestion Parameters
| Parameter | Description | Default |
|---|---|---|
q | Partial query text | Required |
modules | Modules to search | All modules |
limit | Max suggestions | 10 |
fields | Fields to suggest from | name, email, title |
Performance Tips
Optimize search performance with these best practices.
Limit Modules Searched
Searching fewer modules is faster. Specify only the modules you need:
{
"query": "john",
"modules": ["contacts"] // Faster than searching all modules
}Use Filters to Narrow Scope
Filters reduce the dataset before full-text search:
{
"query": "urgent",
"filters": {
"status": "open",
"created_at": { "$gte": "2024-01-01" }
}
}Pagination for Large Result Sets
Use limit and offset instead of fetching all results:
// Page 1
{ "query": "developer", "limit": 25, "offset": 0 }
// Page 2
{ "query": "developer", "limit": 25, "offset": 25 }
// Page 3
{ "query": "developer", "limit": 25, "offset": 50 }Request Only Needed Data
Skip facets and highlights if not needed:
{
"query": "john",
"highlight": false // Skip highlight processing
// Omit "facets" if not needed
}Cache Frequent Searches
For repeated searches (like saved searches or dashboards), cache results client-side for a short duration.
For very large result sets, consider using filters to narrow results rather than paginating through thousands of records.
Error Handling
Common Errors
| Code | Error | Solution |
|---|---|---|
| 400 | invalid_query | Check query syntax |
| 400 | invalid_module | Verify module slug exists |
| 400 | invalid_filter | Check filter field names and operators |
| 429 | rate_limit_exceeded | Reduce request frequency |
Error Response
{
"error": {
"code": "invalid_filter",
"message": "Unknown filter field: statusss",
"details": {
"field": "statusss",
"suggestion": "status"
}
}
}Related: API Overview | Authentication