
TypeScript Patterns for Prismfy Search API Integration for cleaner search integrations.
Prismfy Team
May 7, 2026
This tutorial focuses on a production-friendly search integration pattern, so developers can add a web search tool, fresh public evidence, and better routing logic without overbuilding retrieval.
A lot of client code becomes harder to maintain because it tries to do too much. A search client should not become a mini-framework. It should take a query, call the API, and return a small evidence set that the rest of the application can use.
That is especially true for AI agents. The agent layer already has enough moving parts. The search client should stay boring: one request in, one usable response out.
Prismfy fits that shape because POST /v1/search is a straightforward synchronous call. That makes it easy to wrap in TypeScript without hiding the important parts.
As AI apps move into production, teams care more about observability and source quality. It is no longer enough to say the model “looked it up.” You need to know what it searched, what it found, and whether the answer was based on fresh evidence.
A thin TypeScript client makes that easier. You can log the query, inspect the returned URLs, and pass a small evidence bundle into the model prompt or workflow branch.
The clean pattern is:
search method that calls POST /v1/search.That separation keeps the client reusable. A support agent, a research tool, and a workflow action can all share the same search method without forcing the same behavior.
This TypeScript example wraps Prismfy with a compact client and a helper that returns prompt-ready evidence.
type PrismfyResult = {
title: string
url: string
content?: string
engine?: string
}
type PrismfySearchResponse = {
results: PrismfyResult[]
cached?: boolean
query?: string
meta?: {
page?: number
domain?: string | null
timeRange?: string | null
}
}
export class PrismfyClient {
constructor(
private readonly apiKey = process.env.PRISMFY_API_KEY || "",
private readonly baseUrl = process.env.PRISMFY_BASE_URL || "https://api.prismfy.io",
) {
if (!this.apiKey) {
throw new Error("PRISMFY_API_KEY is required")
}
}
async search(query: string, options: { domain?: string; timeRange?: string } = {}) {
const body: Record<string, unknown> = {
query,
page: 1,
timeRange: options.timeRange ?? "week",
}
if (options.domain) {
body.domain = options.domain
}
const response = await fetch(`${this.baseUrl}/v1/search`, {
method: "POST",
headers: {
Authorization: `Bearer ${this.apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
})
if (!response.ok) {
throw new Error(`Prismfy search failed with ${response.status}`)
}
return (await response.json()) as PrismfySearchResponse
}
async searchEvidence(query: string, options: { domain?: string; timeRange?: string } = {}) {
const data = await this.search(query, options)
return {
cached: data.cached ?? false,
evidence: (data.results ?? []).slice(0, 5).map((item) => ({
title: item.title,
url: item.url,
snippet: (item.content ?? "").slice(0, 200),
engine: item.engine,
})),
}
}
}
This wrapper keeps the API boundary visible. It also makes it easy to swap the caller logic without rewriting the search code. If the agent wants shorter snippets, change the formatter. If the agent wants a narrower search, change the options passed into search.
You can also use the client directly in a route handler or server action. The same search method works whether the caller is a model tool, a UI button, or a background job.
Do not build a client that tries to decide the whole workflow. The client should not guess whether the question needs live search. That decision belongs to the application or agent layer.
Keep the defaults sensible but explicit. A modest freshness window is usually better than a broad evergreen search, but the caller should still be able to override it when the task needs it. The same applies to domain. If one site owns the truth, let the caller say so.
Use the returned cached flag for logging and operational insight. It is useful to know whether the answer came from a cached request, but it should not become a substitute for source evaluation.
The safest output shape is short and structured. You want just enough data to answer the question or justify a follow-up search.
Prismfy fits TypeScript integration because the API is direct and predictable. That makes it easy to wrap without introducing extra layers that hide the real request.
For agent builders, that predictability matters. It means your logs can show the query, your model can inspect the evidence, and your application can keep control over how the search result is used.
A retriever is useful for indexed material you control. A web search API helps when the question depends on fresh public evidence, new pages, current docs, or time-sensitive changes that may not exist in your retriever yet.
Keep the integration narrow: route only freshness-sensitive questions to Prismfy, pass a compact evidence set back to the framework, and ask the model to answer from sources instead of memory.
Create a Prismfy key, test POST /v1/search, and wire the search step into the workflow you care about first.
Try it free
Free tier includes 3,000 requests per 30 days. No credit card required.