---
title: "Export usage statistics"
method: GET
path: "/organizations/{organizationId}/data-export/usage"
tags: ["data-export"]
---

# Export usage statistics

`GET /organizations/{organizationId}/data-export/usage`

## Request

- Base URL: `https://vetnio.com/api/v2`
- URL: `https://vetnio.com/api/v2/organizations/{organizationId}/data-export/usage`
- Auth: HTTP bearer

Returns the same table as Organization → Export in the app, as JSON: `headers` plus one array of cells per row. Choose the period (`days`, or `startDate`/`endDate`), the row level (`grain`), the time bucket (`timePeriod`), clinics (`workspaceIds`) and `columns`. Only `grain=consultation` is paginated. A workspace key only ever gets its own clinic's rows. Read-only; every call is recorded in the audit log. Requests that include note-quality columns run an extra analytics query and are limited per key per day. Requires organization admin rights, like the overview endpoint.

## Path parameters

- `organizationId` string, required: Identifier of the organization (a UUID). With an organization or workspace key, use the `organizationId` returned by `GET /api-key`; any other organization returns 403.

## Query parameters

- `workspaceIds` string: Comma-separated workspace (clinic) IDs to include, for example `furunculotic-loud-chihuahua,brave-quick-heron`. Every ID must belong to the organization (or, for a workspace key, be the key's own clinic), otherwise the request fails with 400. Default: every clinic attached to the organization, including locked clinics.
- `columns` string: Comma-separated column keys, for example `workspaceName,consultationCount,recordingHours`. Columns are always returned in the export's fixed order, not the order listed. Columns that do not apply to the chosen `grain` are dropped silently: vet columns need `grain=vet` or `consultation`, consultation columns need `grain=consultation`, and at `grain=consultation` the aggregate columns are not available. An unknown key fails with 400 and the message lists every valid key. Default: every column except the note-quality ones (`avgReadingSeconds`, `avgEditingSeconds`, `acceptanceRate`, `draftOutcome`), which are only included when listed and are limited to 20 requests per key per day. The Export dialog's “Use via API” button builds this value for you.
- `startDate` string: First day of a fixed date range, `YYYY-MM-DD` (UTC). When set, `days` is ignored. The range may span at most 366 days; longer ranges fail with 400.
- `endDate` string: Last day of the fixed date range, inclusive, `YYYY-MM-DD` (UTC). Only used together with `startDate`; without `startDate` it is ignored. Default: up to the current moment.
- `days` integer: Length of a rolling window ending now, in days (1-366, default 30). Today counts as the first day, so `days=7` covers today and the 6 days before it, starting at midnight UTC. Ignored when `startDate` is set.
- `timePeriod` 'daily' | 'weekly' | 'monthly' | 'yearly': Size of the time bucket each row covers when `grain` is `vet` or `clinic`; ignored for `snapshot` and `consultation`. Buckets are UTC. The first column (`Date`) holds the bucket's first day as `YYYY-MM-DD`, clamped to the start of the range: - `daily` — one bucket per calendar day. - `weekly` — one bucket per week, starting Monday. - `monthly` — one bucket per calendar month. - `yearly` — one bucket per calendar year.
- `grain` 'clinic' | 'vet' | 'snapshot' | 'consultation': What one row represents: - `vet` — one vet in one clinic for one time bucket; only vets with activity get rows, and a vet working in two clinics gets a row for each. - `clinic` — one clinic for one time bucket; every clinic in scope gets a row (zero-filled) for each bucket with any activity. - `snapshot` — one row per clinic for the whole period, without a `Date` column. - `consultation` — one row per consultation, oldest first, including deleted ones (flagged in the `Deleted` column). The only paginated grain.
- `page` integer: Page number, starting at 1. Only `grain=consultation` spans several pages; other grains always return everything on page 1. Pages that start beyond row 50,000 are rejected with 400: split the date range instead.
- `pageSize` integer: Rows per page for `grain=consultation`, 1-5000. Ignored for the other grains.

## Response `200`

One page of the usage table.

- OrganizationUsageExport: One page of the usage table: the same table as the in-app usage CSV export, as JSON.
  - `headers` string[], required: Column titles in display form (for example `Clinic Name`, `Consultations`), in the order of each row's cells. For `grain=vet` and `grain=clinic` the first column is `Date`.
  - `rows` array[], required: Table rows, one cell per header. Cells are strings, numbers or `null` (not applicable or unknown). Dates are `YYYY-MM-DD` strings (the next and last payment dates are full ISO-8601 timestamps), consultation start and end times are `HH:mm` in the clinic's local time, flags are `Yes` or `No`, amounts are rounded to 2 decimals and `Draft Kept (%)` is a percentage from 0 to 100.
    - union[]
      - union
        - string
        - number
  - `start` string, required: First day covered, `YYYY-MM-DD` (UTC).
  - `end` string, required: Last day covered, `YYYY-MM-DD` (UTC).
  - `totalRows` number, required: Number of rows across all pages. For grains other than `consultation` it equals the number of rows returned.
  - `page` number, required: The page returned. Always 1 unless `grain=consultation`.
  - `totalPages` number, required: Only the consultation grain spans several pages; the others always return 1.

## Other responses

- `400`: Invalid input data
- `401`: Authorization not provided
- `403`: Insufficient access
- `404`: Not found
- `500`: Internal server error

---

[API](https://skmtc.dev/vetnio/apis/vetnio-api.md) - [All operations](https://skmtc.dev/vetnio/apis/vetnio-api/llms.txt) - [OpenAPI document](https://skmtc.dev/vetnio/apis/vetnio-api/revisions/d004afd5617d?raw)
