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

# Error handling: HTTP status codes and retries

> Reference for Laso Finance API status codes, x402 payment errors, and strategies to recover from rate limits, insufficient funds, and timeouts.

## HTTP status codes

The Laso Finance API uses standard HTTP status codes. Here's what each means and how to handle it.

### 402 Payment Required

This is the normal x402 flow — not an error. The server is telling you the price and how to pay.

```json theme={null}
{
  "x402Version": 1,
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:8453",
      "maxAmountRequired": "5000000",
      "resource": "https://laso.finance/get-card?amount=5",
      "description": "Get Laso Finance prepaid card",
      "payTo": "0x3291e96b3bff7ed56e3ca8364273c5b4654b2b37"
    }
  ]
}
```

**How to handle:** If you're using an x402 client library (like `x402-axios`), this is handled automatically. The client reads the payment details, constructs a payment, and replays the request.

Note that `GET /auth` also returns 402 when a `SIGN-IN-WITH-X` header is present but fails verification (invalid or expired signature, reused nonce, domain mismatch). It does not return 401 for those failures. The 402 response carries a fresh challenge in the `PAYMENT-REQUIRED` response header, so sign the new challenge and retry. If you keep receiving 402 after sending a `SIGN-IN-WITH-X` header, treat it as a signature failure rather than retrying with the same payload.

### 400 Bad Request

Invalid or missing parameters.

```json theme={null}
{
  "error": "Amount must be at least $5. Received: $2"
}
```

**Common causes:**

* Missing `amount` query parameter on `/get-card`
* Amount below \$5 or above \$1,000
* Missing `grant_type` or `refresh_token` in `POST /auth` request body
* Invalid `format` parameter (must be `json` or `html`)

**How to handle:** Check the error message and fix the request parameters.

### 401 Unauthorized

Token is missing, expired, or invalid.

```json theme={null}
{
  "error": "Invalid or expired token"
}
```

**Common causes:**

* `id_token` has expired (tokens last \~1 hour)
* Malformed `Authorization` header
* Using a revoked refresh token

**How to handle:** Refresh your token using `POST /auth` with `grant_type: "refresh_token"`. If that also returns 401, re-authenticate via `GET /auth`.

### 403 Forbidden

You're authenticated but not authorized for this resource.

```json theme={null}
{
  "error": "Not authorized to view this card"
}
```

**Common causes:**

* Trying to access a card that belongs to a different user
* Using a token from one wallet to access another wallet's data
* The account is frozen (the response includes a `frozen_message` field explaining why)

**How to handle:** Ensure you're using the correct token for the card you're trying to access. Each wallet address has its own cards. For frozen accounts, contact support.

### 404 Not Found

The requested resource doesn't exist.

```json theme={null}
{
  "error": "Card not found"
}
```

**Common causes:**

* Invalid `card_id` in `/get-card-data`
* Typo in the card ID

**How to handle:** Verify the `card_id` from the original `/get-card` response.

### 429 Too Many Requests

A rate limit was exceeded.

```json theme={null}
{
  "error": "Daily card refresh limit reached. You can request at most 24 refreshes for a card in a 24-hour period. Please try again later."
}
```

**Common causes:**

* Calling `POST /refresh-card-data` for the same U.S. card less than 5 minutes after the previous refresh
* Requesting more than 24 refreshes for the same U.S. card in any rolling 24-hour period

**How to handle:** Back off and retry later. For the per-card 5-minute limit, the error message includes how many seconds to wait. For the daily limit, wait until older refreshes of that card age out of the 24-hour window. Do not retry in a tight loop.

### 500 Internal Server Error

Something went wrong on the server.

```json theme={null}
{
  "error": "Failed to order card. Please contact support."
}
```

**How to handle:** Retry after a few seconds. If it persists, contact [support@laso.finance](mailto:support@laso.finance) with the request details.

## Error handling pattern

Here's a robust error handling pattern for agent code:

```typescript theme={null}
async function safeApiCall(fn) {
  try {
    return await fn();
  } catch (error) {
    const status = error.response?.status;
    const message = error.response?.data?.error;

    switch (status) {
      case 400:
        console.error("Bad request:", message);
        throw new Error(`Invalid request: ${message}`);
      case 401:
        console.log("Token expired, refreshing...");
        await refreshTokens();
        return await fn(); // Retry with new token
      case 403:
        console.error("Not authorized:", message);
        throw new Error(`Access denied: ${message}`);
      case 404:
        console.error("Not found:", message);
        throw new Error(`Resource not found: ${message}`);
      default:
        console.error(`Unexpected error (${status}):`, message);
        throw error;
    }
  }
}
```
