Skip to main content
Perplexity’s Agent API combines models with built-in web search. Requires @stigg/agent-sdk-js 0.7.14 or later.

Set up

Wrap either Perplexity’s own client, Perplexity from @perplexity-ai/perplexity_ai, or an OpenAI client whose baseURL points at Perplexity. The SDK recognizes both from the api.perplexity.ai address and selects the Perplexity recipe automatically.
  • @perplexity-ai/perplexity_ai is ESM only. In a CommonJS project, load it with await import('@perplexity-ai/perplexity_ai').
  • With the OpenAI client, use the base URL with /v1.
  • Streamed calls are metered without extra options. The Agent API sends the usage of a streamed call on its response.completed event, and the SDK reads it from there. A stream that ends before Perplexity sends its usage isn’t reported, and it’s raised as a metering failure.
  • A Perplexity address the SDK does not recognize, such as a proxy in front of Perplexity, is metered with the OpenAI recipe. To meter it as Perplexity, pass the recipe yourself, as shown in Event names.
Perplexity ended support for Sonar Chat Completions on September 27, 2026. Use the Agent API’s responses.create, as shown above.

Event names

A client the SDK detects as Perplexity reports under the OpenAI event names, openai.responses.create and openai.chat.completions.create. Earlier versions of the SDK reported Perplexity calls under these names too, so meters that filter on them keep receiving usage. Each event also has a provider dimension set to perplexity, so a meter can filter Perplexity calls apart from OpenAI’s. If the stiggContext already sets a provider dimension, your value is kept. To report under Perplexity’s own event names, pass the recipe to wrap():
If a meter in Stigg filters on an openai.* name for Perplexity traffic, add the perplexity.* name to it before you switch.

Counting total_cost

Perplexity states the price of each call in dollars, including per-call tool fees such as web_search and fetch_url, which token counts don’t cover. The recipe reports it as total_cost, a whole number, so by default it counts in millionths of a dollar: a call that cost $0.0052 is reported as 5200. If the feature or credit type you meter in Stigg uses a different unit, pass the recipe yourself with unitsPerDollar. For example, to report in hundredths of a cent:
A larger unit rounds each call up to a whole unit, so cheap calls are overcharged. Keep the default unless your pricing requires otherwise.
OpenRouter and LiteLLM report their price as cost, and Perplexity as total_cost. A meter that prices all three needs both names.

perplexityRecipe options

What is reported

Perplexity returns a usage object with the tokens each call consumed and the price it charged. The wrapper reads these and reports them to Stigg as the metrics below. For details, see Perplexity’s Agent API docs. Agent API (responses.create) Chat Completions (chat.completions.create) Cache tokens are counted inside input_tokens. If you price both the input metric and the cache metrics, cached tokens are charged twice. total_tokens includes the other token counts, so price the total or the parts, never both. Each event also includes: When a call is free, total_cost is omitted and the token metrics are still reported. The price breakdown Perplexity returns, such as tool_calls_cost and the per-tool tool_calls_details, is included under the raw. prefix. Every usage field the vendor returns is also included, with a raw. prefix. See How usage is reported.

What is not covered

  • search.create, embeddings, contextualizedEmbeddings, decisions, async.chat.completions, batches and browser.sessions aren’t gated or metered. To meter one, write a recipe of your own.
  • A responses.create with background: true is gated but not metered. Its first response is queued and has no usage, and the later retrieve that returns the usage isn’t wrapped.