Spend7

Spend limits and payment risk checks for LangChain agents

Where the check goes

Wrap the payment tool, not the agent. A LangChain agent decides to pay inside a tool call, so the check belongs in that tool's function body, before the transfer and after the arguments are known. Putting it in a callback handler is too late on the ones that matter: by the time on_tool_end fires the money has moved.

Setup

python
from langchain_core.tools import tool
import os, requests

SPEND7 = "https://spend7.com/api/v1/risk-check"
HEADERS = {"Authorization": f"Bearer {os.environ['SPEND7_API_KEY']}"}


@tool
def pay_for_resource(merchant: str, amount_cents: int, resource_url: str) -> str:
    """Pay for a metered resource. Checked against the spend policy first."""
    verdict = requests.post(
        SPEND7,
        headers=HEADERS,
        json={
            "intent": {
                "agentId": "research-agent-01",
                "amountMinor": amount_cents,
                "currency": "USD",
                "merchantId": merchant,
                "category": "data_api",
                "rail": "x402",
            }
        },
        timeout=5,
    ).json()

    if verdict["decision"] == "deny":
        # Return the reason to the model rather than raising: the agent can
        # often re-plan within its budget once it knows what tripped.
        return f"Payment refused by spend policy: {verdict['summary']}"

    if verdict["decision"] == "flag":
        return f"Payment needs human approval: {verdict['summary']}"

    settle(merchant, amount_cents, resource_url)
    return f"Paid. Spend7 payment id {verdict['paymentId']}."

Or use MCP

LangChain reads MCP servers through langchain-mcp-adapters, so you can load the Spend7 tools directly rather than writing the HTTP call above. The wrapped-tool form is still usually what you want for payments: it makes the check unskippable, where an MCP tool the model can simply decline to call is not.

MCP server setup →

Questions

How do I set a spend limit for a LangChain agent?
Configure the cap once against the agent id you pass in agentId, per rolling hour, day, week or month, globally or per merchant, and every risk check for that agent is evaluated against it. The cap lives in Spend7 rather than in your prompt, so an agent cannot talk its way past it.
Will a risk check slow the agent down?
It is one HTTP call before a payment you were about to make anyway. Score it only above a threshold you set if the latency matters for micropayments: most callers check everything above a dollar and let smaller x402 calls through on the cap alone.
What should the agent do on a flag?
Treat it as a stop, not a warning. Return the summary to the model or escalate to a human. A flag means something crossed the step-up threshold: an amount far above that agent's baseline, a first-seen merchant, a burst. The decision is recorded either way, so proceeding is a choice you can later account for.
CrewAI OpenAI Agents SDK Spend limits →