Paid requests in a few lines of TypeScript.
The SDK sends your agent’s paid requests through 402flow. Policy, wallets, receipts, and settlement stay in the control plane, so your code only handles the result.
Install it and make a request.
- Install
@402flow/sdk. It runs on Node 20 or later. - Create one client per agent, with its organization, agent name, and bootstrap key.
- Call
fetchPaidwith the merchant URL and request. Policy runs before anything is paid. - Success comes back with a receipt. Anything else throws a
FetchPaidErrorwith a kind and a reason.
npm install @402flow/sdkimport { AgentPayClient, FetchPaidError } from '@402flow/sdk';
const client = new AgentPayClient({
controlPlaneBaseUrl: 'https://api.402flow.ai',
organization: 'your-org',
agent: 'research-worker',
auth: {
type: 'bootstrapKey',
bootstrapKey: process.env.X402FLOW_BOOTSTRAP_KEY ?? '',
},
});
try {
const result = await client.fetchPaid(merchantUrl, request, {
description: 'research brief',
idempotencyKey: 'brief-2026-09-26',
});
if (result.kind === 'success') console.log(result.receiptId);
} catch (error) {
if (!(error instanceof FetchPaidError)) throw error;
// 'denied': policy stopped it, nothing was paid.
// 'paid_fulfillment_failed': paid, not delivered, receipt kept.
console.log(error.kind, error.reason, error.receiptId);
}Three ways to call it.
Pick the one that matches how much your code needs to see before it pays.
fetchPaid | The request is already known. One call probes the merchant, checks policy, pays, and returns the response. |
|---|---|
preparePaidRequest + executePreparedRequest | Your code wants to look first. Prepare returns the price, the merchant’s parameter hints, any validation issues, and the next action. Execute pays for exactly what was prepared, without asking the merchant again. |
AgentHarness | A model is shaping the request. The harness exposes the same steps as three tools, prepare_paid_request, execute_prepared_request, and get_execution_result, with default instructions for the model. |
Every outcome has a name.
A payment that goes wrong shouldn’t leave you guessing whether money moved. Each result kind says what happened, whether funds might have moved, and what’s safe to do next.
success | Paid and delivered. The receipt ID comes back with the response.Money moved: Yes. Nothing to do. |
|---|---|
passthrough | The merchant didn’t ask for payment.Money moved: No. Nothing to do. |
denied | Policy stopped the request before payment.Money moved: No. Don’t retry until the policy or approval changes. |
preflight_failed | No usable payment method, or payment setup failed.Money moved: Normally no. Fix the reported wallet, funding, or configuration problem first. |
execution_pending | An earlier attempt with the same key is still running.Money moved: Possibly. Retry or reconcile with the same idempotency key. |
execution_failed | Payment started and ended in a hard failure.Money moved: Possibly. Inspect the reason and payment attempt before retrying. |
paid_fulfillment_failed | Payment went through, but the merchant didn’t deliver. The receipt is attached.Money moved: Yes. Don’t pay again without a recovery plan with the merchant. |
execution_inconclusive | The outcome can’t be proven yet.Money moved: Possibly. Reconcile first. Never switch keys to force another payment. |
request_failed | The control plane’s response failed or didn’t match the SDK contract.Money moved: Unknown. Retry with the same key, because the first request may have arrived. |
Before you wire it in.
- Request bodies must be replayable: strings or
URLSearchParams. Streams,FormData, andBlobare rejected, because the SDK sends the exact same body when it pays.createJsonRequestBodyandcreateFormUrlEncodedBodyhelp. - Use a bootstrap key for most integrations. The SDK exchanges it for short-lived runtime tokens.
- Reuse an idempotency key only for the same URL, method, body, agent, and business operation.
- Payment can also be handed to Dexter or pay.sh through
@402flow/sdk-third-party-executors, which needs Node 20.18 or later.
Try it on a real workflow.
In a pilot, we help you wire the SDK into one agent workflow and set up its credentials, wallets, and policies.