Integrations · LangGraph (LangChain)
LangGraph Enrichment — RichAPI as a Tool Node
Wire RichAPI into a LangGraph agent two ways: hand-written @tool functions over the REST API, or the hosted MCP server loaded through langchain-mcp-adapters. Waterfall misses on email_finder, email_verifier and phone_finder cost zero credits, which is what makes a retry loop safe to build.
In short: RichAPI can be used inside a LangGraph agent in two ways. First, as hand-written LangChain @tool functions that POST to the RichAPI REST API at https://api.richapi.ai/api/v1/{endpoint} with the API key in an x-api-key header, bound to the model with bind_tools and executed by a ToolNode routed via tools_condition. Second, through RichAPI's hosted Model Context Protocol server at https://mcp.richapi.ai/mcp, loaded with langchain-mcp-adapters MultiServerMCPClient, which exposes the whole endpoint catalog as tools without hand-writing wrappers. Available endpoints include email_finder, email_verifier, phone_finder, enrich_company, enrich_profile, people_search and web_tech_stack. enrich_company and enrich_profile take a LinkedIn URL, not a domain. On the waterfall endpoints email_finder, email_verifier and phone_finder, a call where every source ran and found nothing returns HTTP 2xx with success false and billed false and costs zero credits, so agent retries on a miss are free; every other endpoint bills on any 2xx response including an empty result, and non-2xx never bills. Route on execution_log rather than on a null field: waterfall calls return one entry per attempt with a status. All tools are read-only lookups. Billing is prepaid credits from one pool shared across REST and MCP. New accounts get 100 free credits with no credit card.
Last updated November 4, 2026
Connect it
1. Create a RichAPI account at app.richapi.ai/signup, copy your key, and export it as RICHAPI_KEY. 100 free credits, no card.
2. Option A, explicit tools: write one @tool per endpoint wrapping a POST to https://api.richapi.ai/api/v1/{endpoint} with an x-api-key header, and give each a docstring the model will actually read.
3. Option B, MCP: pip install langchain-mcp-adapters, point MultiServerMCPClient at https://mcp.richapi.ai/mcp with the x-api-key header, and load the whole catalog as tools in one call.
4. Bind the tools to your model, add a ToolNode, and route with tools_condition — the standard LangGraph agent loop, no custom executor needed.
5. Return the full response body to the model, including success, billed and execution_log, so the agent can decide whether a miss is worth retrying.
6. Cap it. A recursion_limit plus a per-run credit counter in state is the difference between a bug and an invoice.
LangGraph (LangChain)
What you can ask for
Account research graph: enrich_company on a LinkedIn URL → people_search for the buying committee → email_finder per person → verifier on anything risky.
Conditional edge that routes to a personal-email branch only when the work email lookup returns success false.
Human-in-the-loop interrupt before any phone_finder call, because it is the most expensive endpoint in the catalog.
Map-reduce over 50 domains with Send(), one enrich_company per branch, results reduced into a single scored table.
Checkpointed graph that resumes a half-finished list build without re-paying for the rows it already enriched.
Why it Matters
Agents retry. On most enrichment APIs an agent that retries a miss three times pays three times for nothing; on the waterfall endpoints the retry is free, and the execution_log tells the agent whether retrying could ever have helped.
LangGraph enrichment: RichAPI as a tool node
Two ways in. Write the tools yourself against the REST API, or load the hosted MCP server and get the catalog for free. Both end at the same ToolNode, on the same key and the same credit pool.
Option A — explicit `@tool` functions
Pick this when you want the model to see three tools instead of the whole catalog, and when you want to normalise the response before it reaches the context window.
import os, httpx
from langchain_core.tools import tool
BASE = "https://api.richapi.ai/api/v1"
HEADERS = {"x-api-key": os.environ["RICHAPI_KEY"]}
def _post(endpoint: str, payload: dict) -> dict:
r = httpx.post(f"{BASE}/{endpoint}", json=payload, headers=HEADERS, timeout=None)
r.raise_for_status() # non-2xx never bills; let it raise
return r.json()
@tool
def find_work_email(first_name: str, last_name: str, company_domain: str) -> dict:
"""Find a verified work email. Returns success, the email when found,
billed, and execution_log listing each source attempt.
A miss returns success=False and billed=False and costs nothing."""
return _post("email_finder", {
"first_name": first_name, "last_name": last_name, "company_domain": company_domain
})
@tool
def enrich_company_by_linkedin(linkedin_url: str) -> dict:
"""Company data from a LinkedIn company URL: size, industry, specialties.
Takes a LinkedIn URL, NOT a domain. Bills on any 2xx, empty result included."""
return _post("enrich_company", {"linkedin_url": linkedin_url})
The docstrings are the integration. A model that does not know enrich_company wants a LinkedIn URL will confidently hand it a domain, and you will pay for the 2xx that comes back thin. Say it in the docstring, in capitals, and say what a miss costs — a model that knows retries are free on email_finder and expensive on enrich_profile makes better decisions than one guessing.
Leave timeout=None. Enrichment waterfalls take as long as the sources take, and an aggressive client timeout turns a call you were not charged for into a call you cannot see the result of.
Option B — the hosted MCP server
Pick this when you want the whole catalog and you do not want to maintain wrappers as endpoints get added.
from langchain_mcp_adapters.client import MultiServerMCPClient
client = MultiServerMCPClient({
"richapi": {
"url": "https://mcp.richapi.ai/mcp",
"transport": "streamable_http",
"headers": {"x-api-key": os.environ["RICHAPI_KEY"]},
}
})
tools = await client.get_tools()
The catalog is served from live endpoint config rather than baked into a release, so new endpoints appear in tools without a version bump on your side. The tradeoff is the whole catalog's tool descriptions in the prompt; if that hurts, filter the list before binding.
The graph
Standard prebuilt loop, nothing exotic:
from langgraph.graph import StateGraph, MessagesState, START
from langgraph.prebuilt import ToolNode, tools_condition
tools = [find_work_email, enrich_company_by_linkedin]
model = ChatAnthropic(model="claude-sonnet-4-5").bind_tools(tools)
def call_model(state: MessagesState):
return {"messages": [model.invoke(state["messages"])]}
g = StateGraph(MessagesState)
g.add_node("model", call_model)
g.add_node("tools", ToolNode(tools))
g.add_edge(START, "model")
g.add_conditional_edges("model", tools_condition)
g.add_edge("tools", "model")
graph = g.compile()
graph.invoke(
{"messages": [("user", "Find a work email for Jane Doe at acme.com.")]},
{"recursion_limit": 12},
)
Set recursion_limit. An agent that discovers it can call an enrichment endpoint in a loop will do exactly that, and the endpoints that bill on every 2xx do not care that it was an accident.
What the agent should do with a miss
The reason to return the whole body rather than just the email: execution_log shows who ran and what each returned. An agent reading that can tell a real miss from a call worth retrying.
We do not publish the source roster; it changes as sources are added and dropped. The log is what you get instead, and it is per-call and true.
Add a conditional edge that routes on success == False from find_work_email to a personal-email branch rather than back to the model, which otherwise tends to retry the identical arguments.
Cost control in state
| Endpoint | Cost | Retry on a miss |
|---|---|---|
email_finder |
5 credits |
Free |
email_verifier |
2 credits |
Free |
phone_finder |
25 credits |
Free |
enrich_company |
1 credit |
Charged every time |
enrich_profile |
1 credit |
Charged every time |
people_search |
0.1 credits per result |
Charged every time |
Carry a credits_spent int in your state schema, add to it on each tool return, and put a conditional edge in front of phone_finder that hits an interrupt() above a threshold. Human-in-the-loop on the 25-credit endpoint is cheap insurance; on a 1-credit lookup it is theatre. Rates are on pricing.
Guardrails you get for free
Every RichAPI endpoint is a read-only lookup. Nothing in the catalog sends email, posts anything, or writes to a CRM, so a badly-planned graph spends credits rather than mailing a prospect a template with {{first_name}} still in it. That is a real property of the tool surface, and it is why an autonomous loop here is a more reasonable thing to build than one holding a send button.
Where we stop with LangGraph
Data layer only — no prospecting UI, no sequencer, no CRM app. For the same tools in a chat client instead of a graph, see Claude or Cursor, with the rest of the family under integrations. For the non-agentic version of the same pipeline, agent-driven account research and list build and verify.
LangGraph FAQ
REST tools or MCP? MCP to explore, hand-written tools for anything you run on a schedule. Fewer tools, tighter docstrings, better behaviour.
Does streaming work? The graph streams normally; the tool calls are plain blocking HTTP inside a node.
Can I run tools in parallel? Yes — Send() for map-reduce fan-out works fine, subject to whatever your account's rate limits are. Rate-limited responses are non-2xx and do not bill.
How do I stop the agent burning credits in a loop? recursion_limit, a credit counter in state, and an interrupt() before phone_finder. In that order.
Does a checkpointer help? Yes, and it is the underrated one. Resuming a checkpointed graph skips the rows you already paid to enrich.
Same key as my REST code? Yes, one key, one pool. Issue separate keys per graph for per-key usage attribution.
Start with LangGraph
100 free credits, no card. Paste the find_work_email tool above into an existing graph and run one query — it is a five-minute test and the miss costs nothing. Endpoint reference: email finder, person enrichment, full list under platform.
FAQ
Frequently asked questions
More from RichAPI
More companies
Browse company profiles with company overviews, key details, and email formats.
Get 100 free credits to explore RichAPI with no card required.
Free tools
Use our Email Permutator, llms.txt Generator, Waterfall Calculator, and live API demo — all free to try.