{ "openapi": "3.1.1", "info": { "title": "Payment Service", "version": "1.5.0" }, "servers": [ { "url": "/v1" } ], "tags": [ { "name": "Pricing", "description": "Pricing and cost calculation endpoints" }, { "name": "Balance", "description": "Account balance and credit management" }, { "name": "Payments", "description": "Payment processing and top-up operations" }, { "name": "x402", "description": "x402 protocol payment endpoints (EIP-3009 USDC payments)" }, { "name": "ArNS", "description": "Arweave Name System (ArNS) registration and management" }, { "name": "Currencies", "description": "Supported currencies and exchange rates" }, { "name": "Redemption", "description": "Credit redemption and gift processing" }, { "name": "Approvals", "description": "Credit sharing and approval management" }, { "name": "Protected", "description": "Protected routes for inter-service communication (requires PRIVATE_ROUTE_SECRET)" }, { "name": "Webhooks", "description": "Webhook endpoints for external payment providers" }, { "name": "System", "description": "System health and monitoring endpoints" }, { "name": "Info", "description": "Service information and metadata" } ], "components": { "schemas": { "ByteCount": { "type": "integer", "description": "A positive integer representing a byte count of data items", "pattern": "^[0-9]+$", "example": 5242880 }, "CreditResponse": { "type": "object", "properties": { "winc": { "$ref": "#/components/schemas/Winc" }, "adjustments": { "$ref": "#/components/schemas/Adjustment" } } }, "BalanceResponse": { "properties": { "controlledWinc": { "type": "string", "description": "The total amount of winc that a user has if they revoked all approvals they've created" }, "winc": { "type": "string", "description": "The total amount of winc the user can spend without using any approved balances given to them" }, "effectiveBalance": { "type": "string", "description": "The total amount of winc that can currently be spent by the user's balance, including any shared Credits" }, "givenApprovals": { "$ref": "#/components/schemas/CreditShareApprovals" }, "receivedApprovals": { "$ref": "#/components/schemas/CreditShareApprovals" } } }, "FreeAllowanceResponse": { "type": "object", "description": "A wallet's remaining free-tier allowance — the single durable per-wallet\nfact. Advisory only: the authoritative free/charge decision is made at\nupload time (reserve-balance), and a per-IP (subnet) cap is enforced there\nbut deliberately not exposed here (publishing its remaining budget would\nbe an oracle against the anti-farm cap), so `bytesRemaining` is a\nbest-case, wallet-side figure. Deployment-wide free config — whether the\ntier is on, the default caps, the per-item cap — is global (not per-wallet)\nand lives in `/v1/info`, not here.\n", "properties": { "bytesRemaining": { "type": "integer", "nullable": true, "description": "Free bytes this wallet can still upload (never negative). `null` = unlimited (an exempt/partner wallet). `0` when the free tier is disabled." } } }, "PaymentCreditResponse": { "type": "object", "properties": { "winc": { "$ref": "#/components/schemas/Winc" }, "adjustments": { "$ref": "#/components/schemas/Adjustment" }, "fees": { "$ref": "#/components/schemas/Adjustment" }, "actualPaymentAmount": { "$ref": "#/components/schemas/ActualPaymentAmount" }, "quotedPaymentAmount": { "$ref": "#/components/schemas/QuotedPaymentAmount" } } }, "ActualPaymentAmount": { "type": "integer", "description": "The actual payment amount a user will spend in the given currency's smallest unit value. For example, $8 USD is 800", "example": 800 }, "QuotedPaymentAmount": { "type": "integer", "description": "The quoted payment amount without adjustments in the given currency's smallest unit value. For example, $10 USD is 1000", "example": 1000 }, "Winc": { "type": "string", "description": "A big number string representing an amount of credits in winc. One credit is equivalent to 10^12 winc", "example": "332824926" }, "Adjustment": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "description": { "type": "string" }, "operatorMagnitude": { "type": "number" }, "operator": { "type": "string" }, "adjustmentAmount": { "type": "string" }, "promoCode": { "type": "string" } } }, "example": [ { "name": "Adjustment", "description": "Some great subsidy", "operatorMagnitude": "0.6", "operator": "multiply", "adjustmentAmount": "-12300", "promoCode": "SOME-GREAT-CODE" } ] }, "CurrencyType": { "type": "string", "description": "Currency type for a given payment amount", "example": "usd" }, "TokenType": { "type": "string", "description": "Token type for a given transaction. Supported: arweave, ethereum, solana (alias ed25519), matic (alias pol), kyve, base-eth, ario, and the ERC-20 USDC tokens usdc (Ethereum) and base-usdc (Base). A deployment may accept a subset — ACCEPTED_FUNDING_TOKENS is the operator allowlist, and a token omitted from it is rejected with 400 \"Token not supported\".", "example": "arweave" }, "PriceFiatOrTokenType": { "type": "string", "description": "Type for a given price request. Either \"fiat\" type or \"token\" type", "example": "kyve" }, "PaymentAmount": { "type": "integer", "description": "Payment amount in a given currency's smallest unit value. For example, $10 USD is 1000. 1 AR is 1000000000000", "example": 1000 }, "ArNSBuyAntState": { "type": "object", "description": "`buy-name` ONLY — the opening state of the ANT being minted. Identical\nin shape to `@ar.io/sdk`'s `ArNSBuyAntState`, which a browser passes to\n`buyRecord({ antState })` when it settles in ARIO directly, so a client\nsends the same object whichever way the customer pays.\n\nFREE and ATOMIC: these values are written by the same\n`ario_ant::initialize` the customer already signs, which always writes\nthe root `@` record — without `antState` it points at the AR.IO logo TX.\nSo this replaces a default rather than adding work: no second action, no\nsecond signature, no second debit, and the customer's signature covers\nit (which is why no owner proof is required or taken).\n\n⚠️ SIZE BUDGET. The sponsored spawn is ONE Solana transaction against\nthe 1232-byte packet limit, and it also carries Turbo's SOL transfer and\nthe `add_controller` grant. With a worst-case 51-character name only\n~71 bytes are spare: `transactionId` + `targetProtocol` cost ~1 byte\n(the target REPLACES a 43-char default), `ticker` and `logo` fit, and\n`description`/`keywords` at their on-chain maxima do NOT. Over-limit is\na 400 naming the fix, raised before the transaction is handed over and\nwith the debit refunded — never a chain failure. A shorter name buys\nheadroom back, so there is no fixed per-field cap: the service measures\nthe real transaction.\n\nSending `antState` on any action other than `buy-name` is a 400, as is\nsending a TOP-LEVEL `transactionId` on `buy-name` (that spelling means\nthe set-record target; silently ignoring it would leave the name\npointing at the AR.IO logo).\n", "properties": { "transactionId": { "type": "string", "description": "The base `@` record target. A 43-character Arweave TX id when\ntargetProtocol is 0/unset; an IPFS CID when it is 1 (only the\nArweave case is shape-checked).\n" }, "targetProtocol": { "type": "integer", "enum": [ 0, 1 ], "description": "0 = Arweave (default), 1 = IPFS." }, "ticker": { "type": "string", "description": "Defaults to \"ANT\" on chain." }, "logo": { "type": "string", "description": "43-character Arweave TX id. Defaults to the AR.IO logo." }, "description": { "type": "string", "maxLength": 512 }, "keywords": { "type": "array", "maxItems": 16, "items": { "type": "string" } } } }, "ArNSActionCompleted": { "type": "object", "description": "Turbo held the authority and the action is done. Nothing further is\nrequired from the caller.\n", "properties": { "nonce": { "type": "string", "format": "uuid" }, "action": { "type": "string" }, "status": { "type": "string", "enum": [ "completed" ] }, "antId": { "type": "string" }, "messageId": { "type": "string", "description": "On-chain message id, once the write has landed." }, "wincQty": { "type": "string", "description": "Credits debited. Every action debits — the four ARIO actions recover\na registration cost, the other eight a small margin against Turbo's\nsponsored gas/rent. (Actions created before the per-action surcharge\nwent live on 2026-09-01 carry \"0\".)\n" }, "alreadyCompleted": { "type": "boolean", "description": "Present on a replayed /sign; no second purchase occurred." } } }, "ArNSActionAwaitingSignature": { "type": "object", "description": "Only the ANT owner can authorize this. Sign `transaction` with the\nownerAddress key and POST it to /arns/actions/{nonce}/sign.\n", "properties": { "nonce": { "type": "string", "format": "uuid" }, "action": { "type": "string" }, "status": { "type": "string", "enum": [ "awaiting-signature" ] }, "antId": { "type": "string" }, "transaction": { "type": "string", "description": "Base64 wire transaction, ALREADY signed by Turbo as fee payer. Sign\nthese exact bytes — rebuilding the message invalidates Turbo's\nsignature.\n" }, "feePayer": { "type": "string", "description": "Turbo's Solana signer. The customer never pays a fee." }, "expiresAt": { "type": "string", "format": "date-time", "description": "When this stops being signable. The underlying Solana blockhash dies\nin ~60-90 seconds; past this a /sign is refused with a 400 and the\ncredits are refunded automatically.\n" }, "wincQty": { "type": "string" } } }, "SignatureHeader": { "type": "string", "description": "The signature value derived from signing the request's data concatenated with the provided nonce using the private key from the provided public key" }, "NonceHeader": { "type": "string", "description": "The nonce value concatenated with the request's data when deriving the provided the signature" }, "PublicKeyHeader": { "type": "string", "description": "The \"modulus\" of the JWK used to create the signature header" }, "PromoCode": { "type": "string", "description": "Comma-separated list of promo codes" }, "DestinationAddress": { "type": "string", "description": "Destination wallet address for payment", "example": "abcdefghijklmnopqrxtuvwxyz123456789ABCDEFGH" }, "DestinationAddressType": { "type": "string", "description": "Destination wallet address type", "example": "arweave" }, "WinstonCreditAmount": { "type": "string", "description": "A big number string representing an amount of credits in winc. One credit is equivalent to 10^12 winc", "example": "332824926" }, "PendingPaymentTx": { "type": "object", "description": "A payment transaction as our service sees it", "properties": { "transactionId": { "type": "string", "description": "The transaction ID of the pending payment transaction" }, "transactionQuantity": { "type": "integer", "description": "The quantity of the pending payment transaction" }, "createdAt": { "type": "string", "description": "The date and time the transaction was entered into the service" }, "tokenType": { "$ref": "#/components/schemas/TokenType" }, "destinationAddress": { "$ref": "#/components/schemas/DestinationAddress" }, "destinationAddressType": { "$ref": "#/components/schemas/DestinationAddressType" }, "winstonCreditAmount": { "$ref": "#/components/schemas/WinstonCreditAmount" }, "adjustments": { "$ref": "#/components/schemas/Adjustment" } } }, "CreditedPaymentTx": { "type": "object", "description": "A payment transaction as our service sees it", "properties": { "allOf": { "$ref": "#/components/schemas/PendingPaymentTx" }, "blockHeight": { "type": "integer", "description": "The block height at which the transaction was credited" }, "creditedAt": { "type": "string", "description": "The date and time the transaction was credited in the service" } } }, "FailedPaymentTx": { "type": "object", "description": "A payment transaction as our service sees it", "properties": { "allOf": { "$ref": "#/components/schemas/PendingPaymentTx" }, "failedAt": { "type": "string", "description": "The date and time the transaction failed in the service" }, "failureReason": { "type": "string", "description": "The reason the transaction failed in the service" } } }, "TopUpQuote": { "type": "object", "description": "A copy of the top up quote that was saved to the service's database", "properties": { "topUpQuoteId": { "type": "string", "example": "caa8b54a-eb5e-4134-8ae2-a3946a428ec7" }, "destinationAddress": { "$ref": "#/components/schemas/DestinationAddress" }, "destinationAddressType": { "$ref": "#/components/schemas/DestinationAddressType" }, "paymentAmount": { "$ref": "#/components/schemas/ActualPaymentAmount" }, "quotedPaymentAmount": { "$ref": "#/components/schemas/QuotedPaymentAmount" }, "currencyType": { "type": "string", "example": "usd" }, "winstonCreditAmount": { "$ref": "#/components/schemas/WinstonCreditAmount" }, "quoteExpirationDate": { "type": "string", "example": "2023-05-17T21:46:38.404Z" }, "paymentProvider": { "type": "string", "example": "stripe" } } }, "ConversionRates": { "type": "object", "properties": { "winc": { "type": "string", "description": "A big number representing the amount of credits in winc that 1GB of storage costs based on current market rates. One credit is equivalent to 10^12 winc.", "example": 332824926 }, "perDataItemFeeWinc": { "type": "string", "description": "The flat per-data-item surcharge in winc (the same value applied by getWCForDataItem), so clients can compute all-in cost as bytes→winc + perDataItemFeeWinc without a per-item quote.", "example": "20000000" }, "fiat": { "type": "object", "description": "The amount of fiat currencies that 1GB of storage costs based on current market rates.", "example": { "aud": 8.1228081675468, "brl": 26.0465204865588, "cad": 7.1550718332636, "eur": 4.9519274126615995, "gbp": 4.251862830414, "hkd": 42.3539072259708, "inr": 443.50120792114916, "jpy": 781.2411885860027, "sgd": 7.3197929114399995, "usd": 5.4049103776452005 } }, "adjustments": { "$ref": "#/components/schemas/Adjustment" } } }, "PaymentSession": { "type": "object", "description": "The full payment-intent or checkout-session from a payment provider", "properties": { "id": { "type": "string", "description": "The payment provider's given ID for this payment intent", "example": "cs_test_a1lFM2vIpifSqH8VtIjnbSGnr0RAQtEx6R2OMbhvbeK7fradNG7357Roxy" }, "client_secret": { "type": "string", "description": "Available on the payment-intent top up flow, this is the client secret that must be provided in order to confirm the payment intent with a payment method", "example": "cs_test_a1lFM2vIpifSqH8VtIjnbSGnr0RAQtEx6R2OMbhvbeK7fradNG7357Roxy#fidkdWxOYHwnPyd1blpxYHZxWjA0T1BEcXJGPWR1VUpSbkFJbTdDVV9uVG5sTl9AblFqM3J0YklGcVRqRmlJM1YxaTdvaWdnZjBIYkphckpQYVA8UWs8NktLc3REQmdwNDQwaW5PRm1IbG5CNTVdUGNRaGo3fycpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl" }, "url": { "type": "string", "description": "Available on a checkout-session top up flow, this is the URL in which to fulfill the quote", "example": "https://checkout.stripe.com/c/pay/cs_test_a1lFM2vIpifSqH8VtIjnbSGnr0RAQtEx6R2OMbhvbeK7fradNG7357Roxy#fidkdWxOYHwnPyd1blpxYHZxWjA0T1BEcXJGPWR1VUpSbkFJbTdDVV9uVG5sTl9AblFqM3J0YklGcVRqRmlJM1YxaTdvaWdnZjBIYkphckpQYVA8UWs8NktLc3REQmdwNDQwaW5PRm1IbG5CNTVdUGNRaGo3fycpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl" } } }, "ReturnUrl": { "type": "string", "description": "The URL to return to after a successful payment", "default": "https://app.example.com" }, "SuccessUrl": { "type": "string", "description": "The URL to return to after a successful payment", "default": "https://app.example.com" }, "CancelUrl": { "type": "string", "description": "The URL to return to after a canceled payment", "default": "https://app.example.com" }, "UiMode": { "type": "string", "description": "Which UI Mode to create the checkout session in", "default": "hosted", "example": "embedded" }, "CreditShareApprovals": { "type": "array", "items": { "type": "object", "properties": { "approvalDataItemId": { "type": "string", "description": "The data item ID of the approval", "example": "abcdefghijklmnopqrxtuvwxyz123456789ABCDEFGH" }, "approvedAddress": { "type": "string", "description": "Approved wallet address", "example": "abcdefghijklmnopqrxtuvwxyz123456789ABCDEFGH" }, "payingAddress": { "type": "string", "description": "Paying wallet address", "example": "abcdefghijklmnopqrxtuvwxyz123456789ABCDEFGH" }, "approvedWincAmount": { "type": "string", "description": "The amount of winc approved", "example": "332824926" }, "usedWincAmount": { "type": "string", "description": "The amount of winc used", "example": "332824926" }, "creationDate": { "type": "string", "description": "The date and time the approval was created", "example": "2023-05-17T21:46:38.404Z" }, "expirationDate": { "type": "string", "description": "The date and time the approval expires", "example": "2023-05-17T21:46:38.404Z" } } } }, "X402PaymentRequirements": { "type": "object", "description": "x402 payment requirements returned in 402 Payment Required response", "properties": { "scheme": { "type": "string", "description": "The payment scheme (e.g., exact for EIP-3009)", "example": "exact" }, "network": { "type": "string", "description": "The blockchain network identifier", "example": "base-mainnet" }, "maxAmountRequired": { "type": "string", "description": "Maximum payment amount required in USDC atomic units (6 decimals)", "example": "1000000" }, "resource": { "type": "string", "description": "The resource URL being paid for", "example": "/v1/tx" }, "description": { "type": "string", "description": "Human-readable description of the resource", "example": "Upload data to Arweave via AR.IO Bundler" }, "mimeType": { "type": "string", "description": "MIME type of the resource response", "example": "application/json" }, "outputSchema": { "type": "object", "description": "JSON schema describing the resource response structure" }, "payTo": { "type": "string", "description": "The recipient address for the payment", "example": "0x6A0A10FFD285c971B841bee8892878c0d583Bf67" }, "maxTimeoutSeconds": { "type": "integer", "description": "Maximum time in seconds to complete the payment", "example": 300 }, "asset": { "type": "string", "description": "EIP-3009 compliant USDC contract address", "example": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" }, "extra": { "type": "object", "description": "Additional metadata about the payment asset", "properties": { "name": { "type": "string", "example": "USD Coin" }, "version": { "type": "string", "example": "2" } } } } }, "X402PaymentRequiredResponse": { "type": "object", "description": "402 Payment Required response with x402 payment options", "properties": { "x402Version": { "type": "integer", "description": "x402 protocol version", "example": 1 }, "accepts": { "type": "array", "description": "Array of accepted payment methods", "items": { "$ref": "#/components/schemas/X402PaymentRequirements" } }, "error": { "type": "string", "description": "Optional error message if price quote cannot be generated", "example": "Insufficient balance" } } }, "X402PaymentResult": { "type": "object", "description": "Result of x402 payment verification and settlement", "properties": { "success": { "type": "boolean", "description": "Whether the payment was successfully verified and settled", "example": true }, "paymentId": { "type": "string", "format": "uuid", "description": "Unique identifier for this payment transaction (UUID)", "example": "550e8400-e29b-41d4-a716-446655440000" }, "txHash": { "type": "string", "description": "Blockchain transaction hash for the USDC transfer (for on-chain verification)", "example": "0xb8a52725cdc816d060392dcecaa1528872acf9ea0bd097a86e2432dd5d2213ca" }, "network": { "type": "string", "description": "Network where payment was made", "example": "base-mainnet" }, "wincPaid": { "type": "string", "description": "Amount of winc paid/deducted", "example": "1000000" }, "wincReserved": { "type": "string", "description": "Amount of winc reserved for this upload", "example": "1000000" }, "wincCredited": { "type": "string", "description": "Amount of winc credited to account (for topup mode)", "example": "950000" }, "mode": { "type": "string", "description": "Payment mode used", "enum": [ "payg", "topup", "hybrid" ], "example": "hybrid" }, "error": { "type": "string", "description": "Error message if success is false", "example": "Invalid payment signature" } } }, "X402FinalizeResult": { "type": "object", "description": "Result of x402 payment finalization after actual upload size is known", "properties": { "success": { "type": "boolean", "description": "Whether finalization succeeded", "example": true }, "status": { "type": "string", "description": "Finalization status", "enum": [ "confirmed", "refunded", "fraud_penalty" ], "example": "confirmed" }, "actualByteCount": { "type": "integer", "description": "The actual byte count of the uploaded data item", "example": 1024 }, "refundWinc": { "type": "string", "description": "Amount of winc refunded if actual size was less than declared", "example": "50000" }, "error": { "type": "string", "description": "Error message if success is false", "example": "Payment not found" } } }, "ArNSIntent": { "type": "string", "description": "Intent for ArNS name operation", "enum": [ "buy-record", "upgrade-name", "extend-lease", "increase-undername-limit" ], "example": "buy-record" }, "ArNSNameType": { "type": "string", "description": "Type of ArNS name", "enum": [ "lease", "permabuy" ], "example": "lease" }, "ArNSPurchaseReceipt": { "type": "object", "description": "Receipt for an ArNS name purchase transaction", "properties": { "nonce": { "type": "string", "format": "uuid", "description": "Unique identifier for this purchase", "example": "550e8400-e29b-41d4-a716-446655440000" }, "name": { "type": "string", "description": "The ArNS name being purchased", "example": "myname" }, "intent": { "$ref": "#/components/schemas/ArNSIntent" }, "mARIOQty": { "type": "string", "description": "Quantity of mARIO tokens required", "example": "1000000" }, "wincQty": { "type": "string", "description": "Equivalent Winston credits", "example": "5000000000" }, "owner": { "type": "string", "description": "Arweave address of the name owner", "example": "abcdefghijklmnopqrxtuvwxyz123456789ABCDEFGH" }, "processId": { "type": "string", "description": "AR.IO process ID (optional for permabuy)", "example": "process123" }, "increaseQty": { "type": "integer", "description": "Quantity to increase (for increase-undername-limit)" }, "type": { "$ref": "#/components/schemas/ArNSNameType" }, "years": { "type": "integer", "description": "Number of years for lease", "example": 1 }, "messageId": { "type": "string", "description": "AR.IO message ID for the transaction", "example": "msg123" }, "status": { "type": "string", "description": "Status of the purchase", "enum": [ "PENDING", "CONFIRMED", "FAILED" ], "example": "PENDING" }, "usdArRate": { "type": "number", "description": "USD to AR exchange rate at time of purchase", "example": 5.42 }, "usdArioRate": { "type": "number", "description": "USD to ARIO exchange rate at time of purchase", "example": 0.012 } } }, "ArNSPurchaseQuote": { "type": "object", "description": "Quote for an ArNS name purchase via Stripe", "properties": { "nonce": { "type": "string", "format": "uuid", "description": "Unique identifier for this quote" }, "name": { "type": "string", "description": "The ArNS name being quoted" }, "intent": { "$ref": "#/components/schemas/ArNSIntent" }, "mARIOQty": { "type": "string", "description": "mARIO tokens required" }, "wincQty": { "type": "string", "description": "Winston credits equivalent" }, "paymentAmount": { "type": "integer", "description": "Fiat payment amount in smallest currency unit" }, "quotedPaymentAmount": { "type": "integer", "description": "Quoted payment amount before adjustments" }, "currencyType": { "type": "string", "description": "Fiat currency type", "example": "usd" }, "quoteExpirationDate": { "type": "string", "format": "date-time", "description": "When this quote expires" }, "paymentProvider": { "type": "string", "example": "stripe" }, "excessWincAmount": { "type": "string", "description": "Excess winc if payment exceeds minimum" }, "adjustments": { "$ref": "#/components/schemas/Adjustment" } } }, "CheckBalanceResult": { "type": "object", "description": "Result of balance sufficiency check", "properties": { "userHasSufficientBalance": { "type": "boolean", "description": "Whether user has sufficient balance", "example": true }, "bytesCostInWinc": { "type": "string", "description": "Cost in Winston for the byte count", "example": "1000000" }, "userBalanceInWinc": { "type": "string", "description": "User's current balance in Winston", "example": "5000000" }, "freeGrant": { "type": "boolean", "description": "True when the byte count is covered by a free-tier grant (bytesCostInWinc is then \"0\"). Only present on a free grant.", "example": true }, "tier": { "type": "string", "description": "The free-tier bucket that satisfied the grant (present only on a free grant).", "example": "lifetime" }, "adjustments": { "$ref": "#/components/schemas/Adjustment" } } } } }, "paths": { "/price/bytes/{byteCount}": { "get": { "tags": [ "Pricing" ], "summary": "Get Amount of Credits in winc for Byte Count", "description": "Returns the current amount of winc it will cost to upload a given byte count worth of data items", "parameters": [ { "name": "byteCount", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/ByteCount" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreditResponse" } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "default": "Invalid byte count" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "default": "Pricing Oracle Unavailable" } } } } } } }, "/price/{type}/{amount}": { "get": { "tags": [ "Pricing" ], "summary": "Get winc for Payment Type and Amount", "description": "Returns the current amount of winc this service will quote for a given payment type and amount", "parameters": [ { "name": "x-signature", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/SignatureHeader" } }, { "name": "x-nonce", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/NonceHeader" } }, { "name": "x-public-key", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/PublicKeyHeader" } }, { "name": "type", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/PriceFiatOrTokenType" } }, { "name": "amount", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/PaymentAmount" } }, { "name": "promoCode", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/PromoCode" } }, { "name": "destinationAddress", "in": "query", "required": false, "schema": { "type": "string", "description": "Destination wallet address. This will override the signature header's public key if provided" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaymentCreditResponse" } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "description": "Error message string dependent on cause", "example": "Payment Amount is Invalid" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "default": "Fiat Oracle Unavailable" } } } } } } }, "/balance": { "parameters": [ { "name": "x-signature", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/SignatureHeader" } }, { "name": "x-nonce", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/NonceHeader" } }, { "name": "x-public-key", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/PublicKeyHeader" } }, { "name": "address", "in": "query", "required": false, "schema": { "type": "string", "description": "Destination wallet address, required if no signature headers are provided" } } ], "get": { "tags": [ "Balance" ], "summary": "Get Current Balance of winc", "description": "Use a signed request or a previously obtained JWT to get the signing wallet's current service balance in winc", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BalanceResponse" } } } }, "403": { "description": "Forbidden", "content": { "text/plain": { "schema": { "type": "string", "default": "Invalid signature or missing required headers" } } } }, "404": { "description": "Not Found", "content": { "text/plain": { "schema": { "type": "string", "default": "User Not Found" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "default": "Database unavailable" } } } } } } }, "/top-up/{method}/{address}/{currency}/{amount}": { "get": { "tags": [ "Payments" ], "summary": "Get Top Up Quote for Credits", "description": "Get a top up quote and payment session for a given method (payment-intent or checkout-session), destination address, currency type, and payment amount", "parameters": [ { "name": "x-signature", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/SignatureHeader" } }, { "name": "x-nonce", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/NonceHeader" } }, { "name": "x-public-key", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/PublicKeyHeader" } }, { "name": "method", "in": "path", "required": true, "schema": { "type": "string", "example": "checkout-session" } }, { "name": "address", "in": "path", "required": true, "schema": { "type": "string", "description": "Destination wallet address" } }, { "name": "currency", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/CurrencyType" } }, { "name": "amount", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/PaymentAmount" } }, { "name": "promoCode", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/PromoCode" } }, { "name": "uiMode", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/UiMode" } }, { "name": "returnUrl", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/ReturnUrl" } }, { "name": "successUrl", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/SuccessUrl" } }, { "name": "cancelUrl", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/CancelUrl" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "paymentSession": { "allOf": [ { "$ref": "#/components/schemas/PaymentSession" } ] }, "topUpQuote": { "allOf": [ { "$ref": "#/components/schemas/TopUpQuote" } ] }, "adjustments": { "$ref": "#/components/schemas/Adjustment" }, "fees": { "$ref": "#/components/schemas/Adjustment" } } } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "description": "Error message string dependent on cause", "example": "Payment Amount is Invalid!" } } } }, "403": { "description": "Forbidden", "content": { "text/plain": { "schema": { "type": "string", "default": "Destination address is not a valid Arweave native address!" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "default": "Fiat Oracle Unavailable" } } } } } } }, "/currencies": { "get": { "tags": [ "Currencies" ], "summary": "Get Supported Currencies", "description": "Returns the current list of currency types supported by this service", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "supportedCurrencies": { "type": "array", "example": [ "usd", "jpy" ], "items": { "type": "string" } }, "limits": { "type": "object", "example": { "usd": { "minimumPaymentAmount": 500, "maximumPaymentAmount": 1000000, "suggestedPaymentAmounts": [ 2500, 5000, 10000 ], "zeroDecimalCurrency": false }, "jpy": { "minimumPaymentAmount": 750, "maximumPaymentAmount": 1500000, "suggestedPaymentAmounts": [ 3500, 6500, 15000 ], "zeroDecimalCurrency": true } } } } } } } } } } }, "/countries": { "get": { "tags": [ "Currencies" ], "summary": "Get Supported Countries", "description": "Returns the current list of currency types supported by this service", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "array", "example": [ "United Kingdom", "United States" ], "items": { "type": "string" } } } } } } } }, "/rates": { "get": { "tags": [ "Currencies" ], "summary": "Get conversion rates for 1GB of storage", "description": "Returns the supported fiat currency conversion rates for 1GB of storage based on current market prices.", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConversionRates" } } } } } } }, "/rates/{currency}": { "get": { "tags": [ "Currencies" ], "summary": "Get current conversion rate for 1 AR for a given currency", "description": "Returns the supported fiat currency conversion rate for 1AR based on current market prices.", "parameters": [ { "name": "currency", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/CurrencyType" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "currency": { "type": "string", "example": "usd" }, "rate": { "type": "number", "example": 5.61 } } } } } }, "404": { "description": "Not Found", "content": { "text/plain": { "schema": { "type": "string", "default": "Invalid currency" } } } } } } }, "/redeem": { "get": { "tags": [ "Redemption" ], "summary": "Redeem credits gifted via email", "description": "Redeem credits gifted via email by providing the destination wallet address for the credits, the redemption ID, and recipient email address", "parameters": [ { "name": "destinationAddress", "in": "query", "required": true, "schema": { "type": "string", "description": "Destination wallet address" } }, { "name": "id", "in": "query", "required": true, "schema": { "type": "string", "description": "ID for the redemption" } }, { "name": "email", "in": "query", "required": true, "schema": { "type": "string", "description": "Recipient email address for the redemption" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "Payment receipt redeemed for 1000 winc!" }, "userBalance": { "type": "string", "example": 1000 }, "userAddress": { "type": "string", "example": "abcdefghijklmnopqrxtuvwxyz123456789ABCDEFGH" }, "userCreationDate": { "type": "string", "example": "2023-05-17T21:46:38.404Z" } } } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "description": "Error message string dependent on cause", "example": "Failure to redeem payment receipt!" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "default": "Error while redeeming payment receipt. Unable to reach Database!" } } } } } } }, "/account/free": { "get": { "tags": [ "Balance" ], "summary": "Get a wallet's remaining free-tier allowance", "description": "Open-by-address, read-only, and **advisory**: how much of the free tier a\nwallet has left, so a client can decide up front whether an upload will be\nfree. Unlike `/balance` this works for a wallet with no account row yet (a\nbrand-new or free-only wallet still has a full allowance), so it never\n404s the free-tier audience. The authoritative decision still happens at\nupload time (reserve-balance), and the figure is a point-in-time snapshot.\n", "parameters": [ { "name": "address", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Wallet address to look up (Arweave, Ethereum, or Solana). Ethereum addresses are normalized to their EIP-55 checksum form." } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FreeAllowanceResponse" } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "default": "Missing address in query parameters" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "default": "Cloud Database Unavailable" } } } } } } }, "/account/balance": { "get": { "tags": [ "Balance" ], "summary": "Get Current Balance of winc (ecosystem-compatible)", "description": "Stable-API alias for the balance lookup. Resolves the wallet address from\nthe `address` query parameter (or a signed request) and returns the\ncurrent balance in winc.\n", "parameters": [ { "name": "address", "in": "query", "required": false, "schema": { "type": "string", "description": "Wallet address to look up. Required if no signature headers are provided." } }, { "name": "x-signature", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/SignatureHeader" } }, { "name": "x-nonce", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/NonceHeader" } }, { "name": "x-public-key", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/PublicKeyHeader" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BalanceResponse" } } } }, "403": { "description": "Forbidden", "content": { "text/plain": { "schema": { "type": "string", "default": "Invalid signature or missing required headers" } } } }, "404": { "description": "Not Found", "content": { "text/plain": { "schema": { "type": "string", "default": "User Not Found" } } } } } } }, "/account/balance/{token}": { "get": { "tags": [ "Balance" ], "summary": "Get Current Balance of winc for a token (ecosystem-compatible)", "description": "Stable-API alias for the balance lookup, scoped by a token path segment\n(currently unused - kept for ecosystem compatibility). Resolves the wallet\naddress from the `address` query parameter (or a signed request) and\nreturns the current balance in winc.\n", "parameters": [ { "name": "token", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/TokenType" }, "description": "Currently unused, kept for ecosystem compatibility." }, { "name": "address", "in": "query", "required": false, "schema": { "type": "string", "description": "Wallet address to look up. Required if no signature headers are provided." } }, { "name": "x-signature", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/SignatureHeader" } }, { "name": "x-nonce", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/NonceHeader" } }, { "name": "x-public-key", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/PublicKeyHeader" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BalanceResponse" } } } }, "403": { "description": "Forbidden", "content": { "text/plain": { "schema": { "type": "string", "default": "Invalid signature or missing required headers" } } } }, "404": { "description": "Not Found", "content": { "text/plain": { "schema": { "type": "string", "default": "User Not Found" } } } } } }, "post": { "tags": [ "Payments" ], "summary": "Post a pending payment transaction", "description": "Post a transaction ID that has been sent to the payment service's wallet", "requestBody": { "required": true, "description": "JSON with `tx_id` key of the pending payment transaction", "content": { "application/json": { "schema": { "type": "object", "properties": { "tx_id": { "type": "string", "description": "The transaction ID of the pending payment transaction" } } } } } }, "parameters": [ { "name": "token", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/TokenType" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "Transaction credited" }, "creditedTransaction": { "$ref": "#/components/schemas/CreditedPaymentTx" } } } } } }, "202": { "description": "Accepted", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "Transaction pending" }, "pendingTransaction": { "$ref": "#/components/schemas/PendingPaymentTx" } } } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "description": "Error message string dependent on cause", "example": "Transaction ID is invalid!" } }, "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "Transaction has already failed!" }, "failedTransaction": { "$ref": "#/components/schemas/FailedPaymentTx" } } } } } }, "404": { "description": "Not Found", "content": { "text/plain": { "schema": { "type": "string", "default": "Transaction ID not found!" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "default": "Error while processing transaction!" } } } } } } }, "/account/approvals": { "get": { "tags": [ "Approvals" ], "summary": "Get credit share approvals for a given payingAddress and approvedAddress", "description": "Get credit share approvals for a given payingAddress and approvedAddress", "parameters": [ { "name": "payingAddress", "in": "query", "required": true, "schema": { "type": "string", "description": "Paying wallet address" } }, { "name": "approvedAddress", "in": "query", "required": true, "schema": { "type": "string", "description": "Approved wallet address" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "approvals": { "$ref": "#/components/schemas/CreditShareApprovals" }, "amount": { "type": "string", "example": "332824926", "description": "Total amount of remaining approved winc for the given payingAddress and approvedAddress" }, "expiresBy": { "type": "number", "example": 123456789, "description": "The unix timestamp of the earliest expiration date on the approval" } } } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "description": "Error message string dependent on cause", "example": "Invalid paying address!" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "default": "Internal server error" } } } } } } }, "/account/approvals/get": { "get": { "tags": [ "Approvals" ], "summary": "Get all credit share approvals for a given payingAddress and approvedAddress", "description": "Get all credit share approvals for a given userAddress", "parameters": [ { "name": "userAddress", "in": "query", "required": true, "schema": { "type": "string", "description": "Paying wallet address" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "givenApprovals": { "$ref": "#/components/schemas/CreditShareApprovals" }, "receivedApprovals": { "$ref": "#/components/schemas/CreditShareApprovals" } } } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "description": "Error message string dependent on cause", "example": "Invalid paying address!" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "default": "Internal server error" } } } } } } }, "/x402/price/{signatureType}/{address}": { "get": { "tags": [ "x402" ], "summary": "Get x402 payment requirements for upload", "description": "Returns payment requirements for uploading data of a given size. This is the first step in the x402 payment flow.\n\n**IMPORTANT: Per x402 standard, this endpoint returns 200 OK (not 402).**\nThe actual 402 Payment Required response happens at the protected resource (upload endpoint at /v1/tx).\n\n**Three-Phase x402 Flow:**\n1. **Price Quote** (this endpoint): Client gets payment requirements → 200 OK with requirements\n2. **Upload Attempt**: Client uploads to /v1/tx without payment → 402 Payment Required\n3. **Paid Upload**: Client uploads to /v1/tx with X-PAYMENT header → 200 OK with receipt\n\n**Content Negotiation:**\n- **API clients** (Accept: application/json): Receive JSON payment requirements for programmatic use\n- **Browser clients** (Accept: text/html): Receive interactive HTML paywall (if X_402_CDP_CLIENT_KEY configured)\n\n**Browser Paywall Features** (when X_402_CDP_CLIENT_KEY environment variable is set):\n- Interactive payment authorization UI with wallet connection\n- MetaMask integration for EIP-712 signature generation\n- Coinbase Onramp widget for purchasing USDC if user lacks funds\n- Automatic base64 encoding of payment authorization\n- Copy-to-clipboard functionality for X-PAYMENT header value\n\n**Pricing Calculation:**\n- Converts byte count → Winston (Arweave storage cost)\n- Adds pricing buffer (default 5%) for volatility protection\n- Converts Winston → USD → USDC (6 decimals)\n- Returns maxAmountRequired in USDC smallest unit\n\n**Supported Networks:** base-sepolia, base-mainnet (configurable via X402_NETWORKS)\n", "parameters": [ { "name": "signatureType", "in": "path", "required": true, "schema": { "type": "integer", "description": "ANS-104 signature type for the data item:\n- 1: Arweave (RSA-PSS with SHA-256)\n- 3: Ethereum (ECDSA secp256k1)\n- 4: Solana (Ed25519)\n", "enum": [ 1, 3, 4 ], "example": 3 } }, { "name": "address", "in": "path", "required": true, "schema": { "type": "string", "description": "User's wallet address in format matching signatureType.\nUsed for tracking and analytics (not for payment verification).\n", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0" } }, { "name": "bytes", "in": "query", "required": true, "schema": { "type": "integer", "minimum": 1, "description": "Number of bytes to upload (data item size).\nUsed to calculate storage cost and USDC payment amount.\n", "example": 1024 } } ], "responses": { "200": { "description": "OK - Returns x402 payment requirements (per x402 standard, price quotes return 200 not 402).\n\n**Response format depends on Accept header:**\n- application/json: Structured payment requirements for programmatic use\n- text/html: Interactive paywall for browser users (if X_402_CDP_CLIENT_KEY configured)\n", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/X402PaymentRequiredResponse" }, "examples": { "SingleNetwork": { "summary": "Single network (base-mainnet only)", "value": { "x402Version": 1, "accepts": [ { "scheme": "exact", "network": "base-mainnet", "maxAmountRequired": "1000000", "resource": "/v1/tx", "description": "Upload 1024 bytes to Arweave via AR.IO Bundler", "mimeType": "application/json", "outputSchema": { "type": "object", "properties": { "id": { "type": "string", "description": "Data item ID" }, "timestamp": { "type": "number", "description": "Upload timestamp" }, "x402Payment": { "type": "object", "description": "x402 payment details" } } }, "payTo": "0x6A0A10FFD285c971B841bee8892878c0d583Bf67", "maxTimeoutSeconds": 300, "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "extra": { "name": "USD Coin", "version": "2" } } ] } }, "MultipleNetworks": { "summary": "Multiple networks enabled", "value": { "x402Version": 1, "accepts": [ { "scheme": "exact", "network": "base-mainnet", "maxAmountRequired": "1000000", "resource": "/v1/tx", "description": "Upload 1024 bytes to Arweave via AR.IO Bundler", "mimeType": "application/json", "payTo": "0x6A0A10FFD285c971B841bee8892878c0d583Bf67", "maxTimeoutSeconds": 300, "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "extra": { "name": "USD Coin", "version": "2" } }, { "scheme": "exact", "network": "base-sepolia", "maxAmountRequired": "1000000", "resource": "/v1/tx", "description": "Upload 1024 bytes to Arweave via AR.IO Bundler", "mimeType": "application/json", "payTo": "0x6A0A10FFD285c971B841bee8892878c0d583Bf67", "maxTimeoutSeconds": 300, "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e", "extra": { "name": "USD Coin", "version": "2" } } ] } } } }, "text/html": { "schema": { "type": "string", "description": "Interactive HTML paywall (only for browser clients when X_402_CDP_CLIENT_KEY is configured).\n\n**Features:**\n- MetaMask wallet connection\n- EIP-712 payment authorization signing\n- Coinbase Onramp for purchasing USDC\n- Copy X-PAYMENT header to clipboard\n- Automatic retry with payment\n\n**When shown:** Accept: text/html AND User-Agent contains \"Mozilla\" AND X_402_CDP_CLIENT_KEY env var is set\n" }, "example": "\n\n
\nUpload Cost: 0.001000 USDC on Base
\n \n \n \n \n\n" } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "example": "Invalid byte count" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "example": "Pricing oracle unavailable" } } } } } } }, "/x402/payment/{signatureType}/{address}": { "post": { "tags": [ "x402" ], "summary": "Verify and settle x402 payment", "description": "Verifies an EIP-3009 payment authorization and settles payment on-chain according to the specified mode.\n\n**This is Phase 2 of the x402 flow** - verifying and settling the payment.\n\n**Process:**\n1. Decode base64 payment header to extract EIP-3009 authorization\n2. Verify EIP-712 signature matches authorization parameters\n3. Check authorization hasn't been used or expired\n4. Call USDC contract's `receiveWithAuthorization()` to settle payment\n5. Convert USDC → Winston (Arweave storage credits)\n6. Apply payment according to mode (payg, topup, or hybrid)\n7. Record transaction in database with payment ID\n8. Return success with transaction hash for verification\n\n**Payment Modes:**\n- **payg** (Pay-as-you-go): Payment reserved for specific upload only\n- **topup**: Entire payment amount credited to user's account balance\n- **hybrid**: Reserve for upload + credit any excess to balance (DEFAULT)\n\n**Security:**\n- EIP-712 signature verification prevents unauthorized transfers\n- Nonce prevents replay attacks\n- validBefore/validAfter enforce time bounds\n- On-chain settlement provides cryptographic proof\n\n**Called by:** Upload service during data item upload when X-PAYMENT header is present\n", "parameters": [ { "name": "signatureType", "in": "path", "required": true, "schema": { "type": "integer", "description": "ANS-104 signature type (1=Arweave, 3=Ethereum, 4=Solana)", "enum": [ 1, 3, 4 ], "example": 3 } }, { "name": "address", "in": "path", "required": true, "schema": { "type": "string", "description": "User's wallet address (used for tracking, not payment verification)", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0" } } ], "requestBody": { "required": true, "description": "Payment authorization details extracted from X-PAYMENT header.\n\nThe upload service extracts this from the user's X-PAYMENT header and forwards it\nto the payment service for verification and settlement.\n", "content": { "application/json": { "schema": { "type": "object", "required": [ "paymentHeader", "byteCount" ], "properties": { "paymentHeader": { "type": "string", "format": "byte", "description": "Base64-encoded x402 payment authorization (same value from X-PAYMENT header).\n\n**Decodes to JSON with:**\n- x402Version: 1\n- scheme: \"exact\"\n- network: \"base-mainnet\" or \"base-sepolia\"\n- payload:\n - signature: EIP-712 signature of authorization\n - authorization:\n - from: Payer's Ethereum address\n - to: Recipient address (service's Ethereum wallet)\n - value: USDC amount in smallest unit (6 decimals)\n - validAfter: Unix timestamp\n - validBefore: Unix timestamp\n - nonce: Unique nonce (bytes32)\n", "example": "eyJ4NDAyVmVyc2lvbiI6MSwic2NoZW1lIjoiZXhhY3QiLCJuZXR3b3JrIjoiYmFzZS1tYWlubmV0IiwicGF5bG9hZCI6eyJzaWduYXR1cmUiOiIweGFiY2RlZi4uLiIsImF1dGhvcml6YXRpb24iOnsiZnJvbSI6IjB4NzQyZDM1Q2M2NjM0QzA1MzI5MjVhM2I4NDRCYzllNzU5NWYwYkViMCIsInRvIjoiMHg2QTBBMTBGZUQ4NWM5NzFCODQxYmVlODg5Mjg3OGMwZDU4M0JmNjciLCJ2YWx1ZSI6IjEwMDAwMDAiLCJ2YWxpZEFmdGVyIjowLCJ2YWxpZEJlZm9yZSI6MTczNTY4OTYwMCwibm9uY2UiOiIweDEyMzQ1Njc4OTBhYmNkZWYuLi4ifX19" }, "dataItemId": { "type": "string", "description": "Data item ID being uploaded (optional for PAYG mode).\n\nFor PAYG mode, this can be provided later via link endpoint.\nFor hybrid mode, this is required upfront.\n", "example": "QpmY8mZmFEC8RxNsgbxSV6e36OF6quIYaPRKzvUco0o" }, "byteCount": { "type": "integer", "minimum": 1, "description": "Declared byte count for the upload (required for PAYG and hybrid modes).\n\nUsed to calculate Winston cost and determine if payment is sufficient.\nMust match Content-Length header from upload request.\n", "example": 1024 }, "mode": { "type": "string", "description": "Payment mode - determines how payment is applied.\n\n**payg**: Payment reserved for this specific upload only\n**topup**: Entire payment credited to account balance\n**hybrid**: Reserve for upload + credit excess (DEFAULT)\n\nMost x402 clients use \"payg\" for stateless pay-per-upload.\n", "enum": [ "payg", "topup", "hybrid" ], "default": "hybrid", "example": "payg" } } }, "examples": { "PaygMode": { "summary": "Pay-as-you-go (most common for x402)", "value": { "paymentHeader": "eyJ4NDAyVmVyc2lvbiI6MSwic2NoZW1lIjoiZXhhY3QiLCJuZXR3b3JrIjoiYmFzZS1tYWlubmV0IiwicGF5bG9hZCI6ey4uLn19", "dataItemId": "QpmY8mZmFEC8RxNsgbxSV6e36OF6quIYaPRKzvUco0o", "byteCount": 1024, "mode": "payg" } }, "HybridMode": { "summary": "Hybrid (reserve + credit excess)", "value": { "paymentHeader": "eyJ4NDAyVmVyc2lvbiI6MSwic2NoZW1lIjoiZXhhY3QiLCJuZXR3b3JrIjoiYmFzZS1tYWlubmV0IiwicGF5bG9hZCI6ey4uLn19", "dataItemId": "QpmY8mZmFEC8RxNsgbxSV6e36OF6quIYaPRKzvUco0o", "byteCount": 1024, "mode": "hybrid" } } } } } }, "responses": { "200": { "description": "Payment verified and settled successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/X402PaymentResult" } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "example": "Invalid payment header" } } } }, "402": { "description": "Payment verification failed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/X402PaymentResult" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "example": "Payment service unavailable" } } } } } } }, "/x402/finalize": { "post": { "tags": [ "x402" ], "summary": "Finalize x402 payment after upload", "description": "Finalizes an x402 payment after upload completes by comparing declared vs actual byte count.\n\n**This is Phase 3 of the x402 flow** - fraud detection and finalization.\n\n**Called by:** Upload service after data item is fully received and validated.\n\n**Process:**\n1. Retrieve payment record by data item ID\n2. Compare actualByteCount vs declaredByteCount (from X-PAYMENT)\n3. Apply fraud tolerance threshold (default 5%)\n4. Determine status: confirmed, refunded, or fraud_penalty\n5. Issue refund if overpaid (actual < declared)\n6. Keep payment as penalty if underpaid (actual > declared + tolerance)\n7. Update payment record with final status\n\n**Fraud Detection:**\n- **Within tolerance**: Payment confirmed, upload proceeds\n- **Overpayment** (actual < declared - 5%): Refund difference to user\n- **Fraud** (actual > declared + 5%): Keep payment as penalty, reject upload\n\n**Why this matters:**\nUsers must provide Content-Length header accurately. If they lie about upload size\nto pay less, the system detects this and penalizes them by keeping the payment.\n\n**Security:** Prevents users from declaring small uploads but uploading large data.\n", "requestBody": { "required": true, "description": "Actual upload details after data item has been fully received", "content": { "application/json": { "schema": { "type": "object", "required": [ "dataItemId", "actualByteCount" ], "properties": { "dataItemId": { "type": "string", "description": "Data item ID that was uploaded (links to payment record)", "example": "QpmY8mZmFEC8RxNsgbxSV6e36OF6quIYaPRKzvUco0o" }, "actualByteCount": { "type": "integer", "minimum": 1, "description": "Actual byte count after upload completed and data item validated.\n\nThis is the true size of the ANS-104 data item (headers + payload).\nCompared against declaredByteCount from payment verification phase.\n", "example": 1024 } } }, "examples": { "MatchingSize": { "summary": "Actual matches declared (within tolerance)", "value": { "dataItemId": "QpmY8mZmFEC8RxNsgbxSV6e36OF6quIYaPRKzvUco0o", "actualByteCount": 1024 } }, "Overpayment": { "summary": "Actual less than declared (refund issued)", "value": { "dataItemId": "QpmY8mZmFEC8RxNsgbxSV6e36OF6quIYaPRKzvUco0o", "actualByteCount": 900 } }, "FraudAttempt": { "summary": "Actual exceeds declared (fraud penalty)", "value": { "dataItemId": "QpmY8mZmFEC8RxNsgbxSV6e36OF6quIYaPRKzvUco0o", "actualByteCount": 1200 } } } } } }, "responses": { "200": { "description": "Payment finalized successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/X402FinalizeResult" } } } }, "404": { "description": "Payment not found", "content": { "text/plain": { "schema": { "type": "string", "example": "Payment not found for data item" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "example": "Payment service unavailable" } } } } } } }, "/x402/top-up/{signatureType}/{address}": { "post": { "tags": [ "x402" ], "summary": "Top up credits using x402 payment", "description": "Top up your account balance by purchasing storage credits with USDC via x402.\n\n**This is a pure x402 flow** - the resource being purchased is \"storage credits.\"\n\n**Flow:**\n1. **First request (no X-PAYMENT header):** Returns 402 Payment Required with payment requirements\n2. **Retry with X-PAYMENT header:** Verifies payment, settles USDC, credits balance\n\n**Key Differences from Upload Payment:**\n- No data item involved - just purchasing credits\n- Supports multiple signature types (Arweave, Ethereum, Solana)\n- Entire payment amount converted to credits and added to balance\n- Can be used for any future uploads\n\n**Use Case:** AI agents or users who want to prepay for storage using USDC\n\n**Note:** While x402 currently only supports EVM chains (Base, Ethereum, Polygon),\nthis endpoint accepts signatureType for forward compatibility with future payment methods.\n", "parameters": [ { "name": "signatureType", "in": "path", "required": true, "schema": { "type": "integer", "enum": [ 1, 3, 4 ], "description": "ANS-104 signature type:\n- 1: Arweave (RSA-PSS)\n- 3: Ethereum (ECDSA secp256k1)\n- 4: Solana (EdDSA ed25519)\n\nCurrently, x402 only supports signatureType 3 (Ethereum), but this parameter\nis included for forward compatibility.\n", "example": 3 } }, { "name": "address", "in": "path", "required": true, "schema": { "type": "string", "description": "User address that will receive the credits. Format depends on signatureType:\n- signatureType 1: Base64URL Arweave address\n- signatureType 3: 0x-prefixed Ethereum address (current x402 support)\n- signatureType 4: Base58 Solana address\n", "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0" } } ], "requestBody": { "required": true, "description": "Request body for top-up. On first request (without X-PAYMENT), this tells the service\nhow many bytes worth of credits you want to purchase.\n", "content": { "application/json": { "schema": { "type": "object", "required": [ "bytes" ], "properties": { "bytes": { "type": "integer", "minimum": 1, "description": "Number of bytes worth of storage credits to purchase.\n\nThis determines the USDC price. For example:\n- 1 GB (1,000,000,000 bytes) might cost ~$0.005 USDC\n- 10 GB (10,000,000,000 bytes) might cost ~$0.05 USDC\n\nThe service calculates: bytes → Winston → USD → USDC\n", "example": 10000000000 } } }, "examples": { "SmallTopUp": { "summary": "Top up for 1 GB", "value": { "bytes": 1000000000 } }, "LargeTopUp": { "summary": "Top up for 100 GB", "value": { "bytes": 100000000000 } } } } } }, "responses": { "200": { "description": "OK - Payment verified, settled, and credits added to balance.\n\nThe entire USDC payment has been converted to Winston credits and\ncredited to the user's account balance.\n", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "description": "Whether the top-up succeeded", "example": true }, "creditsGranted": { "type": "string", "description": "Amount of Winston credits granted (added to balance)", "example": "10000000000" }, "balance": { "type": "string", "description": "New total account balance in Winston", "example": "15000000000" }, "txHash": { "type": "string", "description": "Blockchain transaction hash for USDC payment", "example": "0xb8a52725cdc816d060392dcecaa1528872acf9ea0bd097a86e2432dd5d2213ca" }, "paymentId": { "type": "string", "format": "uuid", "description": "Unique payment ID for this transaction", "example": "550e8400-e29b-41d4-a716-446655440000" }, "network": { "type": "string", "description": "Network where payment was made", "example": "base-mainnet" } } }, "examples": { "Successful": { "summary": "Successfully topped up 10 GB", "value": { "success": true, "creditsGranted": "10000000000", "balance": "15000000000", "txHash": "0xb8a52725cdc816d060392dcecaa1528872acf9ea0bd097a86e2432dd5d2213ca", "paymentId": "550e8400-e29b-41d4-a716-446655440000", "network": "base-mainnet" } } } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "example": "Invalid bytes parameter" } } } }, "402": { "description": "Payment Required - No X-PAYMENT header provided, or payment verification failed.\n\nClient should:\n1. Parse payment requirements from response\n2. Create EIP-3009 payment authorization\n3. Sign with EIP-712\n4. Retry request with X-PAYMENT header\n", "headers": { "X-Payment-Required": { "schema": { "type": "string", "example": "x402-1" }, "description": "Indicates x402 protocol version 1 is supported" } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/X402PaymentRequiredResponse" }, "examples": { "SingleNetwork": { "summary": "Payment required for 10 GB topup", "value": { "x402Version": 1, "accepts": [ { "scheme": "exact", "network": "base-mainnet", "maxAmountRequired": "50000", "resource": "/v1/x402/top-up/3/0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0", "description": "Top up storage credits for 10000000000 bytes", "mimeType": "application/json", "outputSchema": { "type": "object", "properties": { "success": { "type": "boolean" }, "creditsGranted": { "type": "string", "description": "Winston credits granted" }, "balance": { "type": "string", "description": "New total balance" }, "txHash": { "type": "string", "description": "Blockchain transaction hash" }, "paymentId": { "type": "string", "description": "Payment ID (UUID)" } } }, "payTo": "0x6A0A10FFD285c971B841bee8892878c0d583Bf67", "maxTimeoutSeconds": 300, "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "extra": { "name": "USD Coin", "version": "2" } } ] } } } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "example": "x402 payments are not currently available" } } } } } } }, "/info": { "get": { "tags": [ "Info" ], "summary": "Get service information", "description": "Get the current version of the service and the addresses for the supported blockchains", "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "version": { "type": "string", "example": "0.2.0" }, "addresses": { "type": "object", "description": "Payment recipient addresses per token. Only tokens configured on\nthe service are present. `ed25519` aliases `solana`, and `pol`\naliases `matic`.\n", "properties": { "arweave": { "type": "string", "example": "JNC6vBhjHY1EPwV3pEeNmrsgFMxH5d38_LHsZ7jful8" }, "ethereum": { "type": "string", "example": 6.053775100077233e+47 }, "solana": { "type": "string", "example": "HepiT2k93CFQaSB7i3ZNXhybZKn5MeWiv3UkLsaJKk4i" }, "ed25519": { "type": "string", "description": "Alias for the Solana address.", "example": "HepiT2k93CFQaSB7i3ZNXhybZKn5MeWiv3UkLsaJKk4i" }, "ario": { "type": "string", "description": "ARIO SPL-token payment recipient (defaults to the Solana address unless ARIO_ADDRESS is set).", "example": "HepiT2k93CFQaSB7i3ZNXhybZKn5MeWiv3UkLsaJKk4i" }, "matic": { "type": "string", "example": 6.053775100077233e+47 }, "pol": { "type": "string", "description": "Alias for the Matic (Polygon) address.", "example": 6.053775100077233e+47 }, "base-eth": { "type": "string", "example": 6.053775100077233e+47 }, "usdc": { "type": "string", "description": "ERC-20 USDC on Ethereum. Present when ETHEREUM_ADDRESS is configured — an ERC-20 balance sits at the SAME EOA as `ethereum`, so this is that address, not a separate wallet.", "example": 6.053775100077233e+47 }, "base-usdc": { "type": "string", "description": "ERC-20 USDC on Base. Present when BASE_ETH_ADDRESS is configured — same EOA as `base-eth`.", "example": 6.053775100077233e+47 }, "kyve": { "type": "string", "example": "kyve1clmuh5sjw73784lg0gnf4p07qefzrtk78an698" } }, "example": { "arweave": "JNC6vBhjHY1EPwV3pEeNmrsgFMxH5d38_LHsZ7jful8", "ethereum": 6.053775100077233e+47, "solana": "HepiT2k93CFQaSB7i3ZNXhybZKn5MeWiv3UkLsaJKk4i", "ed25519": "HepiT2k93CFQaSB7i3ZNXhybZKn5MeWiv3UkLsaJKk4i", "ario": "HepiT2k93CFQaSB7i3ZNXhybZKn5MeWiv3UkLsaJKk4i", "matic": 6.053775100077233e+47, "pol": 6.053775100077233e+47, "base-eth": 6.053775100077233e+47, "usdc": 6.053775100077233e+47, "base-usdc": 6.053775100077233e+47, "kyve": "kyve1clmuh5sjw73784lg0gnf4p07qefzrtk78an698" } }, "gateway": { "type": "string", "description": "The primary gateway (first entry of gateways).", "example": "https://arweave.net/" }, "gateways": { "type": "array", "description": "All public-facing gateway URLs advertised by the service.", "items": { "type": "string" }, "example": [ "https://arweave.net/" ] } } } } } } } } }, "/arns/price/{intent}/{name}": { "get": { "tags": [ "ArNS" ], "summary": "Get price for ArNS name registration or operation", "description": "Returns the mARIO (AR.IO token) and Winston credit cost for an ArNS name operation.\n\nOptionally includes a fiat currency estimate if the `currency` query parameter is provided.\n\n**Supported Intents:**\n- **buy-record**: Purchase a new ArNS name\n- **upgrade-name**: Upgrade a lease to permabuy\n- **extend-lease**: Extend the lease duration\n- **increase-undername-limit**: Increase the number of permitted undernames\n", "parameters": [ { "name": "x-signature", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/SignatureHeader" } }, { "name": "x-nonce", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/NonceHeader" } }, { "name": "x-public-key", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/PublicKeyHeader" } }, { "name": "intent", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/ArNSIntent" } }, { "name": "name", "in": "path", "required": true, "schema": { "type": "string", "description": "The ArNS name (without .ar suffix)", "example": "myname" } }, { "name": "currency", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/CurrencyType" }, "description": "If provided, includes a fiat currency estimate in the response" }, { "name": "years", "in": "query", "required": false, "schema": { "type": "integer", "description": "Number of years for lease (required for buy-record and extend-lease)", "example": 1 } }, { "name": "type", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/ArNSNameType" }, "description": "Type of name registration (required for buy-record)" }, { "name": "increaseQty", "in": "query", "required": false, "schema": { "type": "integer", "description": "Quantity to increase (required for increase-undername-limit)" } }, { "name": "processId", "in": "query", "required": false, "schema": { "type": "string", "description": "AR.IO process ID (optional)" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "mARIO": { "type": "string", "description": "mARIO token cost", "example": "1000000" }, "winc": { "type": "string", "description": "Winston credit cost of the NAME ONLY. For a buy-name this EXCLUDES the ANT spawn surcharge — quote wincTotalWithAntSpawn instead, or you will under-quote the purchase.", "example": "974711979594" }, "antSpawnSurchargeWinc": { "type": "string", "description": "Flat cost-recovery surcharge for the Solana rent Turbo fronts when minting the customer's ANT. Present only for intents that mint one (buy-name/buy-record). Config-driven and, with ARNS_RENT_SURCHARGE_ENABLED, derived per-request from live SOL/AR rates — never hardcode it.", "example": "600000000000" }, "wincTotalWithAntSpawn": { "type": "string", "description": "winc + antSpawnSurchargeWinc. THIS is the figure to charge or display for a purchase. Present only when a surcharge applies.", "example": "1474711979594" }, "fiatEstimate": { "type": "object", "description": "Fiat estimate (only if currency parameter provided)", "properties": { "paymentAmount": { "type": "integer", "description": "BASE payment amount in the smallest currency unit — excludes the ANT spawn surcharge. Use paymentAmountWithAntSpawn for the total." }, "paymentAmountWithAntSpawn": { "type": "integer", "description": "Total payment amount including the ANT spawn surcharge. Present only when a surcharge applies." }, "antSpawnSurchargeAmount": { "type": "integer", "description": "The surcharge alone, in the smallest currency unit." }, "quotedPaymentAmount": { "type": "integer", "description": "Quoted amount before adjustments" }, "excessWincAmount": { "type": "string", "description": "Excess winc if payment exceeds minimum" }, "adjustments": { "$ref": "#/components/schemas/Adjustment" }, "fees": { "$ref": "#/components/schemas/Adjustment" } } } } } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "example": "Invalid ArNS name" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "example": "Price Oracle Unavailable" } } } } } } }, "/arns/purchase/{nonce}": { "get": { "tags": [ "ArNS" ], "summary": "Get ArNS purchase status", "description": "Retrieves the status of an ArNS purchase transaction by its nonce (unique ID).\n\nUse this endpoint to track the progress of a purchase initiated via POST /arns/purchase.\n", "parameters": [ { "name": "nonce", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid", "description": "The unique nonce returned when the purchase was initiated" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ArNSPurchaseReceipt" } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "example": "Purchase status not found" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "example": "Database unavailable" } } } } } } }, "/arns/quote/{method}/{address}/{currency}/{intent}/{name}": { "get": { "tags": [ "ArNS" ], "summary": "Get Stripe payment quote for ArNS name purchase", "description": "Creates a Stripe payment session (checkout or payment intent) for purchasing an ArNS name with fiat currency.\n\nThis endpoint:\n1. Calculates the mARIO and Winston credit cost\n2. Converts to the requested fiat currency\n3. Creates a Stripe payment session\n4. Stores a quote in the database\n5. Returns both the quote and payment session\n\n**Payment Methods:**\n- **checkout-session**: Full Stripe Checkout experience (redirects to Stripe)\n- **payment-intent**: Embedded payment flow (integrate in your UI)\n", "parameters": [ { "name": "x-signature", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/SignatureHeader" } }, { "name": "x-nonce", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/NonceHeader" } }, { "name": "x-public-key", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/PublicKeyHeader" } }, { "name": "method", "in": "path", "required": true, "schema": { "type": "string", "enum": [ "checkout-session", "payment-intent" ], "description": "Stripe payment method type" } }, { "name": "address", "in": "path", "required": true, "schema": { "type": "string", "description": "Destination Arweave address" } }, { "name": "currency", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/CurrencyType" } }, { "name": "intent", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/ArNSIntent" } }, { "name": "name", "in": "path", "required": true, "schema": { "type": "string", "description": "The ArNS name (without .ar suffix)" } }, { "name": "promoCode", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/PromoCode" } }, { "name": "uiMode", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/UiMode" } }, { "name": "returnUrl", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/ReturnUrl" } }, { "name": "successUrl", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/SuccessUrl" } }, { "name": "cancelUrl", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/CancelUrl" } }, { "name": "years", "in": "query", "required": false, "schema": { "type": "integer" } }, { "name": "type", "in": "query", "required": false, "schema": { "$ref": "#/components/schemas/ArNSNameType" } }, { "name": "increaseQty", "in": "query", "required": false, "schema": { "type": "integer" } }, { "name": "processId", "in": "query", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "purchaseQuote": { "$ref": "#/components/schemas/ArNSPurchaseQuote" }, "paymentSession": { "$ref": "#/components/schemas/PaymentSession" }, "adjustments": { "$ref": "#/components/schemas/Adjustment" }, "fees": { "$ref": "#/components/schemas/Adjustment" } } } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "example": "Invalid parameters" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "example": "Stripe unavailable" } } } } } } }, "/arns/my-names/{address}": { "get": { "tags": [ "ArNS" ], "summary": "List the ArNS names a wallet bought through Turbo", "description": "Receipt history for a wallet — NOT an ownership oracle. A name that was\ntransferred away keeps its receipt and still appears here, so read\npresent control from the chain using the returned `antId`.\n\nOpen-by-address (no signature), mirroring `/account/balance`.\n", "parameters": [ { "name": "address", "in": "path", "required": true, "schema": { "type": "string", "description": "The wallet's Turbo identity (native address)." } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "names": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "antId": { "type": "string" }, "intent": { "type": "string" }, "type": { "type": "string", "enum": [ "lease", "permabuy" ] }, "years": { "type": "integer" }, "purchaseDate": { "type": "string", "format": "date-time" }, "custodial": { "type": "boolean", "description": "ALWAYS false. Turbo takes custody of no ANT, so\nthere is nothing for this to be true about. Retained\nfor wire compatibility; do not branch on it.\n" }, "selfCustody": { "type": "boolean" } } } } } } } } } } } }, "/arns/actions/{action}": { "post": { "tags": [ "ArNS" ], "summary": "Create an ArNS action", "description": "Creates and (where Turbo holds the authority) immediately performs an\nArNS action. Debits credits once, at creation, for ALL twelve actions —\nno action is free. The four ARIO-spending actions (`buy-name`,\n`extend-lease`, `upgrade-name`, `increase-undername-limit`) recover\ntheir registration cost; the other eight recover a small margin\nagainst Turbo's sponsored gas/rent.\n\n**Authorization:** payer signature always (x-signature / x-public-key /\nx-nonce). The five RECORD-SCOPED actions — `set-record`,\n`remove-record`, `set-record-metadata`, `remove-record-metadata` and\n`transfer-record` — additionally require the ANT owner's action-bound\nproof in the `x-owner-*` headers, verified against the ANT's CURRENT\nON-CHAIN owner. The proof binds every field it carries, so a signature\nauthorizing one set of metadata values does not authorize another.\n\n`set-record-metadata` fields are tri-state: omit one to leave it\nunchanged, or send `null` to clear it. Those are bound distinctly, so\n\"clear the description\" and \"set it to empty\" are different messages.\n\nThe returned `transaction` carries a Solana blockhash that dies in\n~60-90 seconds. Sign those exact bytes — never rebuild the message, or\nTurbo's fee-payer signature stops covering it.\n", "parameters": [ { "name": "action", "in": "path", "required": true, "schema": { "type": "string", "enum": [ "buy-name", "extend-lease", "upgrade-name", "increase-undername-limit", "set-record", "remove-record", "add-controller", "remove-controller", "transfer", "set-record-metadata", "remove-record-metadata", "transfer-record" ] } }, { "name": "x-signature", "in": "header", "required": true, "schema": { "$ref": "#/components/schemas/SignatureHeader" } }, { "name": "x-public-key", "in": "header", "required": true, "schema": { "$ref": "#/components/schemas/PublicKeyHeader" } }, { "name": "x-nonce", "in": "header", "required": true, "schema": { "$ref": "#/components/schemas/NonceHeader" } }, { "name": "x-owner-signature", "in": "header", "required": false, "schema": { "type": "string", "description": "The five RECORD-SCOPED actions only — `set-record`,\n`remove-record`, `set-record-metadata`, `remove-record-metadata`\nand `transfer-record`. Ed25519 signature by the ANT's Solana key\nover `[\"arns\", action, ...fields].join(\"\\n\")` + the x-owner-nonce.\nVerified against the ANT's CURRENT on-chain owner.\n" } }, { "name": "x-owner-public-key", "in": "header", "required": false, "schema": { "type": "string" } }, { "name": "x-owner-nonce", "in": "header", "required": false, "schema": { "type": "string" } }, { "name": "x-owner-signature-type", "in": "header", "required": false, "schema": { "type": "integer", "example": 4, "description": "Signature type of the owner key (4 = Solana)." } }, { "name": "name", "in": "query", "required": false, "schema": { "type": "string" }, "description": "ArNS name. Required for buy-name / extend-lease / upgrade-name / increase-undername-limit." }, { "name": "ownerAddress", "in": "query", "required": false, "schema": { "type": "string" }, "description": "The SOLANA address that owns (or will own) the ANT. NOT the wallet\nthat signed the request. Required for every ANT-scoped action.\n" }, { "name": "antId", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Existing ANT. Required for every action except the four name actions." }, { "name": "target", "in": "query", "required": false, "schema": { "type": "string" }, "description": "transfer destination, or the controller for add/remove-controller (defaults to Turbo)." }, { "name": "type", "in": "query", "required": false, "schema": { "type": "string", "enum": [ "lease", "permabuy" ] } }, { "name": "years", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 5 } }, { "name": "increaseQty", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1 } }, { "name": "undername", "in": "query", "required": false, "schema": { "type": "string", "maxLength": 61 } }, { "name": "transactionId", "in": "query", "required": false, "schema": { "type": "string" } }, { "name": "ttlSeconds", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 60, "maximum": 86400 } }, { "name": "displayName", "in": "query", "required": false, "schema": { "type": "string", "nullable": true }, "description": "set-record-metadata. Tri-state — omit to leave unchanged, send\n`null` (JSON body) to CLEAR, or a value to set.\n" }, { "name": "recordLogo", "in": "query", "required": false, "schema": { "type": "string", "nullable": true }, "description": "set-record-metadata. Tri-state, as displayName." }, { "name": "recordDescription", "in": "query", "required": false, "schema": { "type": "string", "nullable": true }, "description": "set-record-metadata. Tri-state, as displayName." }, { "name": "recordKeywords", "in": "query", "required": false, "schema": { "type": "string", "nullable": true }, "description": "set-record-metadata. Comma-separated in a query string, or a JSON\narray in a body. Tri-state, as displayName.\n" }, { "name": "paidBy", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Comma-separated addresses to charge instead of the signer, via a\ndelegated-payment approval they granted. Accepted in the query\nstring OR the JSON body — the turbo-sdk posts a bare path and puts\nevery param, this one included, in the body.\n" } ], "requestBody": { "required": false, "description": "Every parameter above may be sent as a JSON body instead of a query\nstring; the body wins where both are present. `antState` is\nbody-shaped and is the reason to prefer one — in a query string it\nmust be a JSON-encoded string.\n", "content": { "application/json": { "schema": { "type": "object", "properties": { "antState": { "$ref": "#/components/schemas/ArNSBuyAntState" }, "paidBy": { "type": "string", "description": "As the query parameter of the same name. Also accepted as a\nJSON array.\n" } } } } } }, "responses": { "200": { "description": "OK — inspect `status` to decide whether a signature is needed.", "content": { "application/json": { "schema": { "oneOf": [ { "$ref": "#/components/schemas/ArNSActionCompleted" }, { "$ref": "#/components/schemas/ArNSActionAwaitingSignature" } ] } } } }, "400": { "description": "Client error — unknown action, missing/invalid parameter, the gate is\noff, or the CHAIN rejected the instruction (the body names the Anchor\nerror). None of these succeed on retry.\n" }, "401": { "description": "Missing or invalid signature, or the owner proof is not from the ANT's current on-chain owner." }, "402": { "description": "Insufficient credits." }, "503": { "description": "Genuinely transient — retry is reasonable." } } } }, "/arns/actions/{action}/price": { "get": { "tags": [ "ArNS" ], "summary": "Price an ArNS action before creating it", "description": "Preview the winc a `POST /arns/actions/{action}` call for this SAME\naction will debit, without creating (or being charged for) one.\nCovers only the eight non-purchase actions (`set-record`,\n`remove-record`, `set-record-metadata`, `remove-record-metadata`,\n`transfer-record`, `add-controller`, `remove-controller`,\n`transfer`) — the four ARIO-purchase actions (`buy-name`,\n`extend-lease`, `upgrade-name`, `increase-undername-limit`) are\npriced by `GET /arns/price/{intent}/{name}` instead, since their\nprice depends on `name`/`type`/`years`/`increaseQty`, which this\nroute never asks for.\n\nBoth routes read the SAME pricing resolver the actual debit uses, so\na quote here cannot drift from what create actually charges.\n\n**No signature required.** The amount has no user-specific\ncomponent — it depends only on the action and live SOL/AR rates,\nnot on who is asking. Same 404-avoiding, \"a read costs nothing\"\nreasoning as `GET /arns/purchase/{nonce}`.\n", "parameters": [ { "name": "action", "in": "path", "required": true, "schema": { "type": "string", "enum": [ "set-record", "remove-record", "set-record-metadata", "remove-record-metadata", "transfer-record", "add-controller", "remove-controller", "transfer" ] } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "action": { "type": "string" }, "wincQty": { "type": "string", "description": "What POST /arns/actions/{action} will debit for this action right now." } } } } } }, "400": { "description": "Unknown action, one of the four ARIO-purchase actions (priced\nelsewhere — the body names the correct route), or the ArNS\nactions gate is off.\n" }, "503": { "description": "Genuinely transient (rate oracle unavailable) — retry is reasonable." } } } }, "/arns/actions/{nonce}/sign": { "post": { "tags": [ "ArNS" ], "summary": "Submit the owner-signed transaction for an action", "description": "One submit path for every action. Takes the base64 transaction returned\nby the create call, now carrying the ANT owner's signature.\n\n**No payer auth.** The authorization is the owner's signature inside the\ntransaction, which the chain enforces against those exact instructions;\nthe nonce is a random UUID capability. Requiring a second off-chain\nsignature would break flows where the signer is not the payer.\n\n**Idempotent.** A replay of a completed action returns its envelope with\n`alreadyCompleted: true` and performs no second purchase.\n", "parameters": [ { "name": "nonce", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "transaction" ], "properties": { "transaction": { "type": "string", "description": "Base64 wire transaction from the create call, signed by the ANT owner." } } } } } }, "responses": { "200": { "description": "OK — the action completed.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ArNSActionCompleted" } } } }, "400": { "description": "Unknown nonce, missing/malformed transaction bytes, the action has\nEXPIRED (its blockhash is dead — credits are refunded automatically),\nor the chain rejected the instruction.\n" }, "503": { "description": "Transient — the chain was unreadable, so nothing was submitted." } } } }, "/arns/actions/{nonce}": { "get": { "tags": [ "ArNS" ], "summary": "ArNS action status", "description": "Open by nonce (a random UUID handed only to the caller who created the\naction). Deliberately does NOT echo the transaction bytes.\n", "parameters": [ { "name": "nonce", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "nonce": { "type": "string" }, "action": { "type": "string" }, "status": { "type": "string", "enum": [ "awaiting-signature", "completed", "expired" ] }, "antId": { "type": "string" }, "name": { "type": "string" }, "ownerAddress": { "type": "string", "description": "The SOLANA key that owns the ANT." }, "paidBy": { "type": "string", "description": "The TURBO identity that was debited. Never merged with ownerAddress." }, "messageId": { "type": "string" }, "wincQty": { "type": "string" }, "expiresAt": { "type": "string", "format": "date-time" }, "createdDate": { "type": "string", "format": "date-time" } } } } } }, "404": { "description": "No action found for that nonce." } } } }, "/reserve-balance/{token}/{signerAddress}": { "get": { "tags": [ "Protected" ], "summary": "Reserve user balance for data upload", "description": "**PROTECTED ROUTE** - Requires `PRIVATE_ROUTE_SECRET` authentication header.\n\nReserves Winston credits from a user's balance for an upcoming data upload.\nCalled by the upload service before accepting a data item upload.\n\nThe reservation is temporary and will be:\n- Finalized (deducted) when upload completes successfully\n- Refunded if upload fails or is canceled\n\n**Authorization:** `x-auth-token` header must match `PRIVATE_ROUTE_SECRET` environment variable.\n", "parameters": [ { "name": "x-auth-token", "in": "header", "required": true, "schema": { "type": "string", "description": "Must match PRIVATE_ROUTE_SECRET" } }, { "name": "token", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/TokenType" }, "description": "Currently unused (kept for backward compatibility)" }, { "name": "signerAddress", "in": "path", "required": true, "schema": { "type": "string", "description": "User's wallet address" } }, { "name": "byteCount", "in": "query", "required": true, "schema": { "type": "integer", "description": "Number of bytes being uploaded" } }, { "name": "dataItemId", "in": "query", "required": true, "schema": { "type": "string", "description": "Data item ID for the upload" } }, { "name": "paidBy", "in": "query", "required": false, "schema": { "type": "string", "description": "Comma-separated list of addresses paying (delegated payment)" } }, { "name": "paymentDirective", "in": "query", "required": false, "schema": { "type": "string", "description": "Payment directive (e.g., x402 payment ID)" } }, { "name": "ipBucket", "in": "query", "required": false, "schema": { "type": "string", "description": "The client's subnet bucket, forwarded by the upload service so the per-IP free-tier cap can be evaluated when committing a free grant." } } ], "responses": { "200": { "description": "OK - Balance reserved successfully", "content": { "text/plain": { "schema": { "type": "string", "description": "Reserved Winston amount", "example": "1000000" } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "example": "Invalid parameters" } } } }, "401": { "description": "Unauthorized", "content": { "text/plain": { "schema": { "type": "string", "example": "Invalid authorization token" } } } }, "402": { "description": "Payment Required - Insufficient balance", "content": { "text/plain": { "schema": { "type": "string", "example": "Insufficient balance" } } } }, "404": { "description": "Not Found - User does not exist", "content": { "text/plain": { "schema": { "type": "string", "example": "User not found" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "example": "Error reserving balance" } } } } } } }, "/refund-balance/{token}/{signerAddress}": { "get": { "tags": [ "Protected" ], "summary": "Refund previously reserved balance", "description": "**PROTECTED ROUTE** - Requires `PRIVATE_ROUTE_SECRET` authentication header.\n\nRefunds Winston credits that were previously reserved for a data upload.\nCalled by the upload service when an upload fails or is canceled.\n\n**Authorization:** `x-auth-token` header must match `PRIVATE_ROUTE_SECRET` environment variable.\n", "parameters": [ { "name": "x-auth-token", "in": "header", "required": true, "schema": { "type": "string", "description": "Must match PRIVATE_ROUTE_SECRET" } }, { "name": "token", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/TokenType" }, "description": "Currently unused (kept for backward compatibility)" }, { "name": "signerAddress", "in": "path", "required": true, "schema": { "type": "string", "description": "User's wallet address" } }, { "name": "winstonCredits", "in": "query", "required": true, "schema": { "type": "string", "description": "Winston amount to refund" } }, { "name": "dataItemId", "in": "query", "required": true, "schema": { "type": "string", "description": "Data item ID for the failed/canceled upload" } } ], "responses": { "200": { "description": "OK - Balance refunded successfully", "content": { "text/plain": { "schema": { "type": "string", "example": "Balance refunded" } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "example": "Invalid parameters" } } } }, "401": { "description": "Unauthorized", "content": { "text/plain": { "schema": { "type": "string", "example": "Invalid authorization token" } } } }, "404": { "description": "Not Found - User does not exist", "content": { "text/plain": { "schema": { "type": "string", "example": "User not found" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "example": "Error refunding balance" } } } } } } }, "/check-balance/{token}/{signerAddress}": { "get": { "tags": [ "Protected" ], "summary": "Check if user has sufficient balance", "description": "**PROTECTED ROUTE** - Requires `PRIVATE_ROUTE_SECRET` authentication header.\n\nChecks whether a user has sufficient Winston credits for a given byte count upload.\nCalled by the upload service before accepting a data upload.\n\n**Authorization:** `x-auth-token` header must match `PRIVATE_ROUTE_SECRET` environment variable.\n", "parameters": [ { "name": "x-auth-token", "in": "header", "required": true, "schema": { "type": "string", "description": "Must match PRIVATE_ROUTE_SECRET" } }, { "name": "token", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/TokenType" }, "description": "Currently unused (kept for backward compatibility)" }, { "name": "signerAddress", "in": "path", "required": true, "schema": { "type": "string", "description": "User's wallet address" } }, { "name": "byteCount", "in": "query", "required": true, "schema": { "type": "integer", "description": "Number of bytes to check" } }, { "name": "paidBy", "in": "query", "required": false, "schema": { "type": "string", "description": "Comma-separated list of addresses paying (delegated payment)" } }, { "name": "ipBucket", "in": "query", "required": false, "schema": { "type": "string", "description": "The client's subnet bucket, forwarded by the upload service so the per-IP free-tier cap can be evaluated." } } ], "responses": { "200": { "description": "OK - User has sufficient balance", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CheckBalanceResult" } } } }, "400": { "description": "Bad Request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CheckBalanceResult" } } } }, "401": { "description": "Unauthorized", "content": { "text/plain": { "schema": { "type": "string", "example": "Invalid authorization token" } } } }, "402": { "description": "Payment Required - Insufficient balance", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CheckBalanceResult" } } } }, "404": { "description": "Not Found - User does not exist", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CheckBalanceResult" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "example": "Error checking balance" } } } } } } }, "/account/approvals/create": { "get": { "tags": [ "Protected" ], "summary": "Create delegated payment approval", "description": "**PROTECTED ROUTE** - Requires `PRIVATE_ROUTE_SECRET` authentication header.\n\nCreates an approval allowing another address to spend credits from the paying address's balance.\nThis enables delegated payment scenarios where one user pays for another user's uploads.\n\n**Authorization:** `x-auth-token` header must match `PRIVATE_ROUTE_SECRET` environment variable.\n", "parameters": [ { "name": "x-auth-token", "in": "header", "required": true, "schema": { "type": "string", "description": "Must match PRIVATE_ROUTE_SECRET" } }, { "name": "payingAddress", "in": "query", "required": true, "schema": { "type": "string", "description": "Address that will pay" } }, { "name": "approvedAddress", "in": "query", "required": true, "schema": { "type": "string", "description": "Address that is approved to spend" } }, { "name": "approvedWincAmount", "in": "query", "required": true, "schema": { "type": "string", "description": "Winston amount approved" } }, { "name": "approvalDataItemId", "in": "query", "required": true, "schema": { "type": "string", "description": "Data item ID for the approval" } }, { "name": "expirationDate", "in": "query", "required": true, "schema": { "type": "string", "format": "date-time", "description": "When the approval expires" } } ], "responses": { "200": { "description": "OK - Approval created successfully", "content": { "application/json": { "schema": { "type": "object", "description": "Created approval details" } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "example": "Invalid parameters" } } } }, "401": { "description": "Unauthorized", "content": { "text/plain": { "schema": { "type": "string", "example": "Invalid authorization token" } } } }, "402": { "description": "Payment Required - Insufficient balance", "content": { "text/plain": { "schema": { "type": "string", "example": "Insufficient balance" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "example": "Error creating approval" } } } } } } }, "/account/approvals/revoke": { "get": { "tags": [ "Protected" ], "summary": "Revoke delegated payment approvals", "description": "**PROTECTED ROUTE** - Requires `PRIVATE_ROUTE_SECRET` authentication header.\n\nRevokes one or more delegated payment approvals, preventing the approved address from\nspending any more credits from the paying address.\n\n**Authorization:** `x-auth-token` header must match `PRIVATE_ROUTE_SECRET` environment variable.\n", "parameters": [ { "name": "x-auth-token", "in": "header", "required": true, "schema": { "type": "string", "description": "Must match PRIVATE_ROUTE_SECRET" } }, { "name": "payingAddress", "in": "query", "required": true, "schema": { "type": "string", "description": "Address that pays" } }, { "name": "approvedAddress", "in": "query", "required": true, "schema": { "type": "string", "description": "Address whose approval is being revoked" } }, { "name": "revokeDataItemId", "in": "query", "required": true, "schema": { "type": "string", "description": "Data item ID for the revocation" } } ], "responses": { "200": { "description": "OK - Approvals revoked successfully", "content": { "application/json": { "schema": { "type": "array", "description": "Revoked approval details", "items": { "type": "object" } } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "example": "Invalid parameters" } } } }, "401": { "description": "Unauthorized", "content": { "text/plain": { "schema": { "type": "string", "example": "Invalid authorization token" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "example": "Error revoking approvals" } } } } } } }, "/stripe-webhook": { "post": { "tags": [ "Webhooks" ], "summary": "Stripe webhook for payment events", "description": "Receives webhook events from Stripe when payment events occur.\n\n**Supported Events:**\n- `payment_intent.succeeded` - Payment completed successfully, credits user's account\n- `charge.dispute.created` - Payment disputed, deducts credits if already credited\n\n**Security:** Webhook signature verification using Stripe webhook secret.\n\n**NOTE:** This endpoint is called directly by Stripe servers, not by clients.\n", "requestBody": { "required": true, "description": "Stripe webhook event payload", "content": { "application/json": { "schema": { "type": "object", "description": "Stripe Event object" } } } }, "responses": { "200": { "description": "OK - Event received and processed", "content": { "text/plain": { "schema": { "type": "string", "example": "OK" } } } }, "400": { "description": "Bad Request - Invalid signature", "content": { "text/plain": { "schema": { "type": "string", "example": "Webhook Error!" } } } } } } }, "/health": { "get": { "tags": [ "System" ], "summary": "Health check endpoint", "description": "Simple health check endpoint that returns \"OK\" if the service is running.\n\nUse this for:\n- Load balancer health checks\n- Monitoring/alerting systems\n- Service discovery\n", "responses": { "200": { "description": "OK - Service is healthy", "content": { "text/plain": { "schema": { "type": "string", "example": "OK" } } } } } } }, "/metrics": { "get": { "tags": [ "System" ], "summary": "Prometheus metrics endpoint", "description": "Returns Prometheus-formatted metrics for monitoring and observability.\n\n**Metrics Included:**\n- Default Node.js process metrics (CPU, memory, event loop, etc.)\n- Custom application metrics (payment success/failure counts, etc.)\n\n**Usage:** Configure Prometheus to scrape this endpoint periodically.\n", "responses": { "200": { "description": "OK - Prometheus metrics", "content": { "text/plain": { "schema": { "type": "string", "description": "Prometheus text exposition format", "example": "# HELP process_cpu_user_seconds_total Total user CPU time spent in seconds.\n# TYPE process_cpu_user_seconds_total counter\nprocess_cpu_user_seconds_total 0.123\n" } } } } } } }, "/price/{token}/{amount}": { "servers": [ { "url": "/" } ], "get": { "tags": [ "Pricing" ], "summary": "Arweave-compatible price endpoint (legacy)", "description": "**Legacy endpoint for ArConnect and ecosystem tool compatibility.**\n\nReturns the raw Winston credit amount as a plain string (not JSON).\nThis matches the format expected by ArConnect and other Arweave ecosystem tools.\n\n**Differences from /v1/price/bytes/{byteCount}:**\n- Returns plain string instead of JSON\n- No adjustments metadata\n- Kept for backward compatibility with existing tools\n", "parameters": [ { "name": "x-signature", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/SignatureHeader" } }, { "name": "x-nonce", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/NonceHeader" } }, { "name": "x-public-key", "in": "header", "required": false, "schema": { "$ref": "#/components/schemas/PublicKeyHeader" } }, { "name": "token", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/TokenType" }, "description": "Currently unused, kept for compatibility" }, { "name": "amount", "in": "path", "required": true, "schema": { "$ref": "#/components/schemas/ByteCount" }, "description": "Number of bytes" } ], "responses": { "200": { "description": "OK", "content": { "text/plain": { "schema": { "type": "string", "description": "Winston credit amount as a plain string", "example": "1000000" } } } }, "400": { "description": "Bad Request", "content": { "text/plain": { "schema": { "type": "string", "example": "Invalid byte count" } } } }, "503": { "description": "Service Unavailable", "content": { "text/plain": { "schema": { "type": "string", "example": "Pricing Oracle Unavailable" } } } } } } } } }