---
title: "Industry content demand for a site's vertical"
method: GET
path: "/cms/demand/industry"
tags: ["CMS"]
---

# Industry content demand for a site's vertical

`GET /cms/demand/industry`

## Request

- Base URL: `https://next.frase.io/api/v1`
- URL: `https://next.frase.io/api/v1/cms/demand/industry`
- Auth: API key in header `X-API-KEY`

"What your industry is asking" — trending topics across the site's vertical, demand-ranked and annotated with whether this organization already covers each one. The vertical-level companion to `GET /cms/demand`, which is per-site. Requires the `read:analytics` scope; the site must belong to the authenticated organization or the call is a 404. Cross-organization demand is k-anonymity gated by the same composer the in-app Insights card uses: only cleared, labelled, non-outlier cells are returned, and the payload deliberately carries no peer count, organization count or k value — just the topic label, a relative demand score, its trend, and the viewer's own coverage. When there is no vertical, no Answers data or no cleared cell, `industry_demand` is `null` (the same "card hidden" state the UI shows), never an error; an internal read fault degrades to `null` too.

## Query parameters

- `site_id` string, uuid, required

## Response `200`

Industry demand for the site's vertical, or null when none is available.

- object
  - `data` object
    - `industry_demand` object, nullable
      - `vertical` string: The organization's vertical (for example `saas_software`).
      - `topics` object[]: Trending industry topics, demand-ranked.
        - `topic_id` string: Opaque cell join key (an HMAC of the normalized topic). Stable and safe to store.
        - `topic` string: Human-readable topic, labelled only for k-anonymity-cleared, non-outlier cells.
        - `demand_score` number: Relative cross-organization demand for the topic. Never a peer or organization count.
        - `demand_trend` number, nullable: Period-over-period change in demand. Computed only for the preview subset of uncovered gap topics (a deliberate privacy/perf bound) - every covered topic and every non-preview topic is null by construction, so null does NOT mean the topic is new.
        - `covered` boolean: True when this organization already has a question cluster covering the topic; false means it is a gap.
        - `cluster_id` string, uuid, nullable: This organization's own cluster for the topic, or null when it is a gap.

## Other responses

- `400`: Validation failed
- `401`: Authentication failed
- `403`: Forbidden - action not allowed on this resource
- `404`: Resource not found
- `429`: Rate limit exceeded
- `500`: Unexpected failure reading industry demand.

---

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