Learn how to use the Perplexity Agent API for advanced research workflows. Covers setup, prompt engineering, tool control, cost management, and troubleshooting for multi-step web-grounded research.
This guide covers how to use the Perplexity Agent API for advanced research workflows. It is for developers and power users who want to move beyond simple Q&A and build multi-step, web-grounded research pipelines. You will learn how to configure the API for deep research, write effective prompts, control tool usage, and manage costs.
Before you start, you need the following:
pip install perplexityainpm install @perplexity-ai/perplexity_aiPERPLEXITY_API_KEY.
export PERPLEXITY_API_KEY="your_api_key_here"setx PERPLEXITY_API_KEY "your_api_key_here"The Perplexity API provides three core APIs for different use cases. This guide focuses on the Agent API, but understanding all three helps you choose the right tool.
This is the primary API for web-grounded AI responses. It provides built-in citations and multi-provider model access (OpenAI, Anthropic, Google, xAI). You send a message and get a researched, cited response with conversation context when you need it. You can pick a preset for simplicity or take granular control over model, reasoning, token budgets, and tools. It is best for AI assistants, research and Q&A tools, agentic workflows, and custom AI applications.
This API returns ranked web search results without LLM processing. Use it when you need raw search results for custom AI workflows, data collection, or search integration. It is best for custom AI pipelines, data collection, and search integration.
This API generates high-quality text embeddings for semantic search and RAG. Use it when you need semantic similarity between texts, are building RAG pipelines, or need to cluster, classify, or compare text without generating a response. It is best for semantic search, RAG applications, text classification, and recommendation systems.
The Agent API runs a bounded multi-turn loop. On each turn, the model can call a tool (such as web_search), read the result, and decide whether to continue or answer. This loop is what makes it suitable for advanced research workflows. Prompts that work well with single-shot LLMs often underperform here because the same text shapes tool selection, search query generation, and the final response together.
Two parameters drive most of the prompt design:
instructions: Sets the role, tone, formatting, and grounding rules that apply regardless of the user's question.input: Holds the actual question. It also seeds the first search query, so specificity here directly improves retrieval.For hard constraints on retrieval (allowed domains, date ranges, region) and on the loop itself (max steps), use request parameters rather than prose.
Here is how to make your first API call using the Agent API with a preset. The example uses the low preset, which is designed for fast, focused research.
from perplexity import Perplexity
# Initialize the client (uses PERPLEXITY_API_KEY environment variable)
client = Perplexity()
# Make the API call with a preset
response = client.responses.create(
preset="low",
input="Summarize the core findings of the original 'Attention Is All You Need' transformer paper and explain why it changed NLP.",
)
# Print the AI's response
print(response.output_text)
import Perplexity from '@perplexity-ai/perplexity_ai';
// Initialize the client (uses PERPLEXITY_API_KEY environment variable)
const client = new Perplexity();
// Make the API call with a preset
const response = await client.responses.create({
preset: "low",
input: "Summarize the core findings of the original 'Attention Is All You Need' transformer paper and explain why it changed NLP.",
});
// Print the AI's response
console.log(response.output_text);
curl https://api.perplexity.ai/v1/agent \
-H "Authorization: Bearer $PERPLEXITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"preset": "low",
"input": "Summarize the core findings of the original 'Attention Is All You Need' transformer paper and explain why it changed NLP."
}' | jq
The response includes structured output with tool usage and citations. Here is an example response object with key fields explained:
{
"id": "resp_1234567890",
"created_at": 1756485272,
"model": "openai/gpt-5.1",
"object": "response",
"status": "completed",
"output": [
{
"type": "message",
"id": "msg_abc123",
"role": "assistant",
"status": "completed",
"content": [
{
"type": "output_text",
"text": "Recent developments in AI include...",
"annotations": [
{
"type": "citation",
"url": "https://example.com/article1"
}
],
"logprobs": []
}
]
}
],
"usage": {
"input_tokens": 3681,
"output_tokens": 780,
"total_tokens": 4461,
"cost": {
"currency": "USD",
"input_cost": 0.0046,
"output_cost": 0.0078,
"tool_calls_cost": 0.0025,
"total_cost": 0.0149
},
"input_tokens_details": {
"cached_tokens": 0
},
"output_tokens_details": {
"reasoning_tokens": 0
},
"tool_calls_details": {
"search_web": {
"invocation": 1
}
}
},
"tools": [
{ "type": "web_search" },
{ "type": "fetch_url" }
],
"tool_choice": "auto",
"temperature": 1,
"top_p": 1,
"frequency_penalty": 0,
"presence_penalty": 0,
"max_output_tokens": null,
"max_tool_calls": null,
"parallel_tool_calls": true,
"truncation": "disabled",
"store": true,
"service_tier": "default",
"instructions": "## Abstract...",
"background": false,
"completed_at": 1756485272,
"error": null,
"incomplete_details": null,
"metadata": {},
"previous_response_id": null,
"prompt_cache_key": null,
"reasoning": null,
"safety_identifier": null,
"user": null
}
Key fields to note:
id: The unique identifier for the response.model: The model used. In this case, it is openai/gpt-5.1.output: An array of output items. Each item can be a message or a tool call result. The content array contains the actual text and annotations (citations).usage: Detailed token and cost breakdown. input_tokens are the tokens in your request. output_tokens are the tokens generated in the response. tool_calls_cost is the cost of any tool invocations.tools: The tools available to the model. By default, web_search and fetch_url are available.tool_choice: How the model decides to use tools. auto means the model decides. You can set it to none to disable tools, or required to force a tool call.temperature: Controls randomness. 1 is the default.top_p: Nucleus sampling parameter. 1 means no filtering.frequency_penalty and presence_penalty: Penalties for token repetition and novelty.max_output_tokens: The maximum number of tokens the model can generate. null means no limit.max_tool_calls: The maximum number of tool calls the model can make. null means no limit.parallel_tool_calls: Whether the model can make multiple tool calls in parallel.truncation: How the model handles requests that exceed the context window. disabled means the request will fail if it is too long.store: Whether the response is stored for later retrieval.service_tier: The service tier for the request.instructions: The system prompt used for the request.background: Whether the response was generated in the background.
The Prompt Guide from Perplexity provides detailed advice on how to structure prompts for the Agent API. The key insight is that the same text shapes tool selection, search query generation, and the final response. Therefore, you must be deliberate about what goes into instructions versus input.
instructions ParameterUse the instructions parameter for role, tone, language, formatting, and grounding rules. Instructions apply on every turn of the agent loop, so put things here that hold regardless of the user's question.
Important: Setting instructions with a preset replaces the preset's system prompt. It does not append. Each preset (fast, low, medium) already covers tool-call discipline, query construction, citation, and formatting. You should only override the preset's prompt when app-specific behavior is needed. Without a preset, instructions is the only system prompt the model sees.
Example instructions block:
You are a financial analyst writing for retail investors.
Rules:
- Aim for brief sentences and paragraphs.
- Define jargon the first time you use it.
- Prefer concrete numbers over vague qualifiers ("up 12% YoY" not "growing strongly").
Grounding rules:
- Cite sources inline by domain, e.g. (reuters.com). Do not write full URLs.
- If searches return no relevant results after trying alternative phrasings, or if the only matches are off-topic (different company, different fiscal year, etc.), say so explicitly rather than substituting related results.
Keep instructions focused. They are re-read on every turn of the agent loop, so bloat compounds across tool calls. If your block is growing long, check whether parts of it would be better expressed as request parameters:
response_format with a JSON schema for machine-readable output.web_search filters for retrieval constraints.input.Built-in tools like web_search and fetch_url are tuned to work well without prompt-side guidance. You do not need to describe what they do, when to call them, or how to construct queries. Adjust tool-call count with the max_steps parameter and search constraints with web_search filters.
If you are using custom instructions and want to nudge how the model uses built-in tools, you can reference them there. For custom function tools you define yourself, the model relies on the description and parameter schema you provide, so make those as clear as you can. You can reinforce the tool's role in instructions if the description alone is not enough to steer behavior.
input ParameterUse the input parameter for the actual query you want answered. Input strongly shapes search behavior, so descriptive and specific phrasing directly improves retrieval. Vague inputs lead to vague searches.
Example user prompt:
What are the best sushi restaurants in the world currently?
Here is a complete example that uses both instructions and input:
Python:
from perplexity import Perplexity
client = Perplexity()
response = client.responses.create(
preset="low",
input="Explain how hosted LLM API pricing is typically structured: input vs output tokens, context window limits, and the implication for long-document workloads.",
instructions="You are a concise, well-researched assistant. If searches still return no relevant results after trying alternative phrasings, say so explicitly rather than guessing."
)
print(response.output_text)
TypeScript:
import Perplexity from '@perplexity-ai/perplexity_ai';
const client = new Perplexity();
const response = await client.responses.create({
preset: "low",
input: "Explain how hosted LLM API pricing is typically structured: input vs output tokens, context window limits, and the implication for long-document workloads.",
instructions: "You are a concise, well-researched assistant. If searches still return no relevant results after trying alternative phrasings, say so explicitly rather than guessing."
});
console.log(response.output_text);
cURL:
curl https://api.perplexity.ai/v1/agent \
-H "Authorization: Bearer $PERPLEXITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"preset": "low",
"input": "Explain how hosted LLM API pricing is typically structured: input vs output tokens, context window limits, and the implication for long-document workloads.",
"instructions": "You are a concise, well-researched assistant. If searches still return no relevant results after trying alternative phrasings, say so explicitly rather than guessing."
}' | jq

If you need raw search results without LLM processing, use the Search API. This is useful for building custom AI workflows with your own models or for data collection.
Python:
from perplexity import Perplexity
client = Perplexity()
search = client.search.create(
query="SpaceX Starship architecture and orbital test milestones",
max_results=5
)
for result in search.results:
print(f"{result.title}: {result.url}")
TypeScript:
import Perplexity from '@perplexity-ai/perplexity_ai';
const client = new Perplexity();
const search = await client.search.create({
query: "SpaceX Starship architecture and orbital test milestones",
max_results: 5
});
for (const result of search.results) {
console.log(`${result.title}: ${result.url}`);
}
cURL:
curl -X POST 'https://api.perplexity.ai/search' \
-H "Authorization: Bearer $PERPLEXITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "SpaceX Starship architecture and orbital test milestones",
"max_results": 5
}' | jq
The response includes ranked search results with titles, URLs, and snippets:
{
"results": [
{
"title": "SpaceX Starship Flight 10: Full Mission Recap",
"url": "https://example.com/starship-flight-10",
"snippet": "SpaceX successfully completed its tenth Starship test flight, achieving full booster recovery and orbital insertion...",
"date": "2026-02-20",
"last_updated": "2026-02-21"
},
{
"title": "Starship Launch Manifest: 2026 Schedule and Updates",
"url": "https://example.com/starship-2026-schedule",
"snippet": "SpaceX has announced an ambitious 2026 launch manifest for Starship, targeting monthly flights and the first cargo mission...",
"date": "2026-01-15",
"last_updated": "2026-03-01"
}
],
"query_info": {
"query": "SpaceX Starship architecture and orbital test milestones",
"normalized_query": "spacex starship launch updates 2026"
}
}
The Agent API runs a bounded multi-turn loop. You can control the loop with these parameters:
max_steps: The maximum number of tool calls the agent can make. This is a key parameter for controlling cost and depth of research. A higher value allows the agent to perform more searches and gather more information before answering.max_tool_calls: The maximum number of tool calls the model can make in a single turn.parallel_tool_calls: When set to true, the model can make multiple tool calls in parallel, which can speed up research.Presets are pre-configured system prompts that control the agent's behavior. The available presets are:
fast: Optimized for speed. The agent makes fewer tool calls and provides concise answers.low: A balanced preset for general research. It is the default and is suitable for most use cases.medium: A more thorough preset that allows more tool calls and provides more detailed answers.When you use a preset, you do not need to provide instructions unless you want to override the preset's behavior. If you do provide instructions, it replaces the preset's system prompt entirely.
The Perplexity API uses pay-as-you-go pricing. The cost of a request is determined by the number of input tokens, output tokens, and tool calls. The usage object in the response provides a detailed breakdown:
"usage": {
"input_tokens": 3681,
"output_tokens": 780,
"total_tokens": 4461,
"cost": {
"currency": "USD",
"input_cost": 0.0046,
"output_cost": 0.0078,
"tool_calls_cost": 0.0025,
"total_cost": 0.0149
},
"input_tokens_details": {
"cached_tokens": 0
},
"output_tokens_details": {
"reasoning_tokens": 0
},
"tool_calls_details": {
"search_web": {
"invocation": 1
}
}
}
To manage costs:
input. Vague inputs lead to more searches and higher costs.max_steps. A lower value means fewer tool calls and lower cost.max_output_tokens. Limit the length of the response to control output token costs.Perplexity's API supports the OpenAI Chat Completions format. You can use OpenAI client libraries by pointing to the Perplexity endpoint. See the OpenAI Compatibility Guide for examples.
If the agent reports that it cannot find relevant results, it may be because:
input to be more specific.According to the Prompt Guide, you can instruct the agent to handle this gracefully by adding a rule to your instructions: "If searches return no relevant results after trying alternative phrasings, say so explicitly rather than substituting related results."
If you get an error about the request exceeding the context window, you need to reduce the size of your input. This can happen if you include a very long document in the input or if your conversation history is too long. Solutions include:
truncation parameter to auto to allow the API to truncate the input. However, this may lose important context.If your costs are higher than expected, check the following:
usage object in the response. Are you using a lot of input tokens? Are you making many tool calls?medium preset will make more tool calls and generate longer responses than the low preset.max_steps: Are you setting a high max_steps value? Each tool call adds to the cost.max_output_tokens: Are you setting a high max_output_tokens value? Long responses cost more.To deepen your understanding of the Perplexity API and advanced research workflows, explore the following topics from the documentation:
Learn how to choose between Perplexity's online (web-grounded) and chat (non-search) models when using the Agent API. Covers setup, prompt design, tool configuration, and cost optimization.
Everything you need to know about using Perplexity AI for research and information retrieval
Step-by-step guide to integrating the Perplexity API into your applications
How to use Perplexity AI for rigorous academic research with proper citations
Install, configure, and master the Perplexity Chrome extension for instant AI-powered search
Set up and manage Perplexity Spaces for collaborative team research projects
Workflows from the Neura Market marketplace related to this Perplexity resource