> ## Documentation Index
> Fetch the complete documentation index at: https://docs.meterlane.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Meterlane x402 USDC Payments with OpenAI Agents SDK

> Add a function tool to an OpenAI Agents SDK agent so it can call Meterlane x402 gateway routes and pay with USDC on Base Sepolia automatically.

The OpenAI Agents SDK lets you give an agent a set of callable tools with typed parameters. By wrapping `createAgentClient` from `@meterlane/x402/client` inside a `tool()` definition, your agent can reach any Meterlane x402-gated route without you writing any payment-retry logic — the client handles the 402 → sign → retry cycle transparently inside the tool's `execute` function.

<Note>
  All examples on this page target **Base Sepolia** (`eip155:84532`) and the public sandbox demo route. Do not use mainnet keys or mainnet facilitators in development or CI.
</Note>

<Steps>
  <Step title="Install dependencies">
    You need `@openai/agents` for the agent runtime, `zod` for parameter schemas, and `@meterlane/x402` for the x402 payment client.

    <CodeGroup>
      ```bash npm theme={null}
      npm add @openai/agents zod @meterlane/x402
      ```

      ```bash yarn theme={null}
      yarn add @openai/agents zod @meterlane/x402
      ```

      ```bash pnpm theme={null}
      pnpm add @openai/agents zod @meterlane/x402
      ```
    </CodeGroup>

    Import the MIT-licensed client — not the server middleware:

    ```typescript theme={null}
    import { createAgentClient } from "@meterlane/x402/client";
    ```

    The client is MIT-licensed; audit what it signs before running it with a funded wallet.
  </Step>

  <Step title="Set your environment variable">
    <Warning>
      Never embed your private key in source code or commit it to version control. Store it in `AGENT_PRIVATE_KEY` and load it at runtime. Use a dedicated hot wallet with a limited USDC balance — do not reuse cold-storage or exchange keys.
    </Warning>

    ```bash theme={null}
    AGENT_PRIVATE_KEY=0xYOUR_BASE_SEPOLIA_PRIVATE_KEY
    OPENAI_API_KEY=sk-...
    ```

    Get test USDC for Base Sepolia from the [Circle faucet](https://faucet.circle.com) — select **Base Sepolia** before requesting.
  </Step>

  <Step title="Create the payment tool">
    The tool calls `paidFetch` — a `fetch` wrapper that handles x402 automatically — instead of calling `fetch` directly.

    ```typescript theme={null}
    import { Agent, run, tool } from "@openai/agents";
    import { z } from "zod";
    import type { Hex } from "viem";
    import { createAgentClient } from "@meterlane/x402/client";

    const privateKey = process.env.AGENT_PRIVATE_KEY as Hex | undefined;
    if (!privateKey?.startsWith("0x")) {
      throw new Error("Set AGENT_PRIVATE_KEY to a 0x-prefixed Base Sepolia funded key");
    }

    // Returns a fetch wrapper that pays 402 automatically
    const paidFetch = createAgentClient(privateKey, "eip155:84532");

    const gatewayBase =
      process.env.GATEWAY_URL ?? "https://gateway.meterlane.app";
    const orgSlug = process.env.ORG_SLUG ?? "demo";

    const meterlanePaidGet = tool({
      name: "meterlane_paid_get",
      description:
        "HTTP GET to a Meterlane x402 gateway route. Pays with USDC on Base Sepolia when the server returns 402.",
      parameters: z.object({
        path: z
          .string()
          .describe("Route path under /gateway/:orgSlug, e.g. /demo"),
      }),
      execute: async ({ path }) => {
        const normalized = path.startsWith("/") ? path : `/${path}`;
        const url = `${gatewayBase}/gateway/${orgSlug}${normalized}`;

        const res = await paidFetch(url, { method: "GET" });
        const text = await res.text();

        return {
          ok: res.ok,
          status: res.status,
          bodyPreview: text.slice(0, 500),
        };
      },
    });
    ```
  </Step>

  <Step title="Attach the tool to an agent and run it">
    Pass the tool to an `Agent` instance, then call `run()` with a prompt:

    ```typescript theme={null}
    const agent = new Agent({
      name: "Meterlane payer",
      instructions:
        "You can call meterlane_paid_get to access paid Meterlane API routes. Use path /demo when asked to test connectivity.",
      tools: [meterlanePaidGet],
    });

    async function main() {
      if (!process.env.OPENAI_API_KEY) {
        // Smoke test the payment flow without spending model tokens
        const direct = await meterlanePaidGet.invoke({ path: "/demo" });
        console.log("Direct tool result:", direct);
        return;
      }

      const result = await run(
        agent,
        "Call meterlane_paid_get with path /demo and report the HTTP status code.",
      );
      console.log(result.finalOutput);
    }

    main().catch((err) => {
      console.error(err);
      process.exit(1);
    });
    ```

    Run the file:

    ```bash theme={null}
    AGENT_PRIVATE_KEY=0xYOUR_KEY npx tsx openai-agents-meterlane.ts
    ```

    Without `OPENAI_API_KEY` the script invokes the tool directly, which is useful for verifying that your wallet is funded and the payment flow works before you spend model tokens.

    <Tip>
      The `tool`, `invoke`, and `run` APIs vary slightly across `@openai/agents` versions. Adjust imports to match your installed version — the payment logic inside `execute` stays unchanged regardless.
    </Tip>
  </Step>
</Steps>

## How it works

When the agent calls `meterlanePaidGet`, the `execute` function fires `paidFetch(url)`. The x402 cycle runs inside that call:

1. The client sends a plain `GET` to the gateway.
2. The gateway returns **402** with an `X-Payment-Requirements` header describing the USDC price and receiver address.
3. `ExactEvmScheme` uses your private key to sign an ERC-3009 authorization for that amount on Base Sepolia.
4. The client retries the request with the authorization attached as a payment header.
5. The gateway settles on-chain and returns **200** with the upstream response body.
6. The tool returns `{ ok: true, status: 200, bodyPreview }` to the agent.

Use `"eip155:84532"` (Base Sepolia) with the default public `x402.org` facilitator for all development work. Production deployments that need Base mainnet require a private mainnet-capable facilitator configured in your Meterlane dashboard under **Settings → Developer**.
