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:

ApproachEndpointUse Case
Global SearchPOST /searchSearch across multiple modules at once
Module SearchGET /modules/{module}/searchSearch within a single module

Both endpoints support full-text search, filtering, pagination, and result highlighting.

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

ParameterTypeRequiredDescription
querystringYesSearch query text
modulesstring[]NoModule slugs to search (defaults to all)
filtersobjectNoAdditional filter conditions
limitnumberNoMax results to return (default: 20, max: 100)
offsetnumberNoResults to skip for pagination
highlightbooleanNoInclude highlighted matches (default: false)
facetsstring[]NoFields 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

FieldDescription
data[].idRecord ID
data[].moduleModule slug the record belongs to
data[].scoreRelevance score (0-1, higher is more relevant)
data[].recordFull record data
data[].highlightsMatching text with <em> tags around matches
meta.totalTotal matching records across all modules
meta.took_msQuery execution time in milliseconds
facetsCount of records grouped by facet field values

How It Works

Coherence uses full-text indexing to enable fast, relevant search across your data. The search engine:

  1. Tokenizes your query into individual terms
  2. Matches terms against indexed fields
  3. Ranks results by relevance using TF-IDF scoring
  4. Returns results sorted by score (highest first)

Indexed Fields

By default, text-based fields are automatically indexed:

Field TypeIndexedNotes
TextYesFull-text indexed
Long TextYesFull-text indexed
EmailYesIndexed as text
URLYesIndexed as text
NumberNoUse filters instead
DateNoUse filters instead
ReferencePartialDisplay 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

SyntaxExampleDescription
Simple termsjohn smithMatch records containing both terms
Quoted phrase"john smith"Match exact phrase
OR operatorjohn OR janeMatch either term
Prefix matchjohn*Match terms starting with "john"
Exclude term-inactiveExclude 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

OperatorDescriptionExample
(none)Equals"status": "active"
(array)In list"status": ["active", "pending"]
$gteGreater than or equal"value": { "$gte": 1000 }
$gtGreater than"value": { "$gt": 1000 }
$lteLess than or equal"value": { "$lte": 5000 }
$ltLess than"value": { "$lt": 5000 }
$neNot equal"status": { "$ne": "closed" }
$existsField exists"phone": { "$exists": true }

Filtering by Reference

Filter by linked record IDs:

{
  "query": "urgent",
  "filters": {
    "account_id": "rec_abc123"
  }
}

Search within a single module using the module search endpoint.

Endpoint

GET https://api.getcoherence.io/v1/modules/{module}/search

Query Parameters

ParameterDescriptionExample
qSearch query?q=john+smith
filter[field]Filter by field?filter[status]=active
limitMax results?limit=50
offsetPagination offset?offset=20
highlightEnable 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
  }
}

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

ParameterDescriptionDefault
qPartial query textRequired
modulesModules to searchAll modules
limitMax suggestions10
fieldsFields to suggest fromname, 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

CodeErrorSolution
400invalid_queryCheck query syntax
400invalid_moduleVerify module slug exists
400invalid_filterCheck filter field names and operators
429rate_limit_exceededReduce request frequency

Error Response

{
  "error": {
    "code": "invalid_filter",
    "message": "Unknown filter field: statusss",
    "details": {
      "field": "statusss",
      "suggestion": "status"
    }
  }
}

Related: API Overview | Authentication