{"openapi":"3.1.0","info":{"title":"Toreador Public API","version":"1.0.0","description":"Non-custodial crypto QR code generator and payment session API. Toreador never holds funds; every payment moves directly from payer to merchant wallet on-chain.","contact":{"url":"https://toreador.io","email":"dev@toreador.io"},"license":{"name":"Proprietary","url":"https://toreador.io/legal"}},"servers":[{"url":"https://toreador.io/api/v1/public"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Pro plan API key, format: tdr_<60 hex chars>"}},"schemas":{"TokenInfo":{"type":"object","properties":{"symbol":{"type":"string","example":"BTC"},"name":{"type":"string","example":"Bitcoin"},"decimals":{"type":"integer","example":8}},"required":["symbol","name","decimals"]},"ChainInfo":{"type":"object","properties":{"id":{"type":"string","example":"bitcoin"},"name":{"type":"string","example":"Bitcoin"},"symbol":{"type":"string","example":"BTC"}},"required":["id","name","symbol"]},"Error":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"GenerateQRRequest":{"type":"object","properties":{"token":{"type":"string","example":"BTC","description":"BTC, ETH, SOL, POL, USDC (Solana only)"},"chainId":{"type":"string","example":"bitcoin","description":"bitcoin, ethereum, polygon, base, solana"},"amount":{"type":"string","example":"0.001"},"recipientAddress":{"type":"string","example":"bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"}},"required":["token","chainId","amount","recipientAddress"]},"GenerateQRResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"type":{"type":"string","enum":["native","spl"]},"qrData":{"type":"string","description":"Standard payment URI (BIP21, EIP-681, Solana Pay)"},"qrCodeURL":{"type":"string","description":"data:image/png;base64,..."},"token":{"$ref":"#/components/schemas/TokenInfo"},"chain":{"$ref":"#/components/schemas/ChainInfo"},"amount":{"type":"string"},"recipientAddress":{"type":"string"},"_meta":{"type":"object","description":"Out-of-band response metadata. Useful for AI agents and clients to discover tier and rate limits.","properties":{"tier":{"type":"string","enum":["free","pro"]},"rateLimit":{"type":"object","description":"Present only on free tier responses.","properties":{"scope":{"type":"string","example":"ip"},"limitPerHour":{"type":"integer"},"limitPerDay":{"type":"integer"},"remainingThisHour":{"type":"integer"},"resetsInSeconds":{"type":"integer"}}},"upgrade":{"type":"object","description":"Present only on free tier responses — points to Pro features.","properties":{"message":{"type":"string"},"url":{"type":"string"},"docs":{"type":"string"}}}}}}},"CreateSessionRequest":{"type":"object","properties":{"token":{"type":"string","example":"USDC","description":"USDC, USDT, EURC"},"chainId":{"type":"string","example":"ethereum","description":"ethereum, polygon, base"},"amount":{"type":"string","example":"100"},"recipientAddress":{"type":"string","example":"0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18"}},"required":["token","chainId","amount","recipientAddress"]},"CreateSessionResponse":{"type":"object","properties":{"success":{"type":"boolean"},"sessionId":{"type":"string","example":"ses_987654321"},"securityCode":{"type":"string","example":"4F2A9B","description":"6-character code the merchant must show the payer"},"url":{"type":"string","example":"/pay/ses_987654321"},"expiresAt":{"type":"integer","description":"Unix timestamp (seconds)"},"expiresIn":{"type":"integer","description":"Seconds until expiry"},"token":{"$ref":"#/components/schemas/TokenInfo"},"chain":{"$ref":"#/components/schemas/ChainInfo"},"amount":{"type":"string"},"recipientAddress":{"type":"string"}}},"PaymentStatusResponse":{"type":"object","properties":{"success":{"type":"boolean"},"sessionId":{"type":"string"},"status":{"type":"string","enum":["pending","submitted","confirming","completed","expired","failed"]},"token":{"type":"string"},"chainId":{"type":"string"},"amount":{"type":"string"},"recipientAddress":{"type":"string"},"txHash":{"type":["string","null"]},"confirmations":{"type":"integer"},"requiredConfirmations":{"type":"integer"},"expiresAt":{"type":"integer"},"completedAt":{"type":["integer","null"]}}}}},"paths":{"/generate-qr":{"post":{"summary":"Generate a QR code for a native or Solana SPL token","description":"Returns a base64-encoded PNG QR code that encodes a standard payment URI. Use this for BTC, ETH, SOL, POL and for USDC on Solana. For ERC-20 stablecoins on EVM chains, use /create-session (Pro plan required).\n\n**Free public tier — no API key required.** Anonymous callers are rate-limited per IP: 50 requests/hour and 200 requests/day. Authenticated Pro callers get 100 requests/hour with no daily cap.","security":[{},{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateQRRequest"}}}},"responses":{"200":{"description":"QR code generated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateQRResponse"}}}},"400":{"description":"Invalid input or wrong endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (100/hour)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/create-session":{"post":{"summary":"Create a hosted payment session for ERC-20 stablecoins","description":"Returns a session with a hosted payment URL. Use this for USDC, USDT and EURC on Ethereum, Polygon and Base. Sessions expire 15 minutes after creation.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSessionRequest"}}}},"responses":{"200":{"description":"Session created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSessionResponse"}}}},"400":{"description":"Invalid input or wrong endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/payment/{id}/status":{"get":{"summary":"Get the current status of a payment session","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Session ID returned by /create-session"}],"responses":{"200":{"description":"Status retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentStatusResponse"}}}},"404":{"description":"Session not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/history":{"get":{"summary":"List the 50 most recent generated QR codes for the authenticated user","responses":{"200":{"description":"History returned","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"payments":{"type":"array","items":{"type":"object"}}}}}}}}}},"/sessions":{"get":{"summary":"List the 50 most recent payment sessions for the authenticated user","responses":{"200":{"description":"Sessions returned","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"sessions":{"type":"array","items":{"type":"object"}}}}}}}}}}}}