---
title: X402 Fetch
description: Transparent transaction proxy for X402-enabled endpoints
---

# X402 Fetch

The X402 Fetch API is a transparent proxy that automatically handles HTTP 402 (Payment Required) responses. This is the **recommended** way to interact with X402-enabled APIs.

## How It Works

<Mermaid chart={`sequenceDiagram
    participant App as Your App
    participant Agnic as Agnic
    participant API as Paid API

    App->>Agnic: POST /api/x402/fetch?url=...
    Agnic->>API: Forward request
    API-->>Agnic: 402 Payment Required
    Agnic->>Agnic: Sign authorization
    Agnic->>API: Retry with authorization header
    API-->>Agnic: 200 OK + Response
    Agnic-->>App: Response + transaction info`} />

1. Your app sends a request to Agnic's fetch endpoint
2. Agnic forwards the request to the target URL
3. If the API returns 402, Agnic automatically signs and attaches the authorization
4. The response is returned to your app with transaction metadata

For the underlying wire format, see [X402 Core Concepts](/docs/x402/core-concepts).

## Endpoint

```http
POST /api/x402/fetch?url={target_url}
```

## Query Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `url` | string | Yes | The target URL to fetch |
| `method` | string | No | HTTP method (default: `GET`) |
| `maxValue` | integer | No | Maximum amount in atomic units (USDC has 6 decimals) |
| `timeout` | integer | No | Request timeout in ms (default: 30000) |

## Request Headers

Pass any headers to forward to the target API:

```bash
curl -X POST "https://api.agnic.ai/api/x402/fetch?url=https://api.example.com/data" \
  -H "X-Agnic-Token: agnic_tok_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Custom-Header: value"
```

## Request Body

Any JSON body is forwarded to the target URL:

```bash
curl -X POST "https://api.agnic.ai/api/x402/fetch?url=https://api.example.com/generate&method=POST" \
  -H "X-Agnic-Token: agnic_tok_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Write a poem about AI",
    "max_tokens": 500
  }'
```

## Response Headers

Agnic adds metadata headers to the response:

| Header | Description |
|--------|-------------|
| `X-Agnic-Paid` | `"true"` if a transaction was authorized, `"false"` otherwise |
| `X-Agnic-Amount` | Amount authorized in USD (e.g., `"0.25"`) |
| `X-Agnic-Network` | Blockchain network used (e.g., `"base-sepolia"`) |
| `X-Agnic-Scheme` | Authorization scheme: `"exact"` or `"upto"` |

## Examples

### Basic GET Request

```bash
curl -X POST "https://api.agnic.ai/api/x402/fetch?url=https://api.example.com/data" \
  -H "X-Agnic-Token: agnic_tok_YOUR_TOKEN"
```

### POST with JSON Body

```bash
curl -X POST "https://api.agnic.ai/api/x402/fetch?url=https://api.example.com/generate&method=POST" \
  -H "X-Agnic-Token: agnic_tok_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Hello world"}'
```

### With Maximum Amount Limit

```bash
# Max amount of $0.50 (500000 atomic units)
curl -X POST "https://api.agnic.ai/api/x402/fetch?url=https://api.example.com/data&maxValue=500000" \
  -H "X-Agnic-Token: agnic_tok_YOUR_TOKEN"
```

### Python Example

```python
import requests

response = requests.post(
    "https://api.agnic.ai/api/x402/fetch",
    params={
        "url": "https://api.example.com/paid-endpoint",
        "method": "POST"
    },
    headers={
        "X-Agnic-Token": "agnic_tok_YOUR_TOKEN",
        "Content-Type": "application/json"
    },
    json={
        "prompt": "Generate something"
    }
)

# Check if a transaction was authorized
if response.headers.get("X-Agnic-Paid") == "true":
    print(f"Paid ${response.headers.get('X-Agnic-Amount')}")

print(response.json())
```

### JavaScript Example

```javascript
const response = await fetch(
  'https://api.agnic.ai/api/x402/fetch?url=https://api.example.com/data&method=POST',
  {
    method: 'POST',
    headers: {
      'X-Agnic-Token': 'agnic_tok_YOUR_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ prompt: 'Hello' })
  }
);

// Check transaction info
const paid = response.headers.get('X-Agnic-Paid');
const amount = response.headers.get('X-Agnic-Amount');

if (paid === 'true') {
  console.log(`Paid $${amount}`);
}

const data = await response.json();
```

## Error Handling

### Insufficient Balance

```json
{
  "error": "insufficient_balance",
  "error_description": "Not enough USDC balance to complete transaction"
}
```

### Spending Limit Exceeded

```json
{
  "error": "spending_limit_exceeded",
  "error_description": "Transaction of $0.50 exceeds per-transaction limit of $0.25"
}
```

### Amount Exceeds maxValue

```json
{
  "error": "payment_exceeds_max",
  "error_description": "Required amount exceeds maxValue parameter"
}
```

## Best Practices

1. **Set maxValue** - Always set a maximum amount to prevent unexpected charges
2. **Check response headers** - Verify the transaction was authorized when expected
3. **Handle errors gracefully** - Implement retry logic for transient failures
4. **Monitor spending** - Use the transactions API to track costs

<Cards>
  <Card title="Sign Authorization" href="/docs/x402/sign-payment" />
  <Card title="Transactions" href="/docs/agnicpay-features/transactions" />
</Cards>
