{
  "openapi": "3.0.3",
  "info": {
    "title": "Kaskade Payment Solution API",
    "version": "1.3.0",
    "description": "The Kaskade V1 REST API.\n\n**This document is generated from, and validated against, the actual route implementations** — every path below exists in the codebase, and every public V1 route in the codebase appears below. See scripts/validate-openapi.mjs.\n\n**FROZEN — Kaskade API V1.0.0.** See docs/API_V1_CONTRACT.md.",
    "contact": {
      "name": "Kaskade Payment Solution Inc."
    }
  },
  "servers": [
    {
      "url": "https://kaskade.com/api/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyHeader": []
    },
    {
      "signedRequest": []
    }
  ],
  "tags": [
    {
      "name": "Currencies",
      "description": "Discover what can be accepted and paid out."
    },
    {
      "name": "Payments",
      "description": "Take a crypto payment for a USD price."
    },
    {
      "name": "Invoices",
      "description": "Hosted invoices."
    },
    {
      "name": "Payouts",
      "description": "Withdraw settled balance."
    },
    {
      "name": "Account",
      "description": "Fees and balances."
    },
    {
      "name": "Players",
      "description": "Permanent per-player deposit addresses. Requires the casino product."
    },
    {
      "name": "Ramp",
      "description": "Fiat on/off-ramp: buy crypto with card or bank, or sell it for cash."
    },
    {
      "name": "Conversions",
      "description": "Convert a balance from one asset into another. The default Kaskade conversion service fee is 1.00% of the gross proceeds (your agreement may set another rate). Each external cost — trading, source network, withdrawal, return network — is allocated to you or to Kaskade by your effective commercial policy, and every quote and conversion discloses the fee, each cost and who pays it."
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization: Bearer ks_live_YOUR_API_KEY"
      },
      "apiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Alternative to the Authorization header. Same key."
      },
      "signedRequest": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Kaskade-Signature",
        "description": "HMAC request signing. Send X-Kaskade-Client (your key's Public ID), X-Kaskade-Timestamp (ISO-8601 UTC, within 5 minutes of server time) and X-Kaskade-Signature = base64(HMAC-SHA256(clientSecret, canonical)), where canonical = U+FEFF + METHOD + full URL + clientId + timestamp + rawBody."
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "schema": {
          "type": "string",
          "maxLength": 255
        },
        "description": "Optional. Unique value per logical operation. The first response is stored for 24 hours and replayed for any retry with the same key and body. The same key with a different body returns 409 idempotency_conflict."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Human-readable sentence. Present on every error since V1 launched."
          },
          "code": {
            "$ref": "#/components/schemas/ErrorCode"
          },
          "field": {
            "type": "string",
            "description": "The request field the refusal is about, for example `orderId` or `amountUsd`. Present on validation failures from POST /payments and POST /invoices; absent on every other error."
          }
        },
        "description": "`error` is the original field and is always present. `code` is additive; older responses may omit it. `field` is additive too and appears only on validation failures."
      },
      "ErrorCode": {
        "type": "string",
        "description": "Stable machine-readable code. Treat an unrecognised value defensively.",
        "enum": [
          "invalid_api_key",
          "forbidden",
          "validation_error",
          "unsupported_asset",
          "not_found",
          "payment_not_found",
          "payout_not_available",
          "kyc_required",
          "idempotency_conflict",
          "idempotency_in_progress",
          "upstream_unavailable",
          "internal_error",
          "invalid_request",
          "invalid_amount",
          "invalid_currency",
          "invalid_amount_precision",
          "idempotency_recovery_required",
          "idempotency_unavailable"
        ]
      },
      "AssetStatus": {
        "type": "string",
        "enum": [
          "live",
          "beta",
          "coming_soon",
          "disabled"
        ],
        "description": "Additive. Product lifecycle. Only `live`/`beta` can take money; check depositAvailable."
      },
      "PaymentStatus": {
        "type": "string",
        "description": "Handle unknown future values defensively.",
        "enum": [
          "waiting",
          "confirming",
          "confirmed",
          "sending",
          "partially_paid",
          "finished",
          "failed",
          "refunded",
          "expired"
        ]
      },
      "Currency": {
        "type": "object",
        "required": [
          "code",
          "enabled"
        ],
        "properties": {
          "code": {
            "type": "string",
            "example": "usdttrc20",
            "description": "Kaskade API identifier. Stable — pass this as payCurrency."
          },
          "name": {
            "type": "string",
            "nullable": true,
            "example": "Tether (TRC-20)",
            "description": "Legacy display name. Retained unchanged."
          },
          "network": {
            "type": "string",
            "nullable": true,
            "example": "tron",
            "description": "Legacy network id. Retained unchanged."
          },
          "enabled": {
            "type": "boolean",
            "description": "True when this account can accept the coin today."
          },
          "symbol": {
            "type": "string",
            "example": "USDT",
            "description": "Additive. Ticker as a payer reads it (USDT0 on Polygon)."
          },
          "displayName": {
            "type": "string",
            "example": "Tether",
            "description": "Additive. Full name."
          },
          "networkName": {
            "type": "string",
            "example": "Tron",
            "description": "Additive. Chain name without the token-standard suffix."
          },
          "type": {
            "type": "string",
            "enum": [
              "native",
              "token"
            ],
            "description": "Additive."
          },
          "contract": {
            "type": "string",
            "nullable": true,
            "description": "Additive. Token contract, null for a native coin."
          },
          "decimals": {
            "type": "integer",
            "nullable": true,
            "description": "Additive. On-chain decimals."
          },
          "status": {
            "$ref": "#/components/schemas/AssetStatus"
          },
          "depositAvailable": {
            "type": "boolean",
            "description": "Additive. Can a payment be created in this coin right now?"
          },
          "payoutAvailable": {
            "type": "boolean",
            "description": "Additive. Can money leave on this rail right now?"
          }
        }
      },
      "Payment": {
        "type": "object",
        "description": "The public V1 payment object, produced by an explicit allowlist (src/lib/api/public-dto.ts). Internal columns — Kaskade's margin, webhook bookkeeping, custody identifiers, settlement routing — are never included, and a new database column does not appear here unless it is deliberately added. Money fields are JSON numbers; timestamps are ISO-8601 UTC.",
        "required": [
          "id",
          "status",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Kaskade payment id."
          },
          "npPaymentId": {
            "type": "string",
            "description": "Opaque legacy reference, retained for compatibility with existing reconciliation code and the payment.updated webhook. No guaranteed format or meaning. Deprecated in V2.",
            "nullable": true
          },
          "orderId": {
            "type": "string",
            "description": "Your order reference, echoed back.",
            "nullable": true
          },
          "priceAmount": {
            "type": "number",
            "description": "Fiat price as recorded. In crypto mode the merchant named no fiat price and this is Kaskade's reference valuation at creation — recorded so fees, reports and limits have one currency; it is NOT the amount anyone was asked for. Read pricingMode first.",
            "nullable": true
          },
          "priceCurrency": {
            "type": "string",
            "description": "Fiat currency of priceAmount, e.g. \"usd\". Always a fiat ISO code — never a coin ticker, in either pricing mode.",
            "nullable": true
          },
          "payCurrency": {
            "type": "string",
            "description": "Kaskade coin identifier the payer pays in.",
            "nullable": true
          },
          "payAmount": {
            "type": "number",
            "description": "Crypto amount due, whole units.",
            "nullable": true
          },
          "payAddress": {
            "type": "string",
            "description": "Deposit address for the payer.",
            "nullable": true
          },
          "payExtraId": {
            "type": "string",
            "description": "Memo/destination tag on chains that route by one; null elsewhere.",
            "nullable": true
          },
          "payInHash": {
            "type": "string",
            "description": "On-chain hash of the payer's transfer, once seen.",
            "nullable": true
          },
          "actuallyPaid": {
            "type": "number",
            "description": "Crypto received so far, whole units.",
            "nullable": true
          },
          "status": {
            "$ref": "#/components/schemas/PaymentStatus"
          },
          "invoiceUrl": {
            "type": "string",
            "description": "Hosted checkout URL, when one exists.",
            "nullable": true
          },
          "customerChargeUsd": {
            "type": "number",
            "description": "What the payer was charged, USD.",
            "nullable": true
          },
          "platformFeeUsd": {
            "type": "number",
            "description": "Kaskade's fee to you, USD.",
            "nullable": true
          },
          "merchantExtraUsd": {
            "type": "number",
            "description": "Your own added margin, USD.",
            "nullable": true
          },
          "merchantNetUsd": {
            "type": "number",
            "description": "What you net, USD.",
            "nullable": true
          },
          "payoutCoin": {
            "type": "string",
            "description": "Coin the net was/will be settled in.",
            "nullable": true
          },
          "payoutStatus": {
            "type": "string",
            "description": "Settlement progress for your net: none, pending or paid.",
            "nullable": true
          },
          "payoutTxHash": {
            "type": "string",
            "description": "On-chain hash of your settlement, once sent.",
            "nullable": true
          },
          "payoutAt": {
            "type": "string",
            "description": "When your net was settled.",
            "nullable": true,
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "description": "When the payment window closes. In crypto mode this is when the payment REQUEST expires, not when a quoted rate expires — an exact coin amount has no rate to expire.",
            "nullable": true,
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "description": "Last change.",
            "nullable": true,
            "format": "date-time"
          },
          "pricingMode": {
            "type": "string",
            "enum": [
              "fiat",
              "crypto"
            ],
            "description": "How this was priced. `fiat` — you named a price in your base currency and the coin amount was quoted from it. `crypto` — you named the coin amount itself and the payer owes exactly that."
          },
          "requestedAmount": {
            "type": "string",
            "nullable": true,
            "description": "In crypto mode, the exact amount you asked for, as a decimal string. Null in fiat mode."
          },
          "requestedCurrency": {
            "type": "string",
            "nullable": true,
            "description": "In crypto mode, the Kaskade coin identifier the request was priced in (asset and network). Equal to payCurrency: a coin-denominated request is payable only in the coin it is priced in. Null in fiat mode."
          },
          "amountDueExact": {
            "type": "string",
            "nullable": true,
            "description": "The amount due as a decimal string, in BOTH modes. Same value as payAmount; a string because a chain amount does not always survive a JSON number intact. Use this behind a copy button."
          },
          "payNetwork": {
            "type": "string",
            "nullable": true,
            "description": "The network the payer pays on. `usdttrc20` and `usdterc20` are different assets and never merge."
          },
          "settlementAsset": {
            "type": "string",
            "nullable": true,
            "description": "The asset this payment is meant to become: the invoice's own settlement intent if it had one, else your saved Settlement Preference. NULL means it settles in the asset it was paid in."
          },
          "settlementNetwork": {
            "type": "string",
            "nullable": true
          },
          "conversionRequired": {
            "type": "boolean",
            "description": "True when the payment asset and the settlement asset differ, so a conversion is needed."
          },
          "conversionId": {
            "type": "string",
            "nullable": true,
            "description": "The conversion, once one exists."
          },
          "conversionStatus": {
            "type": "string",
            "nullable": true,
            "description": "Its canonical status. Only COMPLETED means the destination asset has been credited."
          },
          "p12": {
            "$ref": "#/components/schemas/P12PaymentState"
          }
        }
      },
      "Invoice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "number": {
            "type": "string",
            "nullable": true
          },
          "amountUsd": {
            "type": "number",
            "nullable": true,
            "description": "Fiat amount, in your base currency. NULL on a coin-denominated invoice — see requestedAmount."
          },
          "status": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "pricingMode": {
            "type": "string",
            "enum": [
              "fiat",
              "crypto"
            ],
            "description": "How this was priced. `fiat` — you named a price in your base currency and the coin amount was quoted from it. `crypto` — you named the coin amount itself and the payer owes exactly that."
          },
          "requestedAmount": {
            "type": "string",
            "nullable": true,
            "description": "In crypto mode, the exact amount you asked for, as a decimal string. Null in fiat mode."
          },
          "requestedCurrency": {
            "type": "string",
            "nullable": true,
            "description": "In crypto mode, the Kaskade coin identifier the request was priced in (asset and network). Equal to payCurrency: a coin-denominated request is payable only in the coin it is priced in. Null in fiat mode."
          },
          "settlementAsset": {
            "type": "string",
            "nullable": true,
            "description": "This invoice's own settlement intent, overriding your saved Settlement Preference. NULL means the preference applies."
          },
          "settlementNetwork": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "Payout": {
        "type": "object",
        "description": "A payout as the public API renders it. Emitted identically by POST /payouts, both GET routes and the payout.updated webhook.",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "approved",
              "submitted",
              "paid",
              "rejected",
              "failed"
            ],
            "description": "pending, approved and submitted are in flight. paid, rejected and failed are terminal. Only paid means money moved."
          },
          "currency": {
            "type": "string",
            "description": "Coin/network being withdrawn, e.g. usdttrc20."
          },
          "amount": {
            "type": "number",
            "description": "Amount in that coin."
          },
          "address": {
            "type": "string",
            "description": "Destination wallet address the funds are sent to."
          },
          "destinationId": {
            "type": "string",
            "nullable": true,
            "description": "The allowlisted payout destination used. Null means your settlement wallet for the coin."
          },
          "destination": {
            "type": "string",
            "nullable": true,
            "description": "That destination's label, copied at request time so it survives the destination being deleted."
          },
          "txHash": {
            "type": "string",
            "nullable": true,
            "description": "On-chain transaction hash. Null until broadcast."
          },
          "error": {
            "type": "string",
            "nullable": true,
            "description": "Why it did not proceed, sanitised for publication. Null unless something went wrong."
          },
          "reference": {
            "type": "string",
            "nullable": true,
            "description": "Your own free-text reference, echoed back. Not an idempotency key."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "paidAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Set only once status is paid."
          }
        }
      },
      "PayoutDestination": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "currency": {
            "type": "string",
            "description": "Coin/network. Note the create request field is named `coin`."
          },
          "address": {
            "type": "string"
          },
          "tag": {
            "type": "string",
            "nullable": true
          },
          "whitelistStatus": {
            "type": "string",
            "description": "pending until a person approves the address; approved once it may be paid."
          },
          "payable": {
            "type": "boolean",
            "description": "Derived: true when whitelistStatus is approved."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Player": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "externalId": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "coin": {
            "type": "string"
          },
          "depositAddress": {
            "type": "string"
          },
          "depositTag": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "RampOrder": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "checkoutUrl": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "PaymentCreated": {
        "type": "object",
        "description": "The response to Create a payment. Deliberately NARROWER than the retrieved payment object, and it uses `priceUsd` where the retrieved object uses `priceAmount`/`priceCurrency`. This asymmetry predates V1 and is preserved rather than corrected, because changing either shape would break existing integrations. Retrieve the payment for the full object.",
        "required": [
          "id",
          "status"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "npPaymentId": {
            "type": "string",
            "description": "Opaque legacy reference. See the Payment object.",
            "nullable": true
          },
          "priceUsd": {
            "type": "number",
            "nullable": true,
            "description": "The fiat price you asked for. NULL in crypto mode, where you asked for a coin amount instead — see requestedAmount."
          },
          "payAddress": {
            "type": "string",
            "description": " Deposit address for the payer.",
            "nullable": true
          },
          "payExtraId": {
            "type": "string",
            "description": "Memo/destination tag where the chain needs one.",
            "nullable": true
          },
          "payAmount": {
            "type": "number",
            "description": "Crypto amount due.",
            "nullable": true
          },
          "payCurrency": {
            "type": "string",
            "description": "Coin the payer pays in.",
            "nullable": true
          },
          "status": {
            "$ref": "#/components/schemas/PaymentStatus"
          },
          "expiresAt": {
            "type": "string",
            "description": "When the payment window closes. In crypto mode this is when the payment REQUEST expires, not when a quoted rate expires — an exact coin amount has no rate to expire.",
            "nullable": true,
            "format": "date-time"
          },
          "pricingMode": {
            "type": "string",
            "enum": [
              "fiat",
              "crypto"
            ],
            "description": "How this was priced. `fiat` — you named a price in your base currency and the coin amount was quoted from it. `crypto` — you named the coin amount itself and the payer owes exactly that."
          },
          "requestedAmount": {
            "type": "string",
            "nullable": true,
            "description": "In crypto mode, the exact amount you asked for, as a decimal string. Null in fiat mode."
          },
          "requestedCurrency": {
            "type": "string",
            "nullable": true,
            "description": "In crypto mode, the Kaskade coin identifier the request was priced in (asset and network). Equal to payCurrency: a coin-denominated request is payable only in the coin it is priced in. Null in fiat mode."
          },
          "amountDueExact": {
            "type": "string",
            "nullable": true,
            "description": "The amount due as a decimal string, in BOTH modes. Same value as payAmount; a string because a chain amount does not always survive a JSON number intact. Use this behind a copy button."
          }
        }
      },
      "WebhookPayment": {
        "type": "object",
        "description": "The payment representation inside payment.updated. An explicit allowlist, narrower than the REST object.",
        "properties": {
          "id": {
            "type": "string"
          },
          "npPaymentId": {
            "type": "string",
            "description": "Opaque legacy reference.",
            "nullable": true
          },
          "orderId": {
            "type": "string",
            "description": "Your order reference.",
            "nullable": true
          },
          "status": {
            "$ref": "#/components/schemas/PaymentStatus"
          },
          "priceAmount": {
            "type": "number",
            "description": "Fiat price. In crypto mode, Kaskade's reference valuation — read pricingMode.",
            "nullable": true
          },
          "priceCurrency": {
            "type": "string",
            "description": "Fiat currency.",
            "nullable": true
          },
          "payAmount": {
            "type": "number",
            "description": "Crypto amount due.",
            "nullable": true
          },
          "payCurrency": {
            "type": "string",
            "description": "Coin.",
            "nullable": true
          },
          "payAddress": {
            "type": "string",
            "description": "Deposit address.",
            "nullable": true
          },
          "payExtraId": {
            "type": "string",
            "description": "Memo/tag where applicable.",
            "nullable": true
          },
          "actuallyPaid": {
            "type": "number",
            "description": "Crypto received so far.",
            "nullable": true
          },
          "pricingMode": {
            "type": "string",
            "enum": [
              "fiat",
              "crypto"
            ],
            "description": "How this was priced. `fiat` — you named a price in your base currency and the coin amount was quoted from it. `crypto` — you named the coin amount itself and the payer owes exactly that."
          },
          "requestedAmount": {
            "type": "string",
            "nullable": true,
            "description": "In crypto mode, the exact amount you asked for, as a decimal string. Null in fiat mode."
          },
          "requestedCurrency": {
            "type": "string",
            "nullable": true,
            "description": "In crypto mode, the Kaskade coin identifier the request was priced in (asset and network). Equal to payCurrency: a coin-denominated request is payable only in the coin it is priced in. Null in fiat mode."
          },
          "amountDueExact": {
            "type": "string",
            "nullable": true,
            "description": "The amount due as a decimal string, in BOTH modes. Same value as payAmount; a string because a chain amount does not always survive a JSON number intact. Use this behind a copy button."
          },
          "p12": {
            "$ref": "#/components/schemas/P12PaymentState"
          }
        }
      },
      "WebhookDeposit": {
        "type": "object",
        "description": "A confirmed player deposit. Casino-gated accounts only.",
        "properties": {
          "id": {
            "type": "string"
          },
          "playerId": {
            "type": "string"
          },
          "externalId": {
            "type": "string",
            "description": "Your own id for the player."
          },
          "playerName": {
            "type": "string"
          },
          "coin": {
            "type": "string"
          },
          "amount": {
            "type": "number"
          },
          "address": {
            "type": "string",
            "description": "The player's permanent deposit address."
          },
          "txHash": {
            "type": "string",
            "nullable": true
          },
          "blockTime": {
            "type": "string",
            "format": "date-time"
          },
          "confirmedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WebhookInvoice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "amountUsd": {
            "type": "number",
            "nullable": true,
            "description": "Fiat amount. Null on a coin-denominated invoice."
          },
          "number": {
            "type": "string"
          },
          "paymentId": {
            "type": "string",
            "nullable": true
          },
          "pricingMode": {
            "type": "string",
            "enum": [
              "fiat",
              "crypto"
            ],
            "description": "How this was priced. `fiat` — you named a price in your base currency and the coin amount was quoted from it. `crypto` — you named the coin amount itself and the payer owes exactly that."
          },
          "requestedAmount": {
            "type": "string",
            "nullable": true,
            "description": "In crypto mode, the exact amount you asked for, as a decimal string. Null in fiat mode."
          },
          "requestedCurrency": {
            "type": "string",
            "nullable": true,
            "description": "In crypto mode, the Kaskade coin identifier the request was priced in (asset and network). Equal to payCurrency: a coin-denominated request is payable only in the coin it is priced in. Null in fiat mode."
          }
        }
      },
      "ConversionQuote": {
        "type": "object",
        "description": "A price for a conversion. Nothing is created and no balance moves. The Kaskade conversion fee is a separate field and is never folded into `rate`.",
        "properties": {
          "source": {
            "type": "object",
            "properties": {
              "asset": {
                "type": "string"
              },
              "network": {
                "type": "string"
              },
              "amount": {
                "type": "string",
                "description": "Exact decimal string."
              }
            }
          },
          "destination": {
            "type": "object",
            "properties": {
              "asset": {
                "type": "string"
              },
              "network": {
                "type": "string"
              },
              "estimatedGrossAmount": {
                "type": "string"
              },
              "estimatedNetAmount": {
                "type": "string"
              }
            }
          },
          "rate": {
            "type": "string",
            "description": "Destination units per source unit, exact."
          },
          "fees": {
            "type": "object",
            "properties": {
              "conversionFeeBps": {
                "type": "integer",
                "description": "The Kaskade conversion service fee in basis points. Default 100 = 1.00%. See `economics` for the full breakdown."
              },
              "conversionFee": {
                "type": "string",
                "description": "In the destination asset, rounded DOWN to its spendable precision."
              },
              "providerFee": {
                "type": "string",
                "description": "The execution venue's own trading fee, in the destination asset."
              },
              "networkCost": {
                "type": "string",
                "description": "Null at quote time: the settlement transfer is priced when it is made.",
                "nullable": true
              }
            }
          },
          "maxSlippageBps": {
            "type": "integer"
          },
          "quotedAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "riskValueUsd": {
            "type": "string",
            "description": "The USD value the caps are measured against.",
            "nullable": true
          },
          "economics": {
            "$ref": "#/components/schemas/ConversionEconomics"
          },
          "minimumSourceAmount": {
            "type": "string",
            "description": "This route's minimum source amount (route-specific, never platform-wide)."
          },
          "maximumSourceAmount": {
            "type": "string",
            "nullable": true,
            "description": "This route's maximum source amount, or null when the route sets none."
          }
        }
      },
      "Conversion": {
        "type": "object",
        "description": "One conversion. `status` is the canonical lifecycle state; only COMPLETED means the destination asset has been credited.",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "QUOTED",
              "APPROVED_FOR_EXECUTION",
              "FUNDING",
              "FUNDED",
              "TRADING",
              "TRADED",
              "RETURNING",
              "RETURNED",
              "RECONCILING",
              "COMPLETED",
              "HELD",
              "FAILED",
              "RECOVERING",
              "RECOVERED"
            ]
          },
          "source": {
            "type": "object",
            "properties": {
              "asset": {
                "type": "string"
              },
              "network": {
                "type": "string"
              },
              "amount": {
                "type": "string"
              }
            }
          },
          "destination": {
            "type": "object",
            "properties": {
              "asset": {
                "type": "string"
              },
              "network": {
                "type": "string"
              },
              "estimatedAmount": {
                "type": "string",
                "nullable": true
              },
              "grossAmount": {
                "type": "string",
                "nullable": true
              },
              "netAmount": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "fees": {
            "type": "object",
            "properties": {
              "conversionFeeBps": {
                "type": "integer",
                "description": "The Kaskade conversion service fee in basis points. Default 100 = 1.00%. See `economics` for the full breakdown."
              },
              "conversionFee": {
                "type": "string",
                "nullable": true
              },
              "providerFee": {
                "type": "string",
                "nullable": true
              },
              "networkCost": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "rate": {
            "type": "object",
            "properties": {
              "quoted": {
                "type": "string",
                "nullable": true
              },
              "executed": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "maxSlippageBps": {
            "type": "integer",
            "nullable": true
          },
          "observedSlippageBps": {
            "type": "integer",
            "nullable": true
          },
          "paymentId": {
            "type": "string",
            "nullable": true
          },
          "idempotencyKey": {
            "type": "string",
            "nullable": true
          },
          "failureReason": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "executedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "settledAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "quoteExpiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "economics": {
            "$ref": "#/components/schemas/ConversionEconomics"
          }
        }
      },
      "ConversionEconomics": {
        "type": "object",
        "description": "The effective commercial model for this quote or conversion, itemised. Amounts are exact decimal strings in the asset named. On a quote every amount is an estimate; on a settled conversion `actualAmount` carries what was charged. Slippage is not a cost and is never included here.",
        "properties": {
          "kaskadeFee": {
            "type": "object",
            "properties": {
              "bps": {
                "type": "integer",
                "description": "The Kaskade conversion service fee in basis points. Default 100 = 1.00%; 0 means waived."
              },
              "percent": {
                "type": "string",
                "example": "1.00"
              },
              "asset": {
                "type": "string"
              },
              "estimatedAmount": {
                "type": "string",
                "nullable": true
              },
              "actualAmount": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "costs": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "category": {
                  "type": "string",
                  "enum": [
                    "PROVIDER_TRADING_FEE",
                    "SOURCE_NETWORK_FEE",
                    "VENUE_WITHDRAWAL_FEE",
                    "RETURN_NETWORK_FEE"
                  ]
                },
                "payer": {
                  "type": "string",
                  "enum": [
                    "MERCHANT",
                    "KASKADE"
                  ],
                  "description": "Who bears this cost under the conversion's effective commercial policy."
                },
                "asset": {
                  "type": "string"
                },
                "estimatedAmount": {
                  "type": "string",
                  "nullable": true
                },
                "actualAmount": {
                  "type": "string",
                  "nullable": true
                }
              }
            }
          },
          "merchantBorne": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Total costs you bear, per asset."
          },
          "kaskadeBorne": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Total costs Kaskade bears, per asset."
          },
          "destination": {
            "type": "object",
            "properties": {
              "asset": {
                "type": "string"
              },
              "grossAmount": {
                "type": "string",
                "nullable": true
              },
              "merchantNetAmount": {
                "type": "string",
                "nullable": true,
                "description": "Gross less the Kaskade fee and every cost you bear."
              },
              "basis": {
                "type": "string",
                "enum": [
                  "estimate",
                  "actual"
                ]
              }
            }
          }
        }
      },
      "ConversionRoute": {
        "type": "object",
        "description": "A conversion this account can make right now: enabled in Kaskade's Production route matrix and allowed for the account. Provider-neutral: assets and networks only.",
        "required": [
          "source",
          "destination",
          "minimumSourceAmount",
          "maximumSourceAmount"
        ],
        "properties": {
          "source": {
            "type": "object",
            "properties": {
              "asset": {
                "type": "string",
                "example": "btc"
              },
              "network": {
                "type": "string",
                "example": "bitcoin"
              }
            }
          },
          "destination": {
            "type": "object",
            "properties": {
              "asset": {
                "type": "string",
                "example": "usdttrc20"
              },
              "network": {
                "type": "string",
                "example": "tron"
              }
            }
          },
          "minimumSourceAmount": {
            "type": "string",
            "nullable": true,
            "description": "Exact decimal string in source units."
          },
          "maximumSourceAmount": {
            "type": "string",
            "nullable": true,
            "description": "Exact decimal string in source units, or null when the route sets none."
          }
        }
      },
      "P12PaymentState": {
        "type": "object",
        "description": "P12 (V1.3.0, additive). Present only for merchants with partial payments enabled. Exact decimal strings in the payment's asset. Provider-neutral: no custodian ids or evidence.",
        "properties": {
          "paymentState": {
            "type": "string",
            "enum": [
              "WAITING",
              "PARTIALLY_PAID",
              "PAID",
              "OVERPAID",
              "EXPIRED",
              "EXPIRED_PARTIAL",
              "CANCELLED",
              "CANCELLED_PARTIAL"
            ]
          },
          "requestedAmount": {
            "type": "string",
            "nullable": true
          },
          "receivedAmount": {
            "type": "string"
          },
          "remainingAmount": {
            "type": "string",
            "nullable": true
          },
          "completionPercent": {
            "type": "string",
            "description": "0.00–100.00, capped at 100",
            "nullable": true
          },
          "excessAmount": {
            "type": "string"
          },
          "unacceptedAmount": {
            "type": "string",
            "description": "Received but not accepted by the merchant's overpayment policy (held, or being returned)."
          },
          "excessDisposition": {
            "type": "string",
            "enum": [
              "ACCEPTED",
              "HELD",
              "RETURN_REQUESTED",
              "RETURNED"
            ],
            "nullable": true
          },
          "meetsPartialMinimum": {
            "type": "boolean",
            "nullable": true
          },
          "depositCount": {
            "type": "integer"
          },
          "deposits": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "txHash": {
                  "type": "string"
                },
                "amount": {
                  "type": "string"
                },
                "senderAddress": {
                  "type": "string",
                  "nullable": true
                },
                "receivedAt": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "multipleSenders": {
            "type": "boolean"
          },
          "cancelledAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "returnState": {
            "type": "string",
            "enum": [
              "NONE",
              "HOLD_FOR_REVIEW",
              "RETURN_PENDING",
              "PARTIALLY_RETURNED",
              "RETURNED",
              "RETURN_FAILED"
            ]
          },
          "returns": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "REFUND_FULL",
                    "REFUND_PARTIAL",
                    "RETURN_EXCESS",
                    "CANCEL_RETURN"
                  ]
                },
                "state": {
                  "type": "string"
                },
                "amount": {
                  "type": "string"
                },
                "networkFeePayer": {
                  "type": "string",
                  "nullable": true
                },
                "txHash": {
                  "type": "string",
                  "nullable": true
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "completedAt": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true
                }
              }
            }
          },
          "event": {
            "type": "string",
            "description": "Webhook only: the semantic transition carried by this payment.updated — payment.partially_paid, payment.paid, payment.overpaid, payment.cancelled, payment.expired, payment.return_pending, payment.return_completed, payment.return_failed."
          }
        }
      }
    }
  },
  "paths": {
    "/currencies": {
      "get": {
        "tags": [
          "Currencies"
        ],
        "operationId": "listCurrencies",
        "summary": "List currencies this account can accept",
        "description": "By default returns LIVE coins only — unchanged from launch. Pass `include=upcoming` to additionally receive announced, non-transactional assets, which carry `enabled:false` and `depositAvailable:false`.",
        "parameters": [
          {
            "name": "include",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "upcoming",
                "all"
              ]
            },
            "description": "Opt in to announced assets."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "currencies": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Currency"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/currencies/{code}": {
      "get": {
        "tags": [
          "Currencies"
        ],
        "operationId": "getCurrency",
        "summary": "Metadata and live minimum for one currency",
        "description": "Answers for ANY ticker, including ones this account cannot accept.",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "currency": {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Currency"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "minUsd": {
                              "type": "number",
                              "nullable": true,
                              "description": "Live minimum payable amount in USD, or null when unavailable."
                            }
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/rates/estimate": {
      "get": {
        "tags": [
          "Currencies"
        ],
        "operationId": "estimateRate",
        "summary": "Live USD to crypto estimate",
        "parameters": [
          {
            "name": "amount",
            "in": "query",
            "required": true,
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "currency",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "amountUsd": {
                      "type": "number"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "estimatedAmount": {
                      "type": "number"
                    },
                    "rate": {
                      "type": "number",
                      "description": "USD per coin."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing parameters, or a currency we cannot price.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "No pricing source available right now.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/fees": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "getFees",
        "summary": "Fee schedule for this account",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "platformFeePercent": {
                      "type": "number"
                    },
                    "merchantExtraPercent": {
                      "type": "number"
                    },
                    "feeMode": {
                      "type": "string"
                    },
                    "currency": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/balance": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "getBalance",
        "summary": "Available custody balance per coin",
        "description": "Direct-settlement accounts receive an empty object: nothing is held for them.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "balances": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "number"
                      }
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "Balance source unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/payments": {
      "post": {
        "tags": [
          "Payments"
        ],
        "operationId": "createPayment",
        "summary": "Create a payment",
        "description": "Creates a **direct payment**: Kaskade allocates a deposit address and returns it to you with the exact amount due, so you can render your own payment screen. If you would rather we hosted the checkout and gave you a shareable link, call `POST /invoices` instead.\n\n**Price the payment one of two ways — send exactly one amount.**\n\n**Fiat-denominated (`priceUsd`)** — the payment is priced in your base currency and Kaskade calculates the cryptocurrency amount due at the live rate. `{\"priceUsd\": 100, \"payCurrency\": \"usdttrc20\"}` means *$100 worth* of USDT on Tron — approximately 100 USDT, not exactly 100. This is V1.0 behaviour and is unchanged.\n\n**Coin-denominated (`payAmount` + `payCurrency`)** — the payment is priced directly in the coin, as a decimal STRING. No fiat conversion determines the customer principal. `{\"payAmount\": \"100\", \"payCurrency\": \"usdttrc20\"}` means the customer owes **exactly 100 USDT on TRON**; the platform fee is not added to it. A JSON number is rejected — an exact coin amount must be quoted.\n\nSending both amounts, or neither, is a `validation_error`.\n\n**The ticker encodes the network.** `usdttrc20` (USDT on Tron) and `usdterc20` (USDT on Ethereum) are different rails and are never interchangeable; a bare `usdt` is rejected because it does not say which chain the funds should arrive on. There is no separate network field. Discover valid tickers with `GET /currencies`.\n\n**Same asset, same network only.** In V1.1 a coin-denominated payment is settled by that asset on that network and nothing else — Kaskade performs no cross-asset or cross-network conversion.\n\nThe response carries `id`, `payCurrency`, `payAmount`, `amountDueExact`, `payAddress`, `status`, `expiresAt` and `pricingMode` (`fiat` or `crypto`).",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "description": "Give EXACTLY ONE amount. `priceUsd` prices the payment in your base currency (V1.0 behaviour, unchanged); `payAmount` prices it in the coin itself. Sending both, or neither, is a validation_error.",
                "oneOf": [
                  {
                    "title": "FiatDenominated",
                    "type": "object",
                    "required": [
                      "priceUsd",
                      "payCurrency"
                    ],
                    "properties": {
                      "priceUsd": {
                        "type": "number",
                        "description": "Positive fiat price, in your base currency. Quoted into `payCurrency` at the live rate."
                      },
                      "payCurrency": {
                        "type": "string",
                        "description": "Kaskade coin identifier from GET /currencies. Encodes the asset AND its network."
                      },
                      "orderId": {
                        "type": "string",
                        "maxLength": 200
                      },
                      "orderDescription": {
                        "type": "string",
                        "maxLength": 500
                      }
                    }
                  },
                  {
                    "title": "CryptoDenominated",
                    "type": "object",
                    "required": [
                      "payAmount",
                      "payCurrency"
                    ],
                    "properties": {
                      "payAmount": {
                        "type": "string",
                        "description": "Exact amount of `payCurrency`, as a decimal STRING (\"100\", \"0.005\"). The payer owes precisely this — no exchange rate is involved in producing it. A JSON number is rejected: a coin amount does not survive a float intact. Precision is the asset's own, capped at 8 decimal places in this release; anything finer is refused rather than rounded. The network is part of `payCurrency` (usdttrc20, usdterc20, …), so a bare \"usdt\" is refused.",
                        "example": "0.005"
                      },
                      "payCurrency": {
                        "type": "string",
                        "description": "Kaskade coin identifier from GET /currencies. Encodes the asset AND its network."
                      },
                      "orderId": {
                        "type": "string",
                        "maxLength": 200
                      },
                      "orderDescription": {
                        "type": "string",
                        "maxLength": 500
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payment": {
                      "$ref": "#/components/schemas/PaymentCreated"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed, or the coin is not available to this account (unsupported_asset).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key reused with a different body, or the first attempt is still running.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "An Idempotency-Key was supplied but could not be honoured. Nothing was created; retry the identical request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Payments"
        ],
        "operationId": "listPayments",
        "summary": "List payments",
        "description": "Returns the most recent items, newest first, capped server-side. There are no pagination parameters on this endpoint today.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payments": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Payment"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/payments/{id}": {
      "get": {
        "tags": [
          "Payments"
        ],
        "operationId": "getPayment",
        "summary": "Retrieve a payment (refreshes status)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payment": {
                      "$ref": "#/components/schemas/Payment"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such payment on this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/invoices": {
      "post": {
        "tags": [
          "Invoices"
        ],
        "operationId": "createInvoice",
        "summary": "Create a hosted invoice",
        "description": "Creates a **hosted invoice** and returns a shareable Kaskade checkout URL. The `invoice.url` in the response is a page hosted by Kaskade — give it to your customer and they pay there. Use this when you do not want to build a payment screen; use `POST /payments` when you want the deposit address and amount programmatically.\n\n**Price the invoice one of two ways — send exactly one amount.**\n\n**Fiat-denominated (`amountUsd`)** — the invoice is priced in your base currency and Kaskade calculates the cryptocurrency amount due. `{\"amountUsd\": 100, \"payCurrency\": \"usdttrc20\"}` means *$100 worth* of USDT on Tron. `payCurrency` is optional here: set it to lock the invoice to one coin, omit it to let the customer choose any supported coin.\n\n**Coin-denominated (`payAmount` + `payCurrency`)** — the invoice is priced directly in the coin, as a decimal STRING, and `payCurrency` is REQUIRED. `{\"payAmount\": \"100\", \"payCurrency\": \"usdttrc20\"}` means the invoice is for **exactly 100 USDT on TRON**, payable in that asset on that network only. A JSON number is rejected.\n\nSending both amounts, or neither, is a `validation_error`.\n\n**The ticker encodes the network.** `usdttrc20` (USDT on Tron) and `usdterc20` (USDT on Ethereum) are different rails and are never interchangeable; a bare `usdt` is rejected. There is no separate network field. Discover valid tickers with `GET /currencies`.\n\n**Same asset, same network only.** A `usdttrc20` invoice is not settled by USDT sent on Ethereum, and a `usdterc20` invoice is not settled by USDT sent on Tron. Cross-asset and cross-network conversion is not part of V1.1.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "description": "Give EXACTLY ONE amount. `amountUsd` prices the invoice in your base currency (V1.0 behaviour, unchanged); `payAmount` prices it in the coin itself and requires `payCurrency`. Sending both, or neither, is a validation_error.",
                "oneOf": [
                  {
                    "title": "FiatDenominated",
                    "type": "object",
                    "required": [
                      "amountUsd"
                    ],
                    "properties": {
                      "amountUsd": {
                        "type": "number",
                        "description": "Positive fiat amount, in your base currency."
                      },
                      "orderId": {
                        "type": "string",
                        "maxLength": 200
                      },
                      "orderDescription": {
                        "type": "string",
                        "maxLength": 500
                      },
                      "customerEmail": {
                        "type": "string",
                        "format": "email",
                        "maxLength": 200
                      },
                      "payCurrency": {
                        "type": "string",
                        "description": "Optional. Locks the invoice to one coin."
                      },
                      "settlementAsset": {
                        "type": "string",
                        "description": "Optional (V1.2.0). Settle THIS invoice in this asset, overriding your saved Settlement Preference. Requires conversion to be enabled on your account and the asset to be an available settlement rail; an invalid value is refused, never silently ignored."
                      },
                      "settlementNetwork": {
                        "type": "string",
                        "description": "Optional. The settlement asset's network; omitted, the asset's single known rail is used."
                      }
                    }
                  },
                  {
                    "title": "CryptoDenominated",
                    "type": "object",
                    "required": [
                      "payAmount",
                      "payCurrency"
                    ],
                    "properties": {
                      "payAmount": {
                        "type": "string",
                        "description": "Exact amount of `payCurrency`, as a decimal STRING (\"100\", \"0.005\"). The payer owes precisely this — no exchange rate is involved in producing it. A JSON number is rejected: a coin amount does not survive a float intact. Precision is the asset's own, capped at 8 decimal places in this release; anything finer is refused rather than rounded. The network is part of `payCurrency` (usdttrc20, usdterc20, …), so a bare \"usdt\" is refused.",
                        "example": "100"
                      },
                      "payCurrency": {
                        "type": "string",
                        "description": "REQUIRED in this branch: the coin the invoice is priced in. The invoice is payable in this coin only."
                      },
                      "orderId": {
                        "type": "string",
                        "maxLength": 200
                      },
                      "orderDescription": {
                        "type": "string",
                        "maxLength": 500
                      },
                      "customerEmail": {
                        "type": "string",
                        "format": "email",
                        "maxLength": 200
                      },
                      "settlementAsset": {
                        "type": "string",
                        "description": "Optional (V1.2.0). Settle THIS invoice in this asset, overriding your saved Settlement Preference. Requires conversion to be enabled on your account and the asset to be an available settlement rail; an invalid value is refused, never silently ignored."
                      },
                      "settlementNetwork": {
                        "type": "string",
                        "description": "Optional. The settlement asset's network; omitted, the asset's single known rail is used."
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "invoice": {
                      "$ref": "#/components/schemas/Invoice"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "An Idempotency-Key was supplied but could not be honoured. Nothing was created; retry the identical request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Invoices"
        ],
        "operationId": "listInvoices",
        "summary": "List invoices",
        "description": "Returns the most recent items, newest first, capped server-side. There are no pagination parameters on this endpoint today.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "invoices": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Invoice"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/invoices/{id}": {
      "get": {
        "tags": [
          "Invoices"
        ],
        "operationId": "getInvoice",
        "summary": "Retrieve an invoice",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "invoice": {
                      "$ref": "#/components/schemas/Invoice"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/payouts": {
      "post": {
        "tags": [
          "Payouts"
        ],
        "operationId": "createPayout",
        "summary": "Request a payout",
        "description": "Subject to KYC, rail availability, allowlisted destinations and operator release.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "currency",
                  "amount"
                ],
                "properties": {
                  "currency": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "number"
                  },
                  "destinationId": {
                    "type": "string",
                    "description": "An allowlisted payout destination id."
                  },
                  "reference": {
                    "type": "string",
                    "maxLength": 500
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Requested",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payout": {
                      "$ref": "#/components/schemas/Payout"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Payout not available (rails, balance, destination), or idempotency conflict.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "An Idempotency-Key was supplied but could not be honoured. Nothing was created; retry the identical request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Payouts"
        ],
        "operationId": "listPayouts",
        "summary": "List payouts",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Maximum rows to return."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payouts": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Payout"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/payouts/{id}": {
      "get": {
        "tags": [
          "Payouts"
        ],
        "operationId": "getPayout",
        "summary": "Retrieve a payout",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "payout": {
                      "$ref": "#/components/schemas/Payout"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/payout-destinations": {
      "get": {
        "tags": [
          "Payouts"
        ],
        "operationId": "listPayoutDestinations",
        "summary": "List allowlisted destinations",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "destinations": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PayoutDestination"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Payouts"
        ],
        "operationId": "createPayoutDestination",
        "summary": "Add a payout destination",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "label",
                  "currency",
                  "address"
                ],
                "properties": {
                  "label": {
                    "type": "string",
                    "maxLength": 80
                  },
                  "currency": {
                    "type": "string",
                    "maxLength": 32,
                    "description": "Coin/network, e.g. usdttrc20. Returned as `currency` on the destination."
                  },
                  "address": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 256
                  },
                  "tag": {
                    "type": "string",
                    "maxLength": 64,
                    "nullable": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "destination": {
                      "$ref": "#/components/schemas/PayoutDestination"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "An Idempotency-Key was supplied but could not be honoured. Nothing was created; retry the identical request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/players": {
      "post": {
        "tags": [
          "Players"
        ],
        "operationId": "createPlayer",
        "summary": "Create (or return) a player and their permanent deposit address",
        "description": "Requires the casino product on the account, otherwise 403. Naturally idempotent on externalId: calling twice returns the same player and the same permanent address. TRON only today.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "externalId",
                  "name"
                ],
                "properties": {
                  "externalId": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 120
                  },
                  "coin": {
                    "type": "string",
                    "description": "Optional. Defaults to the account's player coin."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "player": {
                      "$ref": "#/components/schemas/Player"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed, or an unsupported coin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The casino product is not enabled for this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Duplicate, or idempotency conflict.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "An Idempotency-Key was supplied but could not be honoured. Nothing was created; retry the identical request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Players"
        ],
        "operationId": "listPlayers",
        "summary": "List players",
        "description": "Returns the most recent items, newest first, capped server-side. There are no pagination parameters on this endpoint today.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "players": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Player"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The casino product is not enabled for this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/players/{id}": {
      "get": {
        "tags": [
          "Players"
        ],
        "operationId": "getPlayer",
        "summary": "Retrieve a player",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "player": {
                      "$ref": "#/components/schemas/Player"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The casino product is not enabled for this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/ramp/onramp": {
      "post": {
        "tags": [
          "Ramp"
        ],
        "operationId": "createOnramp",
        "summary": "Create a fiat on-ramp order",
        "description": "Returns 503 when the fiat ramp is not enabled for the platform.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "priceUsd"
                ],
                "properties": {
                  "priceUsd": {
                    "type": "number"
                  },
                  "payCurrency": {
                    "type": "string"
                  },
                  "fiat": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 3
                  },
                  "externalCustomerId": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "redirectUrl": {
                    "type": "string",
                    "format": "uri"
                  },
                  "orderId": {
                    "type": "string",
                    "maxLength": 200
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ramp": {
                      "$ref": "#/components/schemas/RampOrder"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Ramp provider error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "An Idempotency-Key was supplied but could not be honoured. Nothing was created; retry the identical request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ]
      }
    },
    "/ramp/offramp": {
      "post": {
        "tags": [
          "Ramp"
        ],
        "operationId": "createOfframp",
        "summary": "Create a fiat off-ramp order",
        "description": "Returns 503 when the fiat ramp is not enabled for the platform.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "cryptoAmount",
                  "walletAddress"
                ],
                "properties": {
                  "cryptoAmount": {
                    "type": "number"
                  },
                  "walletAddress": {
                    "type": "string",
                    "minLength": 10
                  },
                  "payCurrency": {
                    "type": "string"
                  },
                  "fiat": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 3
                  },
                  "externalCustomerId": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "redirectUrl": {
                    "type": "string",
                    "format": "uri"
                  },
                  "orderId": {
                    "type": "string",
                    "maxLength": 200
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ramp": {
                      "$ref": "#/components/schemas/RampOrder"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Ramp provider error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "An Idempotency-Key was supplied but could not be honoured. Nothing was created; retry the identical request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ]
      }
    },
    "/ramp/orders/{id}": {
      "get": {
        "tags": [
          "Ramp"
        ],
        "operationId": "getRampOrder",
        "summary": "Retrieve a ramp order",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ramp": {
                      "$ref": "#/components/schemas/RampOrder"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/conversion-quotes": {
      "post": {
        "tags": [
          "Conversions"
        ],
        "operationId": "createConversionQuote",
        "summary": "Price a conversion",
        "description": "Requires the `conversions:read` scope (a write key implies it). Creates nothing and reserves nothing.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "sourceAsset",
                  "sourceNetwork",
                  "destinationAsset",
                  "destinationNetwork",
                  "amount"
                ],
                "properties": {
                  "sourceAsset": {
                    "type": "string",
                    "example": "sol"
                  },
                  "sourceNetwork": {
                    "type": "string",
                    "example": "solana"
                  },
                  "destinationAsset": {
                    "type": "string",
                    "example": "usdttrc20"
                  },
                  "destinationNetwork": {
                    "type": "string",
                    "example": "tron"
                  },
                  "amount": {
                    "type": "string",
                    "description": "Exact decimal string in source units."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Priced.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "quote": {
                      "$ref": "#/components/schemas/ConversionQuote"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed, the assets are the same (`no_conversion_required`), below or above this route's bounds (`conversion_below_minimum`, `conversion_above_maximum`), or unavailable for this amount (`conversion_uneconomic`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope, entitlement or pair allowance.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "No enabled conversion route for this pair on this account (`conversion_route_unavailable`), or conversion is disabled (`conversion_disabled`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "No price is available right now.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/conversions": {
      "post": {
        "tags": [
          "Conversions"
        ],
        "operationId": "createConversion",
        "summary": "Create a conversion",
        "description": "Requires the `conversions:write` scope, which existing keys do not have until it is granted. Prices the conversion, records it and reserves the source balance; execution happens under its own gates. Send `Idempotency-Key`: the same key returns the same conversion, never a second one.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "sourceAsset",
                  "sourceNetwork",
                  "destinationAsset",
                  "destinationNetwork",
                  "amount"
                ],
                "properties": {
                  "sourceAsset": {
                    "type": "string"
                  },
                  "sourceNetwork": {
                    "type": "string"
                  },
                  "destinationAsset": {
                    "type": "string"
                  },
                  "destinationNetwork": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string"
                  },
                  "paymentId": {
                    "type": "string",
                    "description": "The payment whose settlement this conversion is for."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "conversion": {
                      "$ref": "#/components/schemas/Conversion"
                    }
                  }
                }
              }
            }
          },
          "200": {
            "description": "Already created under this idempotency key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "conversion": {
                      "$ref": "#/components/schemas/Conversion"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope, entitlement or pair allowance.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conversion disabled, a cap exceeded, insufficient available balance, or an idempotency conflict.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "No price is available right now.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Conversions"
        ],
        "operationId": "listConversions",
        "summary": "List conversions",
        "description": "Requires `conversions:read`. Newest first.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "starting_after",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "A conversion id from a previous page."
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of conversions.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Conversion"
                      }
                    },
                    "has_more": {
                      "type": "boolean"
                    },
                    "next_cursor": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/conversions/{id}": {
      "get": {
        "tags": [
          "Conversions"
        ],
        "operationId": "getConversion",
        "summary": "Retrieve a conversion",
        "description": "Requires `conversions:read`. A conversion belonging to another merchant is 404.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The conversion.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "conversion": {
                      "$ref": "#/components/schemas/Conversion"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/conversion-routes": {
      "get": {
        "tags": [
          "Conversions"
        ],
        "operationId": "listConversionRoutes",
        "summary": "List available conversion routes",
        "description": "Requires `conversions:read` (a write key implies it). The source/destination asset-and-network pairs this account can convert right now, each with its own minimum and maximum. Routes come from Kaskade's governed Production route matrix; an account without conversion gets an empty list. Narrow to one source with `sourceAsset` and `sourceNetwork`.",
        "parameters": [
          {
            "name": "sourceAsset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "btc"
          },
          {
            "name": "sourceNetwork",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "bitcoin"
          }
        ],
        "responses": {
          "200": {
            "description": "The available routes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "routes"
                  ],
                  "properties": {
                    "routes": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ConversionRoute"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key lacks `conversions:read` (`api_scope_missing`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "x-webhooks": {
    "payment.updated": {
      "post": {
        "summary": "A payment changed status",
        "description": "Signed with x-kaskade-signature. Delivered up to 3 times.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Event id, stable per payment+status."
                  },
                  "event": {
                    "type": "string",
                    "enum": [
                      "payment.updated"
                    ]
                  },
                  "created": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "payment": {
                        "$ref": "#/components/schemas/WebhookPayment"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledged."
          }
        }
      }
    },
    "invoice.paid": {
      "post": {
        "summary": "An invoice was paid",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Event id, stable per object+transition."
                  },
                  "event": {
                    "type": "string",
                    "enum": [
                      "invoice.paid"
                    ]
                  },
                  "created": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "invoice": {
                        "$ref": "#/components/schemas/WebhookInvoice"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledged."
          }
        }
      }
    },
    "payout.updated": {
      "post": {
        "summary": "A payout changed status",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Event id, stable per object+transition."
                  },
                  "event": {
                    "type": "string",
                    "enum": [
                      "payout.updated"
                    ]
                  },
                  "created": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "payout": {
                        "$ref": "#/components/schemas/Payout"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledged."
          }
        }
      }
    },
    "deposit.confirmed": {
      "post": {
        "summary": "A player deposit confirmed on chain",
        "description": "Casino product only.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Event id, stable per object+transition."
                  },
                  "event": {
                    "type": "string",
                    "enum": [
                      "deposit.confirmed"
                    ]
                  },
                  "created": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "deposit": {
                        "$ref": "#/components/schemas/WebhookDeposit"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledged."
          }
        }
      }
    },
    "conversion.created": {
      "post": {
        "summary": "A conversion was created and its source balance reserved",
        "description": "One delivery per canonical status, signed and retried like every other Kaskade webhook. The payload carries the same `Conversion` object the REST resource serves — no venue, market, vault or provider reference appears in it.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Event id, stable per object+transition."
                  },
                  "event": {
                    "type": "string",
                    "enum": [
                      "conversion.created"
                    ]
                  },
                  "created": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "conversion": {
                        "$ref": "#/components/schemas/Conversion"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledged."
          }
        }
      }
    },
    "conversion.processing": {
      "post": {
        "summary": "A conversion is being executed",
        "description": "One delivery per canonical status, signed and retried like every other Kaskade webhook. The payload carries the same `Conversion` object the REST resource serves — no venue, market, vault or provider reference appears in it.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Event id, stable per object+transition."
                  },
                  "event": {
                    "type": "string",
                    "enum": [
                      "conversion.processing"
                    ]
                  },
                  "created": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "conversion": {
                        "$ref": "#/components/schemas/Conversion"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledged."
          }
        }
      }
    },
    "conversion.completed": {
      "post": {
        "summary": "A conversion settled and the destination asset was credited",
        "description": "One delivery per canonical status, signed and retried like every other Kaskade webhook. The payload carries the same `Conversion` object the REST resource serves — no venue, market, vault or provider reference appears in it.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Event id, stable per object+transition."
                  },
                  "event": {
                    "type": "string",
                    "enum": [
                      "conversion.completed"
                    ]
                  },
                  "created": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "conversion": {
                        "$ref": "#/components/schemas/Conversion"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledged."
          }
        }
      }
    },
    "conversion.held": {
      "post": {
        "summary": "A conversion is on hold for a person to look at; the source stays reserved",
        "description": "One delivery per canonical status, signed and retried like every other Kaskade webhook. The payload carries the same `Conversion` object the REST resource serves — no venue, market, vault or provider reference appears in it.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Event id, stable per object+transition."
                  },
                  "event": {
                    "type": "string",
                    "enum": [
                      "conversion.held"
                    ]
                  },
                  "created": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "conversion": {
                        "$ref": "#/components/schemas/Conversion"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledged."
          }
        }
      }
    },
    "conversion.failed": {
      "post": {
        "summary": "A conversion will not complete; the source reservation is released (a recovered conversion arrives here too, with status RECOVERED)",
        "description": "One delivery per canonical status, signed and retried like every other Kaskade webhook. The payload carries the same `Conversion` object the REST resource serves — no venue, market, vault or provider reference appears in it.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Event id, stable per object+transition."
                  },
                  "event": {
                    "type": "string",
                    "enum": [
                      "conversion.failed"
                    ]
                  },
                  "created": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "conversion": {
                        "$ref": "#/components/schemas/Conversion"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledged."
          }
        }
      }
    }
  }
}
