# HTTP — `GET /v1/userFunding`

Settled perpetual-funding history for a user. Public endpoint. Not to be
confused with [`GET /v1/funding`](/api/funding), which reports deposit and
withdrawal requests.

```http
GET /v1/userFunding?user=0x0000000000000000000000000000000000000001&startTime=1780000000000&endTime=1780086400000
```

| Param | Required | Meaning |
| --- | --- | --- |
| `user` | yes | EVM address. Missing fails with `invalid_query`; malformed with `bad_request`. |
| `startTime` | yes | Inclusive start, Unix milliseconds. Missing fails with `invalid_query`. |
| `endTime` | no | Inclusive end, Unix milliseconds; defaults to now. `startTime > endTime` fails with `invalid_time_range`. |
| `cursor` | no | With `order=desc` only: the opaque `nextCursor` from the previous page. A malformed cursor, or any cursor with `order=asc`, fails with `invalid_cursor`. |
| `order` | no | `asc` (default) returns settlements in chronological order. `desc` returns the newest settlements first. Other values fail with `invalid_query`. |
| `limit` | no | Settlements per page, clamped to `1` to `500`, default `500`. A value that is not an integer from `0` to `65535` fails with `invalid_query`. |

```jsonc
{
  "status": "ok",
  "data": {
    "user": "0x0000000000000000000000000000000000000001",
    "userFundings": [
      {
        "fundingId": "2a4d4983-9057-4da9-bcd7-0aa0e4185bb0",
        "fundingTimeMs": 1780000000000,
        "a": "BTC",
        "venue": "hyperliquid",
        "amountUsdc": "-3.6243044439378",
        "positionSize": "49.1477",
        "fundingRate": "0.0000417",
        "oraclePx": "1768.42"
      }
    ]
  },
  "server_time_ms": 1780086400100
}
```

| Field | Meaning |
| --- | --- |
| `fundingId` | Stable settlement ID. |
| `fundingTimeMs` | Settlement time of the funding period, not the time it became visible. |
| `a`, `venue` | Canonical asset and the venue on which the position accrued funding. Two venues in the same asset are separate entries. |
| `amountUsdc` | Signed USDC cash delta: positive received, negative paid. |
| `positionSize` | Signed position size used for the settlement. |
| `fundingRate` | Hourly funding rate applied. |
| `oraclePx` | Oracle price of the venue funding-rate observation used for the settlement. |
| `nextCursor` | With `order=desc` only, and only while `hasMore` is `true`: the `cursor` of the next older page. |
| `hasMore` | With `order=desc` only: `true` while older settlements remain in the range. |

Decimals are strings.

Corrections appear as additional entries with new `fundingId` values for the
same period. Sum `amountUsdc` across distinct IDs to include these adjustments.
A correction's `positionSize` is the recalculated position. Use `amountUsdc`
for the adjustment instead of recalculating it from the size, rate and price.

## Page forward in chronological order

`order=asc` is the default. A page holds `limit` settlements plus every
currently available settlement sharing the last `fundingTimeMs`. Continue with
`startTime = last.fundingTimeMs + 1`. There is no cursor or `hasMore` field;
an empty `userFundings` means no more settlements are currently available in
the range.

## Read the newest settlements first

`order=desc` serves history views that show the newest settlements first and
load older ones on demand. The first page holds the newest settlements at or
before `endTime`:

```http
GET /v1/userFunding?user=0x0000000000000000000000000000000000000001&startTime=0&order=desc&limit=20
```

```jsonc
{
  "status": "ok",
  "data": {
    "user": "0x0000000000000000000000000000000000000001",
    "userFundings": [
      // Up to 20 settlements, newest fundingTimeMs first, with the fields shown above.
    ],
    "nextCursor": "ufnd1_1780084800_0_2a4d4983-9057-4da9-bcd7-0aa0e4185bb0",
    "hasMore": true
  },
  "server_time_ms": 1780086400100
}
```

To read the next older page, pass `nextCursor` as `cursor` and keep `user`,
`startTime`, `endTime`, and `order` unchanged. `limit` can change between pages.
Rows sort by `fundingTimeMs`, newest first, then by `fundingId`. One funding
period can span two pages. The cursor keeps the position inside the period, so
no settlement repeats and none is skipped. When `hasMore` is `false`, the
response has no `nextCursor`.

A walk returns each settlement at most once. A settlement written during the
walk appears only if its period is older than the last settlement already
returned. Start again without a cursor to see settlements written since the
first page.

Settlements can appear later for earlier periods. After recovery or a
suspected gap, query the affected time range again and deduplicate by
`fundingId`.
