> ## Documentation Index
> Fetch the complete documentation index at: https://docs.macroscope.com/llms.txt
> Use this file to discover all available pages before exploring further.

# List daily billing usage

> Daily metered usage and provisional costs, with whole-interval totals on the first page.

Read a daily usage series for your billing reports without requesting each day separately. Results cover the whole workspace, including excluded/deleted repositories and unattributed usage. This read does not incur usage charges.

> [!WARNING]
>
> Amounts are provisional metered usage at current prices, not invoice amounts, balances, or net charges. Even past days can change as usage arrives or prices change. Reads may use cached data and do not form a snapshot.

Use this endpoint for daily trends. For one total per meter, use [billing meter summaries](https://docs.macroscope.com/api-reference/endpoint/list-billing-meter-summaries.md). To see individual agent runs and what each cost, use [agent credit usage](https://docs.macroscope.com/api-reference/endpoint/list-agent-credit-usage.md). Those per-run costs are list-price estimates rounded per run, so their sum won't exactly match the Agent meter amounts here; use the metered endpoints for billing totals.

## Authorization

Requires workspace Read. API keys can read only their bound workspace and do not inherit their creator's Admin permissions. Repository access restrictions do not reduce these workspace-wide totals.

**Authorization** `string` *required*

`Bearer <key>`. See [Authentication](https://docs.macroscope.com/api#authentication).

## Path parameters

**workspaceType** `string` *required*

`GITHUB_ORGANIZATION` or `GITHUB_USER`.

**workspaceId** `string` *required*

Numeric GitHub ID of the organization or user.

## Query parameters

**startTime** `string` *required*

Inclusive start of the requested interval, as an RFC 3339 timestamp. There is no default.

**endTime** `string` *required*

Exclusive end of the interval, as an RFC 3339 timestamp. Must be after `startTime` and at most 366 elapsed days later. There is no default.

**pageSize** `integer` (default: 50)

Complete UTC days per page, from 1 to 200. This counts days, not meters or rate series.

**pageToken** `string`

Opaque `nextPageToken` from the preceding response. Keep the workspace and original date bounds unchanged; `pageSize` may change. Tokens expire after 24 hours and may become invalid earlier. Every page requires valid credentials. An invalid token returns HTTP 400; restart without `pageToken`.

### UTC days and partial days

The interval is half-open: `[startTime, endTime)`. Every UTC day intersecting it is returned, oldest first, even when there is no observed usage. The first and last day may be partial; their returned bounds are clipped to your requested timestamps. An end at midnight does not add the following day.

Partial-day usage is retrieved at minute resolution: the start rounds down and the end rounds up to enclosing minutes. Returned period bounds still preserve your requested timestamps. For example, a start at `12:00:30Z` can include usage from `12:00:00Z`. Use minute-aligned timestamps when this distinction matters.

## Response

**days** `object[]`

Complete days on this page, ordered by `periodStart` ascending. Each day contains all its rate series; meter collections are never truncated.

**Day properties**

**periodStart** `string`

Inclusive start of this clipped UTC day (RFC 3339).

**periodEnd** `string`

Exclusive end of this clipped UTC day (RFC 3339).

**meters** `object[]`

Independent rate series, ordered by `seriesCode`. See [Series fields](#series-fields). Empty, possibly omitted in JSON, when no meters are configured.

**amountStatus** `string`

Always `BILLING_AMOUNT_STATUS_PROVISIONAL`, including historical days.

**intervalMetadata** `object`

Present only on the first page, when you omit `pageToken`. Covers the entire original requested interval, not just the days on this page.

**Interval metadata properties**

**periodStart** `string`

Original inclusive `startTime` (RFC 3339).

**periodEnd** `string`

Original exclusive `endTime` (RFC 3339).

**series** `object[]`

Whole-interval totals for each independent rate series, ordered by `seriesCode`. Uses the same series fields below, without `observed`. Quantity sums that series' displayed daily quantities; amount sums its daily priced amounts, rather than applying a unit price to the interval's quantity.

**amountStatus** `string`

Always `BILLING_AMOUNT_STATUS_PROVISIONAL`.

**nextPageToken** `string`

Pass as `pageToken` to read the next page. Omitted when there are no more pages.

**readTime** `string`

Response construction time (RFC 3339), not a data-freshness watermark.

### Series fields

Daily `meters[]` and whole-interval `series[]` use these fields. Multiple rates on one meter stay separate: use `seriesCode` as the key, not `displayName` or `meterCode`.

**seriesCode** `string`

Opaque identity linking an independent rate series across pages and to its interval total. Do not parse it.

**meterCode** `string`

Opaque meter identity linking to `meterSummaries`. Different rate series can share it; do not add their quantities as if they were different meters.

**displayName** `string`

Display name. Names need not be unique.

**quantity** `string`

Decimal usage quantity in this series' `unit`.

**unit** `string`

Unit of the quantity. Each rate preserves its own unit and conversion.

**usageAmount** `object`

Metered cost: `amount` is a decimal string in major currency units, formatted to cents (for example, `"12.50"`); `currency` is uppercase (for example, `"USD"`).

**observed** `boolean`

Daily points only. `true` means an observation exists, even if its quantity and amount are zero. `false` or an omitted field means no observation; quantity and amount are zero placeholders.

A day with no observed series is missing data, not a measured zero. Missing observations do not mean reporting is complete. No configured meters produces an empty collection, which is different from configured meters with missing observations.

Quantities use 64-bit floating-point precision, not arbitrary-precision decimal arithmetic. For series converted to decimal KB (1000 bytes), each day's quantity rounds to two decimals, with ties away from zero. Other series retain their units. Conversion does not reprice usage: costs round to cents independently for each rate and day. Interval totals use 64-bit floating-point summation before formatting; KB quantities use two decimal places, other quantities use the shortest decimal preserving that precision, and amounts use two decimal places.

## Pagination and totals

1. Omit `pageToken` for the first request. Save `intervalMetadata` once if you need whole-interval totals.
2. Process the complete days in `days`.
3. If `nextPageToken` is present, request the next page with that token and the **original** workspace and date bounds. Continue until the token is absent.

Interval metadata is **not additive across pages** and is not a page total or invoice amount. Continuation pages omit it. A restarted walk returns new metadata; replace the old metadata rather than adding it again.

First-page totals and daily pages are independent reads, not a snapshot. Usage may be cached for up to one minute, and subscription and pricing information for up to five minutes. Reporting can also lag activity. Late usage or subscription/price changes can make the first-page totals differ from a later sum of the pages; there is no freshness guarantee. This endpoint does not reconstruct historical invoices.

## Limits and errors

The maximum interval is 366 elapsed days, with 1–200 complete days per page. Reads support at most 200 independent rate series and 368 usage observations per series. An encoded response exceeding 50 MiB also fails; results are never silently truncated.

| HTTP | Meaning | Action |
| - | - | - |
| `400` | Invalid bounds, page size, or continuation token. | Correct the input; for an invalid token, restart the walk. |
| `400` | `billing collection limit exceeded`. | A rate-series, observation, or response-size limit was exceeded. A smaller interval or page may help with data size, but not with too many configured rate series. |
| `401` | Missing or invalid credentials. | Check your bearer token. |
| `403` | Insufficient permission or wrong workspace. | Check the key's workspace and required permissions. |
| `429` | Rate limited. | Respect `Retry-After` before retrying; do not poll in a tight loop. |
| `500` | Internal error. | Retry with backoff; contact support if it persists. |
| `503` | Temporarily unavailable. | Retry with backoff. |

See the API's shared [errors](https://docs.macroscope.com/api#errors) and [rate limits](https://docs.macroscope.com/api#limits). Request limits do not establish a data-freshness guarantee.

```bash cURL theme={null}
curl --fail-with-body --get https://api.macroscope.com/api/v1/workspaces/GITHUB_ORGANIZATION/12345678/billing/dailyUsage \
  -H "Authorization: Bearer $MACROSCOPE_API_KEY" \
  --data-urlencode "startTime=2026-10-01T00:00:00Z" \
  --data-urlencode "endTime=2026-10-03T00:00:00Z" \
  --data-urlencode "pageSize=1"
```

```python Python pagination theme={null}
import os
import requests

url = "https://api.macroscope.com/api/v1/workspaces/GITHUB_ORGANIZATION/12345678/billing/dailyUsage"
headers = {"Authorization": f"Bearer {os.environ['MACROSCOPE_API_KEY']}"}
params = {
    "startTime": "2026-10-01T00:00:00Z",
    "endTime": "2026-10-03T00:00:00Z",
    "pageSize": 1,
}
interval_metadata = None

while True:
    response = requests.get(url, headers=headers, params=params, timeout=30)
    response.raise_for_status()
    page = response.json()
    if "intervalMetadata" in page:
        interval_metadata = page["intervalMetadata"]
    for day in page.get("days", []):
        print(day)
    token = page.get("nextPageToken")
    if not token:
        break
    params["pageToken"] = token
```

```json 200 theme={null}
{
  "days": [
    {
      "periodStart": "2026-10-01T00:00:00Z",
      "periodEnd": "2026-10-02T00:00:00Z",
      "meters": [
        {
          "meterCode": "meter_example",
          "seriesCode": "series_example",
          "displayName": "Example usage",
          "quantity": "1000.00",
          "unit": "KB",
          "usageAmount": {
            "amount": "10.00",
            "currency": "USD"
          },
          "observed": true
        }
      ],
      "amountStatus": "BILLING_AMOUNT_STATUS_PROVISIONAL"
    }
  ],
  "intervalMetadata": {
    "periodStart": "2026-10-01T00:00:00Z",
    "periodEnd": "2026-10-03T00:00:00Z",
    "series": [
      {
        "seriesCode": "series_example",
        "meterCode": "meter_example",
        "displayName": "Example usage",
        "unit": "KB",
        "quantity": "3000.00",
        "usageAmount": {
          "amount": "30.00",
          "currency": "USD"
        }
      }
    ],
    "amountStatus": "BILLING_AMOUNT_STATUS_PROVISIONAL"
  },
  "nextPageToken": "opaque-continuation-token",
  "readTime": "2026-10-03T00:05:00Z"
}
```

```json 400 theme={null}
{ "code": 9, "message": "billing collection limit exceeded" }
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.