langchain-reefapi
LangChain tools for ReefAPI. ReefAPI is one API key for 600+ site-specific, live web-data APIs ("engines"): Amazon, eBay, Zillow, Reddit, Google Maps, Trustpilot, LinkedIn Jobs, Booking and hundreds more. Each engine fetches its website in real time and returns JSON. Failed calls are not charged.
This package gives a LangChain agent three tools that cover the whole catalog:
| Tool | Name the model sees | What it does | Key needed |
|---|---|---|---|
ReefAPISearchEngines |
reefapi_search_engines |
Find the engine for a website or a data need (keyword search over the live catalog) | no |
ReefAPIGetSchema |
reefapi_get_schema |
An engine's actions, or one action's parameters, allowed values and example | no |
ReefAPICall |
reefapi_call |
Run engine / action with params, return the response data as JSON |
yes |
ReefAPIToolkit returns all three with one shared configuration. The tools are built on the official
Python SDK, reefapi, so retries for retryable errors and the
client-side rate limit (30 requests per 3 seconds per key) come with them.
Install
pip install -U langchain-reefapi
Python 3.10+. Get an API key at reefapi.com and set it in the environment:
export REEFAPI_API_KEY="your-key" # REEFAPI_KEY works too
or pass it to the constructor: ReefAPIToolkit(api_key="..."). The key is held as a SecretStr and
is left out of repr(), logs and serialized tool state. The two discovery tools work without a key.
Example 1: an agent that picks the engine itself
pip install -U langchain-reefapi "langchain[anthropic]"
from langchain.agents import create_agent
from langchain_reefapi import ReefAPIToolkit
agent = create_agent(
model="claude-sonnet-4-6", # any chat model with tool calling
tools=ReefAPIToolkit().get_tools(),
system_prompt="Use the ReefAPI tools for live data from websites. "
"Find the engine first, read its schema, then call it.",
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What are the 3 cheapest iPhone 13 Pro listings on eBay right now?"}]}
)
print(result["messages"][-1].content)
A typical run: the model calls reefapi_search_engines (for example with "ebay listings"), then
reefapi_get_schema("ebay", "search"), then reefapi_call("ebay", "search", {"query": "iphone 13 pro", "sort": "price_low"}).
If it sends a bad parameter, the tool returns the error text (code, whether a retry can help,
request id) to the model instead of raising, and the model can correct itself. That failed call is
not charged.
Example 2: the tools one by one
import json
from langchain_reefapi import ReefAPICall, ReefAPIGetSchema, ReefAPISearchEngines
# 1. which engine? (no key needed)
found = json.loads(ReefAPISearchEngines().invoke({"query": "sold prices on ebay", "max_results": 3}))
print([e["engine"] for e in found["engines"]]) # ['ebay', 'cardladder', 'ebay-sold']
# 2. which parameters? (no key needed)
schema = json.loads(ReefAPIGetSchema().invoke({"engine": "ebay", "action": "search"}))
print(schema["required_params"], schema["example_params"]) # ['query'] {'query': 'iphone 13 pro'}
# 3. call it (uses your key)
data = json.loads(ReefAPICall().invoke(
{"engine": "ebay", "action": "search", "params": {"query": "iphone 13 pro", "max_results": 5}}
))
for item in data["results"]:
print(item["title"], item["price"]["value"], item["price"].get("currency"))
Without action, reefapi_get_schema lists every action of the engine. The same information is on
each engine's docs page, for example reefapi.com/docs/ebay.
Example 3: full data as a tool artifact, sync or async
When the tool runs from a tool call (which is how agents run it), it returns a ToolMessage. The
content is what the model reads: the response data as JSON, cut at max_output_chars
(default 50,000) so one large page of results cannot flood the context. The artifact holds the full,
uncut {"data": ..., "meta": ...} for your own code.
import asyncio
from langchain_reefapi import ReefAPICall
call = ReefAPICall(max_output_chars=4000)
tool_call = {
"type": "tool_call",
"id": "call-1",
"name": "reefapi_call",
"args": {"engine": "trustpilot", "action": "company/reviews",
"params": {"company": "amazon.com", "maxReviews": 20}},
}
msg = call.invoke(tool_call)
print(msg.content[:300]) # what the model sees (at most 4,000 characters)
company = msg.artifact["data"]["results"][0]["company"]
print(company["name"], company.get("trust_score"))
print(msg.artifact["meta"]["request_id"]) # quote this when contacting support
msg = asyncio.run(call.ainvoke(tool_call)) # every tool also has an async path
Errors
Every error the gateway or the SDK reports becomes a ToolException whose text carries the error
code (INVALID_PARAM, MISSING_PARAM, UNKNOWN_API, RATE_LIMITED, QUOTA_EXCEEDED,
TARGET_BLOCKED, UPSTREAM_TIMEOUT, MISSING_API_KEY, ...), retryable=true|false, the HTTP status
and the request id, for example:
ReefAPI error INVALID_PARAM: sort must be one of ... retryable=false. http_status=400. request_id=... Check the parameter names and allowed values with reefapi_get_schema. Failed calls are not charged.
By default (handle_tool_error=True) that text goes back to the agent as the tool result. Set
handle_tool_error=False to get the exception instead; it also has .code, .retryable and
.request_id attributes.
Options
All three tools and the toolkit accept:
| Argument | Default | Meaning |
|---|---|---|
api_key |
REEFAPI_API_KEY, then REEFAPI_KEY |
Your ReefAPI key |
base_url |
https://api.reefapi.com (or REEFAPI_BASE_URL) |
Gateway URL |
timeout |
180 |
Seconds per request. Some engines render pages in a real browser and take over a minute |
max_retries |
2 |
Automatic retries for errors marked retryable and for HTTP 429 |
max_output_chars |
50000 |
(ReefAPICall, toolkit) Cut the model-facing text here; None never cuts |
client / async_client |
built for you | Your own reefapi.ReefAPI / reefapi.AsyncReefAPI (proxies, custom transport) |
The catalog used by reefapi_search_engines is fetched once (about 1.5 MB, no key) and cached for an
hour per process.
Credits
Discovery (reefapi_search_engines, reefapi_get_schema) is free. Each successful reefapi_call
costs credits on your ReefAPI account; failed calls are not charged. Plans and free credits:
reefapi.com/pricing.
MCP
If your agent runs in an MCP client (Claude, Cursor, ChatGPT and others), you can connect the hosted
ReefAPI MCP server at https://api.reefapi.com/mcp instead of installing this package. It has the
same flow (search_engines, get_engine_schema, get_action_schema, call_engine). Use this
package when you build the agent yourself with LangChain or LangGraph.
Links
- ReefAPI: https://reefapi.com
- Docs (every engine, every action): https://reefapi.com/docs
- Python SDK: https://pypi.org/project/reefapi/
- Status: https://api.reefapi.com/status
Development
pip install -e . pytest pytest-asyncio pytest-socket "langchain-tests==1.1.9" "langchain>=1,<2"
pytest # unit tests + LangChain standard tests, offline
REEFAPI_LIVE_TEST=1 REEFAPI_API_KEY=... pytest tests/integration_tests # live, about 7 billable calls
On Linux and macOS, pytest --disable-socket --allow-unix-socket proves the unit tests make no
network calls.
License
MIT
Metadata
Release files for langchain-reefapi 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| langchain_reefapi-0.1.0.tar.gz | 21.2 kB | Without provenance | Details for langchain_reefapi-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| langchain_reefapi-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for langchain_reefapi-0.1.0-py3-none-any.whl |
Total release size: 37.9 kB
Release files / langchain_reefapi-0.1.0.tar.gz
| Download URL | langchain_reefapi-0.1.0.tar.gz |
|---|---|
| Size | 21.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fad19e47c82457c002128edf065f5b2f34a73b36241161a5045aca7585dbe325
|
|
BLAKE2b-256 checksum How to use checksums |
549dd45e594a1b6c362fdb37d41b464969e6cd735a6656391f98621970a340b2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.0
|
Release files / langchain_reefapi-0.1.0-py3-none-any.whl
| Download URL | langchain_reefapi-0.1.0-py3-none-any.whl |
|---|---|
| Size | 16.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
931a49bf3b1e6bf928da63373b8354b0f29b473834e9a32eb553903837871e10
|
|
BLAKE2b-256 checksum How to use checksums |
23110a0e1c7babc25ce61e5adc263d08b5ee75c06a7de881a462d11006d4bc55
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.0
|
Security for langchain-reefapi 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.