{"openapi":"3.1.0","info":{"title":"BitPlan Gateway","version":"1.0.0","summary":"OpenAI-compatible AI inference paid in Bitcoin (BSV) over HTTP 402.","description":"No API keys: the bearer is a token your BSV wallet signs (bitcoin-auth format `pubkey|scheme|timestamp|requestPath|signature`). A call without enough credits answers 402 with a `bsv-tx-v1` challenge; pay it and retry with `X402-Proof`. See https://gateway.bitplan.dev/docs and https://gateway.bitplan.dev/llms.txt.","contact":{"url":"https://gateway.bitplan.dev"}},"servers":[{"url":"https://gateway.bitplan.dev"}],"externalDocs":{"url":"https://gateway.bitplan.dev/docs","description":"Developer docs"},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Wallet-signed token `pubkey|brc77|timestamp|https://gateway.bitplan.dev/v1|signature` (24 h session) or the per-request form with the request path (5 min). Mint one with `bitplan gateway token`, the gateway skill, or the site."}},"parameters":{"depositMode":{"name":"x-gateway-deposit","in":"header","schema":{"type":"string","enum":["exact","minimum"]},"description":"A 402 asks for exactly this call's shortfall (minimum 2,000 sats) by default. `minimum` asks instead for a top-up of at least the minimum deposit, for clients that fund in bulk."},"payment":{"name":"PAYMENT-SIGNATURE","in":"header","schema":{"type":"string"},"description":"x402 v2 PaymentPayload, base64 JSON `{\"x402Version\":2,\"accepted\":<the accepts[0] object of the 402>,\"payload\":{\"transaction\":\"<signed raw transaction, base64>\"}}`. A paid response carries `PAYMENT-RESPONSE`: base64 `{\"success\",\"transaction\":\"<txid>\",\"network\",\"payer\",\"amount\"}`."},"proof":{"name":"X402-Proof","in":"header","schema":{"type":"string"},"description":"Legacy form of PAYMENT-SIGNATURE: base64url JSON `{\"version\":\"bsv-tx-v1\",\"challenge_id\",\"rawtx_base64\",\"txid\"}` paying an earlier 402 challenge."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}},"PaymentRequired":{"type":"object","description":"x402 protocol version 2 PaymentRequired (also sent base64 in the PAYMENT-REQUIRED header), plus the legacy `challenge` and, on authenticated calls, `fund.paymail`.","required":["x402Version","resource","accepts","challenge"],"properties":{"error":{"$ref":"#/components/schemas/Error/properties/error"},"x402Version":{"type":"integer","const":2},"resource":{"type":"object","properties":{"url":{"type":"string"},"description":{"type":"string"},"mimeType":{"type":"string"}}},"accepts":{"type":"array","items":{"type":"object","required":["scheme","network","amount","asset","payTo","maxTimeoutSeconds","extra"],"properties":{"scheme":{"type":"string","const":"exact"},"network":{"type":"string","const":"bip122:000000000019d6689c085ae165831e93"},"amount":{"type":"string","description":"satoshis"},"asset":{"type":"string","const":"BSV"},"payTo":{"type":"string","description":"P2PKH address"},"maxTimeoutSeconds":{"type":"integer"},"extra":{"type":"object","properties":{"challengeId":{"type":"string"},"lockingScript":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"payUrl":{"type":"string"}}}}}},"challenge":{"type":"object","required":["version","challenge_id","amount_sats","payee_address","payee_locking_script_hex","expires_at"],"properties":{"version":{"type":"string","const":"bsv-tx-v1"},"challenge_id":{"type":"string"},"amount_sats":{"type":"integer"},"payee_address":{"type":"string"},"payee_locking_script_hex":{"type":"string"},"expires_at":{"type":"string","format":"date-time"},"pay_url":{"type":"string"}}},"fund":{"type":"object","description":"Authenticated callers only: a person can add credits by sending BSV here.","properties":{"paymail":{"type":"string"},"note":{"type":"string"}}}}},"ChatRequest":{"type":"object","required":["model","messages"],"properties":{"model":{"type":"string","description":"An id from GET /v1/models, e.g. anthropic/claude-fable-5.1 or openrouter/vendor/model."},"messages":{"type":"array","items":{"type":"object"}},"max_tokens":{"type":"integer","description":"Sizes the hold: max_tokens times the output price is reserved before the call."},"stream":{"type":"boolean"}},"additionalProperties":true},"MessagesRequest":{"type":"object","required":["model","max_tokens","messages"],"properties":{"model":{"type":"string","description":"An id from GET /v1/models (e.g. anthropic/claude-fable-5.1), or a bare Anthropic id such as claude-sonnet-4-5 that maps to anthropic/<id>."},"max_tokens":{"type":"integer","description":"Required, as in the Anthropic API; sizes the hold taken before the call."},"messages":{"type":"array","items":{"type":"object"}},"system":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"object"}}]},"tools":{"type":"array","items":{"type":"object"}},"tool_choice":{"type":"object"},"stop_sequences":{"type":"array","items":{"type":"string"}},"temperature":{"type":"number"},"top_p":{"type":"number"},"stream":{"type":"boolean"}},"additionalProperties":true},"ResponsesRequest":{"type":"object","required":["model","input"],"properties":{"model":{"type":"string","description":"An id from GET /v1/models, e.g. anthropic/claude-fable-5.1 or openai/gpt-5.5."},"input":{"description":"A string, or items: message (roles user, assistant, system, developer; parts input_text, output_text, input_image with image_url), function_call and function_call_output. reasoning and item_reference items are dropped.","oneOf":[{"type":"string"},{"type":"array","items":{"type":"object"}}]},"instructions":{"type":"string"},"tools":{"type":"array","items":{"type":"object"},"description":"Client-executed tools only: function tools (name, description, parameters, strict), custom tools (emulated by a function taking input; calls return as custom_tool_call) and namespace tools (flattened; calls return with name and namespace). web_search, file_search, computer and other hosted tools answer 400."},"tool_choice":{"description":"auto, none, required or {\"type\":\"function\",\"name\":...}"},"max_output_tokens":{"type":"integer","description":"Sizes the hold: max_output_tokens times the output price is reserved before the call (default 8192)."},"temperature":{"type":"number"},"top_p":{"type":"number"},"parallel_tool_calls":{"type":"boolean"},"text":{"type":"object","description":"text.format json_schema or json_object becomes the chat response_format."},"stream":{"type":"boolean"},"store":{"type":"boolean","description":"Accepted and ignored."},"previous_response_id":{"type":"string","description":"Not supported (400): nothing is stored, send the history in input."}},"additionalProperties":true},"OpenAIError":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"param":{"type":["string","null"]},"code":{"type":["string","null"]}}}}},"AnthropicError":{"type":"object","properties":{"type":{"type":"string","const":"error"},"error":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}},"Model":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["language","image"]},"recommended":{"type":"boolean"},"byok_only":{"type":"boolean"},"context_window":{"type":["integer","null"]},"reasoning":{"type":"boolean","description":"The model spends output tokens thinking before any text appears; max_tokens below min_max_tokens is raised to it (header x-gateway-max-tokens)."},"min_max_tokens":{"type":["integer","null"]},"markup_bps":{"type":"integer"},"pricing":{"type":"object","additionalProperties":true}}},"Account":{"type":"object","properties":{"identity_key":{"type":"string"},"balance_sats":{"type":"integer"},"pending_confirmation_sats":{"type":"integer"},"paymail":{"type":"string"},"tier":{"type":"object","additionalProperties":true},"byok":{"type":"array","items":{"type":"object"}}}}}},"paths":{"/v1/models":{"get":{"summary":"Models with prices","description":"Every model in BSV, sats and USD per million tokens (markup included), with tiers, peak windows and long-context ladders. With a bearer, priced at your tier.","security":[{},{"bearerAuth":[]}],"responses":{"200":{"description":"Model list","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Model"}},"bsv_usd":{"type":"number"},"markup_bps":{"type":"integer"},"tiers":{"type":"array","items":{"type":"object"}}}}}}}}}},"/v1/rate":{"get":{"summary":"BSV/USD rate and minimum deposit","responses":{"200":{"description":"Rate","content":{"application/json":{"schema":{"type":"object","properties":{"bsv_usd":{"type":"number"},"min_deposit_sats":{"type":"integer"},"min_deposit_usd":{"type":"number"}}}}}}}}},"/v1/chat/completions":{"post":{"summary":"OpenAI chat completions","description":"Same wire format as OpenAI, JSON or `stream: true`. Anonymous calls get an exact 402; the paying key becomes the account.","security":[{},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/depositMode"},{"$ref":"#/components/parameters/payment"},{"$ref":"#/components/parameters/proof"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatRequest"}}}},"responses":{"200":{"description":"Completion (OpenAI shape) or an SSE stream."},"400":{"description":"Bad request, unsupported option, or `byok_required`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Payment required, x402 protocol version 2: the PAYMENT-REQUIRED header carries the base64 PaymentRequired (scheme `exact` on BSV, `amount` in sats, `payTo`), repeated in the body next to the legacy `challenge`. Pay it from a BSV wallet and repeat the identical request with `PAYMENT-SIGNATURE` (or the legacy `X402-Proof`); the result carries `PAYMENT-RESPONSE`.","headers":{"PAYMENT-REQUIRED":{"schema":{"type":"string"},"description":"base64 JSON `{\"x402Version\":2,\"resource\":{\"url\"},\"accepts\":[{\"scheme\":\"exact\",\"network\":\"bip122:000000000019d6689c085ae165831e93\",\"amount\",\"asset\":\"BSV\",\"payTo\",\"maxTimeoutSeconds\",\"extra\":{\"challengeId\",\"lockingScript\",\"expiresAt\",\"payUrl\"}}]}`"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"}}}}}}},"/v1/messages":{"post":{"summary":"Anthropic Messages API","description":"The Anthropic Messages wire format (`anthropic-version` accepted and ignored) over the same metered flow as /v1/chat/completions: holds, 402 challenges, BYOK, tiers and settlement are identical. Point an Anthropic SDK or Claude Code at the gateway: `ANTHROPIC_BASE_URL=https://gateway.bitplan.dev ANTHROPIC_AUTH_TOKEN=<bearer>`. Model ids are catalog ids (`anthropic/claude-fable-5.1`); a bare `claude-*` id is served as `anthropic/<id>` when that model is listed. Errors are `{type:\"error\", error:{type, message}}`; a 402 keeps the `challenge` body with `type: \"error\"` alongside.","security":[{},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/depositMode"},{"$ref":"#/components/parameters/payment"},{"$ref":"#/components/parameters/proof"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessagesRequest"}}}},"responses":{"200":{"description":"An Anthropic message, or with `stream: true` the Anthropic SSE event stream (message_start, content_block_start, content_block_delta, content_block_stop, message_delta, message_stop)."},"400":{"description":"Bad request, unsupported content block, unknown bare claude-* id, or `byok_required`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicError"}}}},"402":{"description":"Payment required, x402 protocol version 2: the PAYMENT-REQUIRED header carries the base64 PaymentRequired (scheme `exact` on BSV, `amount` in sats, `payTo`), repeated in the body next to the legacy `challenge`. Pay it from a BSV wallet and repeat the identical request with `PAYMENT-SIGNATURE` (or the legacy `X402-Proof`); the result carries `PAYMENT-RESPONSE`.","headers":{"PAYMENT-REQUIRED":{"schema":{"type":"string"},"description":"base64 JSON `{\"x402Version\":2,\"resource\":{\"url\"},\"accepts\":[{\"scheme\":\"exact\",\"network\":\"bip122:000000000019d6689c085ae165831e93\",\"amount\",\"asset\":\"BSV\",\"payTo\",\"maxTimeoutSeconds\",\"extra\":{\"challengeId\",\"lockingScript\",\"expiresAt\",\"payUrl\"}}]}`"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"}}}}}}},"/v1/messages/count_tokens":{"post":{"summary":"Anthropic token count (estimate)","description":"Estimates the prompt's input tokens from its UTF-8 size (bytes / 4). Nothing is sent upstream and nothing is charged.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessagesRequest"}}}},"responses":{"200":{"description":"Estimate","content":{"application/json":{"schema":{"type":"object","properties":{"input_tokens":{"type":"integer"}}}}}}}}},"/v1/responses":{"post":{"summary":"OpenAI Responses API","description":"The OpenAI Responses wire format over the same metered flow as /v1/chat/completions: holds, 402 challenges, BYOK, tiers and settlement are identical. Built for OpenAI Codex CLI, whose custom providers only speak `wire_api = \"responses\"`: set `base_url = \"https://gateway.bitplan.dev/v1\"` and `env_key` to a variable holding a gateway bearer. Stateless: `previous_response_id` and `conversation` answer 400 and `store` is ignored; `reasoning` and `include` are dropped. Errors are `{error:{message,type,param,code}}`; a 402 keeps the `challenge` body.","security":[{},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/depositMode"},{"$ref":"#/components/parameters/payment"},{"$ref":"#/components/parameters/proof"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponsesRequest"}}}},"responses":{"200":{"description":"A Response object, or with `stream: true` the Responses SSE event stream (response.created, response.in_progress, response.output_item.added, response.content_part.added, response.output_text.delta, response.output_text.done, response.content_part.done, response.function_call_arguments.delta, response.function_call_arguments.done, response.output_item.done, response.completed / response.incomplete / response.failed), each with `event:` and `sequence_number`."},"400":{"description":"Bad request, unsupported tool or item type, previous_response_id, or `byok_required`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIError"}}}},"402":{"description":"Payment required, x402 protocol version 2: the PAYMENT-REQUIRED header carries the base64 PaymentRequired (scheme `exact` on BSV, `amount` in sats, `payTo`), repeated in the body next to the legacy `challenge`. Pay it from a BSV wallet and repeat the identical request with `PAYMENT-SIGNATURE` (or the legacy `X402-Proof`); the result carries `PAYMENT-RESPONSE`.","headers":{"PAYMENT-REQUIRED":{"schema":{"type":"string"},"description":"base64 JSON `{\"x402Version\":2,\"resource\":{\"url\"},\"accepts\":[{\"scheme\":\"exact\",\"network\":\"bip122:000000000019d6689c085ae165831e93\",\"amount\",\"asset\":\"BSV\",\"payTo\",\"maxTimeoutSeconds\",\"extra\":{\"challengeId\",\"lockingScript\",\"expiresAt\",\"payUrl\"}}]}`"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"}}}}}}},"/v1/images/generations":{"post":{"summary":"OpenAI image generation","security":[{},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/depositMode"},{"$ref":"#/components/parameters/payment"},{"$ref":"#/components/parameters/proof"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["model","prompt"],"properties":{"model":{"type":"string"},"prompt":{"type":"string"},"n":{"type":"integer"},"size":{"type":"string"}},"additionalProperties":true}}}},"responses":{"200":{"description":"Images (OpenAI shape)."},"402":{"description":"Payment required, x402 protocol version 2: the PAYMENT-REQUIRED header carries the base64 PaymentRequired (scheme `exact` on BSV, `amount` in sats, `payTo`), repeated in the body next to the legacy `challenge`. Pay it from a BSV wallet and repeat the identical request with `PAYMENT-SIGNATURE` (or the legacy `X402-Proof`); the result carries `PAYMENT-RESPONSE`.","headers":{"PAYMENT-REQUIRED":{"schema":{"type":"string"},"description":"base64 JSON `{\"x402Version\":2,\"resource\":{\"url\"},\"accepts\":[{\"scheme\":\"exact\",\"network\":\"bip122:000000000019d6689c085ae165831e93\",\"amount\",\"asset\":\"BSV\",\"payTo\",\"maxTimeoutSeconds\",\"extra\":{\"challengeId\",\"lockingScript\",\"expiresAt\",\"payUrl\"}}]}`"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"}}}}}}},"/v1/batches":{"post":{"summary":"Submit many requests to run within 24 hours at the batch price","description":"Batch pricing: the same model at about half its list price (pricing.batch on /v1/models), answered within 24 hours instead of now. Send `endpoint` (the shape every request uses), `model`, and `requests` as `{custom_id, body}` items; bodies follow the endpoint's shape and inherit the batch's model. The whole batch is held up front for its worst case as one call and settled once from the finished batch's usage; unused reserve returns as credits. Answers 202 with the batch; poll GET /v1/batches/{id} for results (the cron also settles batches nobody polls). Text only: no images, audio or files. Runs on OpenRouter's batch endpoint.","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/depositMode"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["model","requests"],"properties":{"endpoint":{"type":"string","enum":["/v1/chat/completions","/v1/responses","/v1/messages"],"default":"/v1/chat/completions"},"model":{"type":"string","description":"A model with pricing.batch on /v1/models, named as there (with or without the openrouter/ prefix)."},"requests":{"type":"array","minItems":1,"maxItems":500,"items":{"type":"object","required":["custom_id","body"],"properties":{"custom_id":{"type":"string"},"body":{"type":"object","description":"The request in the endpoint's shape; `model` may be omitted, `stream` is not allowed."}}}}}}}}},"responses":{"202":{"description":"The batch: id, status (validating, in_progress, finalizing, completed, failed, expired, cancelled), request_counts, hold_sats.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid batch, or OpenRouter refused it."},"402":{"$ref":"#/components/responses/paymentRequired"},"404":{"description":"The model has no batch price."}}},"get":{"summary":"Your recent batches","security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Batches, newest first, without results.","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/batches/{id}":{"get":{"summary":"A batch's status, and its results once it has finished","description":"Refreshes the batch from upstream when it is still open. On completion `results` lists `{custom_id, response: {status_code, body}, error}` per request and `charge_sats` is what the batch settled at.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The batch.","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"No such batch on this account."}}}},"/v1/evaluate":{"post":{"summary":"Typed questions over a state (classify, score, yes/no)","description":"An evaluation model (typesafe-ai/jev by default) answers named questions about `state` in one sub-second call: `choice` picks one of the named criteria, `score` a rubric level (lowest first), `boolean` a probability. Answers carry probabilities. Same metering as chat, priced on input tokens only; the hold is small. Use it for intent classification, routing, grading and verification.","security":[{},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/depositMode"},{"$ref":"#/components/parameters/payment"},{"$ref":"#/components/parameters/proof"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["state","questions"],"properties":{"model":{"type":"string","description":"An evaluation model id (type evaluation on /v1/models). Default typesafe-ai/jev."},"state":{"description":"The text or JSON the questions are about.","oneOf":[{"type":"string"},{"type":"object"},{"type":"array"}]},"questions":{"type":"object","additionalProperties":{"type":"object","required":["type","instructions"],"properties":{"type":{"type":"string","enum":["choice","score","boolean"]},"instructions":{"type":"string"},"criteria":{"description":"choice: {optionName: description | null}; score: [level, ...] lowest first; boolean: optional {true, false} descriptions."}}}}}}}}},"responses":{"200":{"description":"Answers","content":{"application/json":{"schema":{"type":"object","properties":{"model":{"type":"string"},"answers":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string","enum":["choice","score","boolean"]},"choice":{"type":"string"},"score":{"type":"number"},"probability":{"type":"number"},"probabilities":{"type":"object","additionalProperties":{"type":"number"}}}}},"usage":{"type":"object","properties":{"input_tokens":{"type":"integer"},"output_tokens":{"type":"integer"}}},"warnings":{"type":"array"},"provider_metadata":{"type":"object"}}}}}},"402":{"description":"Payment required, x402 protocol version 2: the PAYMENT-REQUIRED header carries the base64 PaymentRequired (scheme `exact` on BSV, `amount` in sats, `payTo`), repeated in the body next to the legacy `challenge`. Pay it from a BSV wallet and repeat the identical request with `PAYMENT-SIGNATURE` (or the legacy `X402-Proof`); the result carries `PAYMENT-RESPONSE`.","headers":{"PAYMENT-REQUIRED":{"schema":{"type":"string"},"description":"base64 JSON `{\"x402Version\":2,\"resource\":{\"url\"},\"accepts\":[{\"scheme\":\"exact\",\"network\":\"bip122:000000000019d6689c085ae165831e93\",\"amount\",\"asset\":\"BSV\",\"payTo\",\"maxTimeoutSeconds\",\"extra\":{\"challengeId\",\"lockingScript\",\"expiresAt\",\"payUrl\"}}]}`"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"}}}}}}},"/v1/account":{"get":{"summary":"Credits, tier, paymail and BYOK status","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"401":{"description":"Missing or invalid bearer"}}}},"/v1/account/usage":{"get":{"summary":"Recent requests and ledger entries","security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":1000},"description":"Rows of each list, newest first; default 50."}],"responses":{"200":{"description":"Usage"}}}},"/v1/deposit":{"post":{"summary":"Add credits","description":"Always answers 402 with a challenge for max(sats, minimum) until repeated with a valid X402-Proof.","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/payment"},{"$ref":"#/components/parameters/proof"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"sats":{"type":"integer"}}}}}},"responses":{"200":{"description":"Deposit recorded","content":{"application/json":{"schema":{"type":"object","properties":{"txid":{"type":"string"},"satoshis":{"type":"integer"},"credited":{"type":"boolean"},"balance_sats":{"type":"integer"}}}}}},"402":{"description":"Payment required, x402 protocol version 2: the PAYMENT-REQUIRED header carries the base64 PaymentRequired (scheme `exact` on BSV, `amount` in sats, `payTo`), repeated in the body next to the legacy `challenge`. Pay it from a BSV wallet and repeat the identical request with `PAYMENT-SIGNATURE` (or the legacy `X402-Proof`); the result carries `PAYMENT-RESPONSE`.","headers":{"PAYMENT-REQUIRED":{"schema":{"type":"string"},"description":"base64 JSON `{\"x402Version\":2,\"resource\":{\"url\"},\"accepts\":[{\"scheme\":\"exact\",\"network\":\"bip122:000000000019d6689c085ae165831e93\",\"amount\",\"asset\":\"BSV\",\"payTo\",\"maxTimeoutSeconds\",\"extra\":{\"challengeId\",\"lockingScript\",\"expiresAt\",\"payUrl\"}}]}`"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"}}}}}}},"/v1/account/paymail":{"put":{"summary":"Claim a paymail handle at @bitplan.dev","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["handle"],"properties":{"handle":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{1,18}[a-z0-9]$"}}}}}},"responses":{"200":{"description":"Paymail info"},"409":{"description":"Handle taken"}}},"delete":{"summary":"Release the handle","security":[{"bearerAuth":[]}],"responses":{"204":{"description":"Released"}}}},"/v1/account/byok":{"put":{"summary":"Store your own provider key (wallet-encrypted)","description":"Ciphertext is BRC-2 encrypted by your wallet to the gateway identity (protocolID [2, \"gateway byok\"], keyID \"1\"). Providers: a lab key (anthropic, openai, google, spacexai, deepseek, mistral, moonshotai, alibaba, zai, minimax, meta), which Vercel AI Gateway uses per request for that lab's models, or a whole-gateway key (vercel, opencode, opencode-go). Calls that ran on your key pay nothing for the model (the lab bills you); only the router, server-side search and evaluation are billed, at your tier. A call Vercel had to serve with its own credentials is billed at list price.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["provider","ciphertext"],"properties":{"provider":{"type":"string","enum":["vercel","opencode","opencode-go"]},"ciphertext":{"type":"string","format":"byte"}}}}}},"responses":{"200":{"description":"Stored"},"400":{"description":"Invalid key or ciphertext"}}},"delete":{"summary":"Forget a stored key","security":[{"bearerAuth":[]}],"parameters":[{"name":"provider","in":"query","schema":{"type":"string"}}],"responses":{"204":{"description":"Removed"}}}},"/v1/credits/packs":{"get":{"summary":"Card credit packs","responses":{"200":{"description":"Packs in USD and what they buy after fees"}}}},"/v1/credits/checkout":{"post":{"summary":"Buy credits by card","description":"Opens a Stripe Checkout session for one pack; a person completes it in a browser. Credits are fuel for inference only: non-refundable, never paid out.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["usd"],"properties":{"usd":{"type":"number","enum":[5,20,50]}}}}}},"responses":{"200":{"description":"Checkout URL","content":{"application/json":{"schema":{"type":"object","properties":{"session_id":{"type":"string"},"url":{"type":"string"}}}}}},"503":{"description":"Card purchases disabled"}}}},"/.well-known/x402-info":{"get":{"summary":"Discovery manifest for x402-aware agents","responses":{"200":{"description":"Manifest"}}}}}}