Build a native Perplexity Sonar Pro example that prints a short researched answer, its finish reason and returned source metadata. Keep the key in your environment and inspect the result before extending the program.

What you'll build

The program asks why an HTTP conditional request can avoid resending an unchanged resource. It prints the answer, finish reason, citations and usage when available. This fixed documentation question needs no private information and is short enough to review against its returned sources.

This example uses the official perplexityai package and its native client.chat.completions.create method with the explicit sonar-pro model. The official Sonar quickstart demonstrates that combination. The Sonar Pro model record and calculator below identify the same model, so the request and estimate can be compared directly.

A successful run establishes the request path and output handling. It does not prove every claim in the generated answer. Open the relevant source references, confirm that the explanation matches them and note any uncertainty. Keep that review as part of the example’s acceptance rather than judging the response only by whether it sounds plausible.

Prerequisites

Follow Perplexity project and key setup and configure PERPLEXITY_API_KEY in the environment that will run the script. Confirm usable project credit and review Perplexity billing by product before executing it. The program does not query your private balance or establish free entitlement.

Use a separate Python environment for the example. This keeps dependency changes and interpreter selection clear, especially if your editor and terminal use different environments. Record the installed native client version after you establish a passing run so a later change can be reproduced.

Begin with the safe documentation question in the example. It needs no personal data or confidential source files. When you replace it with your own workload, choose input you may send to the provider and define the expected artifact. Include a missing-information case before presenting the output as a reliable research feature.

The script also checks for a missing PERPLEXITY_API_KEY before constructing a request. If it reports a missing setting, restore the variable through protected configuration and restart the process where needed. This additional local check is separate from the wrong-model API test below.

Install SDK

python -m pip install perplexityai

Install the package with the interpreter that will execute the script. The import is perplexity, while the package name is perplexityai. The native Sonar quickstart documents both the SDK interface and its environment-variable convention. Do not name your script perplexity.py, because that would shadow the installed package.

Configure the key through a secret manager or your environment tooling without copying it into the source. A local secret file should remain outside version control. If the running process loads settings only at startup, restart it after changing the configuration. Check presence without printing the value when diagnosing a setup issue.

Full script

import json
import os
import sys
import perplexity
from perplexity import Perplexity

key = os.environ.get("PERPLEXITY_API_KEY", "").strip()
if not key:
    raise SystemExit("Set PERPLEXITY_API_KEY before running this script.")

model = "ai-api-hub-invalid-model" if "--bad-model" in sys.argv else "sonar-pro"
prompt = "Explain why an HTTP conditional request can avoid resending an unchanged resource in one sentence."

try:
    with Perplexity(api_key=key, timeout=30.0, max_retries=0) as client:
        response = client.chat.completions.create(
            model=model,
            messages=[{"role": "user", "content": prompt}],
            max_tokens=256,
            temperature=0,
            stream=False,
        )
except perplexity.APIConnectionError:
    raise SystemExit("Connection failed. Check connectivity before retrying.")
except perplexity.APIStatusError as exc:
    print(f"HTTP {exc.status_code}")
    print(exc.response.text)
    raise SystemExit(1)

if not response.choices:
    raise SystemExit("No completion choice was returned.")
choice = response.choices[0]
answer = choice.message.content or ""
if not answer.strip():
    raise SystemExit("No final answer text was returned.")
data = response.model_dump(mode="json")
print("ANSWER")
print(answer)
print("FINISH_REASON", choice.finish_reason)
print("CITATIONS", json.dumps(data.get("citations") or [], ensure_ascii=False))
print("SEARCH_RESULTS", json.dumps(data.get("search_results") or [], ensure_ascii=False))
if data.get("usage") is not None:
    print("USAGE", json.dumps(data["usage"], ensure_ascii=False))
if choice.finish_reason != "stop":
    raise SystemExit("The returned completion did not finish normally.")

Save this as perplexity_first_call.py and run it with the prepared interpreter. The timeout is an example application setting rather than a published service limit. Automatic client retries are disabled here so the initial request path is explicit; the official SDK configuration guide describes how to adjust that policy later. Official Perplexity documentation.

The exception paths print a connection category or the actual HTTP status and response body. The safe fixture contains no private input; remove secrets and private content before sharing a real error transcript. On success, the program reads the completion choice and the response’s citation and search-result fields, matching the documented Sonar response structure. It never substitutes a fabricated source for a missing field.

Expected output

ANSWER
<actual generated answer pending authenticated capture>
FINISH_REASON <actual finish reason>
CITATIONS <actual returned citation array>
SEARCH_RESULTS <actual returned search-result array>
USAGE <actual usage object, when returned>

The labels above are literal strings in the program; the angle-bracket fields are placeholders. This structural illustration is not a captured successful run. A complete authenticated output transcript is still pending. Check that the eventual answer explains the requested HTTP behavior, then inspect whether its actual references support the explanation.

If no citations or search results appear, do not invent evidence links from the answer’s wording. Inspect the actual response and distinguish a supported explanation from one with missing evidence. A source URL alone is not enough: open it, find the relevant passage and check that the answer preserves its meaning.

Review the finish reason as well as the text. The script rejects an empty answer and a finish reason other than stop. Its short output ceiling is an example setting, not a service limit. If it truncates a response, preserve the incomplete outcome and review the request before running another attempt. Do not present partial research as a completed result.

One deliberate error and its fix

Run the same safe fixture with an intentionally invalid model identifier. Keep the credential configured so the request can reach model validation; a missing key tests a different stage.

python perplexity_first_call.py --bad-model

The branch supplies ai-api-hub-invalid-model to the same Sonar method and prints the actual HTTP status and response body if rejected. Do not retry that unchanged request. Remove --bad-model to restore sonar-pro, then inspect the ordinary request independently if it also fails.

Only the model identifier changes in this exercise. The client, prompt, output setting and timeout remain the same, which helps distinguish a model-selection problem from unrelated changes. No preset or fallback model is sent. The Sonar quickstart shows the explicit model-selection field used by the ordinary request.

Preserve the returned code and message rather than assigning a guessed error type. Authentication, funding and request validation can fail at different stages. Official error-handling guidance.

A literal wrong-model response has not yet been captured for this tutorial. The linked official reference does not supply an exact response for this fixture, so no invented error envelope is shown. Run the command with an authorized API credential and retain its actual status and body to complete this verification.

What this request costs

Interactive tool

Estimate your API costs

Your text and estimates stay in this browser. No API requests are sent to model providers.

Loading verified model records…

The calculator is preset to the exact sonar-pro model used by this script. Enter the prompt and completion token counts actually returned by your run. This is a model-token estimate: include any separately applicable request or search charge when reconciling a Sonar bill, and do not treat a component absent from the calculator as free. Check the official pricing categories and returned usage before relying on a total.

When extending the program, estimate the entire accepted task: any additional research, follow-up or correction calls belong in the workload. Keep returned usage with a safe task identifier and compare it with project activity after the experiment. That evidence is more useful than extrapolating a monthly total from the length of the final paragraph.

Next steps

Turn the returned citation and search-result fields into a source display after checking their actual values. Keep citation order and answer references associated with the same response. Add a fixture where the requested fact is absent and verify that the application preserves uncertainty. Validate any structured record and its supporting evidence before accepting it.

If you later move this example to the Agent API, follow the official migration guide and update the request method, output parser and cost assumptions together. The completion-choice parser shown here belongs to this Sonar request. Preserve a known fixture while evaluating the new interface instead of assuming the two response objects are interchangeable.

Review Perplexity product admission rules before adding workers and model and preset selection before changing configuration. Return to the Perplexity API overview for current product context. A useful next milestone is a representative researched artifact your application can validate, account for and recover when it fails.

Frequently asked questions

Which Perplexity interface does this script use?
It uses the official native Python SDK’s Sonar chat-completions method with the explicit sonar-pro model, as documented in the linked Sonar quickstart.
What is the Python package name?
Install perplexityai and import from perplexity. Give the example a different filename so it does not shadow the installed package.
Will the generated answer match the example exactly?
The program uses a fixed prompt and generation settings, but wording, retrieved sources and reported usage can still vary. The displayed output remains a clearly marked structural illustration pending a real capture.
What does the wrong-model exercise verify?
It sends an intentionally invalid identifier through the same Sonar request method and exposes the actual rejection. An authentication or funding error must not be relabeled a wrong-model result.
Does the calculator select the model in this script?
Yes. It is preset to the published Sonar Pro model record. Token cost may not include every request or search component, so reconcile those separately with official pricing and returned usage.
Should I publish every returned answer automatically?
Check the finish reason, required structure and source support first. Preserve missing evidence or incomplete output as a distinct outcome rather than accepting every response.

Sources

Last verified · Source ↗