{
  "openapi": "3.0.4",
  "info": {
    "title": "Chainflip Broker as a Service",
    "description": "Run your own Chainflip Broker without any hassle.",
    "version": "v1",
    "x-onboarding": {
      "freeToStart": true,
      "noKeyNeeded": [
        "/mcp",
        "/assets",
        "/networks"
      ],
      "apiKeys": {
        "selfServe": true,
        "signup": "/register",
        "secret": false
      },
      "sandbox": "Testing environment on the Chainflip Perseverance testnet; its URLs are listed at /onboarding.",
      "firstCall": "GET /assets",
      "facts": "/onboarding"
    }
  },
  "servers": [
    {
      "url": "/",
      "description": "Free to start. The MCP server (/mcp), /assets and /networks need no key or account; get an API key self-serve at /register, free and without payment details. Onboarding facts: /onboarding."
    }
  ],
  "paths": {
    "/assets": {
      "get": {
        "tags": [
          "Assets"
        ],
        "summary": "Get all assets.",
        "description": "Lists every asset you can swap, with its network, ticker, decimals, minimum swap\namount and current USD price. An asset's `id` is what you pass as\n`sourceAsset` or `destinationAsset` on every other endpoint.",
        "operationId": "listAssets",
        "responses": {
          "200": {
            "description": "All available assets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChainflipBaas.Assets.AssetsResponse"
                }
              }
            }
          },
          "500": {
            "description": "An error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                  "title": "An error occurred while processing your request.",
                  "status": 500,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          }
        }
      }
    },
    "/assets/{network}": {
      "get": {
        "tags": [
          "Assets"
        ],
        "summary": "Get all assets on a given network.",
        "description": "The same list as `listAssets`, limited to the assets on one network.",
        "operationId": "listNetworkAssets",
        "parameters": [
          {
            "name": "network",
            "in": "path",
            "description": "The network id to filter on.",
            "required": true,
            "schema": {
              "enum": [
                "btc",
                "eth",
                "dot",
                "arb",
                "sol",
                "hub",
                "tron"
              ],
              "type": "string",
              "description": "Supported networks. Member names are lowercase on purpose: they are the wire-format network\nids used in asset identifiers (e.g. \"usdc.eth\") and API responses.",
              "x-ms-enum": {
                "name": "Network",
                "modelAsString": true
              }
            },
            "example": "eth"
          }
        ],
        "responses": {
          "200": {
            "description": "All available assets.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChainflipBaas.Assets.AssetsResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request has invalid information.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ValidationProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
                  "title": "One or more validation errors occurred.",
                  "status": 400,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                  "errors": {
                    "network": [
                      "The value 'nope' is not valid."
                    ]
                  }
                }
              }
            }
          },
          "500": {
            "description": "An error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                  "title": "An error occurred while processing your request.",
                  "status": 500,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          }
        }
      }
    },
    "/assets/{asset}/logo.svg": {
      "get": {
        "tags": [
          "Assets"
        ],
        "summary": "Get the logo for an asset.",
        "description": "Returns the asset's logo as an SVG image, cacheable for an hour.",
        "operationId": "getAssetLogo",
        "parameters": [
          {
            "name": "asset",
            "in": "path",
            "description": "The asset id, as listed by `listAssets`.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "btc.btc"
          }
        ],
        "responses": {
          "200": {
            "description": "The asset logo in SVG format.",
            "content": {
              "image/svg+xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The request has invalid information.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ValidationProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
                  "title": "One or more validation errors occurred.",
                  "status": 400,
                  "detail": "The request has invalid information.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                  "errors": { }
                }
              }
            }
          },
          "500": {
            "description": "An error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                  "title": "An error occurred while processing your request.",
                  "status": 500,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          }
        }
      }
    },
    "/fees": {
      "get": {
        "tags": [
          "Fees"
        ],
        "summary": "Get earned broker fees.",
        "description": "Returns the broker fees you have earned so far, per asset, in human-readable and\nnative units. The BaaS operating fee is already deducted, so these are the amounts\nthat are yours.",
        "operationId": "getEarnedFees",
        "parameters": [
          {
            "name": "apiKey",
            "in": "query",
            "description": "Your partner API key. A key is required through this parameter OR the X-API-Key header; when both are present, this query parameter wins, even when it is empty, which fails validation rather than falling back to the header.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The earned broker fees.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChainflipBaas.Fees.FeesResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request has invalid information.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ValidationProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
                  "title": "One or more validation errors occurred.",
                  "status": 400,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                  "errors": {
                    "apiKey": [
                      "A value for the 'apiKey' parameter or property was not provided."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "The partner does not have access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.2",
                  "title": "Unauthorized",
                  "status": 401,
                  "detail": "Invalid partner.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "500": {
            "description": "An error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                  "title": "An error occurred while processing your request.",
                  "status": 500,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": [ ]
          },
          {
            "apiKeyHeader": [ ]
          }
        ]
      }
    },
    "/networks": {
      "get": {
        "tags": [
          "Networks"
        ],
        "summary": "Get all networks.",
        "description": "Lists every network you can swap on, with its id, name and logo path.",
        "operationId": "listNetworks",
        "responses": {
          "200": {
            "description": "All available networks.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChainflipBaas.Networks.NetworksResponse"
                }
              }
            }
          },
          "500": {
            "description": "An error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                  "title": "An error occurred while processing your request.",
                  "status": 500,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          }
        }
      }
    },
    "/networks/{network}/logo.svg": {
      "get": {
        "tags": [
          "Networks"
        ],
        "summary": "Get the logo for a network.",
        "description": "Returns the network's logo as an SVG image, cacheable for an hour.",
        "operationId": "getNetworkLogo",
        "parameters": [
          {
            "name": "network",
            "in": "path",
            "description": "The network id, as listed by `listNetworks`.",
            "required": true,
            "schema": {
              "enum": [
                "btc",
                "eth",
                "dot",
                "arb",
                "sol",
                "hub",
                "tron"
              ],
              "type": "string",
              "description": "Supported networks. Member names are lowercase on purpose: they are the wire-format network\nids used in asset identifiers (e.g. \"usdc.eth\") and API responses.",
              "x-ms-enum": {
                "name": "Network",
                "modelAsString": true
              }
            },
            "example": "eth"
          }
        ],
        "responses": {
          "200": {
            "description": "The network logo in SVG format.",
            "content": {
              "image/svg+xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Unknown network.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ValidationProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
                  "title": "One or more validation errors occurred.",
                  "status": 400,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                  "errors": {
                    "network": [
                      "The value 'nope' is not valid."
                    ]
                  }
                }
              }
            }
          },
          "500": {
            "description": "An error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                  "title": "An error occurred while processing your request.",
                  "status": 500,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          }
        }
      }
    },
    "/quote-native": {
      "get": {
        "tags": [
          "Quote"
        ],
        "summary": "Get a quote from native units.",
        "description": "Deprecated: use `getNativeQuotes`, which also returns DCA quotes. This endpoint\nreturns only the regular quote. When Chainflip offers only a DCA quote for the amount,\nit answers 400 with code `insufficient_liquidity`.",
        "operationId": "getNativeQuote",
        "parameters": [
          {
            "name": "apiKey",
            "in": "query",
            "description": "Your partner API key. A key is required through this parameter OR the X-API-Key header; when both are present, this query parameter wins, even when it is empty, which fails validation rather than falling back to the header.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sourceAsset",
            "in": "query",
            "description": "The asset to swap from.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "btc.btc"
          },
          {
            "name": "destinationAsset",
            "in": "query",
            "description": "The asset to swap to.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "usdt.hub"
          },
          {
            "name": "amount",
            "in": "query",
            "description": "The amount to swap in native units.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "50000000"
          },
          {
            "name": "commissionBps",
            "in": "query",
            "description": "An optional override to the charged commission bps.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 15
          }
        ],
        "responses": {
          "200": {
            "description": "A quote for the given assets and amount.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChainflipBaas.Quote.Quote"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input (validation errors), or an upstream rejection of the request as sent (code).",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ValidationProblemDetails"
                    },
                    {
                      "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                    }
                  ]
                },
                "examples": {
                  "validation": {
                    "summary": "Input validation failed",
                    "value": {
                      "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
                      "title": "One or more validation errors occurred.",
                      "status": 400,
                      "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                      "errors": {
                        "apiKey": [
                          "A value for the 'apiKey' parameter or property was not provided."
                        ]
                      }
                    }
                  },
                  "upstream": {
                    "summary": "The upstream cannot fulfil this request",
                    "value": {
                      "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
                      "title": "Bad Request",
                      "status": 400,
                      "detail": "There is currently no quote available for this amount, try a lower amount",
                      "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                      "code": "insufficient_liquidity"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The partner does not have access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.2",
                  "title": "Unauthorized",
                  "status": 401,
                  "detail": "Invalid partner.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "403": {
            "description": "Swaps between these assets are not enabled for the partner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.4",
                  "title": "Forbidden",
                  "status": 403,
                  "detail": "Swaps from BTC to ETH are not enabled for your account.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "503": {
            "description": "A temporary upstream condition, such as maintenance, a disabled asset or the network channel cap. Retry with backoff.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.4",
                  "title": "Service Unavailable",
                  "status": 503,
                  "detail": "One of the assets in this swap is currently disabled on Chainflip",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                  "code": "asset_disabled"
                }
              }
            }
          },
          "500": {
            "description": "An error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                  "title": "An error occurred while processing your request.",
                  "status": 500,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          }
        },
        "deprecated": true,
        "security": [
          {
            "apiKey": [ ]
          },
          {
            "apiKeyHeader": [ ]
          }
        ]
      }
    },
    "/quotes-native": {
      "get": {
        "tags": [
          "Quote"
        ],
        "summary": "Get a list of quotes from native units.",
        "description": "The same as `getQuotes`, with `amount` in the source asset's smallest native\nunit (for example `50000000` satoshis for 0.5 BTC).",
        "operationId": "getNativeQuotes",
        "parameters": [
          {
            "name": "apiKey",
            "in": "query",
            "description": "Your partner API key. A key is required through this parameter OR the X-API-Key header; when both are present, this query parameter wins, even when it is empty, which fails validation rather than falling back to the header.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sourceAsset",
            "in": "query",
            "description": "The asset to swap from.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "btc.btc"
          },
          {
            "name": "destinationAsset",
            "in": "query",
            "description": "The asset to swap to.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "usdt.hub"
          },
          {
            "name": "amount",
            "in": "query",
            "description": "The amount to swap in native units.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "50000000"
          },
          {
            "name": "commissionBps",
            "in": "query",
            "description": "An optional override to the charged commission bps.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 15
          },
          {
            "name": "isVaultSwap",
            "in": "query",
            "description": "Flag for requesting a quote for a vault swap. Network related fees can be different for vault swaps compared to regular swaps.",
            "schema": {
              "type": "boolean"
            },
            "example": true
          }
        ],
        "responses": {
          "200": {
            "description": "A list of quotes for the given assets and amount.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ChainflipBaas.Quote.Quote"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input (validation errors), or an upstream rejection of the request as sent (code).",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ValidationProblemDetails"
                    },
                    {
                      "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                    }
                  ]
                },
                "examples": {
                  "validation": {
                    "summary": "Input validation failed",
                    "value": {
                      "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
                      "title": "One or more validation errors occurred.",
                      "status": 400,
                      "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                      "errors": {
                        "apiKey": [
                          "A value for the 'apiKey' parameter or property was not provided."
                        ]
                      }
                    }
                  },
                  "upstream": {
                    "summary": "The upstream cannot fulfil this request",
                    "value": {
                      "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
                      "title": "Bad Request",
                      "status": 400,
                      "detail": "There is currently no quote available for this amount, try a lower amount",
                      "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                      "code": "insufficient_liquidity"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The partner does not have access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.2",
                  "title": "Unauthorized",
                  "status": 401,
                  "detail": "Invalid partner.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "403": {
            "description": "Swaps between these assets are not enabled for the partner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.4",
                  "title": "Forbidden",
                  "status": 403,
                  "detail": "Swaps from BTC to ETH are not enabled for your account.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "503": {
            "description": "A temporary upstream condition, such as maintenance, a disabled asset or the network channel cap. Retry with backoff.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.4",
                  "title": "Service Unavailable",
                  "status": 503,
                  "detail": "One of the assets in this swap is currently disabled on Chainflip",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                  "code": "asset_disabled"
                }
              }
            }
          },
          "500": {
            "description": "An error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                  "title": "An error occurred while processing your request.",
                  "status": 500,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": [ ]
          },
          {
            "apiKeyHeader": [ ]
          }
        ]
      }
    },
    "/quote": {
      "get": {
        "tags": [
          "Quote"
        ],
        "summary": "Get a quote.",
        "description": "Deprecated: use `getQuotes`, which also returns DCA quotes. This endpoint returns\nonly the regular quote. When Chainflip offers only a DCA quote for the amount, it\nanswers 400 with code `insufficient_liquidity`.",
        "operationId": "getQuote",
        "parameters": [
          {
            "name": "apiKey",
            "in": "query",
            "description": "Your partner API key. A key is required through this parameter OR the X-API-Key header; when both are present, this query parameter wins, even when it is empty, which fails validation rather than falling back to the header.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sourceAsset",
            "in": "query",
            "description": "The asset to swap from.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "btc.btc"
          },
          {
            "name": "destinationAsset",
            "in": "query",
            "description": "The asset to swap to.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "usdt.hub"
          },
          {
            "name": "amount",
            "in": "query",
            "description": "The amount to swap.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "double"
            },
            "example": 0.5
          },
          {
            "name": "commissionBps",
            "in": "query",
            "description": "An optional override to the charged commission bps.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 15
          }
        ],
        "responses": {
          "200": {
            "description": "A quote for the given assets and amount.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChainflipBaas.Quote.Quote"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input (validation errors), or an upstream rejection of the request as sent (code).",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ValidationProblemDetails"
                    },
                    {
                      "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                    }
                  ]
                },
                "examples": {
                  "validation": {
                    "summary": "Input validation failed",
                    "value": {
                      "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
                      "title": "One or more validation errors occurred.",
                      "status": 400,
                      "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                      "errors": {
                        "apiKey": [
                          "A value for the 'apiKey' parameter or property was not provided."
                        ]
                      }
                    }
                  },
                  "upstream": {
                    "summary": "The upstream cannot fulfil this request",
                    "value": {
                      "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
                      "title": "Bad Request",
                      "status": 400,
                      "detail": "There is currently no quote available for this amount, try a lower amount",
                      "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                      "code": "insufficient_liquidity"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The partner does not have access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.2",
                  "title": "Unauthorized",
                  "status": 401,
                  "detail": "Invalid partner.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "403": {
            "description": "Swaps between these assets are not enabled for the partner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.4",
                  "title": "Forbidden",
                  "status": 403,
                  "detail": "Swaps from BTC to ETH are not enabled for your account.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "503": {
            "description": "A temporary upstream condition, such as maintenance, a disabled asset or the network channel cap. Retry with backoff.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.4",
                  "title": "Service Unavailable",
                  "status": 503,
                  "detail": "One of the assets in this swap is currently disabled on Chainflip",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                  "code": "asset_disabled"
                }
              }
            }
          },
          "500": {
            "description": "An error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                  "title": "An error occurred while processing your request.",
                  "status": 500,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          }
        },
        "deprecated": true,
        "security": [
          {
            "apiKey": [ ]
          },
          {
            "apiKeyHeader": [ ]
          }
        ]
      }
    },
    "/quotes": {
      "get": {
        "tags": [
          "Quote"
        ],
        "summary": "Get a list of quotes.",
        "description": "Quotes swapping a human-readable `amount` of `sourceAsset` (for example\n`0.5` BTC) into `destinationAsset`, with your broker fee included. Returns a\nregular quote and, when available, a DCA quote that spreads the swap over time;\nBitcoin quotes also carry a Boost quote. Each quote has the expected output, every fee\ninvolved, the estimated duration, an estimated price and a recommended slippage\ntolerance to use with `startSwap`. `commissionBps` can raise your configured\ncommission for this quote, never lower it.",
        "operationId": "getQuotes",
        "parameters": [
          {
            "name": "apiKey",
            "in": "query",
            "description": "Your partner API key. A key is required through this parameter OR the X-API-Key header; when both are present, this query parameter wins, even when it is empty, which fails validation rather than falling back to the header.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sourceAsset",
            "in": "query",
            "description": "The asset to swap from.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "btc.btc"
          },
          {
            "name": "destinationAsset",
            "in": "query",
            "description": "The asset to swap to.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "usdt.hub"
          },
          {
            "name": "amount",
            "in": "query",
            "description": "The amount to swap.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "double"
            },
            "example": 0.5
          },
          {
            "name": "commissionBps",
            "in": "query",
            "description": "An optional override to the charged commission bps.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 15
          },
          {
            "name": "isVaultSwap",
            "in": "query",
            "description": "Flag for requesting a quote for a vault swap. Network related fees can be different for vault swaps compared to regular swaps.",
            "schema": {
              "type": "boolean"
            },
            "example": true
          }
        ],
        "responses": {
          "200": {
            "description": "A list of quotes for the given assets and amount.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ChainflipBaas.Quote.Quote"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input (validation errors), or an upstream rejection of the request as sent (code).",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ValidationProblemDetails"
                    },
                    {
                      "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                    }
                  ]
                },
                "examples": {
                  "validation": {
                    "summary": "Input validation failed",
                    "value": {
                      "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
                      "title": "One or more validation errors occurred.",
                      "status": 400,
                      "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                      "errors": {
                        "apiKey": [
                          "A value for the 'apiKey' parameter or property was not provided."
                        ]
                      }
                    }
                  },
                  "upstream": {
                    "summary": "The upstream cannot fulfil this request",
                    "value": {
                      "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
                      "title": "Bad Request",
                      "status": 400,
                      "detail": "There is currently no quote available for this amount, try a lower amount",
                      "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                      "code": "insufficient_liquidity"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The partner does not have access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.2",
                  "title": "Unauthorized",
                  "status": 401,
                  "detail": "Invalid partner.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "403": {
            "description": "Swaps between these assets are not enabled for the partner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.4",
                  "title": "Forbidden",
                  "status": 403,
                  "detail": "Swaps from BTC to ETH are not enabled for your account.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "503": {
            "description": "A temporary upstream condition, such as maintenance, a disabled asset or the network channel cap. Retry with backoff.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.4",
                  "title": "Service Unavailable",
                  "status": 503,
                  "detail": "One of the assets in this swap is currently disabled on Chainflip",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                  "code": "asset_disabled"
                }
              }
            }
          },
          "500": {
            "description": "An error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                  "title": "An error occurred while processing your request.",
                  "status": 500,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": [ ]
          },
          {
            "apiKeyHeader": [ ]
          }
        ]
      }
    },
    "/rpc/{apiKey}": {
      "post": {
        "tags": [
          "Rpc"
        ],
        "summary": "Make an RPC call.",
        "description": "A JSON-RPC endpoint compatible with the native Chainflip broker, so code written for\nit, the Chainflip SDK and Swapkit can use BaaS by pointing their broker URL here. Your\nconfigured commission is enforced: a lower commission in the request is raised to it.\nOne call per request, with positional (array) params.",
        "operationId": "brokerRpc",
        "parameters": [
          {
            "name": "apiKey",
            "in": "path",
            "description": "The partner API key.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "An RPC request for the RPC call.",
          "content": {
            "application/json": {
              "schema": { }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "An RPC response for the RPC call.",
            "content": {
              "application/json": {
                "schema": { }
              }
            }
          },
          "400": {
            "description": "The request has invalid information.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ValidationProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
                  "title": "One or more validation errors occurred.",
                  "status": 400,
                  "detail": "The request has invalid information.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                  "errors": { }
                }
              }
            }
          },
          "401": {
            "description": "The partner does not have access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.2",
                  "title": "Unauthorized",
                  "status": 401,
                  "detail": "Invalid partner.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "403": {
            "description": "Swaps between these assets are not enabled for the partner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.4",
                  "title": "Forbidden",
                  "status": 403,
                  "detail": "Swaps from BTC to ETH are not enabled for your account.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "500": {
            "description": "An error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                  "title": "An error occurred while processing your request.",
                  "status": 500,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          }
        }
      }
    },
    "/status-by-deposit-channel": {
      "get": {
        "tags": [
          "Status"
        ],
        "summary": "View status of a swap, by deposit channel.",
        "description": "The same swap status as `getStatusById`, looked up by the deposit channel\n(`issuedBlock`, `network` and `channelId`) that `startSwap` returned.",
        "operationId": "getStatusByDepositChannel",
        "parameters": [
          {
            "name": "apiKey",
            "in": "query",
            "description": "Your partner API key. A key is required through this parameter OR the X-API-Key header; when both are present, this query parameter wins, even when it is empty, which fails validation rather than falling back to the header.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "issuedBlock",
            "in": "query",
            "description": "The block in which the swap deposit address was issued (`issuedBlock` from `startSwap`).",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            },
            "example": 15253762
          },
          {
            "name": "network",
            "in": "query",
            "description": "The source network of the swap, by name (`network` from `startSwap`).",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "Assethub"
          },
          {
            "name": "channelId",
            "in": "query",
            "description": "The channel id of the swap (`channelId` from `startSwap`).",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            },
            "example": 49
          }
        ],
        "responses": {
          "200": {
            "description": "The swap status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChainflipBaas.Status.StatusResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request has invalid information.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ValidationProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
                  "title": "One or more validation errors occurred.",
                  "status": 400,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                  "errors": {
                    "apiKey": [
                      "A value for the 'apiKey' parameter or property was not provided."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "The partner does not have access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.2",
                  "title": "Unauthorized",
                  "status": 401,
                  "detail": "Invalid partner.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "404": {
            "description": "No swap is recorded under this API key for the given deposit channel (code `swap_unknown`), or the swap exists but its status is not available yet (code `swap_pending`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "examples": {
                  "pending": {
                    "summary": "The swap exists but its status is not available yet",
                    "value": {
                      "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
                      "title": "Not Found",
                      "status": 404,
                      "detail": "Swap '42' exists but its status is not available yet; poll again later.",
                      "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                      "code": "swap_pending"
                    }
                  },
                  "unknown": {
                    "summary": "No swap is recorded under this API key for this lookup key",
                    "value": {
                      "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
                      "title": "Not Found",
                      "status": 404,
                      "detail": "No swap is recorded under this API key for '42'.",
                      "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                      "code": "swap_unknown"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "An error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                  "title": "An error occurred while processing your request.",
                  "status": 500,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": [ ]
          },
          {
            "apiKeyHeader": [ ]
          }
        ]
      }
    },
    "/status-by-id": {
      "get": {
        "tags": [
          "Status"
        ],
        "summary": "View status of a swap, by id.",
        "description": "Returns a swap's current state (waiting, receiving, swapping, sending, sent, completed\nor failed) with its deposit channel, deposit, fees, swap progress and payout, looked\nup by the `id` that `startSwap` returned.",
        "operationId": "getStatusById",
        "parameters": [
          {
            "name": "apiKey",
            "in": "query",
            "description": "Your partner API key. A key is required through this parameter OR the X-API-Key header; when both are present, this query parameter wins, even when it is empty, which fails validation rather than falling back to the header.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "swapId",
            "in": "query",
            "description": "The BaaS swap id, as returned by `startSwap`.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 73410
          }
        ],
        "responses": {
          "200": {
            "description": "The swap status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChainflipBaas.Status.StatusResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request has invalid information.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ValidationProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
                  "title": "One or more validation errors occurred.",
                  "status": 400,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                  "errors": {
                    "apiKey": [
                      "A value for the 'apiKey' parameter or property was not provided."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "The partner does not have access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.2",
                  "title": "Unauthorized",
                  "status": 401,
                  "detail": "Invalid partner.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "404": {
            "description": "No swap is recorded under this API key for the given id (code `swap_unknown`), or the swap exists but its status is not available yet (code `swap_pending`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "examples": {
                  "pending": {
                    "summary": "The swap exists but its status is not available yet",
                    "value": {
                      "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
                      "title": "Not Found",
                      "status": 404,
                      "detail": "Swap '42' exists but its status is not available yet; poll again later.",
                      "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                      "code": "swap_pending"
                    }
                  },
                  "unknown": {
                    "summary": "No swap is recorded under this API key for this lookup key",
                    "value": {
                      "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
                      "title": "Not Found",
                      "status": 404,
                      "detail": "No swap is recorded under this API key for '42'.",
                      "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                      "code": "swap_unknown"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "An error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                  "title": "An error occurred while processing your request.",
                  "status": 500,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": [ ]
          },
          {
            "apiKeyHeader": [ ]
          }
        ]
      }
    },
    "/status-by-transaction-hash": {
      "get": {
        "tags": [
          "Status"
        ],
        "summary": "View status of a swap, by transaction hash.",
        "description": "The same swap status as `getStatusById`, looked up by the hash of the\ntransaction that sent the deposit.",
        "operationId": "getStatusByTransactionHash",
        "parameters": [
          {
            "name": "apiKey",
            "in": "query",
            "description": "Your partner API key. A key is required through this parameter OR the X-API-Key header; when both are present, this query parameter wins, even when it is empty, which fails validation rather than falling back to the header.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "transactionHash",
            "in": "query",
            "description": "The hash of the deposit transaction. For a Polkadot Assethub deposit, either Chainflip's `<block>-<extrinsicIndex>` reference (as in `deposit.transactionReference`) or the 0x extrinsic hash; the extrinsic hash matches shortly after the deposit is witnessed.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "0xe3e6e6d9177796e473696d4f3beec9475f2e645f02a8bd524a1d194cd93d0026"
          }
        ],
        "responses": {
          "200": {
            "description": "The swap status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChainflipBaas.Status.StatusResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request has invalid information.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ValidationProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
                  "title": "One or more validation errors occurred.",
                  "status": 400,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                  "errors": {
                    "apiKey": [
                      "A value for the 'apiKey' parameter or property was not provided."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "The partner does not have access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.2",
                  "title": "Unauthorized",
                  "status": 401,
                  "detail": "Invalid partner.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "404": {
            "description": "No deposit transaction with this hash is linked to a swap yet (code `swap_unknown`) — a deposit is linked once it has been witnessed on-chain; retry later. Or the swap exists but its status is not available yet (code `swap_pending`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "examples": {
                  "pending": {
                    "summary": "The swap exists but its status is not available yet",
                    "value": {
                      "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
                      "title": "Not Found",
                      "status": 404,
                      "detail": "Swap '42' exists but its status is not available yet; poll again later.",
                      "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                      "code": "swap_pending"
                    }
                  },
                  "unknown": {
                    "summary": "No swap is recorded under this API key for this lookup key",
                    "value": {
                      "type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
                      "title": "Not Found",
                      "status": 404,
                      "detail": "No swap is recorded under this API key for '42'.",
                      "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                      "code": "swap_unknown"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "An error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                  "title": "An error occurred while processing your request.",
                  "status": 500,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": [ ]
          },
          {
            "apiKeyHeader": [ ]
          }
        ]
      }
    },
    "/swap": {
      "get": {
        "tags": [
          "Swap"
        ],
        "summary": "Start a swap.",
        "description": "Opens a deposit channel and returns the deposit address the user sends\n`sourceAsset` to. Once the deposit arrives the swap runs and pays out to\n`destinationAddress`, with your broker fee taken. `minimumPrice`,\n`refundAddress` and `retryDurationInBlocks` protect against slippage: if the\nprice cannot be met within that time, the deposit is refunded.\n`livePriceSlippageTolerancePercent` adds a limit against Chainflip's oracle price. Optional\nparameters add Boost (Bitcoin), DCA, a commission override and up to four affiliates. Follow the\nswap with `getStatusById` or `getStatusByDepositChannel`.",
        "operationId": "startSwap",
        "parameters": [
          {
            "name": "apiKey",
            "in": "query",
            "description": "Your partner API key. A key is required through this parameter OR the X-API-Key header; when both are present, this query parameter wins, even when it is empty, which fails validation rather than falling back to the header.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sourceAsset",
            "in": "query",
            "description": "The asset to swap from.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "eth.eth"
          },
          {
            "name": "destinationAsset",
            "in": "query",
            "description": "The asset to swap to.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "btc.btc"
          },
          {
            "name": "destinationAddress",
            "in": "query",
            "description": "The address on the destination chain to swap to.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "bc1qujr7jlxeh4m20lldqh4fcsl63ff2ee6uk60g8r"
          },
          {
            "name": "commissionBps",
            "in": "query",
            "description": "An optional override to the charged commission bps.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 15
          },
          {
            "name": "boostFee",
            "in": "query",
            "description": "Maximum accepted boost fee in basis points (100th of a percent).",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 5
          },
          {
            "name": "minimumPrice",
            "in": "query",
            "description": "Minimum accepted human readable price.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "double"
            },
            "example": 2768.95
          },
          {
            "name": "refundAddress",
            "in": "query",
            "description": "Address on the source chain to which the refund will be sent, if the minimum price cannot be met.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "0x2c1f0390f27740257de9f3772d9a6bb46ec13fe3"
          },
          {
            "name": "retryDurationInBlocks",
            "in": "query",
            "description": "Number of blocks after which a deposit is refunded if the minimum price cannot be met. One block corresponds to 6 seconds. Max 14400 = 24 hours. Recommended: 150.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 100
          },
          {
            "name": "livePriceSlippageTolerancePercent",
            "in": "query",
            "description": "Live price protection: how far, in percent (0 to 100, at most 2 decimals), the execution price may fall below Chainflip's oracle price; a swap below it is retried and, after `retryDurationInBlocks`, refunded. Use the quote's `recommendedLivePriceSlippageTolerancePercent` when it has one. Rejected with code `live_price_protection_unavailable` when either asset has no oracle price on Chainflip. When set, a stale oracle price also counts as a violation. Omit it to keep Chainflip's default protection for the pair.",
            "schema": {
              "type": "number",
              "format": "double"
            },
            "example": 0.5
          },
          {
            "name": "numberOfChunks",
            "in": "query",
            "description": "The number of \"sub-swaps\" to perform for a DCA swap.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 32
          },
          {
            "name": "chunkIntervalBlocks",
            "in": "query",
            "description": "The delay between the \"sub-swaps\" of a DCA swap in number of blocks.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 2
          },
          {
            "name": "affiliate1",
            "in": "query",
            "description": "First optional extra affiliate ss58 address to share commission with.",
            "schema": {
              "type": "string"
            },
            "example": "cFMTcq3p1C4Yhpw7NPn88Jdzj6ryVD8cTGPBuVMR4U6tFVdQb"
          },
          {
            "name": "affiliate1CommissionBps",
            "in": "query",
            "description": "First optional extra affiliate commission in basis points.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 10
          },
          {
            "name": "affiliate2",
            "in": "query",
            "description": "Second optional extra affiliate ss58 address to share commission with.",
            "schema": {
              "type": "string"
            },
            "example": "cFMTcq3p1C4Yhpw7NPn88Jdzj6ryVD8cTGPBuVMR4U6tFVdQb"
          },
          {
            "name": "affiliate2CommissionBps",
            "in": "query",
            "description": "Second optional extra affiliate commission in basis points.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 10
          },
          {
            "name": "affiliate3",
            "in": "query",
            "description": "Third optional extra affiliate ss58 address to share commission with.",
            "schema": {
              "type": "string"
            },
            "example": "cFMTcq3p1C4Yhpw7NPn88Jdzj6ryVD8cTGPBuVMR4U6tFVdQb"
          },
          {
            "name": "affiliate3CommissionBps",
            "in": "query",
            "description": "Third optional extra affiliate commission in basis points.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 10
          },
          {
            "name": "affiliate4",
            "in": "query",
            "description": "Fourth optional extra affiliate ss58 address to share commission with.",
            "schema": {
              "type": "string"
            },
            "example": "cFMTcq3p1C4Yhpw7NPn88Jdzj6ryVD8cTGPBuVMR4U6tFVdQb"
          },
          {
            "name": "affiliate4CommissionBps",
            "in": "query",
            "description": "Fourth optional extra affiliate commission in basis points.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 10
          },
          {
            "name": "platform",
            "in": "query",
            "description": "Optional provider to route the swap through. Defaults to chainflip.",
            "schema": {
              "type": "string"
            },
            "example": "chainflip"
          }
        ],
        "responses": {
          "200": {
            "description": "A deposit address for the given swap.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChainflipBaas.Swap.DepositAddress"
                }
              }
            }
          },
          "400": {
            "description": "The request has invalid information.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ValidationProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
                  "title": "One or more validation errors occurred.",
                  "status": 400,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                  "errors": {
                    "apiKey": [
                      "A value for the 'apiKey' parameter or property was not provided."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "The partner does not have access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.2",
                  "title": "Unauthorized",
                  "status": 401,
                  "detail": "Invalid partner.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "403": {
            "description": "Swaps between these assets are not enabled for the partner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.4",
                  "title": "Forbidden",
                  "status": 403,
                  "detail": "Swaps from BTC to ETH are not enabled for your account.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "503": {
            "description": "A temporary upstream condition, such as maintenance, a disabled asset or the network channel cap. Retry with backoff.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.4",
                  "title": "Service Unavailable",
                  "status": 503,
                  "detail": "One of the assets in this swap is currently disabled on Chainflip",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                  "code": "asset_disabled"
                }
              }
            }
          },
          "500": {
            "description": "An error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                  "title": "An error occurred while processing your request.",
                  "status": 500,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": [ ]
          },
          {
            "apiKeyHeader": [ ]
          }
        ]
      },
      "post": {
        "tags": [
          "Swap"
        ],
        "summary": "Start an advanced swap.",
        "description": "The same as `startSwap`, plus a JSON body for parameters that do not fit in a\nquery string, such as a Cross-Chain Messaging payload for the destination chain.",
        "operationId": "startAdvancedSwap",
        "parameters": [
          {
            "name": "apiKey",
            "in": "query",
            "description": "Your partner API key. A key is required through this parameter OR the X-API-Key header; when both are present, this query parameter wins, even when it is empty, which fails validation rather than falling back to the header.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sourceAsset",
            "in": "query",
            "description": "The asset to swap from.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "eth.eth"
          },
          {
            "name": "destinationAsset",
            "in": "query",
            "description": "The asset to swap to.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "btc.btc"
          },
          {
            "name": "destinationAddress",
            "in": "query",
            "description": "The address on the destination chain to swap to.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "bc1qujr7jlxeh4m20lldqh4fcsl63ff2ee6uk60g8r"
          },
          {
            "name": "commissionBps",
            "in": "query",
            "description": "An optional override to the charged commission bps.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 15
          },
          {
            "name": "boostFee",
            "in": "query",
            "description": "Maximum accepted boost fee in basis points (100th of a percent).",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 5
          },
          {
            "name": "minimumPrice",
            "in": "query",
            "description": "Minimum accepted human readable price.",
            "required": true,
            "schema": {
              "type": "number",
              "format": "double"
            },
            "example": 2768.95
          },
          {
            "name": "refundAddress",
            "in": "query",
            "description": "Address on the source chain to which the refund will be sent, if the minimum price cannot be met.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "0x2c1f0390f27740257de9f3772d9a6bb46ec13fe3"
          },
          {
            "name": "retryDurationInBlocks",
            "in": "query",
            "description": "Number of blocks after which a deposit is refunded if the minimum price cannot be met. One block corresponds to 6 seconds. Max 14400 = 24 hours. Recommended: 150.",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 100
          },
          {
            "name": "livePriceSlippageTolerancePercent",
            "in": "query",
            "description": "Live price protection: how far, in percent (0 to 100, at most 2 decimals), the execution price may fall below Chainflip's oracle price; a swap below it is retried and, after `retryDurationInBlocks`, refunded. Use the quote's `recommendedLivePriceSlippageTolerancePercent` when it has one. Rejected with code `live_price_protection_unavailable` when either asset has no oracle price on Chainflip. When set, a stale oracle price also counts as a violation. Omit it to keep Chainflip's default protection for the pair.",
            "schema": {
              "type": "number",
              "format": "double"
            },
            "example": 0.5
          },
          {
            "name": "numberOfChunks",
            "in": "query",
            "description": "The number of \"sub-swaps\" to perform for a DCA swap.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 32
          },
          {
            "name": "chunkIntervalBlocks",
            "in": "query",
            "description": "The delay between the \"sub-swaps\" of a DCA swap in number of blocks.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 2
          },
          {
            "name": "affiliate1",
            "in": "query",
            "description": "First optional extra affiliate ss58 address to share commission with.",
            "schema": {
              "type": "string"
            },
            "example": "cFMTcq3p1C4Yhpw7NPn88Jdzj6ryVD8cTGPBuVMR4U6tFVdQb"
          },
          {
            "name": "affiliate1CommissionBps",
            "in": "query",
            "description": "First optional extra affiliate commission in basis points.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 10
          },
          {
            "name": "affiliate2",
            "in": "query",
            "description": "Second optional extra affiliate ss58 address to share commission with.",
            "schema": {
              "type": "string"
            },
            "example": "cFMTcq3p1C4Yhpw7NPn88Jdzj6ryVD8cTGPBuVMR4U6tFVdQb"
          },
          {
            "name": "affiliate2CommissionBps",
            "in": "query",
            "description": "Second optional extra affiliate commission in basis points.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 10
          },
          {
            "name": "affiliate3",
            "in": "query",
            "description": "Third optional extra affiliate ss58 address to share commission with.",
            "schema": {
              "type": "string"
            },
            "example": "cFMTcq3p1C4Yhpw7NPn88Jdzj6ryVD8cTGPBuVMR4U6tFVdQb"
          },
          {
            "name": "affiliate3CommissionBps",
            "in": "query",
            "description": "Third optional extra affiliate commission in basis points.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 10
          },
          {
            "name": "affiliate4",
            "in": "query",
            "description": "Fourth optional extra affiliate ss58 address to share commission with.",
            "schema": {
              "type": "string"
            },
            "example": "cFMTcq3p1C4Yhpw7NPn88Jdzj6ryVD8cTGPBuVMR4U6tFVdQb"
          },
          {
            "name": "affiliate4CommissionBps",
            "in": "query",
            "description": "Fourth optional extra affiliate commission in basis points.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 10
          },
          {
            "name": "platform",
            "in": "query",
            "description": "Optional provider to route the swap through. Defaults to chainflip.",
            "schema": {
              "type": "string"
            },
            "example": "chainflip"
          }
        ],
        "requestBody": {
          "description": "Advanced swap parameters which are not supported as query string parameters, e.g.: Cross-Chain Messaging payload.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChainflipBaas.Swap.AdvancedSwapRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A deposit address for the given swap.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChainflipBaas.Swap.DepositAddress"
                }
              }
            }
          },
          "400": {
            "description": "The request has invalid information.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ValidationProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
                  "title": "One or more validation errors occurred.",
                  "status": 400,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                  "errors": {
                    "apiKey": [
                      "A value for the 'apiKey' parameter or property was not provided."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "The partner does not have access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.2",
                  "title": "Unauthorized",
                  "status": 401,
                  "detail": "Invalid partner.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "403": {
            "description": "Swaps between these assets are not enabled for the partner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.4",
                  "title": "Forbidden",
                  "status": 403,
                  "detail": "Swaps from BTC to ETH are not enabled for your account.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "503": {
            "description": "A temporary upstream condition, such as maintenance, a disabled asset or the network channel cap. Retry with backoff.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.4",
                  "title": "Service Unavailable",
                  "status": 503,
                  "detail": "One of the assets in this swap is currently disabled on Chainflip",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                  "code": "asset_disabled"
                }
              }
            }
          },
          "500": {
            "description": "An error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                  "title": "An error occurred while processing your request.",
                  "status": 500,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": [ ]
          },
          {
            "apiKeyHeader": [ ]
          }
        ]
      }
    },
    "/feed": {
      "get": {
        "tags": [
          "Swaps"
        ],
        "summary": "View swaps feed, sorted oldest to newest.",
        "description": "Returns your broker's completed swaps oldest to newest, each with a `feedId`, for\nprocessing every swap exactly once. Store the last `feedId` you processed and\npass `feedId + 1` as `offset` next time; an empty list means you are up to\ndate.",
        "operationId": "getSwapFeed",
        "parameters": [
          {
            "name": "apiKey",
            "in": "query",
            "description": "Your partner API key. A key is required through this parameter OR the X-API-Key header; when both are present, this query parameter wins, even when it is empty, which fails validation rather than falling back to the header.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Feed id to return results from.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 42
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Number of results to return, default 50, maximum 500.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "The swaps in completion order.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ChainflipBaas.SwapsFeed.FeedStatusResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request has invalid information.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ValidationProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
                  "title": "One or more validation errors occurred.",
                  "status": 400,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                  "errors": {
                    "apiKey": [
                      "A value for the 'apiKey' parameter or property was not provided."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "The partner does not have access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.2",
                  "title": "Unauthorized",
                  "status": 401,
                  "detail": "Invalid partner.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "500": {
            "description": "An error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                  "title": "An error occurred while processing your request.",
                  "status": 500,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": [ ]
          },
          {
            "apiKeyHeader": [ ]
          }
        ]
      }
    },
    "/swaps": {
      "get": {
        "tags": [
          "Swaps"
        ],
        "summary": "View swaps.",
        "description": "Lists the swaps made through your broker. Without filters it returns the last 50\ncompleted swaps, newest first; filter by `status` and `platform`, and page\nwith `offset`, `limit` (maximum 500) and `sort`.",
        "operationId": "listSwaps",
        "parameters": [
          {
            "name": "apiKey",
            "in": "query",
            "description": "Your partner API key. A key is required through this parameter OR the X-API-Key header; when both are present, this query parameter wins, even when it is empty, which fails validation rather than falling back to the header.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Swap id to return results from, depends on sort.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 42
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Number of results to return, default 50, maximum 500.",
            "schema": {
              "type": "integer",
              "format": "int32"
            },
            "example": 50
          },
          {
            "name": "status",
            "in": "query",
            "description": "Only return swaps which match these statuses. Defaults to completed only.",
            "schema": {
              "type": "array",
              "items": {
                "enum": [
                  "waiting",
                  "receiving",
                  "swapping",
                  "sending",
                  "sent",
                  "completed",
                  "failed"
                ],
                "type": "string",
                "x-ms-enum": {
                  "name": "SwapState",
                  "modelAsString": true
                }
              }
            },
            "example": "completed"
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Sort order, default descending.",
            "schema": {
              "enum": [
                "ascending",
                "descending"
              ],
              "type": "string"
            },
            "example": "descending"
          },
          {
            "name": "platform",
            "in": "query",
            "description": "Optional provider to filter swaps by. Defaults to all platforms.",
            "schema": {
              "type": "string"
            },
            "example": "chainflip"
          }
        ],
        "responses": {
          "200": {
            "description": "The swaps.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ChainflipBaas.Status.StatusResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request has invalid information.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ValidationProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
                  "title": "One or more validation errors occurred.",
                  "status": 400,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00",
                  "errors": {
                    "apiKey": [
                      "A value for the 'apiKey' parameter or property was not provided."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "The partner does not have access.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.2",
                  "title": "Unauthorized",
                  "status": 401,
                  "detail": "Invalid partner.",
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          },
          "500": {
            "description": "An error occurred.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Microsoft.AspNetCore.Mvc.ProblemDetails"
                },
                "example": {
                  "type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
                  "title": "An error occurred while processing your request.",
                  "status": 500,
                  "traceId": "00-982607166a542147b435be3a847ddd71-fc75498eb9f09d48-00"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": [ ]
          },
          {
            "apiKeyHeader": [ ]
          }
        ]
      }
    },
    "/onboarding": {
      "get": {
        "tags": [
          "Onboarding"
        ],
        "summary": "Get the onboarding facts.",
        "description": "Machine-readable onboarding for agents, no key needed: what works without a key (the MCP server, `listAssets`, `listNetworks`), how to get a key self-serve, the testnet sandbox, a first call and the pricing. Every claim carries URLs you can fetch anonymously to verify it, on the origin of the transport you called (onion over Tor).",
        "operationId": "getOnboarding",
        "responses": {
          "200": {
            "description": "The onboarding facts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChainflipBaas.Infrastructure.Http.OnboardingDocument"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ChainflipBaas.Assets.AssetInfo": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "Is the asset available for swapping or not?",
            "example": true
          },
          "id": {
            "type": "string",
            "description": "The asset id, `ticker.network`: what you pass as `sourceAsset` or `destinationAsset` on every\nother endpoint.",
            "example": "flip.eth"
          },
          "direction": {
            "enum": [
              "ingress",
              "egress",
              "both"
            ],
            "type": "string",
            "description": "Direction an asset can be used in. Ingress assets can only be used to swap from. Egress assets can only be used to swap to. Assets with both can be used to swap from and to.",
            "example": "both",
            "x-ms-enum": {
              "name": "AssetDirection",
              "modelAsString": true
            }
          },
          "ticker": {
            "type": "string",
            "description": "Display ticker of the asset.",
            "example": "FLIP"
          },
          "name": {
            "type": "string",
            "description": "Descriptive name of the asset.",
            "example": "Chainflip"
          },
          "network": {
            "type": "string",
            "description": "Name of the network where the asset is located.",
            "example": "Ethereum"
          },
          "contractAddress": {
            "type": "string",
            "description": "The contract address for tokens which have one.",
            "nullable": true,
            "example": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
          },
          "networkLogo": {
            "type": "string",
            "description": "A url to the logo for the network.",
            "readOnly": true,
            "example": "/networks/eth/logo.svg"
          },
          "assetLogo": {
            "type": "string",
            "description": "A url to the logo for the asset.",
            "readOnly": true,
            "example": "/assets/flip.eth/logo.svg"
          },
          "decimals": {
            "type": "integer",
            "description": "Number of decimals the asset native value contains.",
            "format": "int32",
            "example": 18
          },
          "minimalAmount": {
            "type": "number",
            "description": "Minimum amount required to swap the asset.",
            "format": "double",
            "nullable": true,
            "readOnly": true,
            "example": 4
          },
          "minimalAmountNative": {
            "type": "string",
            "description": "Minimum amount in native units required to swap the asset.",
            "nullable": true,
            "readOnly": true,
            "example": "4000000000000000000"
          },
          "usdPrice": {
            "type": "number",
            "description": "Current pool price of the asset in USDC.",
            "format": "double",
            "nullable": true,
            "readOnly": true,
            "example": 4
          },
          "usdPriceNative": {
            "type": "string",
            "description": "Current pool price of the asset in USDC native units.",
            "nullable": true,
            "readOnly": true,
            "example": "4000000000000000000"
          },
          "platforms": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The providers that support this asset. Pass one as `platform` to `startSwap`.",
            "readOnly": true,
            "example": [
              "chainflip"
            ]
          }
        },
        "additionalProperties": false,
        "description": "An asset you can swap: its id, network, decimals, minimum swap amount and current USD price."
      },
      "ChainflipBaas.Assets.AssetsResponse": {
        "type": "object",
        "properties": {
          "assets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainflipBaas.Assets.AssetInfo"
            },
            "description": "All available assets.",
            "readOnly": true
          }
        },
        "additionalProperties": false,
        "description": "The assets you can swap, ordered by id."
      },
      "ChainflipBaas.Fees.FeesResponse": {
        "type": "object",
        "properties": {
          "earnedFees": {
            "type": "object",
            "additionalProperties": {
              "type": "number",
              "format": "double"
            },
            "description": "Earned broker fees per asset.",
            "example": {
              "eth.eth": 0.0173436384794928,
              "flip.eth": 10.151732266480410979,
              "usdc.eth": 87.707768,
              "dot.dot": 0.696349455,
              "btc.btc": 0.00044002
            }
          },
          "earnedFeesNative": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Earned broker fees per asset in native units.",
            "example": {
              "eth.eth": "17343638479492800",
              "flip.eth": "10151732266480410979",
              "usdc.eth": "87707768",
              "dot.dot": "6963494550",
              "btc.btc": "44002"
            }
          },
          "byProvider": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/ChainflipBaas.Fees.FeesResponse"
            },
            "description": "The same fees per provider, keyed by provider (e.g. `chainflip`).",
            "nullable": true,
            "readOnly": true,
            "example": {
              "chainflip": {
                "earnedFees": {
                  "btc.btc": 0.00044002
                },
                "earnedFeesNative": {
                  "btc.btc": "44002"
                }
              }
            }
          }
        },
        "additionalProperties": false,
        "description": "The broker fees you have earned so far, per asset id, after the BaaS operating fee."
      },
      "ChainflipBaas.Infrastructure.Http.ApiKeyOnboarding": {
        "type": "object",
        "properties": {
          "selfServe": {
            "type": "boolean",
            "description": "True: keys are issued by a self-serve signup, no sales contact.",
            "example": true
          },
          "requiredFor": {
            "type": "string",
            "description": "Which calls need a key.",
            "example": "REST quotes, swaps, status, swap history and fees. Optional on the MCP tools."
          },
          "signupUrl": {
            "type": "string",
            "description": "The signup page.",
            "example": "https://chainflip-broker.io/register"
          },
          "signup": {
            "type": "string",
            "description": "What the signup asks for.",
            "example": "One free web form, no payment details: a name, an optional email, your commission and an Ethereum address for payouts. The key is shown at once."
          },
          "secret": {
            "type": "boolean",
            "description": "False: the API key identifies an account and may be shared.",
            "example": false
          },
          "description": {
            "type": "string",
            "description": "What the key is.",
            "example": "The API key identifies your partner account and is safe to share. Only the dashboard admin key is a secret."
          },
          "verify": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "URLs that show the signup is live."
          }
        },
        "additionalProperties": false,
        "description": "How to get an API key."
      },
      "ChainflipBaas.Infrastructure.Http.FirstCall": {
        "type": "object",
        "properties": {
          "method": {
            "type": "string",
            "description": "The HTTP method.",
            "example": "GET"
          },
          "url": {
            "type": "string",
            "description": "The URL to call.",
            "example": "https://chainflip-broker.io/assets"
          },
          "authentication": {
            "type": "string",
            "description": "Always \"none\".",
            "example": "none"
          },
          "curl": {
            "type": "string",
            "description": "The same request as a curl command.",
            "example": "curl -s https://chainflip-broker.io/assets"
          }
        },
        "additionalProperties": false,
        "description": "A first request that needs no key."
      },
      "ChainflipBaas.Infrastructure.Http.NoKeyAccess": {
        "type": "object",
        "properties": {
          "available": {
            "type": "boolean",
            "description": "Always true: keyless access exists.",
            "example": true
          },
          "description": {
            "type": "string",
            "description": "What works without a key.",
            "example": "The MCP server and the asset and network listings work without any key or account."
          },
          "mcpServer": {
            "type": "string",
            "description": "The MCP server, keyless for every tool.",
            "example": "https://chainflip-broker.io/mcp"
          },
          "verify": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Keyless URLs that answer 200 anonymously."
          }
        },
        "additionalProperties": false,
        "description": "What works with no API key or account at all."
      },
      "ChainflipBaas.Infrastructure.Http.OnboardingDocument": {
        "type": "object",
        "properties": {
          "service": {
            "type": "string",
            "description": "The service name.",
            "example": "Chainflip Broker as a Service"
          },
          "noKeyNeeded": {
            "$ref": "#/components/schemas/ChainflipBaas.Infrastructure.Http.NoKeyAccess"
          },
          "apiKeys": {
            "$ref": "#/components/schemas/ChainflipBaas.Infrastructure.Http.ApiKeyOnboarding"
          },
          "sandbox": {
            "$ref": "#/components/schemas/ChainflipBaas.Infrastructure.Http.SandboxEnvironment"
          },
          "firstCall": {
            "$ref": "#/components/schemas/ChainflipBaas.Infrastructure.Http.FirstCall"
          },
          "openApi": {
            "type": "string",
            "description": "The OpenAPI document of this API.",
            "example": "https://chainflip-broker.io/docs/v1/docs.json"
          },
          "llmsTxt": {
            "type": "string",
            "description": "The llms.txt index for agents.",
            "example": "https://chainflip-broker.io/llms.txt"
          },
          "documentation": {
            "type": "string",
            "description": "The getting-started guide, when a docs site is configured.",
            "nullable": true,
            "example": "https://docs.chainflip-broker.io/getting-started/"
          },
          "pricing": {
            "$ref": "#/components/schemas/ChainflipBaas.Infrastructure.Http.PricingSummary"
          }
        },
        "additionalProperties": false,
        "description": "The onboarding facts, for agents deciding whether and how to start: what works without a key, how to get\none, the sandbox and a first call. Every claim carries URLs you can fetch anonymously to verify it."
      },
      "ChainflipBaas.Infrastructure.Http.PricingSummary": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "description": "The pricing in one sentence.",
            "example": "No subscription: a 0.05% (5 bps) operating fee is added to each swap, and you set your own broker fee on top."
          },
          "documentation": {
            "type": "string",
            "description": "The pricing page.",
            "example": "https://docs.chainflip-broker.io/resources/pricing/"
          }
        },
        "additionalProperties": false,
        "description": "How pricing works."
      },
      "ChainflipBaas.Infrastructure.Http.SandboxEnvironment": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Which environment.",
            "example": "Testing environment, connected to the Chainflip Perseverance testnet"
          },
          "description": {
            "type": "string",
            "description": "How it differs from production.",
            "example": "Same API, same paths and parameters, swapping testnet assets with no real value. Register there separately for a testnet API key."
          },
          "apiBaseUrl": {
            "type": "string",
            "description": "Its API base URL (clearnet only).",
            "nullable": true,
            "example": "https://perseverance.chainflip-broker.io/"
          },
          "verify": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "URLs that show the sandbox is live."
          },
          "documentation": {
            "type": "string",
            "description": "Its documentation page, when a docs site is configured.",
            "nullable": true,
            "example": "https://docs.chainflip-broker.io/environments/testing/"
          }
        },
        "additionalProperties": false,
        "description": "The test environment."
      },
      "ChainflipBaas.Networks.NetworkInfo": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The network id, as used in asset ids (`usdc.eth`) and the `/assets/{network}` path.",
            "readOnly": true,
            "example": "eth"
          },
          "name": {
            "type": "string",
            "description": "The network's display name, as used in deposit channel ids (`15253762-Ethereum-49`).",
            "readOnly": true,
            "example": "Ethereum"
          },
          "logo": {
            "type": "string",
            "description": "A url to the logo for the network.",
            "readOnly": true,
            "example": "/networks/eth/logo.svg"
          },
          "platforms": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The providers that offer at least one asset on this network.",
            "example": [
              "chainflip"
            ]
          }
        },
        "additionalProperties": false,
        "description": "A network you can swap on."
      },
      "ChainflipBaas.Networks.NetworksResponse": {
        "type": "object",
        "properties": {
          "networks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainflipBaas.Networks.NetworkInfo"
            },
            "description": "All available networks.",
            "readOnly": true
          }
        },
        "additionalProperties": false,
        "description": "The networks you can swap on: every network with at least one asset you can swap."
      },
      "ChainflipBaas.Quote.BoostQuote": {
        "required": [
          "egressAmount",
          "egressAmountNative",
          "egressAsset",
          "estimatedBoostFeeBps",
          "estimatedDurationSeconds",
          "estimatedDurationsSeconds",
          "estimatedPrice",
          "includedFees",
          "ingressAmount",
          "ingressAmountNative",
          "ingressAsset",
          "lowLiquidityWarning",
          "maxBoostFeeBps",
          "poolInfo",
          "recommendedSlippageTolerancePercent"
        ],
        "type": "object",
        "properties": {
          "ingressAsset": {
            "type": "string",
            "description": "The asset you send.",
            "example": "btc.btc"
          },
          "ingressAmount": {
            "type": "number",
            "description": "The amount you send, in whole units of `ingressAsset`.",
            "format": "double",
            "example": 0.5
          },
          "ingressAmountNative": {
            "type": "string",
            "description": "`ingressAmount` in the asset's smallest unit.",
            "example": "50000000"
          },
          "intermediateAsset": {
            "type": "string",
            "description": "The asset the swap passes through (USDC), when neither asset is USDC.",
            "nullable": true,
            "example": "usdc.eth"
          },
          "intermediateAmount": {
            "type": "number",
            "description": "The amount of the intermediate asset, in whole units.",
            "format": "double",
            "nullable": true,
            "example": 40622.717973
          },
          "intermediateAmountNative": {
            "type": "string",
            "description": "`intermediateAmount` in the asset's smallest unit.",
            "nullable": true,
            "example": "40622717973"
          },
          "egressAsset": {
            "type": "string",
            "description": "The asset you receive.",
            "example": "usdt.hub"
          },
          "egressAmount": {
            "type": "number",
            "description": "The amount you receive with Boost, in whole units of `egressAsset`, after every fee in\n`includedFees` including the boost fee. An estimate: the final amount depends on the price when the\nswap executes.",
            "format": "double",
            "example": 40618.634251
          },
          "egressAmountNative": {
            "type": "string",
            "description": "`egressAmount` in the asset's smallest unit.",
            "example": "40618634251"
          },
          "includedFees": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainflipBaas.Quote.QuoteFee"
            },
            "description": "Every fee taken from the boosted swap, including the boost fee, already accounted for in\n`egressAmount`."
          },
          "recommendedSlippageTolerancePercent": {
            "type": "number",
            "description": "Recommended slippage percentage to use when calculating minimum price for the boosted swap.",
            "format": "double",
            "example": 2.5
          },
          "recommendedRetryDurationInBlocks": {
            "type": "integer",
            "description": "Recommended `retryDurationInBlocks` for `/swap`, in 6-second state-chain blocks.",
            "format": "int32",
            "nullable": true,
            "example": 300
          },
          "recommendedLivePriceSlippageTolerancePercent": {
            "type": "number",
            "description": "Recommended `livePriceSlippageTolerancePercent` for `/swap`. Absent when Chainflip has no\noracle-based protection to recommend for the pair.",
            "format": "double",
            "nullable": true,
            "example": 0.75
          },
          "lowLiquidityWarning": {
            "type": "boolean",
            "description": "A warning in case liquidity is low and there is a risk of high slippage.",
            "example": false
          },
          "poolInfo": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainflipBaas.Quote.PoolInfo"
            },
            "description": "Liquidity pools involved in the swap, as well as estimated liquidity provider fees."
          },
          "estimatedDurationSeconds": {
            "type": "number",
            "description": "The estimated time the swap will take.",
            "format": "double",
            "example": 409.5
          },
          "estimatedDurationsSeconds": {
            "$ref": "#/components/schemas/ChainflipBaas.Quote.EstimatedDurationsSeconds"
          },
          "estimatedBoostFeeBps": {
            "type": "number",
            "description": "The estimated fee (in bps) that the user has to pay (from the deposit amount) to get this swap boosted.",
            "format": "double",
            "example": 5
          },
          "maxBoostFeeBps": {
            "type": "integer",
            "description": "The maximum boost fee (in bps) to open this boosted swap with: pass it as `boostFee` to `/swap`. The\nfee actually charged is the lowest one that boosts the deposit, at most this.",
            "format": "int32",
            "example": 5
          },
          "estimatedPrice": {
            "type": "number",
            "description": "The estimated price in the destination asset for 1 unit of the source asset. Used for slippage calculations.",
            "format": "double",
            "example": 81278.3220021494045035363
          },
          "chunkIntervalBlocks": {
            "type": "integer",
            "description": "The delay between the \"sub-swaps\" of a DCA swap in number of blocks.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "numberOfChunks": {
            "type": "integer",
            "description": "The number of \"sub-swaps\" to perform for a DCA swap.",
            "format": "int32",
            "nullable": true,
            "example": 5
          }
        },
        "additionalProperties": false,
        "description": "The same quote with Boost, for Bitcoin deposits: liquidity providers credit the deposit after one\nconfirmation instead of waiting for all of them, so the swap is faster, for the boost fee listed in\n`includedFees`. To start it, pass `maxBoostFeeBps` as `boostFee` to `startSwap`."
      },
      "ChainflipBaas.Quote.EstimatedDurationsSeconds": {
        "required": [
          "deposit",
          "egress",
          "swap"
        ],
        "type": "object",
        "properties": {
          "deposit": {
            "type": "number",
            "description": "The estimated time for a deposit to be witnessed.",
            "format": "double",
            "example": 906
          },
          "swap": {
            "type": "number",
            "description": "The estimated time for a swap to be fully executed.",
            "format": "double",
            "example": 12
          },
          "egress": {
            "type": "number",
            "description": "The estimated time until the output transaction is included in a block.",
            "format": "double",
            "example": 91.5
          }
        },
        "additionalProperties": false,
        "description": "The estimated duration of each step, in seconds: witnessing the deposit, executing the swap and\nincluding the output transfer in a block on the destination chain."
      },
      "ChainflipBaas.Quote.PoolFee": {
        "required": [
          "amount",
          "amountNative",
          "asset"
        ],
        "type": "object",
        "properties": {
          "asset": {
            "type": "string",
            "description": "The asset the fee is processed in.",
            "example": "usdc.eth"
          },
          "amount": {
            "type": "number",
            "description": "The fee, in whole units of `asset`.",
            "format": "double",
            "example": 0
          },
          "amountNative": {
            "type": "string",
            "description": "`amount` in the asset's smallest unit.",
            "example": "0"
          }
        },
        "additionalProperties": false,
        "description": "A pool's estimated liquidity provider fee."
      },
      "ChainflipBaas.Quote.PoolInfo": {
        "required": [
          "baseAsset",
          "fee",
          "quoteAsset"
        ],
        "type": "object",
        "properties": {
          "baseAsset": {
            "type": "string",
            "description": "The base asset of the pool involved.",
            "example": "usdt.hub"
          },
          "quoteAsset": {
            "type": "string",
            "description": "The quote asset of the pool involved.",
            "example": "usdc.eth"
          },
          "fee": {
            "$ref": "#/components/schemas/ChainflipBaas.Quote.PoolFee"
          }
        },
        "additionalProperties": false,
        "description": "A liquidity pool the swap goes through, with its estimated liquidity provider fee."
      },
      "ChainflipBaas.Quote.Quote": {
        "required": [
          "egressAmount",
          "egressAmountNative",
          "egressAsset",
          "estimatedDurationSeconds",
          "estimatedDurationsSeconds",
          "estimatedPrice",
          "includedFees",
          "ingressAmount",
          "ingressAmountNative",
          "ingressAsset",
          "lowLiquidityWarning",
          "poolInfo",
          "recommendedSlippageTolerancePercent",
          "type"
        ],
        "type": "object",
        "properties": {
          "type": {
            "enum": [
              "regular",
              "dca"
            ],
            "type": "string",
            "description": "`regular`: swapped at once. `dca`: split into `numberOfChunks` chunks swapped\n            `chunkIntervalBlocks` apart, usually at a better price for large amounts.",
            "example": "regular",
            "x-ms-enum": {
              "name": "QuoteType",
              "modelAsString": true
            }
          },
          "ingressAsset": {
            "type": "string",
            "description": "The asset you send.",
            "example": "btc.btc"
          },
          "ingressAmount": {
            "type": "number",
            "description": "The amount you send, in whole units of `ingressAsset`.",
            "format": "double",
            "example": 0.5
          },
          "ingressAmountNative": {
            "type": "string",
            "description": "`ingressAmount` in the asset's smallest unit.",
            "example": "50000000"
          },
          "intermediateAsset": {
            "type": "string",
            "description": "The asset the swap passes through (USDC), when neither asset is USDC.",
            "nullable": true,
            "example": "usdc.eth"
          },
          "intermediateAmount": {
            "type": "number",
            "description": "The amount of the intermediate asset, in whole units.",
            "format": "double",
            "nullable": true,
            "example": 40643.039585
          },
          "intermediateAmountNative": {
            "type": "string",
            "description": "`intermediateAmount` in the asset's smallest unit.",
            "nullable": true,
            "example": "40643039585"
          },
          "egressAsset": {
            "type": "string",
            "description": "The asset you receive.",
            "example": "usdt.hub"
          },
          "egressAmount": {
            "type": "number",
            "description": "The amount you receive, in whole units of `egressAsset`, after every fee in `includedFees`. An\nestimate: the final amount depends on the price when the swap executes.",
            "format": "double",
            "example": 40638.953831
          },
          "egressAmountNative": {
            "type": "string",
            "description": "`egressAmount` in the asset's smallest unit.",
            "example": "40638953831"
          },
          "includedFees": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainflipBaas.Quote.QuoteFee"
            },
            "description": "Every fee taken from the swap, already accounted for in `egressAmount`."
          },
          "recommendedSlippageTolerancePercent": {
            "type": "number",
            "description": "Recommended slippage percentage to use when calculating minimum price.",
            "format": "double",
            "example": 2.5
          },
          "recommendedRetryDurationInBlocks": {
            "type": "integer",
            "description": "Recommended `retryDurationInBlocks` for `/swap`: Chainflip's recommended retry window (30 minutes\nwhen BTC is on either side, otherwise 5 minutes) in 6-second state-chain blocks.",
            "format": "int32",
            "nullable": true,
            "example": 300
          },
          "recommendedLivePriceSlippageTolerancePercent": {
            "type": "number",
            "description": "Recommended `livePriceSlippageTolerancePercent` for `/swap`: how far, in percent, the execution\nprice may fall below Chainflip's oracle price. Absent when Chainflip has no oracle-based protection to\nrecommend for the pair; `/swap` rejects the parameter when either asset has no oracle price.",
            "format": "double",
            "nullable": true,
            "example": 0.75
          },
          "lowLiquidityWarning": {
            "type": "boolean",
            "description": "A warning in case liquidity is low and there is a risk of high slippage.",
            "example": false
          },
          "poolInfo": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainflipBaas.Quote.PoolInfo"
            },
            "description": "Liquidity pools involved in the swap, as well as estimated liquidity provider fees."
          },
          "estimatedDurationSeconds": {
            "type": "number",
            "description": "The estimated time the swap will take.",
            "format": "double",
            "example": 1009.5
          },
          "estimatedDurationsSeconds": {
            "$ref": "#/components/schemas/ChainflipBaas.Quote.EstimatedDurationsSeconds"
          },
          "estimatedPrice": {
            "type": "number",
            "description": "The estimated price in the destination asset for 1 unit of the source asset. Used for slippage calculations.",
            "format": "double",
            "example": 81278.32200114832523636308
          },
          "chunkIntervalBlocks": {
            "type": "integer",
            "description": "The delay between the \"sub-swaps\" of a DCA swap in number of blocks.",
            "format": "int32",
            "nullable": true,
            "example": 1
          },
          "numberOfChunks": {
            "type": "integer",
            "description": "The number of \"sub-swaps\" to perform for a DCA swap.",
            "format": "int32",
            "nullable": true,
            "example": 5
          },
          "boostQuote": {
            "$ref": "#/components/schemas/ChainflipBaas.Quote.BoostQuote"
          },
          "platform": {
            "type": "string",
            "description": "The provider that produced this quote. Pass it as `platform` to `startSwap` to open the swap\nwith the same provider.",
            "readOnly": true,
            "example": "chainflip"
          }
        },
        "additionalProperties": false,
        "description": "A quote: what you send and receive, the fees already taken into account, the recommended slippage\nprotection and retry window, and how long the swap is expected to take. To start the swap, pass\n`estimatedPrice` reduced by your slippage tolerance as `minimumPrice` to `startSwap`."
      },
      "ChainflipBaas.Quote.QuoteFee": {
        "required": [
          "amount",
          "amountNative",
          "asset",
          "type"
        ],
        "type": "object",
        "properties": {
          "type": {
            "enum": [
              "ingress",
              "broker",
              "network",
              "liquidity",
              "egress",
              "boost",
              "refund"
            ],
            "type": "string",
            "description": "The fee: `ingress` (receiving the deposit on the source chain), `network` (Chainflip's network\nfee), `broker` (the broker and affiliate commissions), `liquidity` (a pool's liquidity provider\nfee, also in `poolInfo`), `egress` (sending the output on the destination chain) or\n`boost` (on Boost quotes). `refund` only appears on swap statuses.",
            "example": "network",
            "x-ms-enum": {
              "name": "FeeType",
              "modelAsString": true
            }
          },
          "asset": {
            "type": "string",
            "description": "The asset the fee is processed in.",
            "example": "usdc.eth"
          },
          "amount": {
            "type": "number",
            "description": "The fee, in whole units of `asset`.",
            "format": "double",
            "example": 40.683723
          },
          "amountNative": {
            "type": "string",
            "description": "`amount` in the asset's smallest unit.",
            "example": "40683723"
          }
        },
        "additionalProperties": false,
        "description": "A fee the quote already accounts for: `egressAmount` is what remains after all of them."
      },
      "ChainflipBaas.Status.AffiliateBroker": {
        "type": "object",
        "properties": {
          "account": {
            "type": "string",
            "description": "The Chainflip account (SS58) the commission is paid to.",
            "readOnly": true,
            "example": "cFJZVRaybb2PBwxTiAiRLiQfHY4KPB3RpJK22Q7Fhqk979aCH"
          },
          "commissionBps": {
            "type": "integer",
            "description": "The commission in basis points of the swap.",
            "format": "int32",
            "readOnly": true,
            "example": 5
          }
        },
        "additionalProperties": false,
        "description": "An account earning a commission on the swap."
      },
      "ChainflipBaas.Status.Boost": {
        "type": "object",
        "properties": {
          "maximumBoostFeeBps": {
            "type": "integer",
            "description": "The maximum boost fee accepted, in basis points: the `boostFee` the swap was started with.",
            "format": "int32",
            "readOnly": true,
            "example": 5
          },
          "effectiveBoostFeeBps": {
            "type": "integer",
            "description": "The boost fee actually charged, in basis points; 0 when the deposit could not be boosted.",
            "format": "int32",
            "nullable": true,
            "readOnly": true,
            "example": 5
          },
          "boostedAt": {
            "type": "integer",
            "description": "When the deposit was boosted, as a Unix time in milliseconds.",
            "format": "int64",
            "nullable": true,
            "readOnly": true,
            "example": 1790087700000
          },
          "boostedAtDate": {
            "type": "string",
            "description": "`boostedAt` as a date.",
            "format": "date-time",
            "nullable": true,
            "readOnly": true,
            "example": "2026-09-22T14:35:00+00:00"
          },
          "boostedBlockIndex": {
            "type": "string",
            "description": "The State Chain block and event the deposit was boosted in.",
            "nullable": true,
            "readOnly": true,
            "example": "14930157-12"
          },
          "skippedAt": {
            "type": "integer",
            "description": "When boosting failed (not enough boost liquidity at the fee), as a Unix time in milliseconds. The deposit\nthen waits for all confirmations.",
            "format": "int64",
            "nullable": true,
            "readOnly": true,
            "example": 1790087694000
          },
          "skippedAtDate": {
            "type": "string",
            "description": "`skippedAt` as a date.",
            "format": "date-time",
            "nullable": true,
            "readOnly": true,
            "example": "2026-09-22T14:34:54+00:00"
          },
          "skippedBlockIndex": {
            "type": "string",
            "description": "The State Chain block and event boosting failed in.",
            "nullable": true,
            "readOnly": true,
            "example": "14930156-1088"
          }
        },
        "additionalProperties": false,
        "description": "Boost: liquidity providers credit a Bitcoin deposit after one confirmation instead of waiting for all of them,\nfor a fee."
      },
      "ChainflipBaas.Status.CcmParameters": {
        "type": "object",
        "properties": {
          "gasBudget": {
            "type": "string",
            "description": "The gas budget for executing the message on the destination chain, as given when the swap was started.",
            "readOnly": true,
            "example": "1000000"
          },
          "message": {
            "type": "string",
            "description": "The message passed to the receiver, hex-encoded.",
            "readOnly": true,
            "example": "0xdeadbeef"
          },
          "cfParameters": {
            "type": "string",
            "description": "Legacy field. Chainflip no longer sends it, so it is absent.",
            "nullable": true,
            "readOnly": true
          }
        },
        "additionalProperties": false,
        "description": "The cross-chain message delivered to the receiver on the destination chain with the output."
      },
      "ChainflipBaas.Status.ChunkInfo": {
        "type": "object",
        "properties": {
          "inputAmountNative": {
            "type": "string",
            "description": "`inputAmount` in the source asset's smallest unit.",
            "readOnly": true,
            "example": "99802700000"
          },
          "inputAmount": {
            "type": "number",
            "description": "The chunk's input, in the source asset.",
            "format": "double",
            "readOnly": true,
            "example": 9.98027
          },
          "intermediateAmountNative": {
            "type": "string",
            "description": "`intermediateAmount` in USDC's smallest unit.",
            "nullable": true,
            "readOnly": true,
            "example": "10519896"
          },
          "intermediateAmount": {
            "type": "number",
            "description": "The USDC the chunk passed through, for swaps routed via USDC, once executed.",
            "format": "double",
            "nullable": true,
            "readOnly": true,
            "example": 10.519896
          },
          "outputAmountNative": {
            "type": "string",
            "description": "`outputAmount` in the destination asset's smallest unit.",
            "nullable": true,
            "readOnly": true,
            "example": "102937756"
          },
          "outputAmount": {
            "type": "number",
            "description": "The chunk's output, in the destination asset, once executed.",
            "format": "double",
            "nullable": true,
            "readOnly": true,
            "example": 0.102937756
          },
          "scheduledAt": {
            "type": "integer",
            "description": "When the chunk was scheduled, as a Unix time in milliseconds.",
            "format": "int64",
            "readOnly": true,
            "example": 1792036476000
          },
          "scheduledAtDate": {
            "type": "string",
            "description": "`scheduledAt` as a date.",
            "format": "date-time",
            "readOnly": true,
            "example": "2026-10-15T03:54:36+00:00"
          },
          "scheduledBlockIndex": {
            "type": "string",
            "description": "The State Chain block and event the chunk was scheduled in.",
            "readOnly": true,
            "example": "15253773-1420"
          },
          "executedAt": {
            "type": "integer",
            "description": "When the chunk was executed, as a Unix time in milliseconds.",
            "format": "int64",
            "nullable": true,
            "readOnly": true,
            "example": 1792036488000
          },
          "executedAtDate": {
            "type": "string",
            "description": "`executedAt` as a date.",
            "format": "date-time",
            "nullable": true,
            "readOnly": true,
            "example": "2026-10-15T03:54:48+00:00"
          },
          "executedBlockIndex": {
            "type": "string",
            "description": "The State Chain block and event the chunk was executed in.",
            "nullable": true,
            "readOnly": true,
            "example": "15253775-1682"
          },
          "retryCount": {
            "type": "integer",
            "description": "How often the chunk was retried, for example because the minimum price was not met.",
            "format": "int32",
            "readOnly": true,
            "example": 0
          },
          "latestSwapRescheduledAt": {
            "type": "integer",
            "description": "When the chunk was last rescheduled (retried), as a Unix time in milliseconds.",
            "format": "int64",
            "nullable": true,
            "readOnly": true,
            "example": 1790087748000
          },
          "latestSwapRescheduledAtDate": {
            "type": "string",
            "description": "`latestSwapRescheduledAt` as a date.",
            "format": "date-time",
            "nullable": true,
            "readOnly": true,
            "example": "2026-09-22T14:35:48+00:00"
          },
          "latestSwapRescheduledBlockIndex": {
            "type": "string",
            "description": "The State Chain block and event the chunk was last rescheduled in.",
            "nullable": true,
            "readOnly": true,
            "example": "14930165-2005"
          },
          "latestSwapRescheduledReason": {
            "type": "string",
            "description": "Why the chunk was last rescheduled (retried): a Chainflip reason such as\n`MinPriceViolation`, `PriceImpactLimit`, `OraclePriceSlippageExceeded`,\n`OraclePriceStale`, `PredecessorSwapFailure` or `SafeModeActive`. New values can appear.",
            "nullable": true,
            "readOnly": true,
            "example": "MinPriceViolation"
          },
          "abortedAt": {
            "type": "integer",
            "description": "When the chunk was aborted for good, as a Unix time in milliseconds.",
            "format": "int64",
            "nullable": true,
            "readOnly": true,
            "example": 1790087778000
          },
          "abortedAtDate": {
            "type": "string",
            "description": "`abortedAt` as a date.",
            "format": "date-time",
            "nullable": true,
            "readOnly": true,
            "example": "2026-09-22T14:36:18+00:00"
          },
          "abortedBlockIndex": {
            "type": "string",
            "description": "The State Chain block and event the chunk was aborted in.",
            "nullable": true,
            "readOnly": true,
            "example": "14930170-2208"
          },
          "abortedReason": {
            "type": "string",
            "description": "Why the chunk was aborted for good (the input is then refunded); same reason names as\n`latestSwapRescheduledReason`.",
            "nullable": true,
            "readOnly": true,
            "example": "MinPriceViolation"
          }
        },
        "additionalProperties": false,
        "description": "One swap chunk: the whole input of a regular swap, or one part of a DCA swap."
      },
      "ChainflipBaas.Status.Dca": {
        "type": "object",
        "properties": {
          "lastExecutedChunk": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.ChunkInfo"
          },
          "currentChunk": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.ChunkInfo"
          },
          "executedChunks": {
            "type": "integer",
            "description": "How many chunks have been executed.",
            "format": "int32",
            "readOnly": true,
            "example": 3
          },
          "remainingChunks": {
            "type": "integer",
            "description": "How many chunks are still to run.",
            "format": "int32",
            "readOnly": true,
            "example": 7
          }
        },
        "additionalProperties": false,
        "description": "The progress of a DCA swap, which swaps its input in chunks over time."
      },
      "ChainflipBaas.Status.DcaParameters": {
        "type": "object",
        "properties": {
          "numberOfChunks": {
            "type": "integer",
            "description": "The number of chunks the input is split into.",
            "format": "int32",
            "readOnly": true,
            "example": 10
          },
          "chunkIntervalBlocks": {
            "type": "integer",
            "description": "The State Chain blocks (6 seconds each) between two chunks.",
            "format": "int32",
            "readOnly": true,
            "example": 2
          }
        },
        "additionalProperties": false,
        "description": "How a DCA swap is split."
      },
      "ChainflipBaas.Status.Deposit": {
        "type": "object",
        "properties": {
          "amountNative": {
            "type": "string",
            "description": "The deposited amount in the source asset's smallest unit.",
            "readOnly": true,
            "example": "100000000000"
          },
          "amount": {
            "type": "number",
            "description": "The deposited amount.",
            "format": "double",
            "readOnly": true,
            "example": 10
          },
          "transactionReference": {
            "type": "string",
            "description": "The source-chain transaction of the deposit: the transaction hash, or for Polkadot Assethub Chainflip's\n`block-extrinsicIndex` reference. Use it with `getStatusByTransactionHash`.",
            "nullable": true,
            "readOnly": true,
            "example": "21843947-3"
          },
          "transactionConfirmations": {
            "type": "integer",
            "description": "The deposit's confirmations so far, while Chainflip is still waiting for them.",
            "format": "int32",
            "nullable": true,
            "readOnly": true,
            "example": 1
          },
          "witnessedAt": {
            "type": "integer",
            "description": "When Chainflip witnessed the deposit (or boosted it), as a Unix time in milliseconds.",
            "format": "int64",
            "nullable": true,
            "readOnly": true,
            "example": 1792036476000
          },
          "witnessedAtDate": {
            "type": "string",
            "description": "`witnessedAt` as a date.",
            "format": "date-time",
            "nullable": true,
            "readOnly": true,
            "example": "2026-10-15T03:54:36+00:00"
          },
          "witnessedBlockIndex": {
            "type": "string",
            "description": "The State Chain block and event the deposit was witnessed in.",
            "nullable": true,
            "readOnly": true,
            "example": "15253773-1421"
          },
          "failure": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.Failure"
          },
          "failedAt": {
            "type": "integer",
            "description": "When the deposit was rejected or ignored, as a Unix time in milliseconds.",
            "format": "int64",
            "nullable": true,
            "readOnly": true,
            "example": 1790985636000
          },
          "failedAtDate": {
            "type": "string",
            "description": "`failedAt` as a date.",
            "format": "date-time",
            "nullable": true,
            "readOnly": true,
            "example": "2026-10-03T00:00:36+00:00"
          },
          "failedBlockIndex": {
            "type": "string",
            "description": "The State Chain block and event the deposit was rejected or ignored in.",
            "nullable": true,
            "readOnly": true,
            "example": "15079633-1298"
          }
        },
        "additionalProperties": false,
        "description": "The deposit into the channel (or the vault), in the source asset."
      },
      "ChainflipBaas.Status.DepositChannel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The channel id, `issuedBlock-network-channelId`. Use it with `getStatusByDepositChannel`.",
            "readOnly": true,
            "example": "15253762-Assethub-49"
          },
          "createdAt": {
            "type": "integer",
            "description": "When the channel was opened, as a Unix time in milliseconds.",
            "format": "int64",
            "readOnly": true,
            "example": 1792036410001
          },
          "createdAtDate": {
            "type": "string",
            "description": "`createdAt` as a date.",
            "format": "date-time",
            "readOnly": true,
            "example": "2026-10-15T03:53:30.001+00:00"
          },
          "brokerCommissionBps": {
            "type": "integer",
            "description": "The submitting broker's commission in basis points, the first entry of `brokers`. Kept for\ncompatibility; prefer `brokers`.",
            "format": "int32",
            "readOnly": true,
            "example": 5
          },
          "depositAddress": {
            "type": "string",
            "description": "The address on the source chain to send the source asset to.",
            "readOnly": true,
            "example": "14CPPi1QvzDQxC5mX29uj1Q55kUGX7P3SenYkkzjQqSir8Pq"
          },
          "sourceChainExpiryBlock": {
            "type": "string",
            "description": "The source-chain block height after which the channel stops accepting deposits.",
            "readOnly": true,
            "example": "21887126"
          },
          "estimatedExpiryTime": {
            "type": "integer",
            "description": "Chainflip's estimate of when the channel expires, as a Unix time in milliseconds.",
            "format": "int64",
            "readOnly": true,
            "example": 1792166010001
          },
          "estimatedExpiryDate": {
            "type": "string",
            "description": "`estimatedExpiryTime` as a date.",
            "format": "date-time",
            "readOnly": true,
            "example": "2026-10-16T15:53:30.001+00:00"
          },
          "expectedDepositAmount": {
            "type": "number",
            "description": "The deposit amount announced when the channel was opened, in the source asset. Absent when none was.",
            "format": "double",
            "nullable": true,
            "readOnly": true,
            "example": 10
          },
          "expectedDepositAmountNative": {
            "type": "string",
            "description": "`expectedDepositAmount` in the source asset's smallest unit.",
            "nullable": true,
            "readOnly": true,
            "example": "100000000000"
          },
          "isExpired": {
            "type": "boolean",
            "description": "Whether the channel has expired. Send nothing to an expired channel.",
            "readOnly": true,
            "example": false
          },
          "openedThroughBackend": {
            "type": "boolean",
            "description": "Whether the channel was opened through Chainflip's own swap backend rather than a broker; false for\nchannels opened through BaaS.",
            "readOnly": true,
            "example": false
          },
          "affiliateBrokers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainflipBaas.Status.AffiliateBroker"
            },
            "description": "The affiliates earning a commission on the swap, `brokers` without the submitting broker. Kept for\ncompatibility; prefer `brokers`.",
            "nullable": true,
            "readOnly": true
          },
          "fillOrKillParams": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.FillOrKillParameters"
          },
          "dcaParams": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.DcaParameters"
          }
        },
        "additionalProperties": false,
        "description": "The deposit channel: the address the source asset is sent to, and until when it accepts deposits."
      },
      "ChainflipBaas.Status.Egress": {
        "type": "object",
        "properties": {
          "amountNative": {
            "type": "string",
            "description": "The amount sent, in the asset's smallest unit.",
            "readOnly": true,
            "example": "102923756"
          },
          "amount": {
            "type": "number",
            "description": "The amount sent.",
            "format": "double",
            "readOnly": true,
            "example": 0.102923756
          },
          "scheduledAt": {
            "type": "integer",
            "description": "When Chainflip scheduled the transfer, as a Unix time in milliseconds.",
            "format": "int64",
            "nullable": true,
            "readOnly": true,
            "example": 1792036488000
          },
          "scheduledAtDate": {
            "type": "string",
            "description": "`scheduledAt` as a date.",
            "format": "date-time",
            "nullable": true,
            "readOnly": true,
            "example": "2026-10-15T03:54:48+00:00"
          },
          "scheduledBlockIndex": {
            "type": "string",
            "description": "The State Chain block and event the transfer was scheduled in.",
            "nullable": true,
            "readOnly": true,
            "example": "15253775-1683"
          },
          "transactionReference": {
            "type": "string",
            "description": "The transaction hash of the transfer on its chain, once broadcast.",
            "nullable": true,
            "readOnly": true,
            "example": "2UyZGnAhXvG3WUmiSCfAw19rRuccgydJpPR9nVwV5fBNsJ5AH1LwzkYLGABsiyt2EtTqxhjo2L11nKXTUWK2Lpnj"
          },
          "witnessedAt": {
            "type": "integer",
            "description": "When Chainflip witnessed the transfer on its chain, as a Unix time in milliseconds.",
            "format": "int64",
            "nullable": true,
            "readOnly": true,
            "example": 1792036626001
          },
          "witnessedBlockIndex": {
            "type": "string",
            "description": "The State Chain block and event the transfer was witnessed in.",
            "nullable": true,
            "readOnly": true,
            "example": "15253798-1668"
          },
          "failure": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.Failure"
          },
          "failedAt": {
            "type": "integer",
            "description": "When the transfer failed, as a Unix time in milliseconds.",
            "format": "int64",
            "nullable": true,
            "readOnly": true,
            "example": 1741265580000
          },
          "failedAtDate": {
            "type": "string",
            "description": "`failedAt` as a date.",
            "format": "date-time",
            "nullable": true,
            "readOnly": true,
            "example": "2025-03-06T12:53:00+00:00"
          },
          "failedBlockIndex": {
            "type": "string",
            "description": "The State Chain block and event the transfer failed in.",
            "nullable": true,
            "readOnly": true,
            "example": "6864282-895"
          },
          "destinationAddress": {
            "type": "string",
            "description": "Only on `fallbackEgress`: the fallback address the funds were sent to.",
            "nullable": true,
            "readOnly": true,
            "example": "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin"
          },
          "transactionPayload": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.TransactionPayload"
          }
        },
        "additionalProperties": false,
        "description": "An outgoing transfer: the output (`swapEgress`), a refund (`refundEgress`) or a transfer to the\nfallback address (`fallbackEgress`). Amounts are in that transfer's asset and after its egress fee."
      },
      "ChainflipBaas.Status.EstimatedDurations": {
        "type": "object",
        "properties": {
          "deposit": {
            "type": "number",
            "description": "Until the deposit is witnessed. Absent when Chainflip has no estimate for the source chain.",
            "format": "double",
            "nullable": true,
            "readOnly": true,
            "example": 10.5
          },
          "swap": {
            "type": "number",
            "description": "Until the swap is executed.",
            "format": "double",
            "nullable": true,
            "readOnly": true,
            "example": 12
          },
          "egress": {
            "type": "number",
            "description": "Until the output transfer is included in a block on the destination chain.",
            "format": "double",
            "nullable": true,
            "readOnly": true,
            "example": 90.4
          }
        },
        "additionalProperties": false,
        "description": "Chainflip's estimate of each step's duration, in seconds."
      },
      "ChainflipBaas.Status.Failure": {
        "type": "object",
        "properties": {
          "failedAt": {
            "type": "integer",
            "description": "When it failed, as a Unix time in milliseconds.",
            "format": "int64",
            "readOnly": true,
            "example": 1790985636000
          },
          "failedAtDate": {
            "type": "string",
            "description": "`failedAt` as a date.",
            "format": "date-time",
            "readOnly": true,
            "example": "2026-10-03T00:00:36+00:00"
          },
          "failedBlockIndex": {
            "type": "string",
            "description": "The State Chain block and event it failed in.",
            "readOnly": true,
            "example": "15079633-1298"
          },
          "mode": {
            "type": "string",
            "description": "What failed, for example `DEPOSIT_REJECTED`, `DEPOSIT_IGNORED`, `SENDING_FAILED` or\n`REFUND_OUTPUT_TOO_SMALL`. New values can appear.",
            "readOnly": true,
            "example": "DEPOSIT_REJECTED"
          },
          "reason": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.Reason"
          }
        },
        "additionalProperties": false,
        "description": "Why a deposit or transfer failed."
      },
      "ChainflipBaas.Status.FillOrKillParameters": {
        "type": "object",
        "properties": {
          "retryDurationBlocks": {
            "type": "integer",
            "description": "How long, in State Chain blocks (6 seconds each), the swap is retried before the deposit is refunded.",
            "format": "int32",
            "readOnly": true,
            "example": 150
          },
          "refundAddress": {
            "type": "string",
            "description": "The address on the source chain that refunds are sent to.",
            "readOnly": true,
            "example": "14k6xN8BTcg4bcDCjMRCETrD7NLUfXJGKgEpKFnYVmBemCK8"
          },
          "minimumPrice": {
            "type": "string",
            "description": "The minimum accepted price: destination asset per unit of the source asset.",
            "readOnly": true,
            "example": "0.0102685756257095261"
          },
          "maximumOraclePriceSlippage": {
            "type": "integer",
            "description": "Maximum accepted deviation of the execution price from the oracle price, in basis points.\nAbsent when the channel sets no oracle price guard.",
            "format": "int32",
            "nullable": true,
            "readOnly": true,
            "example": 50
          }
        },
        "additionalProperties": false,
        "description": "The slippage protection: if the swap cannot meet these limits within the retry window, the deposit is\nrefunded."
      },
      "ChainflipBaas.Status.PaidFee": {
        "type": "object",
        "properties": {
          "type": {
            "enum": [
              "network",
              "ingress",
              "egress",
              "broker",
              "boost",
              "liquidity",
              "refund"
            ],
            "type": "string",
            "description": "The fee: `network` (Chainflip's network fee), `ingress` (receiving the deposit on the source\nchain), `egress` (sending on the destination chain), `broker` (the broker and affiliate\ncommissions), `boost`, `refund` (sending a refund) or `liquidity` (liquidity provider fee,\nonly on older swaps).",
            "readOnly": true,
            "example": "broker",
            "x-ms-enum": {
              "name": "FeeType",
              "modelAsString": true
            }
          },
          "asset": {
            "type": "string",
            "description": "The asset the fee was paid in.",
            "readOnly": true,
            "example": "usdc.eth"
          },
          "amountNative": {
            "type": "string",
            "description": "The fee in the asset's smallest unit.",
            "readOnly": true,
            "example": "52863"
          },
          "amount": {
            "type": "number",
            "description": "The fee.",
            "format": "double",
            "readOnly": true,
            "example": 0.052863
          }
        },
        "additionalProperties": false,
        "description": "A fee paid on the swap."
      },
      "ChainflipBaas.Status.Reason": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "Chainflip's machine-readable failure reason, e.g. `TransactionRejectedByBroker` or\n`swapping.NoRefundAmountRemaining`. New values can appear.",
            "readOnly": true,
            "example": "TransactionRejectedByBroker"
          },
          "message": {
            "type": "string",
            "description": "A human-readable explanation. Do not branch on it: the text can change; use `code`.",
            "readOnly": true,
            "example": "The deposit was rejected by the broker"
          }
        },
        "additionalProperties": false,
        "description": "Chainflip's reason for a failure."
      },
      "ChainflipBaas.Status.StatusResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "The BaaS swap id, returned as `id` when the swap was started. Use it with `getStatusById`.\nNot the Chainflip swap id, which is `status.swapId`.",
            "format": "int32",
            "example": 73410
          },
          "platform": {
            "type": "string",
            "description": "The provider that executes the swap.",
            "example": "chainflip"
          },
          "status": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.SwapStatus"
          }
        },
        "additionalProperties": false,
        "description": "A swap made through your broker and its current status."
      },
      "ChainflipBaas.Status.Swap": {
        "type": "object",
        "properties": {
          "originalInputAmountNative": {
            "type": "string",
            "description": "`originalInputAmount` in the source asset's smallest unit.",
            "example": "99802700000"
          },
          "originalInputAmount": {
            "type": "number",
            "description": "The amount that entered the swap, in the source asset: the deposit minus the ingress and any boost fee.",
            "format": "double",
            "example": 9.98027
          },
          "remainingInputAmountNative": {
            "type": "string",
            "description": "`remainingInputAmount` in the source asset's smallest unit.",
            "example": "0"
          },
          "remainingInputAmount": {
            "type": "number",
            "description": "The input not swapped (yet), in the source asset: chunks of a DCA swap still to run, or the part refunded\nwhen the swap was aborted.",
            "format": "double",
            "example": 0
          },
          "swappedInputAmountNative": {
            "type": "string",
            "description": "`swappedInputAmount` in the source asset's smallest unit.",
            "example": "99802700000"
          },
          "swappedInputAmount": {
            "type": "number",
            "description": "The input swapped so far, in the source asset.",
            "format": "double",
            "example": 9.98027
          },
          "swappedIntermediateAmountNative": {
            "type": "string",
            "description": "`swappedIntermediateAmount` in USDC's smallest unit.",
            "example": "10519896"
          },
          "swappedIntermediateAmount": {
            "type": "number",
            "description": "The USDC the swap passed through, for swaps routed via USDC (neither asset is USDC); otherwise 0.",
            "format": "double",
            "example": 10.519896
          },
          "swappedOutputAmountNative": {
            "type": "string",
            "description": "`swappedOutputAmount` in the destination asset's smallest unit.",
            "example": "102937756"
          },
          "swappedOutputAmount": {
            "type": "number",
            "description": "The output so far, in the destination asset, before the egress fee.",
            "format": "double",
            "example": 0.102937756
          },
          "livePriceExecutionDeltaPercentage": {
            "type": "number",
            "description": "Execution price against the live oracle price, in percent. Absent when Chainflip recorded no\noracle delta, e.g. on swaps before October 2025.",
            "format": "double",
            "nullable": true,
            "example": 0.02
          },
          "regular": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.ChunkInfo"
          },
          "dca": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.Dca"
          }
        },
        "additionalProperties": false,
        "description": "The swap itself: how much of the input has been swapped and what it returned, before the egress fee."
      },
      "ChainflipBaas.Status.SwapStatus": {
        "type": "object",
        "properties": {
          "state": {
            "enum": [
              "waiting",
              "receiving",
              "swapping",
              "sending",
              "sent",
              "completed",
              "failed"
            ],
            "type": "string",
            "description": "Where the swap is: `waiting` (no deposit yet), `receiving` (deposit seen, waiting for\nconfirmations), `swapping`, `sending` (output scheduled), `sent` (output broadcast, waiting\nto be confirmed), `completed` or `failed`. A swap that was refunded in full or in part also ends\nas `completed`, with a `refundEgress`.",
            "readOnly": true,
            "example": "completed",
            "x-ms-enum": {
              "name": "SwapState",
              "modelAsString": true
            }
          },
          "swapId": {
            "type": "string",
            "description": "The Chainflip swap request id, as shown on Chainflip's explorer. Absent until the deposit has been\nwitnessed. Not the BaaS swap id used by `getStatusById`.",
            "readOnly": true,
            "example": "1919579"
          },
          "sourceAsset": {
            "type": "string",
            "description": "The asset swapped from.",
            "readOnly": true,
            "example": "dot.hub"
          },
          "destinationAsset": {
            "type": "string",
            "description": "The asset swapped to.",
            "readOnly": true,
            "example": "sol.sol"
          },
          "destinationAddress": {
            "type": "string",
            "description": "The address on the destination chain that receives the output.",
            "readOnly": true,
            "example": "A21o4asMbFHYadqXdLusT9Bvx9xaC5YV9gcaidjqtdXC"
          },
          "depositChannel": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.DepositChannel"
          },
          "fillOrKillParams": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.FillOrKillParameters"
          },
          "brokers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainflipBaas.Status.AffiliateBroker"
            },
            "description": "The accounts earning a commission on the swap, in basis points: first the submitting broker, then the\naffiliates.",
            "nullable": true,
            "readOnly": true
          },
          "dcaParams": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.DcaParameters"
          },
          "fallbackEgress": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.Egress"
          },
          "ccmParams": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.CcmParameters"
          },
          "boost": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.Boost"
          },
          "estimatedDurationSeconds": {
            "type": "number",
            "description": "Chainflip's estimate of the whole swap's duration, in seconds.",
            "format": "double",
            "nullable": true,
            "readOnly": true,
            "example": 112.9
          },
          "estimatedDurationsSeconds": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.EstimatedDurations"
          },
          "sourceChainRequiredBlockConfirmations": {
            "type": "integer",
            "description": "The source-chain confirmations Chainflip waits for before witnessing a deposit. Absent when Chainflip reports\nnone for the source chain (for example Polkadot Assethub).",
            "format": "int32",
            "nullable": true,
            "readOnly": true,
            "example": 3
          },
          "fees": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChainflipBaas.Status.PaidFee"
            },
            "description": "The fees paid so far, one entry per fee type and asset.",
            "nullable": true,
            "readOnly": true
          },
          "deposit": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.Deposit"
          },
          "swap": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.Swap"
          },
          "swapEgress": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.Egress"
          },
          "refundEgress": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.Egress"
          },
          "lastStateChainUpdateAt": {
            "type": "integer",
            "description": "When Chainflip's status service last processed a State Chain block, as a Unix time in milliseconds. Shows\nhow fresh this status is.",
            "format": "int64",
            "nullable": true,
            "readOnly": true,
            "example": 1792153021389
          },
          "lastStateChainUpdateAtDate": {
            "type": "string",
            "description": "`lastStateChainUpdateAt` as a date.",
            "format": "date-time",
            "nullable": true,
            "readOnly": true,
            "example": "2026-10-16T12:17:01.389+00:00"
          }
        },
        "additionalProperties": false,
        "description": "A swap's progress as Chainflip reports it: the deposit channel, the deposit, the swap itself and the outgoing\ntransfers. Sections appear as the swap reaches them. Every `...At` field is a Unix time in milliseconds,\nevery `...AtDate` field the same moment as a date, and every `...BlockIndex` field the Chainflip\nState Chain block and event index it happened in (`block-event`). `...Native` amounts are in the\nasset's smallest unit, the others in whole units."
      },
      "ChainflipBaas.Status.TransactionPayload": {
        "type": "object",
        "properties": {
          "contract": {
            "type": "string",
            "description": "The contract the transaction calls.",
            "nullable": true,
            "readOnly": true,
            "example": "0x79001a5e762f3befc8e5871b42f6734e00498920"
          },
          "value": {
            "type": "string",
            "description": "The value sent with the transaction, in the chain's smallest unit (wei).",
            "nullable": true,
            "readOnly": true,
            "example": "0"
          },
          "chainId": {
            "type": "string",
            "description": "The EVM chain id.",
            "nullable": true,
            "readOnly": true,
            "example": "42161"
          },
          "data": {
            "type": "string",
            "description": "The transaction's calldata, hex-encoded.",
            "nullable": true,
            "readOnly": true,
            "example": "0x5293178e1f2a11943836956f8ae0da6e"
          }
        },
        "additionalProperties": false,
        "description": "The EVM transaction of a transfer whose broadcast Chainflip aborted, so it can be submitted manually."
      },
      "ChainflipBaas.Swap.AdvancedSwapRequest": {
        "type": "object",
        "properties": {
          "ccmPayload": {
            "$ref": "#/components/schemas/ChainflipBaas.Swap.CcmRequest"
          }
        },
        "additionalProperties": false,
        "description": "The parameters of `startAdvancedSwap` that do not fit in a query string."
      },
      "ChainflipBaas.Swap.CcmRequest": {
        "required": [
          "gas_budget",
          "message"
        ],
        "type": "object",
        "properties": {
          "gas_budget": {
            "minLength": 1,
            "pattern": "^[0-9]+$",
            "type": "string",
            "description": "Gas budget for the call on the destination chain. This amount is based on the source asset and will be subtracted from the input amount and swapped to pay for gas.",
            "example": "100000"
          },
          "message": {
            "maxLength": 20002,
            "minLength": 0,
            "pattern": "^0x[0-9a-fA-F]*$",
            "type": "string",
            "description": "Hex-encoded message that is passed to the destination address on the destination chain. The message should be shorter than 10k bytes.",
            "example": "0xdeadc0de"
          }
        },
        "additionalProperties": false,
        "description": "Cross-Chain Messaging payload. More details can be found at https://docs.chainflip.io/swapping/integrations/advanced/cross-chain-messaging/cross-chain-messaging"
      },
      "ChainflipBaas.Swap.DepositAddress": {
        "required": [
          "address",
          "channelId",
          "channelOpeningFee",
          "channelOpeningFeeNative",
          "destinationAddress",
          "explorerUrl",
          "issuedBlock",
          "network",
          "sourceExpiryBlock"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "The BaaS swap id: pass it as `swapId` to `getStatusById`. Absent in the rare case the swap\ncould not be recorded right away; follow it with `getStatusByDepositChannel` then.",
            "format": "int32",
            "nullable": true,
            "example": 42
          },
          "address": {
            "type": "string",
            "description": "The deposit address to send source assets to.",
            "example": "0x8127c88e8b5a92917486bc68a4b481befab12534"
          },
          "issuedBlock": {
            "type": "integer",
            "description": "The block in which the deposit address was issued.",
            "format": "int64",
            "example": 1504251
          },
          "network": {
            "type": "string",
            "description": "The network to send the source assets over.",
            "example": "Ethereum"
          },
          "channelId": {
            "type": "integer",
            "description": "The channel id to monitor the deposit.",
            "format": "int64",
            "example": 107
          },
          "sourceExpiryBlock": {
            "type": "integer",
            "description": "The block (on the source network) in which the deposit address will expire.",
            "format": "int64",
            "example": 850819
          },
          "explorerUrl": {
            "type": "string",
            "description": "The explorer url to monitor the deposit.",
            "example": "https://scan.chainflip.io/channels/1504251-Ethereum-107"
          },
          "channelOpeningFee": {
            "type": "number",
            "description": "Fee in $FLIP to open the deposit channel.",
            "format": "double",
            "example": 0
          },
          "channelOpeningFeeNative": {
            "type": "string",
            "description": "Fee in $FLIP flipperinos to open the deposit channel.",
            "example": "0"
          },
          "destinationAddress": {
            "minLength": 1,
            "type": "string",
            "description": "The destination address the swap was accepted for, exactly as you sent it (no change of case, prefix or\nencoding). Always present.",
            "example": "bc1qujr7jlxeh4m20lldqh4fcsl63ff2ee6uk60g8r"
          }
        },
        "additionalProperties": false,
        "description": "The deposit channel opened for the swap. Send the source asset to `address` on `network` before\nthe channel expires at `sourceExpiryBlock`, then follow the swap with `getStatusById` (using\n`id`) or `getStatusByDepositChannel`."
      },
      "ChainflipBaas.SwapsFeed.FeedStatusResponse": {
        "type": "object",
        "properties": {
          "feedId": {
            "type": "integer",
            "description": "The swap's position in the feed, increasing in completion order. Store the last one you processed and\npass it plus one as `offset` on the next call.",
            "format": "int32",
            "example": 1
          },
          "swapId": {
            "type": "integer",
            "description": "The BaaS swap id, as returned when the swap was started. Use it with `getStatusById`.",
            "format": "int32",
            "example": 73410
          },
          "platform": {
            "type": "string",
            "description": "The provider that executed the swap.",
            "example": "chainflip"
          },
          "status": {
            "$ref": "#/components/schemas/ChainflipBaas.Status.SwapStatus"
          }
        },
        "additionalProperties": false,
        "description": "A completed swap in the swaps feed."
      },
      "Microsoft.AspNetCore.Mvc.ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "A URI reference [RFC3986] that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type (e.g., using HTML [W3C.REC-html5-20141028]). When this member is not present, its value is assumed to be \"about:blank\".",
            "nullable": true
          },
          "title": {
            "type": "string",
            "description": "A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization(e.g., using proactive content negotiation; see[RFC7231], Section 3.4).",
            "nullable": true
          },
          "status": {
            "type": "integer",
            "description": "The HTTP status code([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.",
            "format": "int32",
            "nullable": true
          },
          "detail": {
            "type": "string",
            "description": "A human-readable explanation specific to this occurrence of the problem.",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced.",
            "nullable": true
          },
          "code": {
            "type": "string",
            "description": "A stable, machine-readable error code (lowercase snake_case, e.g. \"asset_disabled\") identifying why the request failed, so clients can branch without matching the human-readable `detail` text. The HTTP status follows the code: 400 when the request as sent cannot be fulfilled, 404 when a status lookup found nothing to answer with, 503 for a temporary upstream condition, 500 when unclassified. Omitted when the failure has no classification. Clients must tolerate both an omitted code and unrecognised future values. See the Error codes reference: https://docs.chainflip-broker.io/features/error-codes",
            "example": "asset_disabled"
          }
        },
        "additionalProperties": {
          "description": "Problem type definitions MAY extend the problem details object with additional members. Extension members appear in the same namespace as other members of a problem type."
        },
        "description": "An error response (RFC 9457 problem details). Branch on `code` when it is present, never on the `detail` text."
      },
      "Microsoft.AspNetCore.Mvc.ValidationProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "A URI reference [RFC3986] that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type (e.g., using HTML [W3C.REC-html5-20141028]). When this member is not present, its value is assumed to be \"about:blank\".",
            "nullable": true
          },
          "title": {
            "type": "string",
            "description": "A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization(e.g., using proactive content negotiation; see[RFC7231], Section 3.4).",
            "nullable": true
          },
          "status": {
            "type": "integer",
            "description": "The HTTP status code([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.",
            "format": "int32",
            "nullable": true
          },
          "detail": {
            "type": "string",
            "description": "A human-readable explanation specific to this occurrence of the problem.",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced.",
            "nullable": true
          },
          "errors": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "The validation errors associated with this problem details."
          }
        },
        "additionalProperties": {
          "description": "Problem type definitions MAY extend the problem details object with additional members. Extension members appear in the same namespace as other members of a problem type."
        },
        "description": "A request that failed input validation (RFC 9457 problem details): `errors` lists the messages per parameter."
      }
    },
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "description": "Your partner API key, from registering at /register on this site. It identifies your account and is not a secret; it grants no access beyond your own partner's quotes, swaps, fees and statuses. There is no OAuth and there are no scopes. A key is also accepted in an X-API-Key request header; when both are present, this query parameter wins, even when it is empty.",
        "name": "apiKey",
        "in": "query"
      },
      "apiKeyHeader": {
        "type": "apiKey",
        "description": "Your partner API key, from registering at /register on this site, sent as a request header so it does not appear in URLs that proxies and access logs capture. It identifies your account and is not a secret; it grants no access beyond your own partner's quotes, swaps, fees and statuses. There is no OAuth and there are no scopes. When an apiKey query parameter is present it wins.",
        "name": "X-API-Key",
        "in": "header"
      }
    }
  },
  "tags": [
    {
      "name": "Assets",
      "description": "The assets you can swap: their ids, decimals, minimum swap amounts, USD prices and logos. No key needed."
    },
    {
      "name": "Fees",
      "description": "The broker fees you have earned."
    },
    {
      "name": "Networks",
      "description": "The networks you can swap on, and their logos. No key needed."
    },
    {
      "name": "Quote",
      "description": "Quotes for a swap: the expected output, every fee, and Chainflip's recommended slippage protection, retry window and live price protection. Ask for one before starting a swap."
    },
    {
      "name": "Rpc",
      "description": "A Chainflip broker JSON-RPC endpoint for the Chainflip SDK and other broker clients: point their broker URL at it and the deposit channels and vault swaps they open earn your commission."
    },
    {
      "name": "Status",
      "description": "Follow a swap, from waiting for the deposit to completed or failed, looked up by BaaS swap id, deposit channel or deposit transaction."
    },
    {
      "name": "Swap",
      "description": "Start a swap: open a deposit channel that the source asset is sent to."
    },
    {
      "name": "Swaps",
      "description": "The swaps made through your broker: a filterable list, and a feed of completed swaps for processing each one exactly once."
    },
    {
      "name": "Onboarding",
      "description": "How to start: what works without a key, how to get one, the sandbox and a first call."
    }
  ]
}