Find app ideas - niches ranked by opportunity score (demand, weak incumbents, competition, monetization, trend).
Use this when a user wants to know what app to build, or how attractive a niche is. Every niche of the App
Store and Google Play (an AI taxonomy of the catalog, e.g. "ADHD habit tracker") is scored weekly from 0 to
100 per store and country:
demand (30%: popularity of the niche's search keywords + ratings the niche holds),
supply_gap (30%: incumbents' rating, apps not updated for a year, a fragmented market, unhappy reviews),
competition (20%: ease, from keyword difficulty and the number of apps with 100k+ ratings),
monetization (10%: incumbents selling IAP / paid, top-grossing chart presence) and
trend (10%: ratings growth, share won by apps released in the last 2 years).
Every component lists its signals with the raw values; a signal without data is left out and confidence
(0–1) drops. Each item has the niche's top keywords (popularity, difficulty), its incumbents and their
complaints from AI-tagged reviews; the top 10 per store in the US also carry an analyst headline and
thesis. Filter by niche (id, slug or words like habit tracker) or category; page with cursor.
Then use GET /v1/keywords on top_keywords and GET /v1/apps/{app} on incumbents to dig deeper.
A page with no results costs nothing.
Request
curl "https://api.appgoat.ai/v1/opportunities" \
-H "x-api-key: $APPGOAT_API_KEY"const res = await fetch("https://api.appgoat.ai/v1/opportunities", {
headers: {
"x-api-key": process.env.APPGOAT_API_KEY,
},
});
const { data, meta } = await res.json();import os, requests
res = requests.get(
"https://api.appgoat.ai/v1/opportunities",
headers={"x-api-key": os.environ["APPGOAT_API_KEY"]}
)
body = res.json()Query parameters
nichestringhealth-fitness/adhd-habit-tracker) or words matched against niche names (habit tracker).categorystringHealth & Fitness, or health-fitness) or Play category (HEALTH_AND_FITNESS).store"apple" | "play"countrystringus; other markets where its keywords are measured (gb, de, …).Default "us"
min_scoreintegersort"score" | "demand" | "supply_gap" | "competition" | "monetization" | "trend" | "confidence"Default "score"
weekstringlimitintegerDefault 20
cursorstringmeta.next_cursor from the previous page.fieldsstringtitle,rating,version.Response
200 with data: Opportunity[]. See the envelope for meta.
idintegerrankintegernicheobjectniche.idintegerniche.slugstringniche.labelstringniche.descriptionstring | nullniche.categorystring | nullstoreStorecountrystringweekstringscorenumberconfidencenumberapp_countintegerheadlinestring | nullthesisstring | nullcomponentsobjectcomponents.demandOpportunityComponentcomponents.supply_gapOpportunityComponentcomponents.competitionOpportunityComponentcomponents.monetizationOpportunityComponentcomponents.trendOpportunityComponenttop_keywordsobject[]top_keywords[].termstringtop_keywords[].popularityinteger | nulltop_keywords[].difficultyinteger | nulltop_keywords[].source"serp" | "seed"top_keywords[].niche_sharenumberincumbentsobject[]incumbents[].app_idstringincumbents[].titlestring | nullincumbents[].developer_namestring | nullincumbents[].icon_urlstring | nullincumbents[].ratingnumber | nullincumbents[].ratings_countinteger | nullincumbents[].updated_atstring | nullincumbents[].days_since_updateinteger | nullincumbents[].released_atstring | nullincumbents[].has_iapboolean | nullincumbents[].iap_pricesstring[]incumbents[].pricenumber | nullincumbents[].in_top_grossingbooleancomplaintsobject[]complaints[].labelstringcomplaints[].reviewsintegerstatsobject{
"data": [
{
"id": 1,
"rank": 1,
"niche": {
"id": 1,
"slug": "health-fitness/adhd-habit-tracker",
"label": "ADHD habit tracker",
"description": "string",
"category": "string"
},
"store": "apple",
"country": "us",
"week": "2026-10-22",
"score": 4.5,
"confidence": 4.5,
"app_count": 1,
"headline": "string",
"thesis": "string",
"components": {
"demand": {},
"supply_gap": {},
"competition": {},
"monetization": {},
"trend": {}
},
"top_keywords": [
{}
],
"incumbents": [
{}
],
"complaints": [
{}
],
"stats": {}
}
],
"meta": {
"credits_used": 50,
"credits_remaining": 9981,
"request_id": "req_123"
}
}Status codes
meta.week = the Monday of the computation).error.param names it).insufficient_credits (the call costs more than you have left; nothing was done) or plan_limit (a feature of a higher plan).not_foundrate_limited