---
title: "live.channel-points-page@1 · OpenVibe.Services"
canonical: "https://openvibe.services/docs/contracts/live.channel-points-page"
updated: null
---

# live.channel-points-page@1 · OpenVibe.Services

HTML: [live.channel-points-page@1 · OpenVibe.Services](https://openvibe.services/docs/contracts/live.channel-points-page)

# LiveChannelPointsPage `live.channel-points-page@1`

Generated at 2026-11-13 06:25:48 UTC from [`openvibe-contracts v0.419.0`](https://github.com/OpenVibers/OpenVibe.Contracts/tree/v0.419.0) and [`openvibe-sdk v0.161.0`](https://github.com/OpenVibers/OpenVibe.SDK/tree/v0.161.0).

- Version: 1.0.0
- Owner: live
- Visibility: first-party
- Status: active
- Compatibility: backward
- Schema: [`https://openvibe.network/contracts/live/channel-points-page.v1.json`](/docs/contracts/live.channel-points-page.json)

live.channel-points-page@1: the answer of GET /internal/channel-points/changes?network\_user\_id=&since\_id=&streamer\_id=&limit= on OpenVibe.Live (live.channel\_points.read, Network service token, loopback): one channel's points moves for the person behind the Network account, oldest first, from Live's own channel\_points\_log. moves carry the ledger's id, the streamer, the ISO time, the signed delta and the raw reason; balance is that channel's points (null without streamer\_id); cursor is the newest move seen, next\_since pages when more exist (null on the last). 400 without network\_user\_id or with a bad streamer\_id, 404 for an unlinked account.

## Fields

| Field | Type | Required | Description | Constraints |
| --- | --- | --- | --- | --- |
| `ok` | const | yes |  | - `= true` |
| `user_id` | integer | yes |  | - `minimum 1` |
| `streamer_id` | integer \| null | yes |  | - `minimum 1` |
| `balance` | integer \| null | yes |  |  |
| `moves` | array of object | yes |  | - `maxItems 501` |
| `moves[].id` | integer | yes |  | - `minimum 1` |
| `moves[].streamer_id` | integer | yes |  | - `minimum 1` |
| `moves[].at` | string | yes |  |  |
| `moves[].delta` | integer | yes |  |  |
| `moves[].reason` | string \| null | yes |  |  |
| `cursor` | integer | yes |  | - `minimum 0` |
| `next_since` | integer \| null | yes |  | - `minimum 0` |

## Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

 Valid: page

~~~~
{
  "ok": true,
  "user_id": 7,
  "streamer_id": 3,
  "balance": 70,
  "moves": [
    {
      "id": 11,
      "streamer_id": 3,
      "at": "2026-11-11T10:00:00Z",
      "delta": 100,
      "reason": "watch"
    },
    {
      "id": 12,
      "streamer_id": 3,
      "at": "2026-11-11T11:00:00Z",
      "delta": -30,
      "reason": "redeem reward 9"
    }
  ],
  "cursor": 12,
  "next_since": null
}
~~~~

Rejected: delta-string

~~~~
{
  "ok": true,
  "user_id": 7,
  "streamer_id": 3,
  "balance": 70,
  "moves": [
    {
      "id": 11,
      "streamer_id": 3,
      "at": "2026-11-11T10:00:00Z",
      "delta": "100",
      "reason": "watch"
    }
  ],
  "cursor": 11,
  "next_since": null
}
~~~~

## Validate

~~~~
const contracts = require('openvibe-contracts');
contracts.validate('live.channel-points-page@1', value);   // { valid, errors: [{ path, message }] }
~~~~
