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

# x402 Pay

> Proxy an API call through the x402 payment protocol, automatically paying in USDC.

<Warning>
  This endpoint is deprecated. Use [POST /v1/pay](/api-reference/agent/unified-pay) with a URL recipient instead.
</Warning>

Proxies an HTTP request to a target API. If the API returns `HTTP 402 Payment Required`, the backend automatically signs an EIP-3009 USDC authorization, retries the request with the x402 payment header, and returns the API response.

<Note>
  Requires a bearer token with the `x402` permission.
</Note>

## Request Body

<ParamField body="url" type="string" required>
  Target API URL. Max 2048 characters.
</ParamField>

<ParamField body="method" type="string" default="GET">
  HTTP method for the request. One of `GET`, `POST`, `PUT`, `DELETE`.
</ParamField>

<ParamField body="headers" type="object">
  Additional HTTP headers to include in the request to the target API.
</ParamField>

<ParamField body="body" type="string">
  Request body for `POST` or `PUT` requests.
</ParamField>

<ParamField body="max_amount_usdc" type="integer" required>
  Maximum micro-USDC to pay (safety cap). 1 USDC = 1,000,000 micro-USDC. Must be greater than 0 and at most 100,000,000 (100 USDC).
</ParamField>

## Response

<ResponseField name="status_code" type="integer" required>
  HTTP status code returned by the target API.
</ResponseField>

<ResponseField name="headers" type="object" required>
  Response headers from the target API.
</ResponseField>

<ResponseField name="body" type="string" required>
  Response body from the target API.
</ResponseField>

<ResponseField name="payment_amount" type="integer" required>
  Actual micro-USDC charged. `0` if the target API did not require payment.
</ResponseField>

<ResponseField name="fee_amount" type="integer" required>
  Platform fee in micro-USDC.
</ResponseField>

<ResponseField name="tx_hash" type="string | null" required>
  On-chain settlement transaction hash. `null` if no payment was required.
</ResponseField>

<ResponseField name="settled" type="boolean" required>
  Whether the payment was settled on-chain.
</ResponseField>

## How It Works

1. The backend makes the initial request to the target URL.
2. If the API returns `HTTP 402 Payment Required`, the response body contains the x402 payment requirements.
3. The backend signs an EIP-3009 USDC authorization using the project's x402 wallet key.
4. The request is retried with an `X-PAYMENT` header containing the signed payment.
5. The x402 facilitator verifies and settles the payment on-chain.
6. The API response is returned to the agent.
7. The USDC amount and platform fee are recorded in the project's ledger.

If the target API does not return 402 (returns 200 directly), the response is passed through without any payment.

## Examples

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.unwall.xyz/v1/x402/pay \
    -H "Authorization: Bearer aw_live_xxxxxxxxxxxx" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://api.example.com/v1/premium-data",
      "method": "GET",
      "max_amount_usdc": 500000
    }'
  ```

  ```python Python theme={null}
  import requests

  resp = requests.post(
      "https://api.unwall.xyz/v1/x402/pay",
      headers={"Authorization": "Bearer aw_live_xxxxxxxxxxxx"},
      json={
          "url": "https://api.example.com/v1/premium-data",
          "method": "GET",
          "max_amount_usdc": 500000,
      },
  )
  result = resp.json()
  print(f"Status: {result['status_code']}")
  print(f"Paid: {result['payment_amount'] / 1_000_000} USDC")
  print(f"Body: {result['body']}")
  ```

  ```typescript TypeScript theme={null}
  const resp = await fetch("https://api.unwall.xyz/v1/x402/pay", {
    method: "POST",
    headers: {
      Authorization: "Bearer aw_live_xxxxxxxxxxxx",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      url: "https://api.example.com/v1/premium-data",
      method: "GET",
      max_amount_usdc: 500000,
    }),
  });
  const result = await resp.json();
  console.log(`Status: ${result.status_code}`);
  console.log(`Paid: ${result.payment_amount / 1_000_000} USDC`);
  console.log(`Body: ${result.body}`);
  ```
</CodeGroup>

```json Response (200 OK) theme={null}
{
  "status_code": 200,
  "headers": {
    "content-type": "application/json"
  },
  "body": "{\"data\": [{\"id\": 1, \"value\": \"premium result\"}]}",
  "payment_amount": 100000,
  "fee_amount": 1500,
  "tx_hash": "0x1a2b3c4d5e6f7890abcdef1234567890abcdef1234567890abcdef1234567890",
  "settled": true
}
```

## Errors

| Status | Cause                                                       |
| ------ | ----------------------------------------------------------- |
| `400`  | `max_amount_usdc` exceeded by the API's payment requirement |
| `400`  | Insufficient USDC balance                                   |
| `403`  | Token lacks `x402` permission                               |
| `502`  | Target API or x402 facilitator returned an error            |

<Warning>
  The `max_amount_usdc` is a safety cap. If the target API requests more USDC than your max, the payment is rejected and the request fails with a 400 error. Always set a reasonable max for the API you are calling.
</Warning>
