Hi @secp, welcome to the community!
Great use case — and yes, the Agent API (POST /v1/agent, also accepted at /v1/responses as an alias for OpenAI SDK compatibility) is the right choice here. The Search API returns raw ranked results for you to process in your own pipeline; whereas the Agent API runs the search and generates a grounded, cited answer in one call, which is what a chat assistant needs. I ran your use case against the live API today, so everything below is tested.
First we’ll go over the levers you have, then a concrete recommended setup.
The levers
Presets. Each preset bundles a model, search config, step budget, and system prompt, and Perplexity keeps configurations updated as evals improve (presets guide). The ladder:
fast for single-fact lookups where latency matters most
low for everyday research questions with light multi-step tool use
medium for multi-hop research chaining evidence across many sources
high for exhaustive expert-level analysis
xhigh for open-ended agentic work.
Any parameter you pass alongside a preset overrides just that default, and tools merge per tool — so you can narrow the preset’s web search with a domain filter without disabling anything else it configures.
Instructions (the system prompt). The instructions parameter is re-read on every turn of the agent loop, so grounding rules placed there apply to the first search and every follow-up (prompt guide). One nuance: setting instructions with a preset replaces the preset’s system prompt, it doesn’t append — so keep it focused on your app-specific rules. The two anti-hallucination patterns that matter most:
- give the model explicit permission to say it didn’t find anything (“if searches don’t return relevant results, say so rather than providing speculative information”)
- require disclosure of near-misses (“if you find related but non-matching results — a different tax year, a different company type — state the mismatch before answering”).
Parameters, not prose, for hard constraints. Source, date, and region constraints belong in web_search tool parameters, not in the prompt — parameters are enforced by the search backend on every call, while prose filters are interpreted by the model and may not carry through every turn. The key ones for you:
search_domain_filter (allowlist of up to 20 domains, subdomains included)
user_location (e.g. {"country": "PK"})
search_recency_filter / last_updated_after_filter for restricting to the current Finance Act/tax year.
Structured outputs. response_format: {"type": "json_schema", ...} gives you schema-validated JSON for tax calculators and Pvt Ltd vs SMC comparisons. Make numeric fields nullable and instruct the model to return null for anything unverified — that’s your machine-readable version of “refuse rather than guess”.
Reasoning effort. reasoning: {"effort": "..."} (minimal → max) controls how many thinking tokens the model spends. Compliance lookups are retrieval-bound, not reasoning-bound, so minimal cuts latency and cost substantially with no loss of grounding.
Citations come from the payload, not the prose. The response carries url_citation annotations and structured search_results items — that’s the authoritative source list to render, rather than asking the model to write URLs (models are prone to mistyping them).
A quick aside: the finance_search tool returns structured market data (quotes, financials, earnings) for supported symbols, but coverage is currently strongest for major exchanges — in my tests, Pakistan Stock Exchange tickers (OGDC, LUCK, HBL) did not resolve, and the model automatically fell back to web search, which still answered correctly in PKR. For SECP/FBR regulatory content and PSX-listed companies, web_search with a domain allowlist is the right tool; only add finance_search if you also cover internationally listed companies.
Recommended setup for your use case
{
"preset": "low",
"input": "What documents are required for SECP company incorporation through eZfile?",
"instructions": "You are a corporate compliance assistant for Pakistan. Answer ONLY using the search results provided. Cite sources for every factual claim. If the search results do not contain the answer, say you could not verify it and refer the user to SECP/FBR. If you find related but non-matching results (a different tax year or company type), state the mismatch before answering. Never guess fee amounts, tax rates, or legal requirements.",
"reasoning": {"effort": "minimal"},
"tools": [{
"type": "web_search",
"filters": {"search_domain_filter": ["secp.gov.pk", "fbr.gov.pk", "pakistan.gov.pk"]},
"user_location": {"country": "PK"}
}]
}
Measured results from my test runs with this exact setup: every cited source came from secp.gov.pk or fbr.gov.pk (deep links into the SECP incorporation FAQs and FBR Finance Bill PDFs), responses in 6–8 seconds, and the structured-output variant returned clean, correctly sourced JSON. Route simple factual lookups through this config, and step up to preset: "medium" (dropping the minimal effort override) for multi-part legal comparisons like a full Pvt Ltd vs SMC analysis.
Happy to dig into any of these levers further — reply here with follow-ups as you build.
And to everyone else building on the Agent API: if you’ve taken a different approach to grounding domain-specific assistants or are thinking about this differently please share in this thread. And if you have your own questions or doubts, feel free to let us know as well!