Tavily was built for retrieval pipelines rather than adapted for one: every result carries a relevance score, and a single call can also return an LLM-ready answer synthesized from what it found, so there’s no separate summarization step. NativePort proxies Tavily’s API under one key and balance; this guide covers the /search endpoint, which covers the bulk of what agents built on Tavily actually call.
What you’ll need
- A NativePort API key. Sign up to get a key and $5 in credits.
- Python 3, standard library only — the example below uses
urllib.request, nopip install. - Your key exported as an environment variable, never hardcoded:
export NATIVEPORT_API_KEY="np_..."
What’s admitted
/tavily/<endpoint> forwards to the matching endpoint on api.tavily.com, POST only — the method Tavily’s own action endpoints document:
search— the general-purpose query endpoint this guide covers.extract— pull the full content of one or more known URLs, no search involved.crawl— start from a URL and follow links outward, gathering content per page.map— discover a site’s URL structure without extracting content.
Tavily’s /usage endpoint (account-wide credit and limit metadata) is deliberately not exposed — it’s account-wide billing state, not a search interface, and a per-client key has no business reading the shared account’s usage. Any endpoint outside the four above 404s before it ever reaches Tavily.
Run a search
import json
import os
import urllib.request
GATEWAY = "https://api.nativeport.ai"
API_KEY = os.environ["NATIVEPORT_API_KEY"]
def search(query, **kwargs):
body = json.dumps({"query": query, **kwargs}).encode()
req = urllib.request.Request(f"{GATEWAY}/tavily/search", data=body, method="POST")
req.add_header("Authorization", f"Bearer {API_KEY}")
req.add_header("Content-Type", "application/json")
req.add_header("User-Agent", "nativeport-python-guide/1.0")
with urllib.request.urlopen(req, timeout=30) as resp:
return json.loads(resp.read())
result = search("what changed in the latest Kubernetes release", max_results=5)
for item in result["results"]:
print(f"{item['score']:.2f} {item['title']} {item['url']}")
query is the only required field; everything else is Tavily’s own optional parameter set, forwarded verbatim — max_results (0–20, default 5), topic (general, news, finance), time_range, include_domains/exclude_domains, and the two fields worth calling out on their own:
include_answer:true(or"basic"/"advanced") adds a synthesizedanswerstring to the response, built from the result set Tavily itself just retrieved.include_raw_content:true(or"markdown"/"text") adds each result’s full page content alongside its snippet, so a follow-upextractcall isn’t needed just to get the whole page.
The response is Tavily’s own shape, untouched:
{
"query": "what changed in the latest Kubernetes release",
"answer": "The release adds ...",
"results": [
{
"title": "Kubernetes v1.34 release notes",
"url": "https://kubernetes.io/releases/...",
"content": "This release introduces...",
"score": 0.94
}
],
"response_time": 1.12,
"usage": {"credits": 1},
"request_id": "..."
}
answer is present only when include_answer was set on the request; usage likewise only shows up when include_usage: true is on the request — set it if you want the response itself to confirm what a call cost, since that’s also the same field the gateway bills from (see below).
Errors you’ll actually hit
402 Payment Required: the NativePort balance is at $0. Every request answers this deterministically rather than degrading, so top up and retry.401 Unauthorized: theAuthorization: Bearer <NATIVEPORT_API_KEY>header is missing, malformed, or doesn’t resolve to an account.403 Forbidden: the key is valid but the account isn’t active.404on/tavily/usageor anything outsidesearch/extract/crawl/map: not admitted at the gateway — see “What’s admitted” above.- An empty
resultsarray with a200: not a gateway error — Tavily itself found nothing for that query at the requestedsearch_depth. Retrying withsearch_depth: "advanced"or a broadertime_rangeis a Tavily-side tuning question, not something to retry blindly.
Security
Treat NATIVEPORT_API_KEY like any other credential: environment variable or secret store, never a literal string in source, never logged. Tavily’s own credential never reaches your process — the gateway injects it server-side.
What this costs
The gateway bills from usage.credits when the response carries it (set include_usage: true to guarantee that), falling back to a 1-credit charge if it’s missing — at Tavily’s own per-credit rate, no NativePort markup. A basic-depth search is 1 credit; search_depth: "advanced" is 2; extract, crawl and map price per URL or page processed rather than per call. Current per-credit pricing is on the Tavily provider page. A zero balance answers every request with 402 instead of degrading. Adding credit carries a flat 5.5% fee on top-ups between $10 and $5,000 — never on the calls themselves. Full breakdown: pricing.
Where to go next
- Tavily provider page: current pricing and benchmark standing.
- Web search leaderboard and sourced answers leaderboard: how Tavily’s search and
include_answeroutput score against the rest of the field. - Pricing: the full billing model.
- Evaluating a unified AI platform instead of a native call like this one? The trade-off against Eden AI lays it out.