{
  "openapi": "3.1.0",
  "info": {
    "title": "Loopscale API",
    "version": "0.1.0"
  },
  "servers": [
    {
      "url": "https://tars.loopscale.com/v1",
      "description": "Loopscale Production Server"
    }
  ],
  "paths": {
    "/markets/collateral/holders": {
      "post": {
        "tags": [
          "stats"
        ],
        "operationId": "query_get_active_collateral_summary",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HolderFilter"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Active collateral holder summary",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CollateralHolderStats"
                  }
                }
              }
            }
          },
          "400": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "summary": "Get collateral holders",
        "description": "Fetches a list of users and total balances for one or more specified collateral mints."
      }
    },
    "/markets/collateral/holders/historical": {
      "post": {
        "tags": [
          "stats"
        ],
        "operationId": "query_get_historical_collateral_summary",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HistoricalCollateralHolderFilter"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Historical collateral holder summary",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/HistoricalCollateralHolderStats"
                  }
                }
              }
            }
          },
          "400": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "summary": "Time-weighted historical collateral deposits per holder",
        "description": "Returns, for each holder, the integral of their collateral balance over the requested time window — expressed as deposit-seconds (decimal-adjusted collateral units multiplied by seconds held). Useful for time-weighted depositor rewards, retroactive incentive splits, etc.\n\nEvent sources folded in:\n  * AddCollateral (+amount, decimal-adjusted)\n  * RemoveCollateral (−amount)\n  * Liquidate (−sum of collateralTransfers[] matching the target mint where toLiquidator = true; the row's top-level amount is principal repaid and is ignored for collateral accounting)\n\nEvents with eventTime < rangeStart are collapsed into a single bucket at rangeStart so they establish the starting balance for the window. Events at exactly rangeEnd contribute zero seconds.\n\nThe mint filter is applied against loan_events_v1.asset_identifier for Add/Remove events and against per-transfer assetMint inside Liquidate metadata. For single-mint collateral these are equal; for CLP/LP collateral, asset_identifier is the pool id — callers should pass the pool id, not an underlying token mint."
      }
    },
    "/markets/lending_vaults/deposits": {
      "post": {
        "tags": [
          "lending_vaults_data"
        ],
        "operationId": "query_get_vault_positions",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserLendingVaultFilter"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/VaultDeposits"
                  }
                }
              }
            }
          },
          "400": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "summary": "Get list of Vault depositors",
        "description": "Fetches a list of users and total balances grouped by Vault."
      }
    }
  },
  "components": {
    "schemas": {
      "CollateralHolderStats": {
        "type": "object",
        "description": "Active-holder summary for one collateral mint: total deposits plus a\nper-holder (wallet → amount) breakdown.",
        "required": [
          "collateralMint",
          "totalDeposits",
          "userDeposits"
        ],
        "properties": {
          "collateralMint": {
            "type": "string"
          },
          "totalDeposits": {
            "type": "number",
            "format": "double"
          },
          "userDeposits": {
            "type": "object",
            "additionalProperties": {
              "type": "number",
              "format": "double"
            },
            "propertyNames": {
              "type": "string"
            }
          }
        }
      },
      "ErrorDetails": {
        "type": "object",
        "description": "Inner detail of the [`ErrorResponse`] envelope.",
        "required": [
          "code",
          "message"
        ],
        "properties": {
          "code": {
            "type": "integer",
            "format": "int32",
            "description": "HTTP status code, mirrored in the response status line",
            "example": 400,
            "minimum": 0
          },
          "message": {
            "type": "string",
            "description": "human-readable, client-safe message (sensitive data redacted)",
            "example": "Request could not be processed."
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "description": "Canonical error envelope for every endpoint. The `x-request-id` response\nheader carries the correlation id for the failing request.",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ErrorDetails",
            "description": "error detail"
          }
        }
      },
      "HistoricalCollateralHolderFilter": {
        "type": "object",
        "required": [
          "mint",
          "rangeStart",
          "rangeEnd"
        ],
        "properties": {
          "mint": {
            "type": "string"
          },
          "pdas": {
            "type": "boolean"
          },
          "rangeEnd": {
            "type": "integer",
            "format": "int64"
          },
          "rangeStart": {
            "type": "integer",
            "format": "int64"
          }
        }
      },
      "HistoricalCollateralHolderStats": {
        "type": "object",
        "description": "Historical holder summary for one collateral mint over `[rangeStart,\nrangeEnd]`: per-holder deposit-seconds (time-weighted exposure).",
        "required": [
          "collateralMint",
          "rangeStart",
          "rangeEnd",
          "userDepositSeconds"
        ],
        "properties": {
          "collateralMint": {
            "type": "string"
          },
          "rangeEnd": {
            "type": "integer",
            "format": "int64"
          },
          "rangeStart": {
            "type": "integer",
            "format": "int64"
          },
          "userDepositSeconds": {
            "type": "object",
            "additionalProperties": {
              "type": "number",
              "format": "double"
            },
            "propertyNames": {
              "type": "string"
            }
          }
        }
      },
      "HolderFilter": {
        "type": "object",
        "description": "asset filter",
        "required": [
          "mints"
        ],
        "properties": {
          "mints": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "assets"
          },
          "pdas": {
            "type": "boolean",
            "description": "Return the PDAs holding the assets, if false it returns the borrower"
          }
        }
      },
      "ParsedVaultPosition": {
        "type": "object",
        "required": [
          "userAddress",
          "amountSupplied"
        ],
        "properties": {
          "amountSupplied": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "userAddress": {
            "type": "string"
          }
        }
      },
      "UserLendingVaultFilter": {
        "type": "object",
        "properties": {
          "lpMints": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "page": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "pageSize": {
            "type": "integer",
            "format": "int64",
            "minimum": 0
          },
          "principalMints": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sort": {
            "type": "integer",
            "format": "int32",
            "description": "Sort key (see `StakeSortType` discriminants).",
            "minimum": 0
          },
          "sortDirection": {
            "type": "integer",
            "format": "int32",
            "description": "Sort direction: `0` = ascending, `1` = descending.",
            "minimum": 0
          },
          "stakeDuration": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int32",
            "minimum": 0
          },
          "status": {
            "type": "integer",
            "format": "int32",
            "description": "Position status filter (see `StakeStatus` discriminants).",
            "minimum": 0
          },
          "userAddress": {
            "type": [
              "string",
              "null"
            ],
            "description": "Depositor wallet. Required by `/lending_vaults/user/v2` (filter-only,\nno header fallback). Optional on legacy paths that read from the auth header."
          },
          "vaultAddresses": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "VaultDeposits": {
        "type": "object",
        "required": [
          "vaultAddress",
          "userDeposits"
        ],
        "properties": {
          "userDeposits": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ParsedVaultPosition"
            }
          },
          "vaultAddress": {
            "type": "string"
          }
        }
      }
    }
  }
}
