Skip to main content
HomeLanding pagesDSPy payment integration
LANDING PAGE

DSPy payment integration

8 min read·Last updated June 2, 2026

Integrating payments into DSPy means giving a module a tool that pays for what it calls. DSPy is Python and the x402 client is Node, so a dspy.Tool calls a small local Node proxy built on createX402Client from @blockchain0x/x402, settling any HTTP 402 in USDC on Base. DSPy optimizers tune prompts and demos, not the tool, so payment behavior stays deterministic.

What integration means

Integrating payments into DSPy means two related things: giving a module the ability to pay for what it calls (a paid API, a data source, another agent), and, when you want it, charging other callers for what your DSPy program serves. The first is the common case; the second is the earn side, turning a DSPy program into a paid service.

This page is the integration reference: the pieces, how they fit, and the one DSPy-specific point about how payment relates to optimization. For the same overview in sibling frameworks, see crewai-payment-integration and agno-payment-integration. The payment API product page is the broader reference. Here the focus is the shape of a DSPy integration, expressed as a tool a module can call.

The Node proxy reality

Start with the fact that shapes everything: DSPy is Python, and the payment packages, @blockchain0x/x402 and @blockchain0x/node, ship for Node. There is no Python payment package, so you do not call Blockchain0x from inside the module directly.

Instead, the payment work runs in a small Node process and the module talks to it over localhost. On the pay side this is a proxy that holds the wallet; on the earn side it is a gateway that gates an endpoint. Both are small, about thirty lines, and both keep every payment identifier on the verified Node surface. It is the same pattern used across the Python-framework integrations, and for DSPy you wrap the call to that proxy in a dspy.Tool.

A dspy.Tool in a ReAct module

DSPy modules that act, like dspy.ReAct, take tools, so the integration is a dspy.Tool whose function calls the proxy.

PYTHON
import requests
import dspy

def pay_and_fetch(url: str) -> str:
    """Fetch a URL, paying in USDC if it requires payment. Returns the body."""
    res = requests.post("http://127.0.0.1:8787", json={"url": url}, timeout=30)
    return res.text if res.status_code == 200 else f"Failed: {res.status_code}"

pay_tool = dspy.Tool(pay_and_fetch)
agent = dspy.ReAct("question -> answer", tools=[pay_tool])

Start the proxy, and the ReAct module can pay: when its reasoning decides a step needs a paid resource, it calls pay_and_fetch, the proxy settles the 402 in USDC on Base, and the result comes back into the module's trajectory. The function's docstring is what DSPy shows the model to decide when to use the tool, so write it plainly, and the wallet's spend limit is the backstop.

Payment stays deterministic

Here is the DSPy-specific point worth understanding, because DSPy is about optimizing programs. DSPy optimizers, like the few-shot and instruction optimizers, tune the prompts and demonstrations a module uses; they do not change the code inside a tool. So the payment logic, which lives in your function and the Node proxy, is untouched by optimization and stays deterministic. What the tool does when called is fixed; only when and how the module decides to call it can shift as the program is optimized.

That separation is healthy: you want the model's reasoning to improve with optimization, but you do not want payment behavior to be something an optimizer tweaks. Keep all payment logic in the tool function and the proxy, never in a prompt that an optimizer might rewrite, and the money path stays stable while the reasoning around it gets better. If you optimize a program that can pay, do it on testnet first so any change in how often the module reaches for the paid tool shows up as test USDC spend rather than real, and confirm the spend pattern is what you expect before moving to mainnet.

The earn side

To charge for what your DSPy program serves, expose it over HTTP and front it with a small Node gateway running createX402Plugin. The gateway returns the 402, verifies payment, and proxies paid requests to your program.

TYPESCRIPT
import Fastify from "fastify";
import { createClient } from "@blockchain0x/node";
import { createX402Plugin } from "@blockchain0x/x402/server/fastify";

const sdk = createClient({ apiKey: process.env.B0X_API_KEY! });
const app = Fastify();
await app.register(createX402Plugin, {
  sdk,
  defaultNetwork: "testnet",
  pricing: { "POST /program/run": { amountUsdc: "0.10", payToAddress: process.env.B0X_PAYTO_ADDRESS!, paymentRequestId: "pr_program" } },
});
app.post("/program/run", async (req) => {
  const r = await fetch("http://127.0.0.1:8000/run", { method: "POST", body: JSON.stringify(req.body) });
  return await r.json();
});
await app.listen({ port: 8080 });

An unpaid call gets a 402; a paid one runs your program. The program's Python code does not change; the gateway is the paywall. Keep a free discovery route so callers can see what the program does before paying.

Cost as part of the metric

DSPy optimizes against a metric, and when a program can spend money, cost is worth folding into that metric. If you optimize purely for answer quality, an optimizer may favor a program that reaches for the paid tool more often, because more data sometimes helps the score, quietly raising spend. You can counter that by having your evaluation metric account for cost, rewarding a program that hits the same quality with fewer paid calls.

You do not need anything exotic: track how many times the paid tool fired during an evaluation run and let the metric prefer cheaper trajectories at equal quality. Because the spend is in dollars, the cost term is in the same unit as any budget you set. This keeps optimization honest about money, so the program you ship is good and economical rather than good at any price, which matters precisely because DSPy is so willing to push the metric upward.

Compatibility

The integration works across DSPy's surfaces because it lives in a tool (pay) or a gateway (earn), not in the framework internals.

DSPy surface Works? Notes
dspy.Tool in dspy.ReAct Yes The common pay path
Custom module calling a tool Yes Any module that invokes the tool works
Optimizers (few-shot, instruction) Yes They tune prompts, not the tool's payment code
Earning from a program endpoint Yes Front it with the Node gateway
Payment package language Node Python DSPy talks to it over localhost

When this fits

The integration fits when a DSPy module needs to pay for what it calls, when you want to charge for what your program serves, or both, and you are comfortable running one or two small Node processes alongside the Python. That covers DSPy programs that touch money: one that pays for a data source mid-reasoning, one that sells a result, or both.

It fits less well when the program never touches paid resources or when a single human-approved payment is the only money movement. For per-call machine payments at agent scale, the dspy.Tool plus proxy, with an optional earn gateway, is the integration that fits DSPy's tool-using modules while keeping payment cleanly outside the optimized prompt.

Pricing

Integration is free; you build it from open packages. What you pay is the wallet platform fee per agent on the pricing page: Free is $0 per agent per month at a 5% transaction fee, Pro is $9 at 2%, Business is $29 at 1%. Per-agent pricing means each agent that transacts, paying or earning, is billed on its own wallet, so you pay for the agents that actually move money.

What to ship today

Wrap pay_and_fetch in a dspy.Tool, give it to a dspy.ReAct module, start a proxy with a sk_test_ key, and make one paid call on Base Sepolia. Keep all payment logic in the tool, not in a prompt, so optimization leaves it deterministic. To earn, front your program with the Node gateway. For sibling-framework overviews see crewai-payment-integration and agno-payment-integration. Pricing is on the pricing page.

FAQ

Frequently asked questions.

Is there a DSPy package from Blockchain0x?

No. DSPy is Python and the x402 client and server adapter ship for Node, so there is no Python package to install. A dspy.Tool calls a small local Node proxy built on createX402Client from @blockchain0x/x402, and the proxy holds the wallet. There is no dedicated DSPy adapter package; the tool plus proxy is the pattern.

How does a DSPy module pay for something?

You wrap a function that posts a target to a local Node proxy in a dspy.Tool and give it to a module that uses tools, such as dspy.ReAct. The proxy settles any HTTP 402 in USDC on Base through createX402Client and returns the result. The module calls the tool when its reasoning needs a paid resource, bounded by the wallet's spend limit.

Will a DSPy optimizer change how payment works?

No. DSPy optimizers tune the prompts and few-shot demonstrations a module uses, not the code inside a tool. The payment logic lives in the tool's function and the Node proxy, which the optimizer does not touch, so what the tool does when called stays deterministic across optimization. Optimization can change when the module decides to call the tool, not what the call does.

Can a DSPy program also earn?

Yes. To charge for what your DSPy program serves, expose it over HTTP and front it with a small Node gateway running createX402Plugin from @blockchain0x/x402. An unpaid request gets a 402; a paid one runs your program. Paying uses the tool and proxy, earning uses the gateway, and both settle USDC on Base.

Which network and token does it use?

USDC, 6 decimals, on Base. A sk_test_ key (on the proxy or gateway) settles on Base Sepolia (eip155:84532), a sk_live_ key on Base mainnet (eip155:8453). The network is read from the key prefix, so the same integration works on either by swapping the key.

Create your free agent wallet in 5 minutes.

First payment confirmed in under ten minutes. Free to start.