Skip to main content
Builder Codes enable onchain attribution of x402 payments by appending ERC-8021 Schema 2 codes to settlement transaction calldata.

Get started

The fastest way is to point your AI agent at the setup instructions. Copy this into Claude Code, Cursor, Codex, or any coding agent:
Follow https://docs.cdp.coinbase.com/x402/builder-code.skill.md to integrate Base Builder Codes into my x402 app.
Builder Codes are supported on EVM networks only, in the TypeScript and Go SDKs. The CDP Facilitator automatically appends its own wallet code (cdp_facil) to every settlement that includes attribution.

Get a Base Builder Code

Register at base.dev to generate your builder code. This code identifies your app in onchain transaction data.
  1. Log in at base.dev
  2. Register your app name
  3. Add and verify your domain
  4. Go to Settings → Builder Codes to get your code (e.g. bc_b7k3p9da)
Codes must match ^[a-z0-9_]{1,32}$ — lowercase letters, digits, and underscores only, 1–32 characters.

Types of codes

Three parties each contribute a code that is encoded into the onchain calldata suffix at settlement:
FieldNameSet byDescription
aApp codeSellerIdentifies the application that exposed the paid endpoint
wWallet codeFacilitatorIdentifies the facilitator that settled the payment — CDP uses cdp_facil
sService codeClient (optional)Identifies the client or intermediary that initiated the payment
All codes must match the pattern ^[a-z0-9_]{1,32}$ — lowercase letters, digits, and underscores only, between 1 and 32 characters.

For sellers

Declare your app code per-route in the payment middleware configuration. The code is included in the 402 Payment Required response so clients can echo it back at payment time.
npm install @x402/extensions
import { paymentMiddleware, x402ResourceServer } from "@x402/express";
import { ExactEvmScheme } from "@x402/evm/exact/server";
import { BUILDER_CODE, declareBuilderCodeExtension } from "@x402/extensions/builder-code";

app.use(
  paymentMiddleware(
    {
      "GET /weather": {
        accepts: [
          {
            scheme: "exact",
            price: "$0.001",
            network: "eip155:8453",
            payTo: "0xYourAddress",
          },
        ],
        description: "Weather data",
        mimeType: "application/json",
        extensions: {
          [BUILDER_CODE]: declareBuilderCodeExtension("my_weather_app"),
        },
      },
    },
    new x402ResourceServer(facilitatorClient).register("eip155:8453", new ExactEvmScheme()),
  ),
);
declareBuilderCodeExtension validates the format and throws if the code doesn’t match ^[a-z0-9_]{1,32}$.

For buyers

Clients can optionally register a service code (s) to include their own attribution in every payment payload. The client SDK also automatically echoes the server’s app code (a) from the 402 response — this is required by the facilitator and happens automatically.
import { x402Client, wrapFetchWithPayment } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { BuilderCodeClientExtension } from "@x402/extensions/builder-code";

const client = new x402Client();
client.register("eip155:*", new ExactEvmScheme(signer));
client.registerExtension(new BuilderCodeClientExtension("my_client_app"));

const fetchWithPayment = wrapFetchWithPayment(fetch, client);
const response = await fetchWithPayment("https://example.com/weather");

CDP Facilitator behavior

When the CDP Facilitator settles a payment that includes attribution, it:
  1. Verifies that the client’s echoed a matches the server’s declared a. A mismatch causes the settlement to be rejected.
  2. Reads a (app code) and s (service code) from the payment payload.
  3. Adds its own wallet code: w: "cdp_facil".
  4. CBOR-encodes all three fields and appends the ERC-8021 Schema 2 suffix to the settlement transaction calldata.
The resulting calldata suffix is structured as:
[CBOR-encoded map of a/s/w] [2-byte CBOR length] [0x02 schema ID] [16-byte ERC-8021 marker]
This suffix is readable by any offchain tool that knows the ERC-8021 format.

Verifying attribution onchain

After a payment settles, you can confirm attribution in two ways:
import { createPublicClient, http } from "viem";
import { base } from "viem/chains";
import { parseBuilderCodeSuffixFromCalldata } from "@x402/extensions/builder-code";

const publicClient = createPublicClient({ chain: base, transport: http() });
const tx = await publicClient.getTransaction({ hash: txHash });

const attribution = parseBuilderCodeSuffixFromCalldata(tx.input);
if (attribution) {
  console.log(attribution);
  // { a: "my_weather_app", w: "cdp_facil", s: "my_client_app" }
}
The s field (service code) will appear if the buyer integrated a Builder Code. The w field will appear if the CDP Facilitator settled the payment. The a field (app code) will only appear if the seller also declared a Builder Code extension.
View your attribution data and app metrics at base.dev.