Searches API
Search semantically with text queries and vector embeddings
Search semantically with text queries and vector embeddings. Find resources across your business using natural language queries or semantic similarity.
Overview
Business searches provide semantic discovery through:
- Text-based keyword search
- Vector similarity search with embeddings
- Filter and sort capabilities
- Pagination for large result sets
- Type-specific searches
import { createBusinessApi } from 'business-as-code'
const api = createBusinessApi({
apiKey: process.env.APIS_DO_KEY,
})
// Text search
const results = await api.searches.query({
query: 'enterprise customers in california',
types: ['Customer'],
filters: {
state: 'CA',
tier: 'enterprise',
},
})query()
Perform a text-based search query.
Signature
query(
query: BusinessQuery
): Promise<BusinessResource[]>Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| query | BusinessQuery | Yes | Search query object |
Query Properties
| Property | Type | Required | Description |
|---|---|---|---|
| query | string | Yes | Search query text |
| types | string[] | No | Resource types to search |
| filters | object | No | Additional filters |
| sort | object | No | Sort order (field and order) |
| pagination | object | No | Pagination settings (page and pageSize) |
Returns
Promise that resolves to an array of matching BusinessResource objects.
Example
// Simple text search
const customers = await api.searches.query({
query: 'acme corporation',
types: ['Customer'],
})
// Search with filters
const results = await api.searches.query({
query: 'enterprise plan',
types: ['Customer', 'Organization'],
filters: {
plan: 'enterprise',
status: 'active',
'revenue.gt': 100000,
},
})
// Search with sorting
const recentOrders = await api.searches.query({
query: 'pending orders',
types: ['Order'],
filters: {
status: 'pending',
},
sort: {
field: 'orderDate',
order: 'desc',
},
})
// Paginated search
const page1 = await api.searches.query({
query: 'customers',
types: ['Customer'],
pagination: {
page: 1,
pageSize: 25,
},
})vector()
Perform vector similarity search using embeddings.
Signature
vector(
embedding: number[],
filters?: Record<string, any>
): Promise<BusinessResource[]>Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| embedding | number[] | Yes | Vector embedding (e.g., from OpenAI) |
| filters | object | No | Additional filters |
Returns
Promise that resolves to an array of semantically similar BusinessResource objects.
Example
// Generate embedding (using OpenAI or similar)
const embedding = await generateEmbedding('Looking for customers interested in AI and automation')
// Vector search
const similarCustomers = await api.searches.vector(embedding, {
types: ['Customer'],
limit: 10,
})
console.log(`Found ${similarCustomers.length} similar customers`)Complete Vector Search Example
import { createBusinessApi } from 'business-as-code'
import OpenAI from 'openai'
const api = createBusinessApi({
apiKey: process.env.APIS_DO_KEY,
})
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
})
// Generate embedding for search query
async function semanticSearch(query: string) {
// Generate embedding
const embeddingResponse = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: query,
})
const embedding = embeddingResponse.data[0].embedding
// Search with vector
const results = await api.searches.vector(embedding, {
types: ['Customer', 'Product', 'Article'],
limit: 20,
})
return results
}
// Use it
const results = await semanticSearch('enterprise customers interested in AI automation tools')
results.forEach((resource) => {
console.log(`${resource.$type}: ${resource.name}`)
})Search Examples
Customer Search
Search and filter customers using semantic queries:
// Find customers by name → https://actions.org.ai/find.Customer
const results = await api.searches.query({
query: 'acme',
types: ['Customer'],
})
// Find customers by location → https://actions.org.ai/find.Customer
const californiaCustomers = await api.searches.query({
query: 'california technology companies',
types: ['Customer', 'Organization'],
filters: {
'address.state': 'CA',
industry: 'Technology',
},
})
// Find high-value customers → https://actions.org.ai/find.Customer
const enterpriseCustomers = await api.searches.query({
query: 'enterprise',
types: ['Customer'],
filters: {
tier: 'enterprise',
'lifetimeValue.gt': 100000,
},
sort: {
field: 'lifetimeValue',
order: 'desc',
},
})Semantic Abstraction: find.Customer
Product Search
Search products with filters and semantic similarity:
// Find products by name → https://actions.org.ai/find.Product
const laptops = await api.searches.query({
query: 'laptop',
types: ['Product'],
filters: {
category: 'Electronics',
availability: 'InStock',
},
})
// Find products in price range → https://actions.org.ai/find.Product
const affordableProducts = await api.searches.query({
query: 'office equipment',
types: ['Product'],
filters: {
'price.gte': 50,
'price.lte': 500,
category: 'Office Supplies',
},
sort: {
field: 'price',
order: 'asc',
},
})
// Find similar products (vector search) → https://actions.org.ai/find.Product
const productEmbedding = await generateEmbedding('High-performance laptop for developers')
const similarProducts = await api.searches.vector(productEmbedding, {
types: ['Product'],
filters: {
category: 'Electronics',
'price.lte': 2000,
},
limit: 10,
})Semantic Abstraction: find.Product
Order Search
Search orders by status, date, customer, and more:
// Find recent orders → https://actions.org.ai/find.Order
const recentOrders = await api.searches.query({
query: 'orders',
types: ['Order'],
filters: {
'orderDate.gte': '2024-10-01',
},
sort: {
field: 'orderDate',
order: 'desc',
},
pagination: {
page: 1,
pageSize: 50,
},
})
// Find orders by customer → https://actions.org.ai/find.Order
const customerOrders = await api.searches.query({
query: 'customer orders',
types: ['Order'],
filters: {
'customer.$id': 'cust-123',
},
})
// Find pending orders → https://actions.org.ai/find.Order
const pendingOrders = await api.searches.query({
query: 'pending',
types: ['Order'],
filters: {
status: 'pending',
'total.gte': 100,
},
})Semantic Abstraction: find.Order
Content Search
Search articles, documentation, and other content semantically:
// Find articles by topic → https://actions.org.ai/find.Article
const aiArticles = await api.searches.query({
query: 'artificial intelligence machine learning',
types: ['Article'],
filters: {
status: 'published',
'publishDate.gte': '2024-01-01',
},
})
// Semantic article search → https://actions.org.ai/find.Article
const queryEmbedding = await generateEmbedding('How to implement business automation using AI')
const relevantArticles = await api.searches.vector(queryEmbedding, {
types: ['Article', 'Documentation'],
filters: {
status: 'published',
},
limit: 10,
})
// Find popular content → https://actions.org.ai/find.Article
const popularContent = await api.searches.query({
query: 'popular articles',
types: ['Article'],
filters: {
'views.gte': 1000,
},
sort: {
field: 'views',
order: 'desc',
},
})Semantic Abstraction: find.Article
Filter Operators
Comparison Operators
// Greater than
filters: {
'price.gt': 100 // price > 100
}
// Greater than or equal
filters: {
'price.gte': 100 // price >= 100
}
// Less than
filters: {
'price.lt': 1000 // price < 1000
}
// Less than or equal
filters: {
'price.lte': 1000 // price <= 1000
}
// Equal
filters: {
status: 'active' // status === 'active'
}
// Not equal
filters: {
'status.ne': 'cancelled' // status !== 'cancelled'
}Array Operators
// In array
filters: {
'status.in': ['pending', 'processing', 'completed']
}
// Not in array
filters: {
'status.nin': ['cancelled', 'failed']
}
// Contains
filters: {
'tags.contains': 'urgent'
}String Operators
// Starts with
filters: {
'email.startsWith': 'admin@'
}
// Ends with
filters: {
'email.endsWith': '@company.com'
}
// Contains substring
filters: {
'name.contains': 'corp'
}
// Case-insensitive match
filters: {
'name.icontains': 'acme' // Matches 'ACME', 'Acme', 'acme'
}Date Operators
// Date range
filters: {
'createdAt.gte': '2024-01-01',
'createdAt.lte': '2024-12-31'
}
// Relative dates
filters: {
'createdAt.gte': new Date(Date.now() - 7 * 86400000).toISOString() // Last 7 days
}Pagination
Basic Pagination
async function getAllResults(query: BusinessQuery) {
const allResults = []
let page = 1
const pageSize = 100
while (true) {
const results = await api.searches.query({
...query,
pagination: { page, pageSize },
})
allResults.push(...results)
if (results.length < pageSize) {
break // Last page
}
page++
}
return allResults
}
// Use it
const allCustomers = await getAllResults({
query: 'customers',
types: ['Customer'],
})Cursor-Based Pagination
async function paginateWithCursor(query: BusinessQuery) {
const allResults = []
let cursor = null
while (true) {
const results = await api.searches.query({
...query,
pagination: {
cursor,
pageSize: 100,
},
})
allResults.push(...results)
if (results.length === 0 || !results.nextCursor) {
break
}
cursor = results.nextCursor
}
return allResults
}Sorting
Single Field Sort
// Sort by single field
const results = await api.searches.query({
query: 'customers',
types: ['Customer'],
sort: {
field: 'createdAt',
order: 'desc',
},
})Multiple Field Sort
// Sort by multiple fields (client-side)
const results = await api.searches.query({
query: 'customers',
types: ['Customer'],
})
results.sort((a, b) => {
// First by tier
if (a.tier !== b.tier) {
return a.tier.localeCompare(b.tier)
}
// Then by revenue
return (b.revenue || 0) - (a.revenue || 0)
})Advanced Patterns
Faceted Search
async function facetedSearch(query: string) {
// Get all results
const results = await api.searches.query({
query,
types: ['Product'],
})
// Calculate facets (client-side)
const facets = {
categories: {},
priceRanges: {
'0-50': 0,
'50-100': 0,
'100-500': 0,
'500+': 0,
},
availability: {},
}
results.forEach((product) => {
// Category facet
facets.categories[product.category] = (facets.categories[product.category] || 0) + 1
// Price range facet
if (product.price < 50) facets.priceRanges['0-50']++
else if (product.price < 100) facets.priceRanges['50-100']++
else if (product.price < 500) facets.priceRanges['100-500']++
else facets.priceRanges['500+']++
// Availability facet
facets.availability[product.availability] = (facets.availability[product.availability] || 0) + 1
})
return { results, facets }
}
const { results, facets } = await facetedSearch('laptop')
console.log('Facets:', facets)Search with Highlighting
async function searchWithHighlights(query: string) {
const results = await api.searches.query({
query,
types: ['Article'],
})
// Add highlights (client-side)
return results.map((article) => ({
...article,
highlighted: {
title: highlightText(article.title, query),
description: highlightText(article.description, query),
},
}))
}
function highlightText(text: string, query: string): string {
const regex = new RegExp(`(${query})`, 'gi')
return text.replace(regex, '<mark>$1</mark>')
}Autocomplete Search
async function autocomplete(prefix: string, type: string) {
const results = await api.searches.query({
query: prefix,
types: [type],
filters: {
'name.startsWith': prefix,
},
pagination: {
page: 1,
pageSize: 10,
},
})
return results.map((r) => ({
id: r.$id,
label: r.name,
value: r.$id,
}))
}
// Use it
const suggestions = await autocomplete('acm', 'Customer')
// [
// { id: 'cust-1', label: 'Acme Corp', value: 'cust-1' },
// { id: 'cust-2', label: 'Acme Industries', value: 'cust-2' }
// ]Best Practices
1. Use Specific Queries
// ✅ Good - specific query
await api.searches.query({
query: 'enterprise customers in san francisco',
types: ['Customer'],
filters: { tier: 'enterprise', 'address.city': 'San Francisco' },
})
// ❌ Avoid - too broad
await api.searches.query({
query: 'customers',
})2. Limit Result Sets
// ✅ Good - pagination and limits
await api.searches.query({
query: 'products',
types: ['Product'],
pagination: { page: 1, pageSize: 50 },
})
// ❌ Avoid - fetching everything
await api.searches.query({
query: 'products',
types: ['Product'],
// No pagination - could return thousands
})3. Use Appropriate Search Type
// ✅ Good - vector search for semantic similarity
const embedding = await generateEmbedding('enterprise automation solutions')
const similar = await api.searches.vector(embedding, { types: ['Product'] })
// ✅ Good - text search for exact matches
const exact = await api.searches.query({
query: 'SKU-12345',
types: ['Product'],
filters: { sku: 'SKU-12345' },
})4. Cache Results
const searchCache = new Map()
async function cachedSearch(query: BusinessQuery) {
const cacheKey = JSON.stringify(query)
if (searchCache.has(cacheKey)) {
const { data, timestamp } = searchCache.get(cacheKey)
// Return cached if fresh (5 minutes)
if (Date.now() - timestamp < 5 * 60 * 1000) {
return data
}
}
const results = await api.searches.query(query)
searchCache.set(cacheKey, { data: results, timestamp: Date.now() })
return results
}Next Steps
- Resources API - Learn about searchable resources
- Actions API - Search for actions
- Events API - Search for events