# api\_v2

## API V2 Reference

### Overview

API V2 extends the existing V1 API with tokenization (JR/GYT) and marketplace related features. All V1 endpoints remain fully functional. V2 adds new Looper statuses/fields, the entire GYT trading namespace, and Aave/Morpho integration endpoints.

**Base URL**: <https://bondify.cian.app/>

> **Note:** CBR and SLF endpoints are unchanged — continue using V1 API.

***

### Looper Changes

All changes are backward-compatible with V1. The V1 Looper endpoints remain available.

***

#### Looper User List (V2)

**Endpoint:**

```
GET /looper/v2/user/list/{address}
```

**Description:** Retrieves a user's Looper positions with extended tokenization status. Adds two new position statuses and three new fields compared to V1.

**Query Parameters:**

* **id** *(optional)*: Looper Config ID — filter positions for a specific pool
* **status** *(optional)*: Filter by status — `live` (default, active positions), `closed` (expired), `selling` (has pending sell order), `locked` (minted into YT, locked until expiry)

**New Statuses (V2):**

* **selling**: Position has an associated GYT sell order in the order book
* **locked**: Position has been minted into a YT token and is locked until expiry

**New Response Fields (V2):**

* **associated\_order**: Related order hash string; empty string if no associated order
* **locked\_until**: Lock expiry timestamp; `0` if not locked
* **yt\_amount**: Locked YT amount as string (18 decimals); `"0"` if none

**Example Request:**

```bash
curl -X GET "${BASE}/looper/v2/user/list/0xabcdef1234567890abcdef1234567890abcdef12?status=live"
```

**Example Response:**

```json
{
  "status": 0,
  "code": "ok",
  "msg": "ok",
  "data": [
    {
      "id": 1,
      "config_id": 0,
      "status": "selling",
      "associated_order": "0xabc123...",
      "locked_until": 0,
      "yt_amount": "0",
      "deposit_amount": "1000000",
      "leverage_amount": "3000000"
    }
  ]
}
```

***

#### Looper User History (V2)

**Endpoint:**

```
GET /looper/v2/user/history/{address}
```

**Description:** Retrieves user operation history with new split/merge operation types for tokenized position management.

**Query Parameters:**

* **id** *(optional)*: Looper Config ID — filter history for a specific pool

**New Operation Types (V2):**

* **split\_from**: Source position in a split operation
* **split\_to**: Destination position created by a split
* **merge\_from**: Source position consumed by a merge
* **merge\_to**: Destination position receiving the merge

**Example Request:**

```bash
curl -X GET "${BASE}/looper/v2/user/history/0xabcdef1234567890abcdef1234567890abcdef12?id=0"
```

***

#### Looper Status

**Endpoint:**

```
GET /looper/v2/status
```

**Description:** Batch-queries the current status of multiple Looper positions by ID.

**Query Parameters:**

* **id** *(required)*: Comma-separated list of position IDs

**New Statuses (V2):**

* **selling**: Position has a pending sell order
* **locked**: Position is minted into YT and locked

**Example Request:**

```bash
curl -X GET "${BASE}/looper/v2/status?id=1,2,3"
```

**Example Response:**

```json
{
  "status": 0,
  "code": "ok",
  "msg": "ok",
  "data": [
    {
      "id": 1,
      "status": "selling"
    },
    {
      "id": 2,
      "status": "locked"
    },
    {
      "id": 3,
      "status": "live"
    }
  ]
}
```

***

### GYT Namespace

All GYT endpoints reside under `${BASE}/gyt`. This namespace covers YT token information, price history, order book (RFQ), order management, and user data.

***

#### GYT YT Info List

**Endpoint:**

```
GET /gyt/ytinfo/list
```

**Description:** Retrieves paginated list of available YT tokens with metadata including converter, underlying asset, expiry, and associated Looper configs.

**Query Parameters:**

* **converter** *(optional)*: Filter by converter contract address
* **underlying** *(optional)*: Filter by underlying asset address
* **looper\_id** *(optional)*: Filter by Looper config ID
* **omitcontract** *(optional)*: If `true`, omit fields that require on-chain calls
* **expiry\_before** *(optional)*: Only return YTs expiring before this timestamp
* **expiry\_after** *(optional)*: Only return YTs expiring after this timestamp
* **limit** *(optional)*: Results per page (default 20, max 100)
* **page** *(optional)*: Page number (default 1)

**Response Fields:**

* **total**: Total number of matching records
* **page**: Current page number
* **list**: Array of YT info objects
  * **converter**: Converter contract address
  * **conversion\_id**: Internal ID within the converter (may overlap across converters)
  * **router**: Swap router address for this YT
  * **underlying**: Underlying asset address
  * **looper\_configs**: Array of Looper config IDs that support this YT
  * **associated\_yt**: Associated YT ID; absent if this converter does not support YT conversion
  * **expiry**: Expiry timestamp
  * **token\_address**: GYT ERC20 token address
  * **total\_supply**: GYT total supply (18 decimals)

**Example Request:**

```bash
curl -X GET "${BASE}/gyt/ytinfo/list?underlying=0xabcdef&limit=10&page=1"
```

**Example Response:**

```json
{
  "status": 0,
  "code": "ok",
  "msg": "ok",
  "data": {
    "total": 100,
    "page": 1,
    "list": [
      {
        "converter": "0x1234567890abcdef1234567890abcdef12345678",
        "conversion_id": 1,
        "router": "0xabcdef1234567890abcdef1234567890abcdef12",
        "underlying": "0xabcdef1234567890abcdef1234567890abcdef12",
        "looper_configs": [1, 2, 3],
        "associated_yt": 1,
        "expiry": 1700000000,
        "token_address": "0x9876543210fedcba9876543210fedcba98765432",
        "total_supply": "1000000000000000000000"
      }
    ]
  }
}
```

***

#### GYT Market Price History

**Endpoint:**

```
GET /gyt/market/history
```

**Description:** Retrieves historical price, volume, and yield data for a specific GYT token. Only one GYT can be queried per request.

**Query Parameters:**

* **converter** *(required)*: Converter contract address
* **conversion\_id** *(required)*: Converter internal ID
* **limit** *(optional)*: Results per page
* **page** *(optional)*: Page number

**Response Fields:**

* **time**: Timestamp
* **price**: Price denominated in the underlying token
* **volume**: Trading volume
* **underlying\_apy**: Underlying token annual percentage yield
* **implied\_apy**: Implied annual percentage yield
* **liquidity**: RFQ depth at this point in time

**Example Request:**

```bash
curl -X GET "${BASE}/gyt/market/history?converter=0x1234&conversion_id=1&limit=50"
```

**Example Response:**

```json
{
  "status": 0,
  "code": "ok",
  "msg": "ok",
  "data": [
    {
      "time": 17333333333,
      "price": 0.01,
      "volume": 1000000,
      "underlying_apy": 0.02,
      "implied_apy": 0.03,
      "liquidity": 10000000
    }
  ]
}
```

***

#### GYT RFQ (Request For Quote)

**Endpoint:**

```
GET /gyt/rfq
```

**Description:** Retrieves order book data for a specific GYT with optional DEX liquidity aggregation. Returns signed orders for on-chain execution.

**Query Parameters:**

* **converter** *(required)*: Converter contract address
* **conversion\_id** *(required)*: Converter internal ID
* **amount** *(optional)*: Desired fill amount (18 decimals)
* **use\_dex** *(optional)*: Enable DEX aggregation (default `false`)

> **Note:** If `use_dex` is true but DEX liquidity is insufficient, a non-zero status code is returned.

**Response Fields:**

* **router\_type**: Order data type — `aave` and `slf` have different order structures
* **orders**: Array of RFQ orders with signatures
  * **maker**: Maker address
  * **order\_version**: Order version
  * **order\_epoch**: Order epoch
  * **deadline**: Order expiry timestamp
  * **flags**: Order flags
  * **conversion\_id**: Converter internal ID
  * **opaque\_position\_id**: Position identifier
  * **max\_sold\_amount**: Maximum sell amount
  * **min\_price**: Minimum acceptable price (18 decimals)
  * **remain**: Remaining fillable amount
  * **signature**: EIP-712 signature
  * **nonce**: Order nonce
* **router\_address**: Swap router contract address
* **current\_price**: Current market price (18 decimals)
* **dex**: Whether DEX routing is active
* **swap\_data**: DEX swap calldata (present when `dex` is true)
* **fulfilled**: Whether the requested amount can be fully filled

**Example Request:**

```bash
curl -X GET "${BASE}/gyt/rfq?converter=0x1234&conversion_id=1&amount=1000000000000000000&use_dex=false"
```

**Example Response:**

```json
{
  "status": 0,
  "code": "ok",
  "msg": "ok",
  "data": {
    "router_type": "aave",
    "orders": [
      {
        "maker": "0xabcdef1234567890abcdef1234567890abcdef12",
        "order_version": 1,
        "order_epoch": 0,
        "deadline": 1677700000,
        "flags": 0,
        "conversion_id": 1,
        "opaque_position_id": "0x11111",
        "max_sold_amount": "1000000000000",
        "min_price": "1000000000000000000",
        "remain": "50000000000",
        "signature": "0xaaaaaaaa",
        "nonce": "0x11111111"
      }
    ],
    "router_address": "0x9876543210fedcba9876543210fedcba98765432",
    "current_price": "1000000000000000000",
    "dex": false,
    "swap_data": "",
    "fulfilled": true
  }
}
```

***

#### GYT Order Book Depth

**Endpoint:**

```
GET /gyt/depth
```

**Description:** Retrieves the current order book depth (total liquidity and queue length) for a specific GYT.

**Query Parameters:**

* **converter** *(required)*: Converter contract address
* **conversion\_id** *(required)*: Converter internal ID

**Response Fields:**

* **max\_depth**: Maximum available depth (18 decimals)
* **queue\_length**: Number of orders in the order book

**Example Request:**

```bash
curl -X GET "${BASE}/gyt/depth?converter=0x1234&conversion_id=1"
```

**Example Response:**

```json
{
  "status": 0,
  "code": "ok",
  "msg": "ok",
  "data": {
    "max_depth": "1000000000000000000000",
    "queue_length": 10
  }
}
```

***

#### GYT Order Queue Position

**Endpoint:**

```
GET /gyt/order/position
```

**Description:** Queries the position of a specific order in the order book queue.

**Query Parameters:**

* **order\_hash** *(required)*: Order hash

**Response Fields:**

* **position**: Queue position (1 = front of queue; higher = further back; -1 = not in queue, likely cancelled or filled)

**Example Request:**

```bash
curl -X GET "${BASE}/gyt/order/position?order_hash=0xabc123"
```

**Example Response:**

```json
{
  "status": 0,
  "code": "ok",
  "msg": "ok",
  "data": {
    "position": 10
  }
}
```

***

#### GYT Create Order

**Endpoint:**

```
POST /gyt/order/create
```

**Description:** Submits a new GYT sell order to the order book. The order must be signed with EIP-712.

**Request Body:**

* **maker**: User address
* **router**: Router contract address
* **order\_version**: Order version
* **order\_epoch**: Order epoch
* **deadline**: Order expiry timestamp
* **flags**: Order flags
* **conversion\_id**: Converter internal ID
* **opaque\_position\_id**: Position identifier
* **max\_sold\_amount**: Maximum amount to sell
* **min\_price**: Minimum acceptable price (18 decimals)
* **signature**: EIP-712 signature

**Response Fields:**

* **submit**: Submission status — `success` or `failed`
* **order\_hash**: Order hash (empty on failure)
* **verification**: Order executability status — `passed` or `failed`

**Example Request:**

```bash
curl -X POST "${BASE}/gyt/order/create" \
  -H "Content-Type: application/json" \
  -d '{
    "maker": "0xabcdef1234567890abcdef1234567890abcdef12",
    "router": "0x9876543210fedcba9876543210fedcba98765432",
    "order_version": 1,
    "order_epoch": 0,
    "deadline": 1677700000,
    "flags": 0,
    "conversion_id": 1,
    "opaque_position_id": "0x11111",
    "max_sold_amount": "1000000000000",
    "min_price": "1000000000000000000",
    "signature": "0xaaaaaaaa"
  }'
```

**Example Response:**

```json
{
  "status": 0,
  "code": "ok",
  "msg": "ok",
  "data": {
    "submit": "success",
    "order_hash": "0xabc123def456...",
    "verification": "passed"
  }
}
```

***

#### GYT List User Orders

**Endpoint:**

```
GET /gyt/order/list/{maker}
```

**Description:** Lists all orders belonging to a specific maker with optional filtering by router, status, and order hash.

**Path Parameters:**

* **maker** *(required)*: Maker address

**Query Parameters:**

* **router** *(optional)*: Filter by router address
* **status** *(optional)*: Filter by order status — `live`, `cancelled`, `partial`, `filled`
* **limit** *(optional)*: Results per page (default 20, max 100)
* **page** *(optional)*: Page number (default 1)
* **order\_hash** *(optional)*: Filter by specific order hash

**Response Fields:**

* **total**: Total matching records
* **page**: Current page
* **list**: Array of order objects
  * **maker**: Maker address
  * **router**: Router contract address
  * **order\_version**: Order version
  * **order\_epoch**: Order epoch
  * **deadline**: Order expiry timestamp
  * **flags**: Order flags
  * **conversion\_id**: Converter internal ID
  * **opaque\_position\_id**: Position identifier
  * **max\_sold\_amount**: Maximum sell amount
  * **remain\_amount**: Remaining unfilled amount
  * **order\_hash**: Order hash
  * **min\_price**: Minimum price (18 decimals). Signature is deliberately excluded to prevent order archiving
  * **status**: Order status — `live`, `cancelled`, `partial`, `filled`
  * **in\_order\_position**: Position included in the order (only for Looper sell orders)
  * **target\_position**: Target position for minting (only for Looper sell orders that have been partially/fully filled)
  * **creation\_time**: Order creation timestamp
  * **position**: Queue position (0 = front; higher = further back; -1 = not in queue)

**Example Request:**

```bash
curl -X GET "${BASE}/gyt/order/list/0xabcdef1234567890abcdef1234567890abcdef12?status=live&limit=10"
```

**Example Response:**

```json
{
  "status": 0,
  "code": "ok",
  "msg": "ok",
  "data": {
    "total": 100,
    "page": 1,
    "list": [
      {
        "maker": "0xabcdef1234567890abcdef1234567890abcdef12",
        "router": "0x9876543210fedcba9876543210fedcba98765432",
        "order_version": 1,
        "order_epoch": 0,
        "deadline": 1677700000,
        "flags": 0,
        "conversion_id": 1,
        "opaque_position_id": "0x11111",
        "max_sold_amount": "1000000000000",
        "remain_amount": "100000",
        "order_hash": "0xabc123def456...",
        "min_price": "1000000000000000000",
        "status": "live",
        "in_order_position": "1",
        "target_position": "2",
        "creation_time": 1677700000,
        "position": 1
      }
    ]
  }
}
```

***

#### GYT Cancel Order

**Endpoint:**

```
POST /gyt/order/cancel
```

**Description:** Soft-cancels a GYT order. If the order has already been (partially) filled, the API returns `reject` — in that case, guide the user to invoke on-chain cancellation.

**Request Body:**

* **user\_address**: User address
* **order\_hash**: Order hash to cancel
* **signature**: Cancel signature — sign the string `"cancel_order:" + order_hash` with `eth_personalSign`

**Response Fields:**

* **cancel**: Cancel result — `success`, `failed` (signature verification failed), or `reject` (already filled, must cancel on-chain)

**Example Request:**

```bash
curl -X POST "${BASE}/gyt/order/cancel" \
  -H "Content-Type: application/json" \
  -d '{
    "user_address": "0xabcdef1234567890abcdef1234567890abcdef12",
    "order_hash": "0xabc123def456...",
    "signature": "0xsignature..."
  }'
```

**Example Response:**

```json
{
  "status": 0,
  "code": "ok",
  "msg": "ok",
  "data": {
    "cancel": "success"
  }
}
```

***

#### GYT User Info

**Endpoint:**

```
GET /gyt/user/info/{address}
```

**Description:** Retrieves GYT and YT holdings for a specific user address.

**Response Fields:**

* **yt\_holdings**: Array of user's YT token holdings
  * **yt\_id**: YT identifier
  * **converter**: Converter contract address
  * **conversion\_id**: Converter internal ID
  * **underlying**: Underlying asset address
  * **expiry**: Expiry timestamp
  * **token\_address**: GYT token address
  * **gyt\_balance**: User's GYT balance (18 decimals)

**Example Request:**

```bash
curl -X GET "${BASE}/gyt/user/info/0xabcdef1234567890abcdef1234567890abcdef12"
```

**Example Response:**

```json
{
  "status": 0,
  "code": "ok",
  "msg": "ok",
  "data": {
    "yt_holdings": [
      {
        "yt_id": 1,
        "converter": "0x1234567890abcdef1234567890abcdef12345678",
        "conversion_id": 1,
        "underlying": "0xabcdef1234567890abcdef1234567890abcdef12",
        "expiry": 1700000000,
        "token_address": "0x9876543210fedcba9876543210fedcba98765432",
        "gyt_balance": "250000000000000000"
      }
    ]
  }
}
```

***

#### GYT User Claimable Rewards

**Endpoint:**

```
GET /gyt/user/claimable/{address}
```

**Description:** Retrieves claimable reward campaigns for a specific user, including calldata for on-chain claiming.

**Response Fields:**

* Array of claimable reward objects:
  * **campaign**: Reward campaign identifier
  * **claimable\_amount**: Amount available to claim (18 decimals)
  * **token**: Reward token address
  * **target**: Claim target contract address
  * **calldata**: Pre-built transaction calldata for claiming

**Example Request:**

```bash
curl -X GET "${BASE}/gyt/user/claimable/0xabcdef1234567890abcdef1234567890abcdef12"
```

**Example Response:**

```json
{
  "status": 0,
  "code": "ok",
  "msg": "ok",
  "data": [
    {
      "campaign": "reward_campaign_1",
      "claimable_amount": "1000000000000000000",
      "token": "0x1234567890abcdef1234567890abcdef12345678",
      "target": "0xabcdef1234567890abcdef1234567890abcdef12",
      "calldata": "0xabcdef..."
    }
  ]
}
```

***

#### GYT User Trade History

**Endpoint:**

```
GET /gyt/user/history/{address}
```

**Description:** Retrieves a user's GYT trading history with filtering by router, conversion, and token.

**Path Parameters:**

* **address** *(required)*: User address; pass `all` to return all trades (only `fill` status trades)

**Query Parameters:**

* **router** *(optional)*: Filter by router address
* **conversion\_id** *(optional)*: Filter by converter internal ID (requires `router` to be set)
* **gyt\_address** *(optional)*: Filter by GYT token address
* **limit** *(optional)*: Results per page (default 20, max 100)
* **page** *(optional)*: Page number (default 1)

**Response Fields:**

* **total**: Total matching records
* **page**: Current page
* **list**: Array of trade records
  * **timestamp**: Trade timestamp
  * **router**: Router contract address
  * **conversion\_id**: Converter internal ID
  * **amount**: Trade amount (18 decimals)
  * **type**: Trade type — `buy`, `sell`, etc.
  * **tx\_hash**: Transaction hash (if available)
  * **price**: Execution price (18 decimals)
  * **order\_hash**: Related order hash
  * **order\_owner**: Order owner address
  * **operator**: Operator address
  * **flags**: Order flags
  * **position\_id**: Related position ID

**Example Request:**

```bash
curl -X GET "${BASE}/gyt/user/history/0xabcdef1234567890abcdef1234567890abcdef12?limit=20&page=1"
```

**Example Response:**

```json
{
  "status": 0,
  "code": "ok",
  "msg": "ok",
  "data": {
    "total": 100,
    "page": 1,
    "list": [
      {
        "timestamp": 1677700000,
        "router": "0x9876543210fedcba9876543210fedcba98765432",
        "conversion_id": 1,
        "amount": "500000000000000000",
        "type": "buy",
        "tx_hash": "0xdef456...",
        "price": "2000000000000000000",
        "order_hash": "0xabc123...",
        "order_owner": "0xabcdef1234567890abcdef1234567890abcdef12",
        "operator": "0x1234567890abcdef1234567890abcdef12345678",
        "flags": "0x00",
        "position_id": "0x11111"
      }
    ]
  }
}
```

***

### Aave Integration

***

#### Aave Allowed Conversions

**Endpoint:**

```
GET /aave/allowed_conversions
```

**Description:** Returns the list of allowed Aave asset conversions (e.g., USDC → aUSDC) with associated router and conversion identifiers.

**Response Fields:**

* Array of conversion objects:
  * **id**: Conversion identifier
  * **from\_asset**: Source asset address
  * **to\_asset**: Target asset address
  * **name**: Human-readable conversion name (e.g., "USDC -> AUSDC")
  * **router**: Router contract address
  * **token**: Token address
  * **conversion\_id**: Conversion ID

**Example Request:**

```bash
curl -X GET "${BASE}/aave/allowed_conversions"
```

**Example Response:**

```json
{
  "status": 0,
  "code": "ok",
  "msg": "ok",
  "data": [
    {
      "id": 1,
      "from_asset": "0x1234567890abcdef1234567890abcdef12345678",
      "to_asset": "0xabcdef1234567890abcdef1234567890abcdef12",
      "name": "USDC -> AUSDC",
      "router": "0x9876543210fedcba9876543210fedcba98765432",
      "token": "0xfedcba9876543210fedcba9876543210fedcba98",
      "conversion_id": 1
    }
  ]
}
```

***

#### Aave GYT Info

**Endpoint:**

```
GET /aave/gyt/list
```

**Description:** Retrieves a list of Aave-based GYT tokens with pricing, yield, and leverage information.

**Response Fields:**

* Array of Aave GYT info objects:
  * **id**: Token identifier
  * **order\_weight**: Sorting weight
  * **name**: Token pair name
  * **symbol**: Token symbol
  * **underlying**: Underlying asset name
  * **underlying\_address**: Underlying asset contract address
  * **borrow\_address**: Borrow asset contract address
  * **expire**: Expiry timestamp
  * **lev\_rate**: Leverage rate
  * **points\_rate**: Points multiplier
  * **estimated\_apy**: Estimated annual percentage yield
  * **price**: Current price in underlying token terms
  * **underlying\_apy**: Underlying token annual percentage yield
  * **implied\_apy**: Implied annual percentage yield

**Example Request:**

```bash
curl -X GET "${BASE}/aave/gyt/list"
```

**Example Response:**

```json
{
  "status": 0,
  "code": "ok",
  "msg": "ok",
  "data": [
    {
      "id": "0x111111111111111111111",
      "order_weight": 0,
      "name": "SLA/ETH",
      "symbol": "SYM",
      "underlying": "SLA",
      "underlying_address": "0x1234567890abcdef1234567890abcdef12345678",
      "borrow_address": "0xabcdef1234567890abcdef1234567890abcdef12",
      "expire": 17333333333,
      "lev_rate": 11,
      "points_rate": 1.5,
      "estimated_apy": 0.05,
      "price": 0.01,
      "underlying_apy": 0.02,
      "implied_apy": 0.03
    }
  ]
}
```

***

### Morpho Integration

***

#### Morpho Allowed Conversions

**Endpoint:**

```
GET /morpho/allowed_conversions
```

**Description:** Returns the list of allowed Morpho asset conversions with the additional `market_id` field specific to Morpho markets.

**Response Fields:**

* Array of conversion objects:
  * **id**: Conversion identifier
  * **from\_asset**: Source asset address
  * **to\_asset**: Target asset address
  * **market\_id**: Morpho market identifier
  * **name**: Human-readable conversion name
  * **router**: Router contract address
  * **token**: Token address
  * **conversion\_id**: Conversion ID

**Example Request:**

```bash
curl -X GET "${BASE}/morpho/allowed_conversions"
```

**Example Response:**

```json
{
  "status": 0,
  "code": "ok",
  "msg": "ok",
  "data": [
    {
      "id": 1,
      "from_asset": "0x1234567890abcdef1234567890abcdef12345678",
      "to_asset": "0xabcdef1234567890abcdef1234567890abcdef12",
      "market_id": "0xfedcba9876543210fedcba9876543210fedcba98",
      "name": "USDC -> AUSDC",
      "router": "0x9876543210fedcba9876543210fedcba98765432",
      "token": "0xfedcba9876543210fedcba9876543210fedcba98",
      "conversion_id": 1
    }
  ]
}
```
