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

# x402 Create API key

> GET /agent/x402/api-keys/create — Create a new API key for your agent. Costs $0.001 USDC. Agents only; use the same wallet as for subscribe.

<Note>
  **Agent endpoints are in beta.** MPP equivalent: `GET /agent/mpp/api-keys/create`. Overview: [Agentic payments](/guides/agentic-payments).
</Note>

<Note>
  **Agents only.** This endpoint is for **agents** (wallet-based, programmatic access). Dashboard customers create API keys at [admin.mobula.io](https://admin.mobula.io), not via this x402 endpoint.
</Note>

`GET /agent/x402/api-keys/create` creates a new API key for your agent. No query parameters. The paying wallet is verified against your subscription; the new key is tied to the same agent. Cost: **\$0.001 USDC** (facilitator fee). You must have an active plan (subscribe first).

***

## Request flow

1. Call `GET /agent/x402/api-keys/create` with no payment → **402 Payment Required** with \$0.001 USDC.
2. Sign the payment and retry with an `x-payment` header → **200 OK** with `api_key` and `user_id`.

**Response (200 OK):**

```json theme={null}
{
  "api_key": "mbl_xxxxxxxxxxxxxxxxxxxxxxxx",
  "user_id": "agt_xxxxxxxxxxxxxxxxxxxxxxxx"
}
```

**404** — No agent for this wallet. Subscribe first via [x402 Subscribe to a plan](/guides/x402-agent-subscribe).

***

## Reference scripts

Uses the same wallet as for subscribe.

<Tabs>
  <Tab title="Solana">
    **Prerequisites:** Solana wallet with USDC for \$0.001 and SOL for fees.

    **Full script** (uses `@solana/kit`, `@x402/core`, `@x402/svm`). Inline `base58ToBytes` below, or use `import { base58ToBytes } from './base58.ts'` when running from `scripts/src/x402/`.

    ```typescript theme={null}
    import { createKeyPairSignerFromBytes } from '@solana/kit';
    import { x402Client, x402HTTPClient } from '@x402/core/client';
    import { registerExactSvmScheme } from '@x402/svm/exact/client';

    const BASE_URL = process.env.API_URL ?? 'http://localhost:4058';
    const PRIVATE_KEY_B58 = process.env.SOLANA_PRIVATE_KEY;
    const endpoint = '/agent/x402/api-keys/create';

    function base58ToBytes(b58: string): Uint8Array {
      const ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
      const map = new Uint8Array(256).fill(255);
      for (let i = 0; i < ALPHABET.length; i++) map[ALPHABET.charCodeAt(i)] = i;
      const bytes: number[] = [0];
      for (const char of b58) {
        const value = map[char.charCodeAt(0)];
        if (value === undefined || value === 255) throw new Error(`Invalid base58: ${char}`);
        let carry: number = value;
        for (let j = bytes.length - 1; j >= 0; j--) {
          carry += (bytes[j] as number) * 58;
          bytes[j] = carry & 0xff;
          carry >>= 8;
        }
        while (carry > 0) {
          bytes.unshift(carry & 0xff);
          carry >>= 8;
        }
      }
      for (const char of b58) {
        if (char !== '1') break;
        bytes.unshift(0);
      }
      return new Uint8Array(bytes);
    }

    async function main() {
      if (!PRIVATE_KEY_B58) {
        console.error('ERROR: Set SOLANA_PRIVATE_KEY (base58, same wallet used to subscribe)');
        process.exit(1);
      }

      const signer = await createKeyPairSignerFromBytes(base58ToBytes(PRIVATE_KEY_B58));

      console.log(`[1] GET ${BASE_URL}${endpoint} (no payment)`);
      const probeRes = await fetch(`${BASE_URL}${endpoint}`);
      if (probeRes.status !== 402) {
        console.error(probeRes.status, await probeRes.text());
        process.exit(1);
      }

      const paymentRequiredHeader = probeRes.headers.get('payment-required');
      if (!paymentRequiredHeader) {
        console.error('Missing payment-required header');
        process.exit(1);
      }

      const decoded = JSON.parse(Buffer.from(paymentRequiredHeader, 'base64').toString('utf-8'));
      const svmOption = decoded.accepts?.find((a: { network: string }) => a.network?.startsWith('solana:'));
      if (!svmOption) {
        console.error('No Solana option in 402');
        process.exit(1);
      }
      console.log('[2] Create API key price: $0.001 USDC');

      console.log('[3] Signing payment...');
      const client = new x402Client();
      registerExactSvmScheme(client, { signer });
      const httpClient = new x402HTTPClient(client);
      const paymentRequired = httpClient.getPaymentRequiredResponse((name) => probeRes.headers.get(name), decoded);

      let paymentHeaders: Record<string, string>;
      try {
        const payload = await httpClient.createPaymentPayload(paymentRequired);
        paymentHeaders = httpClient.encodePaymentSignatureHeader(payload);
      } catch (err) {
        console.error('Payment creation failed:', err);
        process.exit(1);
      }

      console.log(`[4] GET ${BASE_URL}${endpoint} (with payment)`);
      const paidRes = await fetch(`${BASE_URL}${endpoint}`, { headers: paymentHeaders });
      const body = await paidRes.text();

      if (paidRes.status === 404) {
        console.error('No agent found for this wallet. Subscribe first with agent-subscribe-solana.ts');
        process.exit(1);
      }
      if (paidRes.status !== 200) {
        console.error('Request failed:', paidRes.status, body);
        process.exit(1);
      }

      const data = JSON.parse(body) as { api_key: string; user_id: string };
      console.log('New API key created.');
      console.log('   api_key:', data.api_key);
      console.log('   user_id:', data.user_id);
      process.exit(0);
    }

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

  <Tab title="EVM (Base)">
    **Prerequisites:** EVM wallet on Base mainnet with USDC for \$0.001.

    **Full script:**

    ```typescript theme={null}
    import { x402Client, x402HTTPClient } from '@x402/core/client';
    import { registerExactEvmScheme } from '@x402/evm/exact/client';
    import { privateKeyToAccount } from 'viem/accounts';

    const BASE_URL = process.env.API_URL ?? 'https://api.mobula.io';
    const PRIVATE_KEY = process.env.TEST_PRIVATE_KEY as `0x${string}` | undefined;

    async function main() {
      if (!PRIVATE_KEY) {
        console.error('TEST_PRIVATE_KEY required');
        process.exit(1);
      }

      const account = privateKeyToAccount(PRIVATE_KEY);
      const endpoint = '/agent/x402/api-keys/create';

      const probeRes = await fetch(`${BASE_URL}${endpoint}`);
      if (probeRes.status !== 402) {
        console.error(probeRes.status, await probeRes.text());
        process.exit(1);
      }

      const paymentRequiredHeader = probeRes.headers.get('payment-required');
      if (!paymentRequiredHeader) {
        console.error('Missing payment-required header');
        process.exit(1);
      }

      const decoded = JSON.parse(Buffer.from(paymentRequiredHeader, 'base64').toString('utf-8'));
      const evmOption = decoded.accepts?.find((a: { network: string }) => a.network?.startsWith('eip155:'));
      if (!evmOption) {
        console.error('No EVM option in 402');
        process.exit(1);
      }

      const client = new x402Client();
      registerExactEvmScheme(client, { signer: account });
      const httpClient = new x402HTTPClient(client);
      const paymentRequired = httpClient.getPaymentRequiredResponse((name) => probeRes.headers.get(name), decoded);

      let paymentHeaders: Record<string, string>;
      try {
        const payload = await httpClient.createPaymentPayload(paymentRequired);
        paymentHeaders = httpClient.encodePaymentSignatureHeader(payload);
      } catch (err) {
        console.error('Payment failed:', err);
        process.exit(1);
      }

      const paidRes = await fetch(`${BASE_URL}${endpoint}`, { headers: paymentHeaders });
      const body = await paidRes.text();

      if (paidRes.status !== 200) {
        console.error(paidRes.status, body);
        process.exit(1);
      }

      console.log(body);
      process.exit(0);
    }

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

    Response body is JSON: `{ "api_key": "mbl_...", "user_id": "agt_..." }`.
  </Tab>
</Tabs>

***

To revoke an API key: [x402 Revoke API key](/guides/x402-agent-api-key-revoke). Full walkthrough: [x402 Subscription and top-up](/guides/x402-subscription-and-topup).
