# Usage Report Endpoint

The **`GET /v1/usagereport`** endpoint is a **self-service monitoring tool**. It lets you, the API consumer, see how many calls your application has made against the Dentrix Ascend Public API **so far this month**, broken down by endpoint.

It is **not** a billing report, an entitlement check, or a per-organization audit. Its sole purpose is to let you watch your own month-to-date traffic so you can stay ahead of your monthly allotment.

## TL;DR

- The endpoint returns the **month-to-date request count for your apiConsumer**, broken down by endpoint.
- Counts are aggregated **per apiConsumer (your `developer_app` / `client_id`)** — **not** per organization, and **not** per `apiConsumer` + organization combination.
- The **`Organization-ID` header is required**, but only because every Public API call requires one for authentication. It does **not** filter or scope the numbers you get back.
- The endpoint **does not return data on the first day of the month** — there is nothing to report yet.


## What this endpoint is for

Use `GET /v1/usagereport` to answer questions like:

- "How many API calls has my integration made this month?"
- "Which endpoints am I hitting most?"
- "Am I trending toward my monthly call allotment?"


This is intended as a lightweight monitoring tool you can poll from your own dashboards or operational tooling. It is the same data we use internally to track consumer-level traffic against the proxy.

## What this endpoint is **not**

It is a common point of confusion, so to be explicit — `GET /v1/usagereport` is **not**:

- A **per-organization** usage report. The numbers returned are not scoped to the organization you pass in the `Organization-ID` header.
- A **billing** report or **invoice**. Per-location billing is calculated separately. See [Location-Based API Billing](/publicapi/location-filtering) for how billing usage is computed.
- A **rate-limit** status endpoint. It does not tell you how close you are to a per-minute or per-second throttle — only your aggregated month-to-date counts.
- A **historical** report. The valid date range is constrained to the current month (see [Filters](#filters) below).


## How aggregation works

Usage is counted **per `apiConsumer`**, where the `apiConsumer` is your registered application credential (internally `developer_app`, surfaced to your code as `client_name` / `client_id`).

If your `apiConsumer` is linked to multiple organizations, every call made by that `apiConsumer` — regardless of which `Organization-ID` was on the request — contributes to the **same** total. There is no per-org breakdown in the response, and changing the `Organization-ID` header on your `GET /v1/usagereport` request will **not** change the numbers you receive.

### Why the `Organization-ID` header is still required

`Organization-ID` is required on **every** Public API request as part of standard authentication. The Public API verifies that your `client_id` is authorized for the organization in the header before it will service the request. See the [API Consumer Guide — Authentication](/publicapi/api-consumer-guide) for the broader header requirements.

For `/v1/usagereport` specifically:

- The header is checked for **security/authorization** only.
- It is **not** used as a filter on the returned data.
- Any organization your `apiConsumer` is authorized for is a valid value here, and you will get the **same** month-to-date counts back regardless of which one you use.


## Request

```
GET /api/v1/usagereport
Organization-ID: <any organization your apiConsumer is authorized for>
Authorization: Bearer <access_token>
```

### Filters

All filters are optional and use the `==` (equals) operator, consistent with other Public API filter syntax.

| Filter | Required | Default | Notes |
|  --- | --- | --- | --- |
| `startDate` | No | First day of the current month | Cannot be earlier than the first day of the current month. Cannot equal `endDate`. |
| `endDate` | No | The current date | Cannot be later than the current date. Cannot equal `startDate`. Cannot be earlier than `startDate`. |
| `endpoint` | No | *(all endpoints)* | Must be a known endpoint name with no version prefix or special characters (for example, `appointments`, not `/v1/appointments`). If omitted, the response is broken down by endpoint. |


Dates use `YYYY-MM-DD` format and are interpreted as the **start of day in UTC** (for example, `2026-03-01` is equivalent to `2026-03-01T00:00:00Z`).

### Example requests

**Default — month-to-date totals for every endpoint:**

```
GET /api/v1/usagereport
```

**Narrow to a specific endpoint:**

```
GET /api/v1/usagereport?filter=endpoint=="appointments"
```

**Narrow to a date range within the current month:**

```
GET /api/v1/usagereport?filter=startDate=="2026-06-01",endDate=="2026-06-15"
```

**Combine all three filters:**

```
GET /api/v1/usagereport?filter=startDate=="2026-06-01",endDate=="2026-06-15",endpoint=="appointments"
```

## Response

```json
{
  "statusCode": 200,
  "data": {
    "usagePerEndpoint": [
      { "endpoint": "appointments",  "requestCount": 12345 },
      { "endpoint": "transactions",  "requestCount":  4321 },
      { "endpoint": "patients",      "requestCount":  9876 }
    ]
  }
}
```

| Field | Type | Description |
|  --- | --- | --- |
| `usagePerEndpoint` | array | One entry per endpoint your `apiConsumer` has called in the requested time range. |
| `usagePerEndpoint[].endpoint` | string | The endpoint name (no version prefix). |
| `usagePerEndpoint[].requestCount` | number | Total request count for that endpoint across **all** organizations your `apiConsumer` is linked to, within the requested time range. |


> Endpoints your `apiConsumer` has not called in the requested time range are simply omitted from the array. An empty `usagePerEndpoint` array means no traffic was recorded.


## Constraints and edge cases

- **First day of the month** — The endpoint will not return statistics if called on the first day of the month. There is no aggregated data yet for the current period.
- **Date range must be within the current month** — `startDate` cannot be earlier than the first day of the current month, and `endDate` cannot be later than today. To look at a prior month's totals, you must capture and store the response yourself before the month rolls over.
- **`startDate` and `endDate` cannot be equal** — Use a range of at least one day.
- **Stats are aggregated, not real-time** — Counts come from analytics and may lag the most recent traffic by a short period. Treat the numbers as month-to-date observations, not as a live counter you can use for fine-grained throttling decisions.


## Common misunderstandings

| Misunderstanding | Reality |
|  --- | --- |
| "The numbers I see are for the org in my `Organization-ID` header." | No — the header is for **authentication only**. The numbers are aggregated for your **`apiConsumer`** across every organization it is linked to. |
| "I should call `/v1/usagereport` per org to see per-org usage." | The endpoint does not break out usage by organization. Every call you make to `/v1/usagereport` returns the **same** apiConsumer-level totals, regardless of the `Organization-ID` header. |
| "This endpoint tells me what I will be billed." | No — billing (especially per-location billing) is computed independently. See [Location-Based API Billing](/publicapi/location-filtering). |
| "Why am I getting an error on the 1st of the month?" | The endpoint intentionally returns no statistics on the first day of the month — there is nothing to aggregate yet. Resume calls on the 2nd. |
| "I want to see last month's totals." | The endpoint only supports the **current** month. Capture and persist the response near the end of each month if you need a historical record. |


## Best practices

1. **Poll on a sensible cadence.** Hourly or every few hours is typically plenty for trend monitoring. There is no benefit to polling every minute — the underlying analytics are not real-time and you would just be burning your own allotment.
2. **Persist your own snapshots** if you need historical (prior-month) totals. The endpoint will not give them to you after the month rolls over.
3. **Use the `endpoint` filter** when you only care about traffic to a specific endpoint — it makes the response easier to consume in dashboards.
4. **Do not use it as a rate-limit gate.** It is a monitoring aid, not an authoritative real-time counter. For rate-limit behavior, see the [API Consumer Guide — Rate Limiting](/publicapi/api-consumer-guide).
5. **Combine with [Location-Based API Billing](/publicapi/location-filtering)** when planning your integration's overall API footprint — `usagereport` tells you *how many* calls you've made, while location billing explains *what those calls cost*.