{
  "openapi": "3.1.0",
  "info": {
    "title": "Soheil Router API",
    "version": "1.0.0",
    "description": "Swaps through our own contract (SoheilRouter): one transaction takes the fees (10 bps to the router, your fee to your address), runs the swap at the best price the router finds, and pays the recipient.\n\nConventions: addresses are lower case in answers (any case in requests); amounts are decimal strings in the token's smallest unit; transactionRequest.value is hex; ids and hashes are 0x + 64 hex; times are unix seconds; unknown values are null. Within v1 nothing is renamed or removed; new fields, endpoints and enum values may appear (bridges will add some), so ignore unknown fields and treat unknown values as documented. Each quote's transaction is meant to be sent once: the contract does not refuse a reused id.\n\nDocs: https://soheil.fi/developers/docs/"
  },
  "servers": [
    {
      "url": "https://api.soheil.fi"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "paths": {
    "/v1/health": {
      "get": {
        "summary": "Whether the API can serve",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          },
          "503": {
            "description": "Down",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                }
              }
            }
          }
        }
      }
    },
    "/v1/info": {
      "get": {
        "summary": "Version, fees and how keys are given",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Info"
                }
              }
            }
          }
        }
      }
    },
    "/v1/openapi.json": {
      "get": {
        "summary": "This description",
        "security": [],
        "responses": {
          "200": {
            "description": "OpenAPI 3.1",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/v1/chains": {
      "get": {
        "summary": "Networks where the router is live",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Chain"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/quote": {
      "get": {
        "summary": "A quote with the transaction to sign",
        "parameters": [
          {
            "name": "fromChainId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "Chain ID where the user sends from."
          },
          {
            "name": "toChainId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "Chain ID where the recipient receives; the same as fromChainId until bridges come."
          },
          {
            "name": "fromToken",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^0x[0-9a-fA-F]{40}$"
            },
            "description": "Token sold; the coin is 0x0000000000000000000000000000000000000000 (0xeee…e accepted)."
          },
          {
            "name": "toToken",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^0x[0-9a-fA-F]{40}$"
            },
            "description": "Token bought."
          },
          {
            "name": "fromAmount",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]+$"
            },
            "description": "Amount sold, above 0, fitting a uint256."
          },
          {
            "name": "fromAddress",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^0x[0-9a-fA-F]{40}$"
            },
            "description": "The wallet that signs and pays."
          },
          {
            "name": "toAddress",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^0x[0-9a-fA-F]{40}$"
            },
            "description": "Who receives, on toChainId; fromAddress by default. Never a token or the router contract."
          },
          {
            "name": "slippageBps",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 5000,
              "default": 50
            }
          },
          {
            "name": "integratorBps",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 90
            },
            "description": "Your fee for this request, up to your key's ceiling; your key's default when left out."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Quote"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests a minute for your key."
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the minute starts again."
              }
            }
          },
          "401": {
            "description": "No key or a wrong one (UNAUTHORIZED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key switched off (KEY_DISABLED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over a limit (RATE_LIMITED, QUOTA_EXCEEDED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait."
              }
            }
          },
          "500": {
            "description": "Our error (INTERNAL)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "A network we read from did not answer (UPSTREAM)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "400": {
            "description": "A field is missing or wrong (INVALID)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Not possible (UNSUPPORTED_CHAIN, NO_ROUTE)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Not trading on this network (PAUSED, NOT_READY)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "The same, with the fields as JSON",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuoteRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Quote"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests a minute for your key."
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the minute starts again."
              }
            }
          },
          "401": {
            "description": "No key or a wrong one (UNAUTHORIZED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key switched off (KEY_DISABLED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over a limit (RATE_LIMITED, QUOTA_EXCEEDED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait."
              }
            }
          },
          "500": {
            "description": "Our error (INTERNAL)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "A network we read from did not answer (UPSTREAM)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "400": {
            "description": "A field is missing or wrong (INVALID)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Not possible (UNSUPPORTED_CHAIN, NO_ROUTE)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Not trading on this network (PAUSED, NOT_READY)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/status": {
      "get": {
        "summary": "Where a sent trade stands",
        "description": "chainId is the network the transaction was sent on. A transaction holding more than one trade shows the first.",
        "parameters": [
          {
            "name": "chainId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "txHash",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^0x[0-9a-fA-F]{64}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Status"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests a minute for your key."
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the minute starts again."
              }
            }
          },
          "400": {
            "description": "A field is missing or wrong (INVALID)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Not a network of the router (UNSUPPORTED_CHAIN)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No key or a wrong one (UNAUTHORIZED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key switched off (KEY_DISABLED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over a limit (RATE_LIMITED, QUOTA_EXCEEDED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait."
              }
            }
          },
          "500": {
            "description": "Our error (INTERNAL)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "A network we read from did not answer (UPSTREAM)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/me": {
      "get": {
        "summary": "Your key, its limits and what its trades earned",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Me"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests a minute for your key."
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the minute starts again."
              }
            }
          },
          "401": {
            "description": "No key or a wrong one (UNAUTHORIZED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Key switched off (KEY_DISABLED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over a limit (RATE_LIMITED, QUOTA_EXCEEDED)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait."
              }
            }
          },
          "500": {
            "description": "Our error (INTERNAL)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "A network we read from did not answer (UPSTREAM)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "description": "One code per condition: INVALID, UNAUTHORIZED, KEY_DISABLED, NOT_FOUND, METHOD_NOT_ALLOWED, UNSUPPORTED_CHAIN, NO_ROUTE, RATE_LIMITED, QUOTA_EXCEEDED, INTERNAL, UPSTREAM, PAUSED, NOT_READY. New codes may be added: handle an unknown one by its HTTP status.",
                "examples": [
                  "NO_ROUTE"
                ]
              },
              "message": {
                "type": "string",
                "description": "Safe to show to your users."
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "Partner": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "contract": {
            "type": "string",
            "pattern": "^0x[0-9a-f]{40}$",
            "description": "An address, lower case (requests take any case)."
          }
        },
        "required": [
          "name",
          "contract"
        ],
        "description": "A contract a trade's transaction may call on this network."
      },
      "Chain": {
        "type": "object",
        "properties": {
          "chainId": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "contract": {
            "type": "string",
            "pattern": "^0x[0-9a-f]{40}$",
            "description": "An address, lower case (requests take any case)."
          },
          "routerBps": {
            "type": "integer"
          },
          "feeCollector": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^0x[0-9a-f]{40}$",
                "description": "An address, lower case (requests take any case)."
              },
              {
                "type": "null"
              }
            ]
          },
          "explorer": {
            "anyOf": [
              {
                "type": "string",
                "format": "uri"
              },
              {
                "type": "null"
              }
            ]
          },
          "partners": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Partner"
            }
          }
        },
        "required": [
          "chainId",
          "name",
          "contract",
          "routerBps",
          "feeCollector",
          "explorer",
          "partners"
        ]
      },
      "Fees": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "pattern": "^0x[0-9a-f]{40}$",
            "description": "An address, lower case (requests take any case)."
          },
          "totalBps": {
            "type": "integer"
          },
          "routerBps": {
            "type": "integer"
          },
          "integratorBps": {
            "type": "integer"
          },
          "routerFee": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "A whole number in the token's smallest unit, as a decimal string."
          },
          "integratorFee": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "A whole number in the token's smallest unit, as a decimal string."
          }
        },
        "required": [
          "token",
          "totalBps",
          "routerBps",
          "integratorBps",
          "routerFee",
          "integratorFee"
        ],
        "description": "Taken from fromAmount, in token, inside the transaction. *Bps are basis points, *Fee are amounts."
      },
      "TransactionRequest": {
        "type": "object",
        "properties": {
          "to": {
            "type": "string",
            "pattern": "^0x[0-9a-f]{40}$",
            "description": "An address, lower case (requests take any case)."
          },
          "data": {
            "type": "string",
            "pattern": "^0x[0-9a-f]*$"
          },
          "value": {
            "type": "string",
            "pattern": "^0x[0-9a-f]+$",
            "description": "Hex wei."
          },
          "chainId": {
            "type": "integer"
          }
        },
        "required": [
          "to",
          "data",
          "value",
          "chainId"
        ],
        "description": "Send as it is, once."
      },
      "QuoteRequest": {
        "type": "object",
        "properties": {
          "fromChainId": {
            "type": "integer",
            "description": "Chain ID where the user sends from."
          },
          "toChainId": {
            "type": "integer",
            "description": "Chain ID where the recipient receives; the same as fromChainId until bridges come."
          },
          "fromToken": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$",
            "description": "Token sold; the coin is 0x0000000000000000000000000000000000000000 (0xeee…e accepted)."
          },
          "toToken": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$",
            "description": "Token bought."
          },
          "fromAmount": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "Amount sold, above 0, fitting a uint256."
          },
          "fromAddress": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$",
            "description": "The wallet that signs and pays."
          },
          "toAddress": {
            "type": "string",
            "pattern": "^0x[0-9a-fA-F]{40}$",
            "description": "Who receives, on toChainId; fromAddress by default. Never a token or the router contract."
          },
          "slippageBps": {
            "type": "integer",
            "minimum": 1,
            "maximum": 5000,
            "default": 50
          },
          "integratorBps": {
            "type": "integer",
            "minimum": 0,
            "maximum": 90,
            "description": "Your fee for this request, up to your key's ceiling; your key's default when left out."
          }
        },
        "required": [
          "fromChainId",
          "toChainId",
          "fromToken",
          "toToken",
          "fromAmount",
          "fromAddress"
        ]
      },
      "Quote": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^0x[0-9a-f]{64}$",
            "description": "The trade's request id: bytes32 in the call and in the Traded event."
          },
          "type": {
            "type": "string",
            "description": "swap (one network) or, later, bridge. More may come.",
            "examples": [
              "swap"
            ]
          },
          "fromChainId": {
            "type": "integer"
          },
          "toChainId": {
            "type": "integer"
          },
          "fromToken": {
            "type": "string",
            "pattern": "^0x[0-9a-f]{40}$",
            "description": "An address, lower case (requests take any case)."
          },
          "toToken": {
            "type": "string",
            "pattern": "^0x[0-9a-f]{40}$",
            "description": "An address, lower case (requests take any case)."
          },
          "fromAmount": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "A whole number in the token's smallest unit, as a decimal string."
          },
          "toAmount": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "Expected output, both fees already taken."
          },
          "toAmountMin": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "The least the recipient gets; the transaction reverts below it."
          },
          "fees": {
            "$ref": "#/components/schemas/Fees"
          },
          "approvalAddress": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^0x[0-9a-f]{40}$",
                "description": "Approve exactly fromAmount of fromToken to it first; null when selling the coin."
              },
              {
                "type": "null"
              }
            ]
          },
          "transactionRequest": {
            "$ref": "#/components/schemas/TransactionRequest"
          },
          "gasEstimate": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "Gas units, our contract's own work included."
          },
          "validUntil": {
            "type": "integer",
            "description": "Unix seconds: how long the price is fresh (not an on-chain deadline). Send before it, or quote again."
          },
          "estimatedDurationSeconds": {
            "type": "integer",
            "description": "From the transaction mined to the recipient holding toToken: 0 for a swap."
          }
        },
        "required": [
          "id",
          "type",
          "fromChainId",
          "toChainId",
          "fromToken",
          "toToken",
          "fromAmount",
          "toAmount",
          "toAmountMin",
          "fees",
          "approvalAddress",
          "transactionRequest",
          "gasEstimate",
          "validUntil",
          "estimatedDurationSeconds"
        ]
      },
      "Leg": {
        "type": "object",
        "properties": {
          "chainId": {
            "type": "integer"
          },
          "txHash": {
            "type": "string",
            "pattern": "^0x[0-9a-f]{64}$"
          },
          "blockNumber": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "timestamp": {
            "anyOf": [
              {
                "type": "integer",
                "description": "Unix seconds."
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "chainId",
          "txHash",
          "blockNumber",
          "timestamp"
        ],
        "description": "One transaction of a trade; blockNumber and timestamp are null until mined (timestamp also when the network could not be asked)."
      },
      "Trade": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^0x[0-9a-f]{64}$"
          },
          "sender": {
            "type": "string",
            "pattern": "^0x[0-9a-f]{40}$",
            "description": "An address, lower case (requests take any case)."
          },
          "recipient": {
            "type": "string",
            "pattern": "^0x[0-9a-f]{40}$",
            "description": "An address, lower case (requests take any case)."
          },
          "fromToken": {
            "type": "string",
            "pattern": "^0x[0-9a-f]{40}$",
            "description": "An address, lower case (requests take any case)."
          },
          "fromAmount": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "A whole number in the token's smallest unit, as a decimal string."
          },
          "toToken": {
            "type": "string",
            "pattern": "^0x[0-9a-f]{40}$",
            "description": "An address, lower case (requests take any case)."
          },
          "toAmount": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "A whole number in the token's smallest unit, as a decimal string."
          },
          "routerFee": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "A whole number in the token's smallest unit, as a decimal string."
          },
          "integratorFee": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "A whole number in the token's smallest unit, as a decimal string."
          },
          "integratorAddress": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^0x[0-9a-f]{40}$",
                "description": "An address, lower case (requests take any case)."
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "sender",
          "recipient",
          "fromToken",
          "fromAmount",
          "toToken",
          "toAmount",
          "routerFee",
          "integratorFee",
          "integratorAddress"
        ],
        "description": "What the contract recorded (its Traded event)."
      },
      "Status": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "PENDING, DONE, FAILED, NOT_OURS or NOT_FOUND. More may come: treat an unknown one as PENDING.",
            "examples": [
              "DONE"
            ]
          },
          "substatus": {
            "anyOf": [
              {
                "type": "string",
                "description": "NOT_MINED, COMPLETED or REVERTED today; bridges will add their own."
              },
              {
                "type": "null"
              }
            ]
          },
          "sending": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Leg"
              },
              {
                "type": "null"
              }
            ]
          },
          "receiving": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Leg"
              },
              {
                "type": "null"
              }
            ]
          },
          "trade": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Trade"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "status",
          "substatus",
          "sending",
          "receiving",
          "trade"
        ]
      },
      "TokenTotal": {
        "type": "object",
        "properties": {
          "chainId": {
            "type": "integer"
          },
          "token": {
            "type": "string",
            "pattern": "^0x[0-9a-f]{40}$",
            "description": "An address, lower case (requests take any case)."
          },
          "symbol": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "decimals": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "volume": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "A whole number in the token's smallest unit, as a decimal string."
          },
          "integratorFee": {
            "type": "string",
            "pattern": "^[0-9]+$",
            "description": "A whole number in the token's smallest unit, as a decimal string."
          }
        },
        "required": [
          "chainId",
          "token",
          "symbol",
          "decimals",
          "volume",
          "integratorFee"
        ],
        "description": "symbol and decimals are null when the network could not be asked."
      },
      "Earned": {
        "type": "object",
        "properties": {
          "trades": {
            "type": "integer"
          },
          "byToken": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TokenTotal"
            },
            "description": "Every token sold, on every network; not paginated."
          }
        },
        "required": [
          "trades",
          "byToken"
        ]
      },
      "Me": {
        "type": "object",
        "properties": {
          "prefix": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "integratorAddress": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^0x[0-9a-f]{40}$",
                "description": "An address, lower case (requests take any case)."
              },
              {
                "type": "null"
              }
            ]
          },
          "integratorBps": {
            "type": "integer"
          },
          "maxIntegratorBps": {
            "type": "integer"
          },
          "perMinute": {
            "type": "integer"
          },
          "monthlyQuota": {
            "type": "integer"
          },
          "requestsThisMonth": {
            "type": "integer"
          },
          "routerBps": {
            "type": "integer"
          },
          "earned": {
            "$ref": "#/components/schemas/Earned"
          }
        },
        "required": [
          "prefix",
          "name",
          "integratorAddress",
          "integratorBps",
          "maxIntegratorBps",
          "perMinute",
          "monthlyQuota",
          "requestsThisMonth",
          "routerBps",
          "earned"
        ]
      },
      "Health": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ok",
              "down"
            ]
          },
          "networks": {
            "type": "integer"
          }
        },
        "required": [
          "status",
          "networks"
        ]
      },
      "Info": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "networks": {
            "type": "integer"
          },
          "routerBps": {
            "type": "integer"
          },
          "maxIntegratorBps": {
            "type": "integer"
          },
          "keys": {
            "type": "string",
            "description": "self (made in the developer panel) or request (asked by email or form)."
          },
          "keyRequests": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "docs": {
            "type": "string",
            "format": "uri"
          },
          "openapi": {
            "type": "string",
            "format": "uri"
          }
        },
        "required": [
          "name",
          "version",
          "networks",
          "routerBps",
          "maxIntegratorBps",
          "keys",
          "keyRequests",
          "docs",
          "openapi"
        ]
      }
    }
  }
}