Skip to content

Search: Integration patterns

This page collects the most common ways teams integrate microlink.search into production systems. Each pattern includes the surface choice, the query strategy, and the expansion depth that makes sense for the workflow.

Agent tool calling

Expose microlink.search(query, options) as a tool and let the model decide when to search, which surface to use, and when to expand:
import createClient from 'microlink.io'

const microlink = createClient({
  apiKey: process.env.MICROLINK_API_KEY
})

const searchTool = {
  name: 'web_search',
  description: 'Search the web for current information. Returns structured results.',
  parameters: {
    query: { type: 'string', description: 'The search query' },
    type: {
      type: 'string',
      enum: ['search', 'news', 'scholar', 'shopping', 'images', 'places'],
      description: 'Which search surface to use'
    }
  },
  execute: async ({ query, type = 'search' }) => {
    const page = await microlink.search(query, { type })
    return page.results.map(r => ({
      title: r.title,
      url: r.url,
      description: r.description
    }))
  }
}
The key insight: keep the tool result lightweight. Return title, url, and description from the first call. If the model needs full page content, expose the markdown method as a second tool.

Separate expansion tool

const expandTool = {
  name: 'read_page',
  description: 'Fetch the full content of a URL as Markdown.',
  parameters: {
    url: { type: 'string', description: 'URL to read' }
  },
  execute: ({ url }) => microlink.markdown(url)
}
This two-tool pattern gives the model explicit control over cost and depth.

RAG source expansion

Start with search to find relevant sources, then expand the best matches into your retrieval pipeline:
const page = await microlink.search('site:openai.com function calling guide')

const documents = await Promise.all(
  page.results.slice(0, 3).map(async result => ({
    title: result.title,
    url: result.url,
    content: await result.markdown()
  }))
)
For broader coverage, combine autocomplete to discover related queries, then search each one:
const suggestions = await microlink.search('how to fine tune', { type: 'autocomplete' })
const queries = suggestions.results.slice(0, 5).map(s => s.value)

const allResults = []
for (const query of queries) {
  const page = await microlink.search(query)
  allResults.push(...page.results)
}

When to paginate

Pagination adds recall at the cost of latency and API calls. Paginate when:
  • your query is broad and the first page may miss relevant sources
  • you need comprehensive coverage for competitive analysis or literature reviews
  • the model's confidence is still low after the first page
let page = await microlink.search('vector database benchmarks')
const sources = [...page.results]

if (sources.length < 5) {
  page = await page.next()
  sources.push(...page.results)
}

News monitoring

Use news with period to build monitoring and alerting workflows:
const page = await microlink.search('data breach', {
  type: 'news',
  period: 'day'
})

const alerts = page.results.map(result => ({
  title: result.title,
  publisher: result.publisher,
  date: result.date,
  url: result.url
}))
For multi-region monitoring, run parallel queries with different location values:
const regions = ['us', 'gb', 'de', 'jp']

const results = await Promise.all(
  regions.map(async location => {
    const page = await microlink.search('regulatory update', {
      type: 'news',
      location,
      period: 'week'
    })
    return { location, results: page.results }
  })
)

Entity and local lookup

Use places or maps when your workflow needs business or geographic context:
const page = await microlink.search('coworking spaces barcelona', { type: 'places' })

const locations = page.results.map(result => ({
  name: result.title,
  address: result.address,
  coordinates: {
    lat: result.latitude,
    lng: result.longitude
  },
  rating: result.rating
}))
Use maps instead of places when you also need opening hours, price levels, or Google Place IDs for downstream API calls:
const page = await microlink.search('restaurants near times square', { type: 'maps' })

page.results[0].opening?.hours
// { Monday: '11:00 AM – 10:00 PM', ... }

page.results[0].place?.id
// 'ChIJgTwKgJcpQg0RaSKMYcHeNsQ'

Academic research

Use scholar to build literature review or citation analysis workflows:
const page = await microlink.search('retrieval augmented generation', { type: 'scholar' })

const papers = page.results
  .sort((a, b) => b.citations - a.citations)
  .slice(0, 5)
  .map(result => ({
    title: result.title,
    year: result.year,
    citations: result.citations,
    pdf: result.pdf?.url,
    url: result.url
  }))
For research agents, combine scholar with content expansion to fetch full papers:
const page = await microlink.search('transformer architecture', { type: 'scholar' })

for (const result of page.results.slice(0, 3)) {
  if (result.pdf?.url) {
    console.log(`PDF available: ${result.pdf.url}`)
  } else {
    const content = await result.markdown()
    console.log(`Abstract page: ${content.slice(0, 500)}`)
  }
}

Product intelligence

Use shopping for price monitoring, competitive analysis, and product comparison:
const page = await microlink.search('mechanical keyboard', { type: 'shopping' })

const products = page.results.map(result => ({
  name: result.title,
  price: result.price.amount,
  currency: result.price.symbol,
  merchant: result.publisher,
  rating: result.rating?.score
}))
Prices are already parsed into numeric values, so you can sort, filter, and aggregate without string processing:
const affordable = products.filter(p => p.price < 150)
const avgPrice = products.reduce((sum, p) => sum + p.price, 0) / products.length

Vertical routing

Instead of a single search tool, route the query to the most appropriate surface based on intent:
const route = (intent) => {
  const routes = {
    current_events: 'news',
    product_lookup: 'shopping',
    academic_paper: 'scholar',
    local_business: 'places',
    general: 'search'
  }
  return routes[intent] || 'search'
}

const page = await microlink.search(query, { type: route(detectedIntent) })
This reduces noise in the results and gives the downstream consumer exactly the fields it needs.

Query expansion

Use autocomplete to discover related queries before running heavier searches:
const suggestions = await microlink.search('how to deploy', { type: 'autocomplete' })

console.log(suggestions.results.map(s => s.value))
// [
//   'how to deploy a website',
//   'how to deploy to production',
//   'how to deploy docker container',
//   ...
// ]
This is useful for:
  • Coverage: expand a vague query into specific variants before searching
  • Demand modeling: understand what people are actually searching for
  • Prompt seeding: generate suggestions for search UIs or chat interfaces

See also

  • Search — install the SDK and make your first query.
  • Web Search, News, Scholar, and more — field reference for each surface.
  • Content expansion — the two-step retrieval model and when to use .html() vs .markdown().