# impartire API — Reference: Analytics

Every path is under `https://impartire.com/api/v1`. The machine-readable contract is https://impartire.com/api/v1/openapi.json (OpenAPI 3.1).

#### GET /api/v1/analytics/summary

Read consumption analytics over a range

The numbers of the app's analytics dashboard: views, unique viewers, playback time and downloads over `range` reporting days ending today (the org's reporting day — its time zone and start hour — not a UTC calendar day), the same over the range before it, one point per day, the ten most viewed assets, and the device and audience breakdowns. `viewer_type` filters to one audience (`api` — developer-API downloads). Reading it first materializes every reporting day that has ended into the rollup, as the app's dashboard does (a write of derived data only). Channel audience is not served. For an OAuth token, its person needs membership of the org (no platform-admin bypass) and an asset's name is null when they may not read the asset; a key reads the whole org. 404 when the org does not have analytics, and for an OAuth token whose person is not a member of the org.

Scopes: `analytics:read`

Parameters:

- `range` (query, "7d" | "30d" | "90d" | "365d") — How many reporting days, today included. Default `30d`.
- `viewer_type` (query, "all" | "internal" | "consumer" | "embed" | "api") — Filter to one audience. Default `all`.

Response 200 — `ConsumptionAnalytics`: How the org's content was consumed over a range: the numbers of the app's analytics dashboard.

- `range` (object, required)
  - `from` (string (date), required) — The first reporting day of the range (YYYY-MM-DD).
  - `to` (string (date), required) — The last reporting day of the range (YYYY-MM-DD), today included.
- `reporting_day` (object, required) — The org's reporting day: every day, range and bucket here is one of these, not a UTC calendar day.
  - `timezone` (string, required) — The org's reporting-day time zone (IANA).
  - `day_start_hour` (integer, required) — The hour (0–23, in that zone) a reporting day starts — a broadcaster's day may start at 06:00.
- `viewer_type` ("all" | "internal" | "consumer" | "embed" | "api", required) — The audience the figures are filtered to (`all` — none). `by_viewer_type` ignores it.
- `summary` (AnalyticsTotals, required) — Consumption totals over a range.
  - `total_views` (integer, required) — Views: a surface that renders the asset was opened (once per session and asset).
  - `unique_viewers` (integer, required) — Distinct viewers over the whole range — exact, not a sum of daily uniques.
  - `total_playback_ms` (integer, required) — Milliseconds of playback watched.
  - `total_downloads` (integer, required) — Downloads: the bytes were taken.
- `previous_period` (object, required) — The same totals over the range of equal length ending the day before `range.from`.
  - `total_views` (integer, required) — Views: a surface that renders the asset was opened (once per session and asset).
  - `unique_viewers` (integer, required) — Distinct viewers over the whole range — exact, not a sum of daily uniques.
  - `total_playback_ms` (integer, required) — Milliseconds of playback watched.
  - `total_downloads` (integer, required) — Downloads: the bytes were taken.
  - `from` (string (date), required)
  - `to` (string (date), required)
- `series` (array of object, required) — One point per reporting day of the range, oldest first, zero-filled.
  - `day` (string (date), required)
  - `views` (integer, required)
  - `unique_viewers` (integer, required) — Distinct viewers that day.
  - `watched_ms` (integer, required)
  - `downloads` (integer, required)
- `top_assets` (array of object, required) — The ten most viewed assets of the range (every version of an asset counts toward it), most viewed first.
  - `asset` (object, required)
    - `id` (string (uuid), required) — The asset's current version id (GET /api/v1/assets/{id}).
    - `name` (string or null, required) — The asset's name. Null — for an OAuth token — when its person may not read the asset: the figures are org figures every member sees on the dashboard; the name is not disclosed.
  - `views` (integer, required)
  - `downloads` (integer, required)
- `by_device` (array of object, required) — Views, downloads and playback sessions together, by device, largest first.
  - `device_type` (string, required) — `desktop`, `mobile`, `tablet` or `unknown`.
  - `count` (integer, required)
- `by_viewer_type` (array of object, required) — Views, downloads and playback sessions together, by audience, largest first — over every audience, whatever `viewer_type` is.
  - `viewer_type` (string, required) — `internal` (a member), `consumer`, `embed` (a share link) or `api` (a developer-API download).
  - `count` (integer, required)

Other responses:

- 401 (Problem) — unauthenticated — no key, or an unknown, revoked or expired one.
- 403 (Problem) — insufficient-scope — the key lacks a required scope.
- 404 (Problem) — not-found.
- 422 (Problem) — validation — a bad `range` or `viewer_type` (`errors[].path` names it).
- 429 (Problem) — rate-limited — the key's request budget is spent; wait Retry-After seconds.
- 500 (Problem) — internal.

#### GET /api/v1/analytics/operations

Read operations analytics over a range

The numbers of the app's operations view over `range` reporting days ending today: workflow runs started, completed, failed and open, with durations; approvals and their latency; open incidents; delivery attempts, outcomes and latency; assets created, time to first approval, and the assets nobody opened. `workflows.active` and `incidents.active` are true now, not range figures. For an OAuth token, its person needs membership of the org (no platform-admin bypass) and an asset's name is null when they may not read the asset; a key reads the whole org. 404 when the org does not have analytics, and for an OAuth token whose person is not a member of the org.

Scopes: `analytics:read`

Parameters:

- `range` (query, "7d" | "30d" | "90d" | "365d") — How many reporting days, today included. Default `30d`.

Response 200 — `OperationsAnalytics`: How the DAM was operated over a range — runs, approvals, incidents, deliveries, assets: the numbers of the app's operations view.

- `range` (object, required)
  - `from` (string (date), required) — The first reporting day of the range (YYYY-MM-DD).
  - `to` (string (date), required) — The last reporting day of the range (YYYY-MM-DD), today included.
- `reporting_day` (object, required) — The org's reporting day: every day, range and bucket here is one of these, not a UTC calendar day.
  - `timezone` (string, required) — The org's reporting-day time zone (IANA).
  - `day_start_hour` (integer, required) — The hour (0–23, in that zone) a reporting day starts — a broadcaster's day may start at 06:00.
- `workflows` (object, required)
  - `started` (integer, required) — Runs started in the range.
  - `completed` (integer, required) — Runs that completed in the range (dated by when they ended).
  - `failed` (integer, required)
  - `cancelled` (integer, required)
  - `active` (integer, required) — Runs open right now, whenever they started.
  - `duration_p50_ms` (integer or null, required) — Median start-to-completion time of the runs completed in the range; null when none.
  - `duration_p90_ms` (integer or null, required)
- `approvals` (object, required)
  - `submitted` (integer, required)
  - `approved` (integer, required)
  - `latency_p50_ms` (integer or null, required) — Median submit-to-approve time of the approvals given in the range; null when none.
  - `latency_p90_ms` (integer or null, required)
- `incidents` (object, required)
  - `active` (integer, required) — Run steps parked for an operator right now.
- `deliveries` (object, required)
  - `attempted` (integer, required) — Deliveries attempted in the range; `delivered` and `failed` count how those turned out (the rest are pending).
  - `delivered` (integer, required)
  - `failed` (integer, required)
  - `success_rate` (number or null, required) — delivered / attempted, 0–1; null when nothing was attempted.
  - `latency_p50_ms` (integer or null, required)
- `assets` (object, required)
  - `created` (integer, required)
  - `time_to_first_approval_p50_ms` (integer or null, required) — Median time from an asset's creation to its first approval, over first approvals given in the range.
  - `unconsumed` (object, required)
    - `count` (integer, required) — Assets that existed when the range opened and were not viewed, downloaded or played during it.
    - `sample` (array of object, required) — Up to ten of them, newest first.
      - `asset` (object, required)
        - `id` (string (uuid), required) — The asset's current version id (GET /api/v1/assets/{id}).
        - `name` (string or null, required) — The asset's name. Null — for an OAuth token — when its person may not read the asset: the figures are org figures every member sees on the dashboard; the name is not disclosed.
      - `created_at` (string (date-time), required)
- `series` (array of object, required) — One point per reporting day of the range, oldest first, zero-filled.
  - `day` (string (date), required)
  - `workflows_completed` (integer, required)
  - `deliveries_delivered` (integer, required)

Other responses:

- 401 (Problem) — unauthenticated — no key, or an unknown, revoked or expired one.
- 403 (Problem) — insufficient-scope — the key lacks a required scope.
- 404 (Problem) — not-found.
- 422 (Problem) — validation — a bad `range`.
- 429 (Problem) — rate-limited — the key's request budget is spent; wait Retry-After seconds.
- 500 (Problem) — internal.

#### GET /api/v1/analytics/search

Read search analytics over a range

The numbers of the app's search view over `range` reporting days ending today: asset searches, those that found nothing, unique searchers, the same over the range before it, one point per day, and the top queries and top zero-result queries. For an OAuth token, its person needs membership of the org (no platform-admin bypass) and an asset's name is null when they may not read the asset; a key reads the whole org. 404 when the org does not have analytics, and for an OAuth token whose person is not a member of the org.

Scopes: `analytics:read`

Parameters:

- `range` (query, "7d" | "30d" | "90d" | "365d") — How many reporting days, today included. Default `30d`.

Response 200 — `SearchAnalytics`: What people searched the asset library for, and did not find, over a range: the numbers of the app's search view.

- `range` (object, required)
  - `from` (string (date), required) — The first reporting day of the range (YYYY-MM-DD).
  - `to` (string (date), required) — The last reporting day of the range (YYYY-MM-DD), today included.
- `reporting_day` (object, required) — The org's reporting day: every day, range and bucket here is one of these, not a UTC calendar day.
  - `timezone` (string, required) — The org's reporting-day time zone (IANA).
  - `day_start_hour` (integer, required) — The hour (0–23, in that zone) a reporting day starts — a broadcaster's day may start at 06:00.
- `summary` (SearchTotals, required) — Asset-search totals over a range.
  - `searches` (integer, required)
  - `zero_result_searches` (integer, required)
  - `unique_searchers` (integer, required)
- `previous_period` (object, required) — The same totals over the range of equal length ending the day before `range.from`.
  - `searches` (integer, required)
  - `zero_result_searches` (integer, required)
  - `unique_searchers` (integer, required)
  - `from` (string (date), required)
  - `to` (string (date), required)
- `series` (array of object, required) — One point per reporting day, oldest first, zero-filled.
  - `day` (string (date), required)
  - `searches` (integer, required)
  - `zero_results` (integer, required)
- `top_queries` (array of object, required) — The 20 most frequent queries.
  - `query` (string, required)
  - `searches` (integer, required)
  - `avg_results` (number, required) — Mean result count, one decimal.
- `zero_result_queries` (array of object, required) — The 20 most frequent queries that found nothing.
  - `query` (string, required)
  - `searches` (integer, required)

Other responses:

- 401 (Problem) — unauthenticated — no key, or an unknown, revoked or expired one.
- 403 (Problem) — insufficient-scope — the key lacks a required scope.
- 404 (Problem) — not-found.
- 422 (Problem) — validation — a bad `range`.
- 429 (Problem) — rate-limited — the key's request budget is spent; wait Retry-After seconds.
- 500 (Problem) — internal.
