# Get bandwidth by hostname
`GET https://usages.livepush.io/usage/cdn/hostnames`
Returns every delivery hostname on the account with its billable bytes for
the range, which is how you split CDN bandwidth per channel.

**Picking a range.** Send nothing and you get the current billing term,
from the day it started through today, with `range.isCurrentTerm` set to
`true`. Send `from`, `till`, or both to ask for specific UTC days instead.
`from` on its own runs to today; `till` on its own starts at the current
term. The maximum span is 400 days.

**Reading the rows.** The account's primary hostname comes first, then the
rest by descending bytes, then a synthetic `_other` row holding traffic
recorded against hostnames that are no longer configured. `_other` is
always present, even at zero, so the rows always sum to `accountBytes`.

Only a hostname with `assignment: dedicated` belongs to a single stream.
A `pooled` or `shared` row covers more than one stream and cannot be
split further, so do not divide it.

**These are delivery figures, not an invoice.** Quota, allowance and
overage are not reported here; they come from the account's subscription.
Figures are written by a collector that runs periodically, so the current
day is always partial and `lastUpdated` says how fresh the numbers are.
Add `daily=true` for a per-day series on every row.
- **Tag:** Usage
- **Operation ID:** `getUsageCdnHostnames`
- **Authentication:** Bearer token required
- **Docs:** https://developers.livepush.io/usage/get-bandwidth-by-hostname/

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `from` | string<date> | no | First UTC day to include, as YYYY-MM-DD. Defaults to the start of the current billing term. |
| `till` | string<date> | no | Last UTC day to include, as YYYY-MM-DD. Defaults to today. |
| `daily` | boolean | no | Include a per-day series on every hostname. Days with no traffic are omitted rather than returned as zero. |


### Example request

```bash
curl -X GET 'https://usages.livepush.io/usage/cdn/hostnames' \
  -H 'Authorization: Bearer YOUR_API_TOKEN'
```


### Responses


#### 200 — Bandwidth per hostname. Also returned with enabled: false and empty figures when the account has no CDN delivery configured.

- `enabled` (boolean) — false when the account has no CDN delivery configured. Everything else is then empty or null; this is a normal 200, not an error.
- `cpcode` (integer) — The account's CDN reporting code. null when delivery is not configured.
- `range` (object) — The UTC days the figures actually cover, after defaults are applied. Both bounds are inclusive.
  - `from` (string<date>) — First UTC day included.
  - `till` (string<date>) — Last UTC day included. Today's figure is always partial.
  - `isCurrentTerm` (boolean) — true when no dates were sent and the range was filled in from the current billing term. When true the totals come from the stored term rows rather than from summing days, which is what the dashboard shows.
- `term` (object) — The current CDN billing term. null when the account has no active cdn subscription and no stored term row to fall back on.
  - `start` (string<date-time>) — Start of the current term.
  - `end` (string<date-time>) — End of the current term, or null when the term is open-ended or was recovered from a stored usage row rather than from a subscription.
- `accountBytes` (integer<int64>) — Sum of bytes across every row below, including other. This is a delivery figure for display, not the billing figure: quota, allowance and overage are reported by the account's subscription, not by this endpoint.
- `lastUpdated` (string<date-time>) — When the collector last wrote any row in this response. The collector runs periodically, so the current day is always partial and this says how stale the figures are.
- `hostnames` (object[]) — Primary hostname first, then the rest by descending bytes, then the other bucket last. The other row is always present, even at zero.
  - `hostname` (string) — Lowercase delivery hostname. The synthetic value other carries traffic recorded against hostnames that are no longer configured on the account.
  - `label` (string) — Display name for the hostname. Falls back to the hostname itself when no label is set. The other row is always labelled Unassigned hostnames.
  - `isPrimary` (boolean) — true for the account's primary hostname, which carries every stream that has no hostname of its own plus any traffic still arriving on older links.
  - `assignment` (string) — How this hostname is used. | Value | Meaning | | --- | --- | | dedicated | Exactly one stream delivers on it | | shared | Several streams, or none yet, deliver on it | | pooled | The account's primary hostname | | other | The synthetic other bucket |
  - `streamIds` (string[]) — Streams assigned to this hostname. Always empty for the primary hostname and for other, because their traffic cannot be attributed per stream.
  - `otherHostnames` (string[]) — Present on the other row only. The hostnames whose rows were folded into it, so you can see what the unattributed traffic was delivered on.
  - `bytes` (integer<int64>) — Billable bytes for this hostname across the range.
  - `daily` (object[]) — Per-day series, present only when daily=true was sent. Days with no traffic are omitted rather than returned as zero.
    - `date` (string<date>)
    - `bytes` (integer<int64>) — Billable bytes recorded for this day.


```json
{
  "enabled": true,
  "cpcode": 1234567,
  "range": {
    "from": "2026-10-02",
    "till": "2026-10-15",
    "isCurrentTerm": true
  },
  "term": {
    "start": "2026-10-02T04:03:40.000Z",
    "end": "2026-11-02T04:03:40.000Z"
  },
  "accountBytes": 5541960000000,
  "lastUpdated": "2026-10-15T04:03:20.000Z",
  "hostnames": [
    {
      "hostname": "hls-acme-livepush.akamaized.net",
      "label": "Acme Channel",
      "isPrimary": false,
      "assignment": "dedicated",
      "streamIds": [
        "st_xxxxxxxxxxxxx"
      ],
      "otherHostnames": [
        "hls-retired-livepush.akamaized.net"
      ],
      "bytes": 1234567890,
      "daily": [
        {
          "date": "2026-10-06",
          "bytes": 123456789
        }
      ]
    }
  ]
}
```


#### 400 — invalidrange — a date was not YYYY-MM-DD, from is after till, or the span is over 400 days. message says which.

- `error` (string) — Stable machine-readable code.
- `message` (string) — Human-readable detail. Present on invalidrange, which says exactly which parameter was wrong.


```json
{
  "error": "invalid_range",
  "message": "range is 500 days; the maximum is 400"
}
```


#### 401 — Unauthorized

