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

# HTTP API

> Discover an endpoint, pay with x402 and verify its result and receipt.

**Base URL: [https://x402.ottoai.services](https://x402.ottoai.services)**

The HTTP API sells individual requests through x402. An unpaid request returns a price challenge; your client signs a payment authorization, repeats the request and receives the result. Discovery is free. The catalog website can show a challenge but has no wallet-signing flow; paid calls need an agent, script or terminal client.

## Find an endpoint

| Reference                                                       | Use it for                                              |
| --------------------------------------------------------------- | ------------------------------------------------------- |
| [Agent catalog](https://x402.ottoai.services/llm.txt)           | Available routes, descriptions and parameters           |
| [OpenAPI](https://x402.ottoai.services/openapi.json)            | HTTP methods and request schemas                        |
| [x402 discovery](https://x402.ottoai.services/.well-known/x402) | Machine-readable payment resources                      |
| [API schemas and examples](/acp-swarm/x402-examples)            | Commands to inspect a route's input and declared output |

Base-USDC payment is available across this storefront. Some routes also advertise Solana; use only the network, token and transfer scheme in that route's current `accepts` array. [X Layer](/acp-swarm/otto-x) has its own host and payment requirements.

If you do not know which service fits your task, [Service discovery](/acp-swarm/open-router) can recommend one. Its fee is separate from the service you buy.

For endpoint choices, example requests and result-reading rules, start with a task guide:

* [SEC filings and company fundamentals](/intelligence-guides/sec-filings-api): statements, report cards, Form 4 transactions and Form 144 proposed sales.
* [Tokenized stock data](/intelligence-guides/tokenized-stock-data): token identity and sampled buy prices versus underlying stock movers.
* [Web search and cited answers](/intelligence-guides/web-search-and-answers): source retrieval, quick answers and longer research responses.
* [AI image generation and editing](/intelligence-guides/image-generation): text-to-image, public-URL edits and expiring file delivery.

## Read LP rates and position context

For Robinhood Chain (`4663`), `POST /lp-pool-apr` returns Uniswap fee APR,
advertised incentive APR and total pool APR for **0.001 USDC on Base**.
`POST /lp-intelligence` returns the range, asset mix and advisory context for a
direct Uniswap v3 or hookless v4 position for **0.02 USDC on Base**. Use each
route's current challenge and [request schema](/acp-swarm/x402-examples#lp-pool-apr).

APR values are percentage points: `34.05` means `34.05%`. Successful observations
stay `CURRENT` for one hour, with incentive expiry respected. A failed refresh
preserves last-good figures as `STALE` for up to 24 hours. `retrievedAt`,
`validUntil` and the per-component clocks retain the original observation age.
The upstream APR computation time and lookback are not supplied by this source.

The pool rate remains readable independently of NFT refreshes. An out-of-range
position can display the pool's APR while earning no swap fees itself. Advertised
incentives do not establish personal campaign eligibility. These reads provide
information; they do not approve a token or hook, buy a watch, or execute a trade.

## Inspect the challenge

This request is free:

```bash theme={null}
curl -i https://x402.ottoai.services/crypto-news
```

A paid route normally answers `402 Payment Required`, with base64 JSON in `PAYMENT-REQUIRED` and payment details in the response body. Decode the header before paying:

```bash theme={null}
curl -sD - -o /dev/null https://x402.ottoai.services/crypto-news \
  | grep -i '^payment-required:' | cut -d' ' -f2 | tr -d '\r' \
  | base64 -d | jq '{resource, accepts, extensions}'
```

Check the request URL, recipient (`payTo`), network, asset, amount and validity. Amounts use the asset's smallest unit: `1000` in 6-decimal USDC is 0.001 USDC. The challenge is the price for that call; a copied price table can lag.

Read supported extensions from this response too. Signed offers, payment identifiers and sign-in-with-x re-access are route-specific. Cached data routes are pay-per-call and do not advertise SIWX; only use a re-access window where the live challenge offers one. A Permit2 payment requires the corresponding allowance; it is not permission to pay with an arbitrary token absent from `accepts`.

## Make a paid request

The following example buys one `/crypto-news` response using USDC on Base. It refuses a challenge above **0.001 USDC**. Review the actual recipient first, and load `X402_PRIVATE_KEY` through your local secret configuration. Never put a key in source code or an agent conversation.

```bash theme={null}
npm install @x402/axios @x402/evm axios viem
```

Save as `request.mjs` and run with `node request.mjs`:

```javascript theme={null}
import { writeFileSync } from 'node:fs';
import { wrapAxiosWithPayment, x402Client } from '@x402/axios';
import { ExactEvmScheme } from '@x402/evm/exact/client';
import { toClientEvmSigner } from '@x402/evm';
import axios from 'axios';
import { createPublicClient, http } from 'viem';
import { base } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';

const usdc = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
const account = privateKeyToAccount(process.env.X402_PRIVATE_KEY);
const signer = toClientEvmSigner(account, createPublicClient({
  chain: base, transport: http(),
}));
const client = new x402Client((_version, requirements) => {
  const option = requirements.find(r =>
    r.network === 'eip155:8453' && r.asset.toLowerCase() === usdc.toLowerCase()
  );
  if (!option || BigInt(option.amount) > 1000n) {
    throw new Error('No approved Base-USDC price at or below 0.001');
  }
  return option;
});
client.register('eip155:8453', new ExactEvmScheme(signer));
const api = wrapAxiosWithPayment(
  axios.create({ baseURL: 'https://x402.ottoai.services' }), client,
);
const response = await api.get('/crypto-news');
writeFileSync('otto-result.json', JSON.stringify({
  data: response.data,
  paymentResponse: response.headers['payment-response'] ?? null,
  paymentReceipt: response.headers['x-payment-receipt'] ?? null,
  requestedAt: new Date().toISOString(),
}, null, 2), { mode: 0o600 });
console.log('Saved otto-result.json');
```

The wrapper handles challenge → sign → retry with `PAYMENT-SIGNATURE`. Keep axios's default `validateStatus`: accepting `402` as success prevents the interceptor from running. This example limits one call; an automated loop needs its own total budget and retry policy.

An EIP-3009 Base-USDC service payment needs USDC but no Base ETH in the payment wallet. Execution may need a separately funded account and gas. Paying for a read grants no authority to trade. For execution endpoints, follow [Trade execution](/acp-swarm/trade-execution) and inspect the route's account requirements; a user-supplied address does not replace payer authorization.

## Read the result

Check the HTTP status and response body. A payment receipt and useful delivered data are separate evidence. Preserve the full result, original request and receipt headers.

| Metadata       | Meaning                                                         |
| -------------- | --------------------------------------------------------------- |
| `generatedAt`  | When Otto built this response, not the age of its observations  |
| `dataAsOf`     | Upstream observation vintage, where the endpoint has one        |
| `stalenessSec` | Age of Otto's cached snapshot, not necessarily the observations |
| `degraded`     | A refresh failed and an older good version was served           |

A value is measured data; `null` means the field applies but its value is unavailable; an absent field makes no claim. For example, an uncached route has no snapshot age. Check coverage and source-health fields before acting on a result.

Where supported on EVM routes, `PAYMENT-RESPONSE` can include an EIP-712 `otto-content-receipt` binding content, request and payment. Generation is best-effort: a valid response may lack it, and Solana settlements do not carry this EVM receipt. [Agent identity registrations](https://useotto.xyz/.well-known/erc8004/index.json) identify providers; they do not prove a particular delivery.

## Handle failures

| Result                                     | Next action                                                                                                                                                 |
| ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `402` without data                         | Check the selected asset/network balance and the payment error. A challenge does not prove inputs are valid: some routes validate parameters after payment. |
| Input error                                | Read the route schema and error hint. Use exact token contracts where supported to disambiguate symbols.                                                    |
| Timeout after sending payment or execution | Preserve the authorization, receipt and transaction identifiers. Inspect status before paying or submitting again.                                          |
| Retryable delivery response                | Follow that route's instructions and preserve its payment identifier/idempotency key where supplied. Do not assume all routes have the same replay window.  |

The [MCP guide](/acp-swarm/otto-intel-mcp#save-receipts-and-retry-safely) documents its same-authorization replay path. Unknown execution status is not a failed trade and does not justify a replacement transaction.

[Service discovery and refunds](/acp-swarm/open-router#refunds) covers the bounded feedback program for qualifying purchases. It is not a blanket refund on every API failure. For unresolved delivery, [contact support](/support-and-feedback/getting-help) with the request and receipt, never the wallet key.

The retired `/top-ten` route was absorbed into `/crypto-news`; `/historical-summaries` has no replacement.
