generated: '2026-09-19' method: searched source: https://api.solvela.ai/openapi.json derived_from: openapi/solvela-ai-openapi.json docs: - https://github.com/solvela-ai/solvela/blob/main/dashboard/content/docs/concepts/x402.mdx - https://github.com/solvela-ai/solvela/blob/main/dashboard/content/docs/concepts/escrow.mdx - https://github.com/solvela-ai/solvela/blob/main/dashboard/content/docs/concepts/spend-down-channel.mdx - https://github.com/solvela-ai/solvela/blob/main/dashboard/content/docs/concepts/a2a.mdx - https://github.com/solvela-ai/solvela/blob/main/dashboard/content/docs/api/errors.mdx - https://github.com/solvela-ai/solvela/blob/main/dashboard/content/docs/api/rate-limits.mdx - https://github.com/solvela-ai/solvela/blob/main/dashboard/content/docs/operations/security.mdx base_url: https://api.solvela.ai media_type: application/json (text/event-stream when stream is true) api_style: OpenAI-compatible REST over HTTPS; JSON-RPC 2.0 for A2A at /a2a; x402 payment on every paid call auth: style: >- Payment is the authorization. A paid request without PAYMENT-SIGNATURE gets a 402 quote; the retry carries a signed Solana USDC-SPL transaction (exact), an escrow deposit (escrow) or a channel voucher in that header. Free ($0) models need nothing. Enterprise routes take Bearer solvela_k_ organisation keys; operator routes take a Bearer admin token. No OAuth, no OIDC. detail: authentication/solvela-ai-authentication.yml idempotency: supported: false coverage: none mechanism: null header: null scope: [] retention: undocumented description: >- No Idempotency-Key header, parameter or body field exists on the one write operation in the contract (createChatCompletion), on the undeclared paid routes (/v1/messages, /v1/search, /v1/solana/price) or on A2A message/send, and the docs describe none. What the provider documents instead is REPLAY PROTECTION on the money: each signed transaction signature is accepted once (Redis SET NX EX 120), a channel voucher must carry a strictly increasing cumulative bound to the SHA-256 of the exact request bytes, and an A2A task holds a per-task settlement lock so a payment leg is exactly-once. That prevents a captured payment from being replayed by a third party; it does not give a legitimate client a safe retry after an ambiguous outcome — a fresh exact payment is a second charge if the first call did succeed. Two narrower mechanisms are documented: when PostgreSQL is configured the escrow claim queue dedupes POST /v1/escrow/settle by (service_id, agent), and on the A2A channel path a provider failure takes no draw and the SAME voucher may be resubmitted. Neither reaches the primary REST write surface, so coverage is none. gaps: - No idempotency key on POST /v1/chat/completions, the operation that spends money. - No documented safe-retry guidance for a timeout after the gateway has settled an exact payment; the receipt (X-Solvela-Receipt / GET /v1/receipts/{id}) is the only after-the-fact evidence. - Escrow narrows the exposure (only actual cost is claimed, remainder refunds) but the deposit transaction itself is one-shot. dry_run_mode: supported: true status: documented mechanism: unpaid request returns the quote without executing surfaces: - operation: createChatCompletion how: send without PAYMENT-SIGNATURE returns: 402 with cost_breakdown, accepts[] and (on this route) extensions.bazaar carrying the input JSON Schema and an output example cost: free observed: '2026-09-19 — quote of 0.122883 USDC for a one-word prompt to anthropic/claude-sonnet-4-5-20250929, priced at the model''s full completion ceiling' - operation: 'createChatCompletion with a $0 model (model: free / oss / open, or a zero-priced id)' how: full request/response cycle at no cost, no wallet cost: free; 5/min per IP, 12/min global - operation: 'A2A message/send without taskId' how: returns a Task in input-required state carrying the same PaymentRequired quote; tasks/cancel or the 10-minute TTL discards it cost: free detail: sandbox/solvela-ai-sandbox.yml reversibility: grade: verified docs: https://github.com/solvela-ai/solvela/blob/main/dashboard/content/docs/concepts/escrow.mdx note: >- Graded verified on the escrow scheme, where a reversal path (the on-chain refund instruction) AND its window (after max_timeout_seconds, 300 s in the live 402) are both stated by the provider. The grade is scoped and the scope matters: it reverses an UNCLAIMED deposit when the gateway fails to deliver; a delivered completion cannot be un-delivered on any scheme, and the exact scheme has no reversal at all. Nothing below asserts a window the provider has not written down. write_surfaces: - operation: createChatCompletion (scheme exact) action: Pay the quoted USDC to the gateway wallet and receive a completion reversal: none reversal_operation: null window: null stated_terms: - source: concepts/escrow.mdx comparison table verbatim: 'Agent protection: None — gateway gets funds before serving' - source: api/errors.mdx verbatim: 'No provider could serve a paid request (type: upstream_unavailable — payment not charged)' note: On-chain transfer, wallet to wallet; overpayment is not refunded (the receipt documents "the divergence from the raw on-chain transfer on agent overpayment"). - operation: createChatCompletion (scheme escrow) action: Deposit USDC into the escrow PDA; the gateway claims the actual cost after delivery and the remainder is returned in the same claim transaction reversal: agent reclaims the full deposit on-chain if the gateway never claims reversal_operation: escrow program `refund` instruction (program 9neDHouXgEgHZDde5SpmqqEZ9Uv35hFcjtFEPxomtHLU); optional POST /v1/escrow/settle to trigger the claim early window: after max_timeout_seconds (300 s in the observed 402; MCP deposit_escrow default 300 s) stated_terms: - source: concepts/escrow.mdx "Refund behavior" verbatim: 'If the gateway fails to claim within max_timeout_seconds, the agent can invoke the refund instruction on the escrow program to reclaim their deposit. The refund path is enforced on-chain by the Anchor program — no trust in the gateway is required.' - source: concepts/escrow.mdx verbatim: 'In one transaction the escrow program pays the provider the actual token cost, refunds the remainder (deposit − actual) to the agent, and closes the vault and escrow accounts (rent returned to the agent).' verified: true - operation: 'spend-down channel (POST /v1/channel/open ... /v1/channel/close; undeclared in the OpenAPI)' action: Fund once; each request draws by signed voucher reversal: close the channel and the unspent balance refunds on-chain to the funding wallet reversal_operation: POST /v1/channel/close window: any time after open; hosted caps 100 USDC max deposit and 500 USDC/day refund cap stated_terms: - source: concepts/spend-down-channel.mdx verbatim: 'When done, the client signs a close message with the session key and POSTs /v1/channel/close. The unspent balance (deposit minus settled) is refunded on-chain to the funding wallet.' - source: docs/product/feature-state.md verbatim: 'bounded: 100 USDC max deposit, 500 USDC/day refund cap' - operation: 'A2A message/send (JSON-RPC)' action: Quote then pay for a completion as a Task reversal: tasks/cancel while the task is input-required (before any funds move); after payment the escrow/channel rules above apply reversal_operation: tasks/cancel window: until payment is submitted or the task expires (10 minutes after last state change) stated_terms: - source: concepts/a2a.mdx verbatim: 'tasks/cancel takes { "id": "" } and cancels a task only while it is input-required (the natural "agent declines the quote" path — no funds have moved).' read_only_operations: [listModels, getReceipt, health] pagination: style: none note: listModels returns the whole catalog (44 entries) in one array; GET /v1/services likewise. No cursors, no limit parameter, no Link headers. field_expansion: supported: false metadata: supported: false note: No client metadata field on requests; receipts carry the gateway's own cost breakdown instead. request_tracing: request_id_header: x-solvela-request-id legacy_alias: x-rcr-request-id (same UUID, emitted alongside; RCR was the product's former name) receipt_header: X-Solvela-Receipt — UUIDv4 receipt id on paid responses; look it up at GET /v1/receipts/{receipt_id} observability_headers_exposed_via_cors: [x-solvela-model, x-solvela-tier, x-solvela-score, x-solvela-profile, x-solvela-provider, x-solvela-cache, x-solvela-latency-ms, x-solvela-payment-status, x-solvela-token-estimate-in, x-solvela-token-estimate-out, x-solvela-session, x-solvela-fallback, x-solvela-receipt, x-session-id] observed: 'x-solvela-request-id and x-rcr-request-id present on every response on 2026-09-19; access-control-expose-headers lists the full set above.' versioning: scheme: URI path prefix current: v1 detail: lifecycle/solvela-ai-lifecycle.yml changelog: changelog/solvela-ai-changelog.yml error_envelope: media_type: application/json rfc9457: false shape: '{ "error": { "type", "message" } }' exception: 402 without a payment header returns the x402 PaymentRequired object at the top level (detect by x402_version) detail: errors/solvela-ai-problem-types.yml decline_codes: errors/solvela-ai-decline-codes.yml rate_limits: signal_status: 429 headers: [x-ratelimit-limit, x-ratelimit-remaining, x-ratelimit-reset (window length in seconds), retry-after] primary_limit: 60 requests / 60 s per payer wallet (IP fallback) detail: rate-limits/solvela-ai-rate-limits.yml payment_quoting: currency: USDC-SPL on Solana mainnet (CAIP-2 solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp) units: accepts[].amount is atomic USDC (6 decimals) as a string; cost_breakdown values are decimal strings basis: quoted against the model's full completion-token ceiling (or max_tokens if set), so the quote is an upper bound; escrow and channel settle actual cost, exact charges the quote validity: max_timeout_seconds 300 fee: platform fee 0% on the hosted gateway (software default 5%); every 402 carries fee_percent schemes_advertised: [exact, escrow] schemes_accepted_but_not_advertised: [channel voucher] discovery: [GET /.well-known/x402, GET /v1/supported, x-payment-info on the OpenAPI operation, extensions.bazaar in the 402 body] streaming: rest: SSE (text/event-stream) when stream is true; for escrow the client may call POST /v1/escrow/settle after the stream ends to claim immediately a2a: not supported (message/stream not routed; card says streaming false) caching: response_cache: exact-match on (model, messages, temperature), wallet-agnostic; a hit returns the prior answer at zero upstream cost semantic_cache: Tier 2 near-duplicate cache enabled on the hosted gateway 2026-07-14 (bge-small-en-v1.5 embeddings); an escrow request that hits it is billed less than quoted header: x-solvela-cache routing: profiles: [eco, auto, premium, free] profile_aliases: {cheap: eco, budget: eco, balanced: auto, default: auto, best: premium, quality: premium, oss: free, open: free} model_aliases: [opus, sonnet, haiku, gpt5, gemini, flash, grok, deepseek, reasoner, o3-mini] model_id_form: '/ (NVIDIA NIM ids double the prefix, e.g. nvidia/nvidia/nemotron-nano-9b-v2)' other_conventions: - name: Money-free pre-checks detail: Prompt-guard (injection/jailbreak/PII) runs before any funds move on A2A; a blocked message costs nothing. - name: Timeouts detail: 120 s per request (408); A2A serve bound 540 s. - name: Content detail: Text and image_url content parts (vision models only, else 415); A2A is text-only. - name: No PII detail: The provider states it never collects names, emails or identifiers and does not persist prompts or responses.