> ## 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 Revoke API key

> DELETE /agent/x402/api-keys/revoke — Revoke (delete) an API key for your agent. Query param api_key required. Costs $0.001 USDC. Agents only.

<Note>
  **Agent endpoints are in beta.** MPP equivalent: `GET /agent/mpp/api-keys/revoke?api_key=...` (this x402 route uses **DELETE**). Overview: [Agentic payments](/guides/agentic-payments).
</Note>

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

`DELETE /agent/x402/api-keys/revoke` revokes (soft-deletes) an API key that belongs to your agent. The key must belong to the same agent as the paying wallet. Cost: **\$0.001 USDC** (facilitator fee). You must have an active plan.

***

## Query parameters

| Parameter | Required | Description                                       |
| --------- | -------- | ------------------------------------------------- |
| `api_key` | Yes      | The API key to revoke (must belong to this agent) |

***

## Request flow

1. Call `DELETE /agent/x402/api-keys/revoke?api_key=<key>` with no payment → **402 Payment Required** with \$0.001 USDC.
2. Sign the payment and retry with an `x-payment` header → **200 OK** with `{ "deleted": true }`.

**404** — No agent for this wallet, or the given `api_key` does not belong to this agent.

***

## Reference scripts

Uses the same wallet as for subscribe. Set `API_KEY` to the key you want to revoke.

<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 API_KEY = process.env.API_KEY;

    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('SOLANA_PRIVATE_KEY required');
        process.exit(1);
      }
      if (!API_KEY?.trim()) {
        console.error('API_KEY required');
        process.exit(1);
      }

      const signer = await createKeyPairSignerFromBytes(base58ToBytes(PRIVATE_KEY_B58));
      const endpoint = `/agent/x402/api-keys/revoke?api_key=${encodeURIComponent(API_KEY)}`;

      const probeRes = await fetch(`${BASE_URL}${endpoint}`, { method: 'DELETE' });
      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);
      }

      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 failed:', err);
        process.exit(1);
      }

      const paidRes = await fetch(`${BASE_URL}${endpoint}`, { method: 'DELETE', 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);
    });
    ```
  </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;
    const API_KEY = process.env.API_KEY;

    async function main() {
      if (!PRIVATE_KEY) {
        console.error('ERROR: Set TEST_PRIVATE_KEY=0x<your_private_key> (same wallet used to subscribe)');
        process.exit(1);
      }
      if (!API_KEY || API_KEY.trim() === '') {
        console.error('ERROR: Set API_KEY=<the_api_key_to_delete>');
        process.exit(1);
      }

      const account = privateKeyToAccount(PRIVATE_KEY);

      console.log(`[1] DELETE ${BASE_URL}/agent/x402/api-keys/revoke?api_key=*** (no payment)`);
      const probeRes = await fetch(`${BASE_URL}/agent/x402/api-keys/revoke?api_key=${encodeURIComponent(API_KEY)}`, {
        method: 'DELETE',
      });
      console.log(`    Status: ${probeRes.status}`);

      if (probeRes.status !== 402) {
        const text = await probeRes.text();
        console.log(`    Body: ${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.log(`[2] Revoke API key price: $${Number(evmOption.amount) / 1_000_000} USDC`);
      }

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

      let paymentPayload;
      try {
        paymentPayload = await httpClient.createPaymentPayload(paymentRequired);
      } catch (err) {
        console.error('    Payment creation failed:', err);
        process.exit(1);
      }

      const paymentHeaders = httpClient.encodePaymentSignatureHeader(paymentPayload);
      console.log(`[4] DELETE ${BASE_URL}/agent/x402/api-keys/revoke (with payment)`);
      const paidRes = await fetch(`${BASE_URL}/agent/x402/api-keys/revoke?api_key=${encodeURIComponent(API_KEY)}`, {
        method: 'DELETE',
        headers: paymentHeaders,
      });
      const body = await paidRes.text();

      console.log(`    Status: ${paidRes.status}`);
      console.log('    Result:', body || '(empty)');

      if (paidRes.status === 404) {
        console.error('\n No agent found for this wallet, or API key does not belong to this agent.');
        process.exit(1);
      }

      if (paidRes.status !== 200) {
        console.error('\n Request failed.');
        process.exit(1);
      }

      const data = JSON.parse(body) as { deleted: true };
      console.log('\n API key revoked.', data);
      process.exit(0);
    }

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

***

To create a new API key: [x402 Create API key](/guides/x402-agent-api-key-create). Full walkthrough: [x402 Subscription and top-up](/guides/x402-subscription-and-topup).
