Developer docs

List content ideas

GET/sites/{siteId}/competitors/content-ideas
Scope
search:read

Content ideas: keyword gaps grouped by topic The keyword gaps (competitors rank, we do not; off-topic and competitor-brand keywords left out) grouped by topic, most opportunity first; topic null holds keywords not reviewed yet. suggestion: new_page (no page of ours ranks in the topic), expand (ourPages already rank in it) or review. Reads the stored monthly gap refresh: no new lookups. Also accepted in snake_case (min_volume for minVolume).

Parameters

NameInDetails
siteIdRequiredpathstringWebsite id, from GET /sites.
domainsquerystringComma-separated competitor domains, each in the set. Default: the ones the Keyword gaps table compares (the competitors that drive gaps and have data, at most three).
minVolumequeryintegermin 0, max 10000000Only keywords with at least this many monthly searches. Also accepted in snake_case (min_volume for minVolume).
maxDifficultyqueryintegermin 0, max 100Only keywords at most this hard (0–100; 0 = no limit).
keywordsqueryintegerdefault 5, min 1, max 50Top keywords listed per topic.
pagequeryintegerdefault 1, min 1Page number, from 1.
perqueryintegerdefault 20, min 1, max 200Topics per page, 1 to 200.

Response

200 · application/json

FieldDetails
domainslist of string · required; The competitors compared
totalinteger · required; Rows that match, over all pages
pageinteger · required; This page, from 1
perinteger · required; Rows per page
hasMoretrue or false · required; More rows after this page
gapKeywordsinteger · required; Gap keywords over all topics
hiddenKeywordsinteger · required; Off-topic and competitor-brand keywords left out
topicslist of object · required
topics[].topicstring or null · required; The topic; null: keywords not reviewed yet
topics[].keywordsinteger · required; Gap keywords in the topic
topics[].volumeinteger · required; Monthly searches summed (estimate)
topics[].opportunityinteger · required; Sum of the keywords' opportunity
topics[].bestOpportunityinteger · required; The highest keyword opportunity, 0–100
topics[].avgDifficultyinteger or null · required; Average difficulty, 0–100
topics[].suggestionnew_page | expand | review · required; What to do
topics[].ourPageslist of object · required; Our pages already ranking in the topic (at most 5)
topics[].ourPages[].urlstring · required; Page address
topics[].ourPages[].pathstring · required; Path of the address
topics[].ourPages[].keywordsinteger · required; Keywords of the topic it ranks for
topics[].competitorPageslist of object · required; Competitor pages ranking for most of the topic (at most 5)
topics[].competitorPages[].urlstring · required; Page address
topics[].competitorPages[].pathstring · required; Path of the address
topics[].competitorPages[].keywordsinteger · required; Keywords of the topic it ranks for
topics[].toplist of object · required; The best keywords of the topic
topics[].top[].keywordstring · required; The search phrase
topics[].top[].volumeinteger or null · required; Monthly searches (estimate)
topics[].top[].difficultyinteger or null · required; How hard it is to rank, 0–100
topics[].top[].opportunityinteger · required; 0–100
topics[].top[].relevanceinteger or null · required; Fit with the website, 0–100
topics[].top[].positionsobject · required; Each competitor's Google position, by domain
topics[].top[].positions.bikeworld.examplenumber
topics[].top[].positions.cyclehub.examplenumber
topics[].top[].pagesobject · required; Each competitor's ranking page, by domain
topics[].top[].pages.bikeworld.examplestring
topics[].top[].pages.cyclehub.example
notestring · required; How to read the numbers
linkaddress (URL) · required; The Competitors screen in the app

Errors

StatusMeaning
400Bad request. Codes: unknown_competitor, bad_keywords, bad_minVolume, bad_maxDifficulty, bad_page, bad_per.
401Missing, unknown or revoked key. Codes: missing_key, invalid_key.
403The key lacks the scope, covers another website, or its owner lost access. Codes: missing_scope, other_site, owner_left, no_owner, forbidden.
404Not found. Codes: not_found.
429Too many requests this hour for this key. Codes: rate_limited.

Example request

curl \
  -H "Authorization: Bearer mr_ws_…" \
  "https://app.monoranks.com/api/v1/sites/SITE_ID/competitors/content-ideas"

Example response

{
  "domains": [
    "bikeworld.example",
    "cyclehub.example"
  ],
  "total": 12,
  "page": 1,
  "per": 20,
  "hasMore": false,
  "gapKeywords": 318,
  "hiddenKeywords": 23,
  "topics": [
    {
      "topic": "Tires",
      "keywords": 24,
      "volume": 18400,
      "opportunity": 1210,
      "bestOpportunity": 74,
      "avgDifficulty": 31,
      "suggestion": "expand",
      "ourPages": [
        {
          "url": "https://acmebikes.com/tires/gravel/",
          "path": "/tires/gravel/",
          "keywords": 6
        }
      ],
      "competitorPages": [
        {
          "url": "https://bikeworld.example/tires/tubeless/",
          "path": "/tires/tubeless/",
          "keywords": 9
        }
      ],
      "top": [
        {
          "keyword": "tubeless gravel tires",
          "volume": 1900,
          "difficulty": 28,
          "opportunity": 74,
          "relevance": 90,
          "positions": {
            "bikeworld.example": 4,
            "cyclehub.example": 9
          },
          "pages": {
            "bikeworld.example": "https://bikeworld.example/tires/tubeless/",
            "cyclehub.example": null
          }
        }
      ]
    }
  ],
  "note": "Keyword gaps grouped by topic, most opportunity first.",
  "link": "https://app.monoranks.com/sites/3f6c2a1e-8b4d-4c7a-9e21-5d0b7a6f4c13/competitors"
}

The MCP server does the same with the tool content_ideas.