GET /v1/brands/{brand_id}/content-opportunities

List content opportunities

Report-driven content ideas for the brand: prompts where the brand is absent from AI answers (missed_prompt) plus competitors cited in its place (competitor), each pre-classified to a content format and pre-filled with topic, keywords, and context.

Ranked with not-yet-covered opportunities first, then by impact. Filter with kind and search (every word must appear in the title, topic, keywords or competitor, ignoring case and accents), order with sort and order, and page with limit (1-50, default 24) and offset while has_more; total is the size of the filtered set. Each row carries metrics with the search volume, Google and AI difficulty and Search Console numbers behind its score.

The set is computed on the first read of a brand and stored; summary.refresh_available says when newer data would change it.

Path parameters

Query parameters

  • limit integer optional

    Number of opportunities to return (1-50, default 24).

    default: 24

  • offset integer optional

    Opportunities to skip, for the next page.

    default: 0

  • sort string (enum) optional

    score with order=desc ranks uncovered opportunities first, then by impact.

    one of score, title, source · default: score

  • order string (enum) optional

    Sort direction.

    one of asc, desc · default: desc

  • kind string optional

    Only opportunities of this kind.

  • content_type string optional

    Only opportunities suggesting this format (e.g. ranked_list).

  • dry_run boolean optional

    Preview the call without executing it. Runs auth, scope, eligibility and body validation, then returns 200 with a dry_run object reporting the request-unit and credit cost plus a non-consuming quota snapshot. Nothing is debited, reserved, dispatched or mutated. An invalid body still returns 422.

    default: false

Responses

Returned content opportunities application/json
Type: ContentOpportunityList
  • data array of ContentOpportunity required
  • has_more boolean required

    True when more items exist past this page. Fetch them with a larger offset.

  • limit integer required

    Page size that was applied.

    min: 1

  • offset integer required

    Number of items skipped before this page.

    min: 0

  • summary ContentOpportunitySummary required

    Aggregate counts for the opportunity set.

    Show fields
    Type: ContentOpportunitySummary
    • actionable integer required

      Opportunities in the whole stored set, of any kind, not yet covered by a brief.

      min: 0

    • competitors integer required

      Distinct competitors cited where the brand is absent.

      min: 0

    • missed_prompts integer required

      Distinct prompts where the brand is absent from AI answers.

      min: 0

    • opportunities integer required

      Opportunities returned in data (bounded by limit).

      min: 0

    • prompts_analyzed integer required

      Prompts actually examined across those reports.

      min: 0

    • reports_analyzed integer required

      Recent reports scanned to build these opportunities.

      min: 0

    • computed_at string (nullable) nullable

      When this set was last computed.

    • object string

      Always content_opportunity_summary.

      default: `content_opportunity_summary`

    • true when the data the set was built from has moved since computed_at (a new report, a Search Console or keyword gap refresh, tracked keywords or articles changed).

      default: `false`

    • total integer (nullable) nullable

      Opportunities matching the kind filter across the whole stored set. Page with offset.

  • total integer required

    Total number of items matching the query, across all pages.

    min: 0

  • object string

    default: `list`

Example response
{
  "data": [
    {
      "competitor": "Asana",
      "content_context": {
        "listSize": 7,
        "listTheme": "project management tools for agencies"
      },
      "content_type": "ranked_list",
      "has_existing_brief": false,
      "id": "prompt:9a17c4f8-4e31-92fa-7d1e-3b5c8b2a9a17",
      "kind": "missed_prompt",
      "metrics": {
        "ai_difficulty": 58,
        "keyword_difficulty": 34,
        "object": "content_opportunity_metrics",
        "search_volume": 1900
      },
      "object": "content_opportunity",
      "platforms_missed": [
        "ChatGPT",
        "Perplexity"
      ],
      "reason": "You are absent on ChatGPT, Perplexity; Asana is cited instead.",
      "score": 71,
      "score_reasons": [
        "1,900 searches a month",
        "Absent on 2 of 3 AI engines",
        "Asana is cited instead"
      ],
      "source": "Missed prompt",
      "target_keywords": [
        "best project management tools for agencies"
      ],
      "title": "best project management tools for agencies",
      "topic": "What are the best project management tools for agencies?"
    }
  ],
  "has_more": false,
  "limit": 24,
  "object": "list",
  "offset": 0,
  "summary": {
    "actionable": 21,
    "competitors": 6,
    "missed_prompts": 42,
    "object": "content_opportunity_summary",
    "opportunities": 24,
    "prompts_analyzed": 137,
    "reports_analyzed": 10,
    "total": 57
  },
  "total": 1
}
Request validation failed application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "validation_error",
    "message": "Request validation failed"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
Missing or invalid credentials application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "unauthorized",
    "message": "Missing or invalid credentials"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
You do not have permission to access this resource application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "forbidden",
    "message": "You do not have permission to access this resource"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
Resource not found application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "not_found",
    "message": "Resource not found"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
Resource conflict application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "conflict",
    "message": "Resource conflict"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
Per-minute rate limit exceeded application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Per-minute rate limit exceeded"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
An unexpected error occurred application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "internal_error",
    "message": "An unexpected error occurred"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}
Service temporarily unavailable, please retry application/json
Type: ApiError
  • error object required
    Show fields
    • code string required

      Stable machine-readable error code from the catalog.

    • message string required

      Human-readable description suitable for logging.

    • details object

      Optional, code-specific context (e.g. errors array for validation_error, retry_after for service_unavailable). Shape depends on error.code; treat as opaque otherwise.

      Show fields

      Empty object (no properties).

  • Server-generated correlation id for the request. Mirrors the X-Correlation-ID response header. Include this when contacting support.

    format: `uuid`

Example response
{
  "error": {
    "code": "service_unavailable",
    "message": "Service temporarily unavailable, please retry"
  },
  "request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}