> For the complete documentation index, see [llms.txt](https://docs.hydromancer.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hydromancer.xyz/readme/rest-api/historical-data/builderapprovednonfundingledgerupdatesbytime.md).

# builderApprovedNonFundingLedgerUpdatesByTime

Deposits, withdrawals, transfers and other non-funding ledger updates made by users who had an active builder-fee approval for your builder address.

The ledger counterpart of [builderApprovedFillsByTime](/readme/rest-api/historical-data/builderapprovedfillsbytime.md): every non-funding ledger update — deposits, withdrawals, transfers, vault flows, liquidations and the rest — made by a user while they had approved your builder, across all of those users at once. Each row is exactly a [userNonFundingLedgerUpdates](/readme/rest-api/historical-data/usernonfundingledgerupdates.md) row with the `user` it was attributed to, their `role`, and the `txIndex` needed to page added.

{% hint style="info" %}
**Attribution is by approval, not by routing.** Ledger updates carry no builder code, so the only way to attribute one is to ask who the user had approved at that block. A deposit made through any frontend by a user who had approved your builder appears here.
{% endhint %}

### Why you need this

Deposits and withdrawals are the earliest and latest signals you have about a user: a first deposit precedes any fill, and a withdrawal often precedes churn. Funding aside, this is the rest of the money movement for the users who approved you, without polling `userNonFundingLedgerUpdates` per user.

## POST Request

<table><thead><tr><th width="180">Field</th><th width="110">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>type</code></td><td>string</td><td>Required. <code>"builderApprovedNonFundingLedgerUpdatesByTime"</code></td></tr><tr><td><code>builder</code></td><td>string</td><td>Required. Builder address, 42-char hex.</td></tr><tr><td><code>startTime</code></td><td>number</td><td>Required unless <code>cursor</code> is given. Inclusive, milliseconds.</td></tr><tr><td><code>endTime</code></td><td>number</td><td>Optional. Inclusive, milliseconds.</td></tr><tr><td><code>cursor</code></td><td>string</td><td>Optional. Continue from a previous page. Format <code>"{time}_{txIndex}_{user}_{role}"</code>.</td></tr><tr><td><code>limit</code></td><td>number</td><td>Optional. Default and maximum 2000.</td></tr></tbody></table>

Results are returned oldest-first, ordered by `(time, txIndex, user, role)`.

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST https://api.hydromancer.xyz/info \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "type": "builderApprovedNonFundingLedgerUpdatesByTime",
    "builder": "0x1924b8561eef20e70ede628a296175d358be80e5",
    "startTime": 1786000000000,
    "limit": 100
  }'
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

resp = requests.post(
    "https://api.hydromancer.xyz/info",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "type": "builderApprovedNonFundingLedgerUpdatesByTime",
        "builder": "0x1924b8561eef20e70ede628a296175d358be80e5",
        "startTime": 1786000000000,
        "limit": 100,
    },
)
updates = resp.json()
```

{% endtab %}

{% tab title="Javascript" %}

```javascript
const resp = await fetch("https://api.hydromancer.xyz/info", {
  method: "POST",
  headers: { "Content-Type": "application/json", "X-API-Key": "YOUR_API_KEY" },
  body: JSON.stringify({
    type: "builderApprovedNonFundingLedgerUpdatesByTime",
    builder: "0x1924b8561eef20e70ede628a296175d358be80e5",
    startTime: 1786000000000,
    limit: 100,
  }),
});
const updates = await resp.json();
```

{% endtab %}
{% endtabs %}

***

## Pagination

Take the last returned row and build `cursor` as `"{time}_{txIndex}_{user}_{role}"`, then repeat the request with that `cursor` instead of `startTime`. A page shorter than `limit` means you have reached the end of the range.

Several updates land in one block and share `time`, and a self-transfer even shares `txIndex` and `user` across its two rows, so the cursor carries all four parts: it resumes exactly after the last row you saw without repeating or skipping the rest of the block.

## Semantics

* **One row per participating approving user.** A transfer names two users, and each is attributed independently. If the sender approved you, you get their row with `role: "sender"`; if the receiver approved you, you get theirs with `role: "receiver"`; if both did, you get both. `delta` is what `userNonFundingLedgerUpdates` shows that participant: `user` is always the sender and `destination` the receiver on either row, and the fee appears on the sender's row only — `role` is what tells you which side the row is for. Single-party updates such as deposits carry `role: "user"`.
* **Attributed at the block.** An approval applies from the block it lands in, and a revocation likewise. An update that happened while an approval was active stays attributed permanently — revoking does not remove past rows from this endpoint.
* **Same row as `userNonFundingLedgerUpdates`.** `time`, `hash` and `delta` are byte-for-byte what [userNonFundingLedgerUpdates](/readme/rest-api/historical-data/usernonfundingledgerupdates.md) returns for that user; only `user`, `role` and `txIndex` are added. Funding is excluded here exactly as it is there — use [builderApprovedFundingByTime](/readme/rest-api/historical-data/builderapprovedfundingbytime.md) for it.

## Response Fields

| Field     | Type   | Description                                                                                                                                                                                            |
| --------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `user`    | string | The participant this row is attributed to, who had approved your builder at the time.                                                                                                                  |
| `role`    | string | `"user"` for single-party updates; `"sender"` or `"receiver"` for the side of a transfer this row is for.                                                                                              |
| `time`    | int    | Block timestamp (ms).                                                                                                                                                                                  |
| `txIndex` | int    | Position of the update within its block. Needed only to build `cursor`.                                                                                                                                |
| `hash`    | string | Transaction hash.                                                                                                                                                                                      |
| `delta`   | object | Ledger update details, identical to `userNonFundingLedgerUpdates`. Fields vary by `delta.type`; see [that page](/readme/rest-api/historical-data/usernonfundingledgerupdates.md) for every delta type. |

<details>

<summary>Response</summary>

```json
[
  {
    "user": "0x0000000000000000000000000000000000000001",
    "role": "user",
    "time": 1786000001000,
    "txIndex": 0,
    "hash": "0xdc02464296095090dd7c04304bdac40205640028310c6f627fcaf195550d2a7b",
    "delta": {
      "type": "deposit",
      "usdc": "1000.50"
    }
  },
  {
    "user": "0x0000000000000000000000000000000000000002",
    "role": "receiver",
    "time": 1786000002000,
    "txIndex": 3,
    "hash": "0x9d3f0a2c4b6e8f1a3c5e7a9b1d3f5a7c9e1b3d5f7a9c1e3b5d7f9a1c3e5b7d9f",
    "delta": {
      "type": "internalTransfer",
      "usdc": "25.00",
      "user": "0x0000000000000000000000000000000000000001",
      "destination": "0x0000000000000000000000000000000000000002",
      "fee": "0.00"
    }
  }
]
```

</details>
