Can I use the Exa SDK with UpRock?
Yes, for search and get_contents. Create the client with the base URL https://edge.uprock.com/compat/exa and your UpRock API key. Search returns live results from several engines in Exa's format, and get_contents loads each page in a real browser and returns its text. Search results carry a short snippet, not the full page, so call get_contents on the URLs you want in full. find_similar and answer aren't available on UpRock.
Updated · Read as markdown
Change two values
UpRock answers Exa's search and contents requests under https://edge.uprock.com/compat/exa and returns Exa's response shape, so the official SDKs work once you change the base URL and the key. Get a key at uprock.ai/app/api-keys.
Python
# pip install exa-py env: UPROCK_API_KEYimport osfrom exa_py import Exaexa = Exa(api_key=os.environ["UPROCK_API_KEY"], base_url="https://edge.uprock.com/compat/exa")found = exa.search("best espresso machine 2026", num_results=5)for r in found.results: print(r.title, r.url)pages = exa.get_contents([found.results[0].url], text=True)print(pages.results[0].text[:300])TypeScript
// npm i exa-js (Node 18+) env: UPROCK_API_KEYimport Exa from "exa-js";const exa = new Exa(process.env.UPROCK_API_KEY, "https://edge.uprock.com/compat/exa");const found = await exa.search("best espresso machine 2026", { numResults: 5 });for (const r of found.results) console.log(r.title, r.url);const pages = await exa.getContents([found.results[0].url], { text: true });console.log(pages.results[0]?.text?.slice(0, 300));Search takes 5 to 20 seconds. get_contents loads each page in a real browser on an opted-in device, so a fresh page usually takes 10 to 40 seconds.
Which calls and options work
We ran each call below with exa-py 2.28.0 and exa-js 2.28.0 against the live API on 10 Nov 2026.
| Call or option | On UpRock |
|---|---|
search with query and num_results (up to 20) | Works. Each result has title, url, published_date when known, and a short text snippet |
include_domains, exclude_domains, start_published_date | Work |
search_and_contents with text (and max_characters) | Works, but text is the snippet, not the page. Use get_contents for full text |
type, category, highlights, summary | Accepted; type and category don't change the results, and highlights and summary come back empty |
get_contents with a list of URLs and text (and max_characters) | Works. Returns the page's full text and a statuses entry per URL |
find_similar, answer | 404, raised as ValueError in Python and ExaError in TypeScript. Keep Exa for these |
A missing or wrong key returns 401, which exa-py raises as ValueError and exa-js as ExaError: Invalid API key.
We ran both examples above against the live API on 10 Nov 2026. For one Wikipedia page, search with text returned 280 characters and get_contents returned 121,174.
FAQ
Is it the same search as Exa's?
No. Exa searches its own index by meaning; that index is Exa's and can't be copied. UpRock answers the same request with live results from several search engines, in Exa's response format, so your code keeps working but the results differ. type and category are accepted and don't change the results.
Why is the text in search results so short?
Search returns a snippet for each result (about 150 to 400 characters), even when you ask for text. For the full page, pass the URLs to get_contents, which loads each page in a real browser. That's two calls instead of one, and only the pages you need are fetched.
Can I keep my code and change only the URL?
Almost. Put your UpRock key where your Exa key was, and pass the base URL when you create the client (base_url in Python, the second argument in JavaScript). exa-py 2.28.0 and exa-js 2.28.0 don't read the base URL from an environment variable.
How do I see why a page failed?
get_contents lists each URL in statuses. A page that answers 404 comes back as status error with the tag CRAWL_HTTP_404, so the HTTP code isn't lost.
What does it cost?
A search is billed as one web research query, $1 per 1,000 searches by card or USDC. get_contents is billed per page delivered, $0.50 per 1,000 pages.
Other use cases to explore
- Add UpRock next to Exa: what Exa does best, published prices side by side, and fallback code.
- Use the Tavily SDK with UpRock: search and extract through tavily-python or @tavily/core with one changed URL.
- Use the Firecrawl SDK with UpRock: scrape through firecrawl-py or @mendable/firecrawl-js with one changed URL.
- Turn web pages into markdown: clean text from pages that need JavaScript, ready for an LLM.
References
- Exa Python SDK (exa-py), checked 10 Nov 2026
- Exa TypeScript SDK (exa-js), checked 10 Nov 2026
- exa-py on PyPI, checked 10 Nov 2026
- exa-js on npm, checked 10 Nov 2026
- UpRock API spec (POST /compat/exa/search and /compat/exa/contents), checked 10 Nov 2026
- UpRock, everything in one file (API, CLI, MCP, pricing), checked 10 Nov 2026
Get started
Add UpRock in one paste.
Paste this into Claude Code, Codex, Cursor or any agent with a terminal. It reads our docs, sets up the MCP server or CLI, and tells you the cost before it spends anything.
Set up UpRock for me: read https://uprock.ai/agents.md, connect the UpRock MCP server, and run one test crawl. Tell me what it costs before you spend anything.