{"openapi":"3.1.0","info":{"title":"AppGoat API","version":"1.0.0","summary":"App Store + Google Play data for agents and apps.","description":"Every app and developer in both stores, daily top charts, reviews, change feeds, metric history and keyword\n(search-rank) intelligence.\n\n**Conventions**\n- `{app}` accepts anything that identifies an app: an App Store id (`284882215`, `id284882215`), a Play\n  package (`com.spotify.music`), an Apple bundle id (`com.spotify.client`), a store URL, `apple:<id>` /\n  `play:<id>`, or a name (`spotify` → best match, with a warning in `meta.warnings`). Add `store=apple|play`\n  to disambiguate. `data.linked` is the same app in the other store when we know it.\n- Freshness is automatic: app-scoped reads refresh data older than `max_age` seconds from the store first\n  (1 credit per country fetched, capped at 10). `wait=true` (default) blocks up to ~25 s; on timeout, or with\n  `wait=false`, you get the cached data with `meta.freshness.refreshing: true` and a `job_id` to poll at\n  `GET /v1/jobs/{id}` (free).\n- `country` defaults to `us`; pass a comma list (paid plans) or `all` (Studio).\n- `include=` adds sections, `fields=` keeps only the listed top-level fields, lists page with `cursor`\n  (pass `meta.next_cursor` back unchanged).\n- Every success is `{ data, meta }`; `meta.credits_used` is what the call cost and `meta.credits_remaining`\n  what is left. Errors are `{ error: { code, message, hint, docs } }`: read `hint`, it says what to do next.\n- `x-credits` on each operation documents its price.\n- Watches turn store changes into events: `POST /v1/watches`, then poll `GET /v1/events` or add a webhook\n  (`POST /v1/webhooks`). Watches, events and webhooks are free; only the plan's watched-app and keyword-slot\n  limits apply. `/v1/tracked-keywords` is deprecated: use keyword watches.\n","contact":{"email":"support@appgoat.ai","url":"https://appgoat.ai"}},"servers":[{"url":"https://api.appgoat.ai/v1"}],"security":[{"apiKey":[]}],"tags":[{"name":"Apps"},{"name":"Search & charts"},{"name":"Keywords"},{"name":"Developers"},{"name":"Audits"},{"name":"Watches & events","description":"Watch apps, competitors and keywords; significant changes become events (feed, webhooks, Slack, GitHub, daily email digest)."},{"name":"Webhooks"},{"name":"Connections"},{"name":"Actions"},{"name":"Opportunities"},{"name":"Jobs"},{"name":"Account"}],"paths":{"/apps/{app}":{"get":{"operationId":"getApp","tags":["Apps"],"summary":"Get everything about one app (metadata, ratings, price, markets, linked app in the other store).","description":"Use this first when a user mentions an app. Pass any identifier or a name in `{app}`. Data older than\n`max_age` (default 7 days) is refreshed from the store; an app we never saw is fetched on the spot (if it\nis still being fetched after ~25 s you get HTTP 202 with `data: null` and a `job_id`).\n`include` adds sections: `markets` (every storefront), `iap` (in-app purchases), `versions` (version\nhistory with release notes), `privacy` (App Store privacy labels), `estimates` (modelled downloads /\nrevenue), `charts` (current top-chart positions), `summary` (AI summary, coming soon).\n","x-credits":"1 + 1 per country refreshed from the store (max 10)","parameters":[{"$ref":"#/components/parameters/App"},{"$ref":"#/components/parameters/StoreHint"},{"$ref":"#/components/parameters/Country"},{"name":"include","in":"query","description":"Comma list of extra sections.","schema":{"type":"string","example":"versions,iap"}},{"$ref":"#/components/parameters/MaxAgeApp"},{"$ref":"#/components/parameters/Wait"},{"$ref":"#/components/parameters/Fields"}],"responses":{"200":{"description":"The app.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/App"}}}]},"example":{"data":{"store":"apple","app_id":"324684580","bundle_id":"com.spotify.client","title":"Spotify: Music and Podcasts","developer":{"id":"324684583","name":"Spotify"},"rating":4.78,"ratings_count":42668141,"version":"9.1.92","markets":[{"country":"us","available":true,"price":0,"currency":"USD","rating":4.78,"ratings_count":42668141,"version":"9.1.92","fetched_at":"2026-10-22T15:03:07Z"}],"linked":{"store":"play","app_id":"com.spotify.music","title":"Spotify: Music and Podcasts","icon_url":"https://…","match":"developer"}},"meta":{"credits_used":1,"credits_remaining":9981,"store":"apple","freshness":{"fetched_at":"2026-10-22T15:03:07Z","age_seconds":3600,"stale":false,"refreshing":false,"job_id":null},"request_id":"req_123"}}}}},"202":{"$ref":"#/components/responses/Fetching"},"400":{"$ref":"#/components/responses/InvalidParam"},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/AppNotFound"}}}},"/apps/{app}/reviews":{"get":{"operationId":"listReviews","tags":["Apps"],"summary":"List an app's user reviews, newest first, with filters (rating, version, date, text).","description":"Up to 100 reviews per page (1 credit per page). Combine `rating=1-2` with `since` to find recent\ncomplaints, `q` for full-text search, `version` to see what users say about a release. The latest US\nreviews are refreshed when older than `max_age` (default 1 day). AI tags (`sentiment`, `intent`,\n`severity`, `topic`) are filled for tagged reviews (popular apps first) and null otherwise; filtering by\nthem excludes untagged reviews. `intent=bug,crash&since=…` is the \"what broke in the last release\" query.\n","x-credits":"1 per page + 1 if the US reviews are refreshed","parameters":[{"$ref":"#/components/parameters/App"},{"$ref":"#/components/parameters/StoreHint"},{"$ref":"#/components/parameters/Country"},{"name":"rating","in":"query","description":"Star rating filter, `1`, `1,2` or a range `1-3`.","schema":{"type":"string","example":"1-2"}},{"name":"version","in":"query","description":"Only reviews written for this app version.","schema":{"type":"string"}},{"$ref":"#/components/parameters/Since"},{"name":"until","in":"query","description":"Only reviews created before this ISO date / datetime.","schema":{"type":"string","format":"date-time"}},{"name":"q","in":"query","description":"Case-insensitive text search in the title and body.","schema":{"type":"string","example":"crash"}},{"name":"sentiment","in":"query","description":"AI sentiment filter (comma list): positive, neutral, negative.","schema":{"type":"string","example":"negative"}},{"name":"intent","in":"query","description":"AI intent filter (comma list): bug, crash, feature_request, pricing, ux, praise, spam, other.","schema":{"type":"string","example":"bug,crash"}},{"name":"topic","in":"query","description":"AI topic filter (comma list of topic labels, case-insensitive, or topic ids).","schema":{"type":"string"}},{"$ref":"#/components/parameters/MaxAgeReviews"},{"$ref":"#/components/parameters/Wait"},{"$ref":"#/components/parameters/Limit100"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Fields"}],"responses":{"200":{"description":"A page of reviews.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Review"}}}}]}}}},"400":{"$ref":"#/components/responses/InvalidParam"},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/AppNotFound"}}}},"/apps/{app}/history":{"get":{"operationId":"getAppHistory","tags":["Apps"],"summary":"Get an app's daily metric history (rating, ratings count, installs, star histogram, price).","description":"One row per country and day **on which a value changed** — carry the previous row forward for the days\nin between. Defaults to the last 90 days. Use it to chart growth or spot rating drops.\n","x-credits":"1 + 1 per country refreshed (max 10)","parameters":[{"$ref":"#/components/parameters/App"},{"$ref":"#/components/parameters/StoreHint"},{"$ref":"#/components/parameters/Country"},{"name":"from","in":"query","description":"Start date (ISO), default 90 days before `to`.","schema":{"type":"string","format":"date"}},{"name":"to","in":"query","description":"End date (ISO), default today.","schema":{"type":"string","format":"date"}},{"$ref":"#/components/parameters/MaxAgeApp"},{"$ref":"#/components/parameters/Wait"}],"responses":{"200":{"description":"Metric rows, by country then date.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/HistoryPoint"}}}}]}}}},"400":{"$ref":"#/components/responses/InvalidParam"},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/AppNotFound"}}}},"/apps/{app}/changes":{"get":{"operationId":"listAppChanges","tags":["Apps"],"summary":"List what changed in an app's store listing (version, title, subtitle, screenshots, price, IAP, …).","description":"Typed change feed, newest first: one entry per changed field with `old` and `new` values. Fields include\nversion, release_notes, title, subtitle, description, screenshots, icon, price, iap, iap_range, privacy,\nin_app_events, badges, featured, editors_choice, installs, content_rating, developer. Ideal for competitor\nmonitoring (\"what did X change this month?\").\n","x-credits":"1 + 1 if the US listing is refreshed","parameters":[{"$ref":"#/components/parameters/App"},{"$ref":"#/components/parameters/StoreHint"},{"name":"country","in":"query","description":"Only changes seen in these storefronts (comma list). Default all storefronts.","schema":{"type":"string"}},{"name":"field","in":"query","description":"Only these fields (comma list), e.g. `version,title,subtitle`.","schema":{"type":"string"}},{"$ref":"#/components/parameters/Since"},{"$ref":"#/components/parameters/MaxAgeApp"},{"$ref":"#/components/parameters/Wait"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"Changes, newest first.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Change"}}}}]}}}},"400":{"$ref":"#/components/responses/InvalidParam"},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/AppNotFound"}}}},"/apps/{app}/keywords":{"get":{"operationId":"listAppKeywords","tags":["Apps"],"summary":"List the search keywords an app ranks for, best rank first, with popularity and difficulty.","description":"From the latest ranking we hold for each term: our keyword universe (re-ranked weekly, top 50) plus your\nown tracked keywords (`source: tracked`). Use it for ASO audits and to find keyword gaps against a\ncompetitor (call it for both apps and compare).\n","x-credits":1,"parameters":[{"$ref":"#/components/parameters/App"},{"$ref":"#/components/parameters/StoreHint"},{"$ref":"#/components/parameters/Country"},{"name":"max_rank","in":"query","description":"Only terms where the app ranks at or above this position.","schema":{"type":"integer","minimum":1,"maximum":500}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":100}},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"Ranked terms.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AppKeyword"}}}}]}}}},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/AppNotFound"}}}},"/apps/{app}/competitors":{"get":{"operationId":"listCompetitors","tags":["Apps"],"summary":"Find an app's competitors (store \"similar apps\" plus apps ranking for the same keywords).","description":"Scored list: `shared_keywords` (search terms both apps rank for) counts most, the store's own similar-apps\nlist (`similar_position`) adds a boost. Feed the result into `getApp` / `listAppChanges` for a\ncompetitor digest.\n","x-credits":1,"parameters":[{"$ref":"#/components/parameters/App"},{"$ref":"#/components/parameters/StoreHint"},{"$ref":"#/components/parameters/Country"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Competitors, best first.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Competitor"}}}}]}}}},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/AppNotFound"}}}},"/apps/{app}/insights":{"get":{"operationId":"getAppInsights","tags":["Apps"],"summary":"Review intelligence for an app - top issues with trends and samples, topics per version, weekly sentiment.","description":"Built from the AI tags on every review (sentiment, intent, severity, topic). `top_issues` are topics carried\nby negative / bug / crash / UX / pricing reviews, with `last_30d` vs `prev_30d` counts and sample reviews;\n`versions` shows what each release changed in sentiment and topics; `sentiment_over_time` is weekly. Use it\nfor \"what do users complain about since v2.3?\" or a reviews → GitHub issues playbook. Reviews not tagged yet\nonly count in the totals (`tagged` < `reviews`, see `meta.warnings`).\n","x-credits":25,"parameters":[{"$ref":"#/components/parameters/App"},{"$ref":"#/components/parameters/StoreHint"},{"name":"country","in":"query","description":"One storefront; omit for every storefront we hold reviews for.","schema":{"type":"string"}},{"name":"since_days","in":"query","schema":{"type":"integer","minimum":7,"maximum":730,"default":180}},{"name":"versions","in":"query","description":"How many of the latest versions to break down.","schema":{"type":"integer","minimum":1,"maximum":20,"default":6}}],"responses":{"200":{"description":"Insights.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Insights"}}}]}}}},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/AppNotFound"}}}},"/apps/{app}/audit":{"post":{"operationId":"runAppAudit","tags":["Audits"],"summary":"Run an App Audit - prioritised ASO actions, metadata rewrites and findings with evidence (first one free).","description":"Refreshes the listing, tags recent reviews, probes ~20 search terms (popularity, difficulty, the app's\nrank, relevance), compares competitors, then writes a prioritised report: `report.actions` (what to do\nfirst, with the evidence and a playbook), `report.metadata` (title / subtitle / keyword-field rewrites\nwithin the character limits) and `report.findings` (deterministic checks with numbers). Every statement\nin the narrative is checked against the measured facts; unsupported ones are dropped.\nTakes 1-3 minutes: with `wait=true` (default) the call blocks up to ~25 s, then answers 202 with the audit\n`id`; poll `GET /v1/audits/{id}` (free). The shareable page is `url` (appgoat.ai/r/..., not indexed).\nAn audit of the same app, country and mode from the last 24 h is returned again for 0 credits unless\n`fresh=true`.\nFailed audits are never charged: one that fails within `wait` costs 0, one that fails after the 202 is\nrefunded automatically (the refund shows on the same request in your usage logs).\n","x-credits":"100 (the first audit of an organization is free)","parameters":[{"$ref":"#/components/parameters/App"},{"$ref":"#/components/parameters/StoreHint"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"country":{"type":"string","default":"us","description":"One storefront."},"mode":{"type":"string","enum":["full","lite"],"default":"full","description":"lite = cached data, fewer reviews and keywords (cheaper and faster for us; same price)."},"wait":{"type":"boolean","default":true},"fresh":{"type":"boolean","default":false,"description":"Run again even if a recent audit exists."},"free_only":{"type":"boolean","default":false,"description":"Only run when it is the free first audit (402 free_audit_used otherwise)."},"white_label":{"type":"boolean","default":false,"description":"Studio: the report page carries your branding (brand name, logo, accent colour, CTA, footer; set them in the dashboard under Settings → Report branding) instead of AppGoat's. 402 plan_limit on other plans. Re-using a recent audit applies the branding to it for 0 credits."},"label":{"type":["string","null"],"maxLength":80,"description":"Your label for the audit list, e.g. the client or prospect name."}}}}}},"responses":{"200":{"description":"The finished audit (or a recent one re-used).","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Audit"}}}]}}}},"202":{"description":"Still running; poll `GET /v1/audits/{data.id}`.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Audit"}}}]}}}},"400":{"$ref":"#/components/responses/InvalidParam"},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/AppNotFound"}}}},"/search":{"get":{"operationId":"searchApps","tags":["Search & charts"],"summary":"Search the catalog (~5M apps in both stores) by app name or id.","description":"Exact title matches first, then prefix, then substring; most ratings first within each group.","x-credits":1,"parameters":[{"name":"q","in":"query","required":true,"description":"App name (≥ 2 characters) or exact id.","schema":{"type":"string","example":"photo editor"}},{"name":"store","in":"query","schema":{"$ref":"#/components/schemas/Store"}},{"name":"category","in":"query","description":"Store category name, e.g. `Photo & Video` (App Store) or `PHOTOGRAPHY` (Play).","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Fields"}],"responses":{"200":{"description":"Matching apps.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AppCard"}}}}]}}}},"400":{"$ref":"#/components/responses/InvalidParam"},"402":{"$ref":"#/components/responses/PaymentRequired"}}}},"/charts":{"get":{"operationId":"getChart","tags":["Search & charts"],"summary":"Get a top chart (free, paid, grossing) for a store, country and category, today or on a past date.","description":"Entries carry `delta` (positions gained since the previous changed capture; negative = dropped) and\n`is_new`; `dropped` lists apps that fell out. Charts are captured daily for every country × category.\n","x-credits":1,"parameters":[{"name":"store","in":"query","schema":{"$ref":"#/components/schemas/Store","default":"apple"}},{"name":"country","in":"query","schema":{"type":"string","default":"us"}},{"name":"chart","in":"query","schema":{"type":"string","enum":["free","paid","grossing"],"default":"free"}},{"name":"category","in":"query","description":"App Store genre id (`36` or `all` = all apps, `6014` = games, …) or Play category (`GAME_PUZZLE`; `APPLICATION` = all apps).","schema":{"type":"string"}},{"name":"date","in":"query","description":"The chart as of this date (ISO). Default the latest capture.","schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":100}}],"responses":{"200":{"description":"The chart.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Chart"}}}]}}}},"400":{"$ref":"#/components/responses/InvalidParam"},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/keywords":{"get":{"operationId":"getKeywords","tags":["Keywords"],"summary":"Get keyword metrics (popularity, difficulty) for up to 25 terms; with include=related, keyword research.","description":"`popularity` is 5–100 (search volume proxy; `popularity_source: apple` = Apple Search Ads data),\n`difficulty` 0–100 (how entrenched the top 10 is), `est_downloads_at_1` the modelled daily downloads of the\n#1 result. Terms not measured in the last 7 days are measured live (≤ 5 per call, 2–5 s each) when\n`wait=true`; others return `pending: true` — call again in a minute.\n`include=related` adds ~10 related terms with their metrics, `suggestions` the store's autocomplete,\n`top_apps` the current top 10 apps. Pass `app=` to get that app's rank and a metadata `relevance` (0–1) for\nevery term — the core of an ASO keyword audit.\n","x-credits":"1 per keyword; 5 per seed with include=related or suggestions","parameters":[{"name":"q","in":"query","description":"One term. Use `qs` for several.","schema":{"type":"string","example":"photo editor"}},{"name":"qs","in":"query","description":"Comma-separated terms (≤ 25; ≤ 5 with related / suggestions).","schema":{"type":"string","example":"photo editor,collage maker"}},{"name":"store","in":"query","description":"Required unless `app` is given.","schema":{"$ref":"#/components/schemas/Store"}},{"name":"country","in":"query","schema":{"type":"string","default":"us"}},{"name":"include","in":"query","description":"Comma list: related, suggestions, top_apps.","schema":{"type":"string"}},{"name":"app","in":"query","description":"Any app identifier (as in `{app}`); adds `app.rank` and `app.relevance` per term.","schema":{"type":"string"}},{"$ref":"#/components/parameters/Wait"}],"responses":{"200":{"description":"One entry per term, in request order.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Keyword"}}}}]},"example":{"data":[{"term":"photo editor","store":"apple","country":"us","popularity":62,"popularity_source":"proxy","difficulty":81,"results_count":200,"est_downloads_at_1":2900,"measured_at":"2026-10-20T10:00:00Z","pending":false,"top_app_ids":["1","2"],"app":{"store":"apple","app_id":"1","rank":14,"relevance":1}}],"meta":{"credits_used":1,"store":"apple"}}}}},"400":{"$ref":"#/components/responses/InvalidParam"},"402":{"$ref":"#/components/responses/PaymentRequired"}}}},"/tracked-keywords":{"get":{"operationId":"listTrackedKeywords","deprecated":true,"tags":["Keywords"],"summary":"List your tracked keywords with their latest top 10.","x-credits":0,"parameters":[{"name":"store","in":"query","schema":{"$ref":"#/components/schemas/Store"}},{"name":"country","in":"query","schema":{"type":"string"}},{"name":"q","in":"query","description":"Substring filter on the term.","schema":{"type":"string"}}],"responses":{"200":{"description":"Tracked keywords.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TrackedKeyword"}}}}]}}}}}},"post":{"operationId":"trackKeywords","deprecated":true,"tags":["Keywords"],"summary":"Start tracking search ranks for keywords (daily re-rank; idempotent).","description":"Each (term × store × country) uses one keyword slot of your plan; a request that would exceed it tracks nothing and returns 402 plan_limit.","x-credits":0,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["store"],"properties":{"term":{"type":"string"},"terms":{"type":"array","items":{"type":"string"},"maxItems":500},"store":{"type":"string","enum":["apple","play","both"]},"countries":{"type":"array","items":{"type":"string"},"default":["us"]},"depth":{"type":"integer","description":"How many results to keep per ranking (default 100 Apple / 50 Play)."},"cadenceMinutes":{"type":"integer","description":"Minutes between re-ranks (paid plans can go below 1440)."},"tags":{"type":"array","items":{"type":"string"}}}},"example":{"terms":["photo editor","collage maker"],"store":"both","countries":["us","gb"]}}}},"responses":{"201":{"description":"One row per tracked (store, country, term).","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"store":{"$ref":"#/components/schemas/Store"},"country":{"type":"string"},"term":{"type":"string"},"created":{"type":"boolean","description":"false = you already tracked it."}}}}}}]}}}},"400":{"$ref":"#/components/responses/InvalidParam"},"402":{"$ref":"#/components/responses/PaymentRequired"}}}},"/tracked-keywords/{id}":{"parameters":[{"$ref":"#/components/parameters/TrackedKeywordId"}],"get":{"operationId":"getTrackedKeyword","deprecated":true,"tags":["Keywords"],"summary":"Get one tracked keyword and its latest top 10.","x-credits":0,"responses":{"200":{"description":"The tracked keyword.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/TrackedKeyword"}}}]}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"operationId":"updateTrackedKeyword","deprecated":true,"tags":["Keywords"],"summary":"Change a tracked keyword's depth, cadence or tags.","x-credits":0,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"depth":{"type":"integer"},"cadenceMinutes":{"type":"integer"},"tags":{"type":["array","null"],"items":{"type":"string"}}}}}}},"responses":{"200":{"description":"The updated tracked keyword.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/TrackedKeyword"}}}]}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"operationId":"untrackKeyword","deprecated":true,"tags":["Keywords"],"summary":"Stop tracking a keyword (frees its slot).","x-credits":0,"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"object","properties":{"deleted":{"type":"boolean"}}}}}]}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/tracked-keywords/{id}/ranks":{"get":{"operationId":"getTrackedKeywordRanks","tags":["Keywords"],"summary":"Get a tracked keyword's ranking history (or one app's rank over time with app=).","x-credits":1,"parameters":[{"$ref":"#/components/parameters/TrackedKeywordId"},{"name":"from","in":"query","description":"Default 90 days ago.","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"app","in":"query","description":"Store app id; returns `rank` per point instead of the full id list.","schema":{"type":"string"}}],"responses":{"200":{"description":"One point per capture.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"type":"object","properties":{"at":{"type":"string","format":"date-time"},"changed":{"type":"boolean"},"rank":{"type":["integer","null"]},"appIds":{"type":"array","items":{"type":"string"}}}}}}}]}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/tracked-keywords/{id}/run":{"post":{"operationId":"runTrackedKeyword","tags":["Keywords"],"summary":"Re-rank a tracked keyword now instead of waiting for the next scheduled run (paid plans).","description":"If it was ranked within the last hour you get that ranking back (200, `queued:false`, free) instead.","x-credits":"1 when queued, 0 when the last hour's ranking is returned","parameters":[{"$ref":"#/components/parameters/TrackedKeywordId"}],"responses":{"200":{"description":"Ranked recently; the latest ranking.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"202":{"description":"Queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/developers":{"get":{"operationId":"listDevelopers","tags":["Developers"],"summary":"Find app developers to pitch - a filtered lead list with each developer's best scored business email (Studio plan).","description":"Developer lead lists (Studio). Filter by store, top category, country, total ratings range, app count, last\napp update and email quality; page with `cursor`. Each row has the developer's profile, reach and the best\nbusiness contact we found and scored (`email`, `email_score` 0-100, `email_role`, `email_mx_ok`). Personal\naddresses, addresses that failed the MX check or opted out, and developers who asked not to be contacted are\nnever returned. 1 credit per page (up to 500 rows). Other plans get 402 `plan_limit`; `GET /v1/developers/{dev}`\nworks on every plan.\n","x-credits":"1 per page","parameters":[{"name":"store","in":"query","schema":{"$ref":"#/components/schemas/Store"}},{"name":"q","in":"query","description":"Name substring, exact domain or developer id.","schema":{"type":"string"}},{"name":"category","in":"query","description":"The developer's top category (as in the store, e.g. Productivity, GAME_PUZZLE).","schema":{"type":"string"}},{"name":"country","in":"query","description":"Developer country (2-letter ISO, best effort from address / website).","schema":{"type":"string","example":"us"}},{"name":"min_ratings","in":"query","description":"Total ratings across the developer's apps, at least.","schema":{"type":"integer","minimum":0}},{"name":"max_ratings","in":"query","description":"Total ratings, at most (e.g. 20000 to skip big brands).","schema":{"type":"integer","minimum":0}},{"name":"min_installs","in":"query","description":"Total Google Play installs, at least.","schema":{"type":"integer","minimum":0}},{"name":"min_apps","in":"query","description":"Number of apps they publish, at least.","schema":{"type":"integer","minimum":0}},{"name":"max_apps","in":"query","description":"Number of apps, at most (e.g. 20 for indie studios).","schema":{"type":"integer","minimum":0}},{"name":"updated_since","in":"query","description":"Some app of theirs was updated in the store on or after this date.","schema":{"type":"string","format":"date","example":"2026-01-01"}},{"name":"updated_within_days","in":"query","description":"Same as updated_since, relative (e.g. 365).","schema":{"type":"integer","minimum":1,"maximum":3650}},{"name":"has_email","in":"query","description":"Only developers with a usable scored business email.","schema":{"type":"boolean","default":false}},{"name":"min_email_score","in":"query","description":"Only developers whose best email scores at least this (0-100; implies has_email). 60+ is a good outreach threshold.","schema":{"type":"integer","minimum":0,"maximum":100}},{"name":"sort","in":"query","description":"reach = ratings + installs/100; ratings; apps; recent = most recent app update.","schema":{"type":"string","enum":["reach","ratings","apps","recent"],"default":"reach"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":50}},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"One page of developers; `meta.next_cursor` for the next.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DeveloperLead"}}}}]}}}},"400":{"$ref":"#/components/responses/InvalidParam"},"402":{"$ref":"#/components/responses/PaymentRequired"}}}},"/developers/{dev}":{"get":{"operationId":"getDeveloper","tags":["Developers"],"summary":"Get a developer's profile, all their apps and the same company in the other store.","description":"Contact emails (with where they were found) are included on Studio and above.","x-credits":1,"parameters":[{"name":"dev","in":"path","required":true,"description":"`apple:<artist id>`, `play:<developer id>`, a numeric Apple artist id, a Play developer id (often the name), or the website domain (`spotify.com`).","schema":{"type":"string","example":"apple:324684583"}},{"$ref":"#/components/parameters/StoreHint"},{"$ref":"#/components/parameters/Fields"}],"responses":{"200":{"description":"The developer.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Developer"}}}]}}}},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/audits":{"get":{"operationId":"listAudits","tags":["Audits"],"summary":"List your organization's App Audits, newest first, with status and score (free).","x-credits":0,"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"Audits.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AuditSummary"}}}}]}}}}}}},"/audits/{id}":{"get":{"operationId":"getAudit","tags":["Audits"],"summary":"Get one App Audit by id - poll this after POST /v1/apps/{app}/audit answered 202 (free).","description":"`status`: queued, running, batched (narrative queued in the batch API), done or failed. `include=facts` adds the measured facts the report is built from.","x-credits":0,"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","example":"aud_3fK9aQ2mXc81LpRt"}},{"name":"include","in":"query","schema":{"type":"string","enum":["facts"]}}],"responses":{"200":{"description":"The audit.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Audit"}}}]}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"operationId":"updateAudit","tags":["Audits"],"summary":"White-label an App Audit report with your branding (Studio) or switch it back, and set its label (free).","description":"`white_label: true` re-applies your current branding (use it after changing the branding), `false` shows the standard AppGoat report. 402 plan_limit for white_label on plans without white-label audits.","x-credits":0,"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","example":"aud_3fK9aQ2mXc81LpRt"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"white_label":{"type":"boolean"},"label":{"type":["string","null"],"maxLength":80}}}}}},"responses":{"200":{"description":"The updated audit.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Audit"}}}]}}}},"400":{"$ref":"#/components/responses/InvalidParam"},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/watches":{"get":{"operationId":"listWatches","tags":["Watches & events"],"summary":"List your watches (apps, competitor sets, keyword sets) with usage against your plan's limits.","description":"`meta.usage` has watched apps and keyword slots used vs your plan (`null` limit = unlimited).","x-credits":0,"parameters":[{"name":"kind","in":"query","schema":{"$ref":"#/components/schemas/WatchKind"}},{"name":"app","in":"query","description":"Only watches that include this app (any `{app}` input).","schema":{"type":"string"}},{"$ref":"#/components/parameters/StoreHint"}],"responses":{"200":{"description":"Watches, newest first.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Watch"}}}}]}}}},"400":{"$ref":"#/components/responses/InvalidParam"}}},"post":{"operationId":"createWatch","tags":["Watches & events"],"summary":"Watch an app, a set of competitors or a set of keywords and get events when something significant changes.","description":"Use this when the user wants to be told about changes (\"tell me when a competitor updates\", \"alert me when my\nrating drops\", \"track my ranks for these keywords\"). Kinds:\n- `app` { app }: new versions, metadata / price changes, featuring, rating drops, review and ratings spikes,\n  chart entries for that app.\n- `competitor_set` { app?, competitors[] }: the same for every app in the set (your own `app` optional).\n- `keyword` { terms[], store, app? }: search-rank moves of `app` for each term (`rank_change`) and new apps in\n  the top N (`keyword_entrant`).\nWatched apps (competitors included) count against `limits.watches`; keyword watches use one keyword slot per\nterm × store × country (`limits.keywords`). Exceeding either returns 402 plan_limit and changes nothing.\nWatched apps are refreshed daily. Events appear at `GET /v1/events` and go to your webhooks.\n","x-credits":0,"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchInput"},"examples":{"app":{"value":{"kind":"app","app":"com.spotify.music","countries":["us","de"]}},"competitors":{"value":{"kind":"competitor_set","app":"284882215","competitors":["389801252","com.zhiliaoapp.musically"],"event_types":["new_version","metadata_change","price_change"]}},"keywords":{"value":{"kind":"keyword","app":"284882215","terms":["photo editor","collage maker"],"store":"apple","countries":["us","gb"],"settings":{"rank_move":3}}}}}}},"responses":{"201":{"description":"The watch.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Watch"}}}]}}}},"400":{"$ref":"#/components/responses/InvalidParam"},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/AppNotFound"}}}},"/watches/{id}":{"parameters":[{"$ref":"#/components/parameters/WatchId"}],"get":{"operationId":"getWatch","tags":["Watches & events"],"summary":"Get one watch with its apps, keyword slots, thresholds and event types.","x-credits":0,"responses":{"200":{"description":"The watch.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Watch"}}}]}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"operationId":"updateWatch","tags":["Watches & events"],"summary":"Change a watch (apps, competitors, terms, countries, event types, thresholds) or pause it with active=false.","description":"Send only what changes; `settings` is merged into the current settings. Growing a watch re-checks your plan's limits (402 plan_limit).","x-credits":0,"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchPatch"},"example":{"competitors":["389801252","com.instagram.android"],"settings":{"significance":0.7}}}}},"responses":{"200":{"description":"The updated watch.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Watch"}}}]}}}},"400":{"$ref":"#/components/responses/InvalidParam"},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"operationId":"deleteWatch","tags":["Watches & events"],"summary":"Stop watching (frees its apps and keyword slots; past events are kept).","x-credits":0,"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"object","properties":{"deleted":{"type":"boolean"}}}}}]}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/events":{"get":{"operationId":"listEvents","tags":["Watches & events"],"summary":"List significant changes on your watched apps and keywords, newest first (free; poll this to wake an agent).","description":"Each event has a deterministic one-line `title`, an AI `summary` (or null), a `significance` (0–1) and a typed\n`payload`. Only changes that reach the watch's `settings.significance` become events. To poll, pass\n`since=` the `created_at` of the newest event you already handled (or remember its id and stop paging there).\n","x-credits":0,"parameters":[{"name":"type","in":"query","description":"Comma list of event types.","schema":{"type":"string","example":"new_version,rating_drop"}},{"name":"app","in":"query","description":"Only events of this app (any `{app}` input).","schema":{"type":"string"}},{"$ref":"#/components/parameters/StoreHint"},{"name":"watch","in":"query","description":"Only events of this watch id.","schema":{"type":"integer"}},{"$ref":"#/components/parameters/Since"},{"name":"min_significance","in":"query","schema":{"type":"number","minimum":0,"maximum":1}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"Events.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Event"}}}}]}}}},"400":{"$ref":"#/components/responses/InvalidParam"}}}},"/webhooks":{"get":{"operationId":"listWebhooks","tags":["Webhooks"],"summary":"List your event endpoints (signed webhooks, Slack incoming webhooks, GitHub repository_dispatch).","x-credits":0,"responses":{"200":{"description":"Endpoints.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}}}}]}}}}}},"post":{"operationId":"createWebhook","tags":["Webhooks"],"summary":"Send events to a URL, a Slack channel or a GitHub repository (repository_dispatch) as they happen (paid plans).","description":"`kind`:\n- `webhook` (default): POST of the event JSON, signed with `appgoat-signature: t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>`.\n  The `secret` is returned once, here (rotate with PATCH rotate_secret). Answer 2xx within 10 s.\n- `slack`: `url` is a Slack incoming webhook (https://hooks.slack.com/services/…).\n- `github`: `url` is `owner/repo`, `github_token` a fine-grained token with Contents: read and write on it.\n  Sends `{ event_type: \"appgoat.<type>\", client_payload: <event> }` to start a workflow `on: repository_dispatch`.\nFailed deliveries are retried after 1 min, 5 min, 30 min, 2 h, 6 h, 12 h and 24 h; an endpoint failing 50 times\nin a row is disabled (PATCH active=true re-enables it). Free plan: 402 plan_limit (use GET /v1/events).\n","x-credits":0,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","description":"https URL (webhook), Slack incoming webhook URL (slack) or owner/repo (github)."},"kind":{"type":"string","enum":["webhook","slack","github"],"default":"webhook"},"event_types":{"type":["array","null"],"items":{"$ref":"#/components/schemas/EventType"},"description":"null = every type."},"description":{"type":["string","null"]},"github_token":{"type":"string","description":"kind github only; never returned."}}},"examples":{"webhook":{"value":{"url":"https://example.com/hooks/appgoat","event_types":["new_version","rating_drop"]}},"github":{"value":{"kind":"github","url":"acme/my-app","github_token":"github_pat_xxx","event_types":["negative_review_spike"]}}}}}},"responses":{"201":{"description":"The endpoint, with its signing `secret` (only now).","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/WebhookEndpoint"}}}]}}}},"400":{"$ref":"#/components/responses/InvalidParam"},"402":{"$ref":"#/components/responses/PaymentRequired"}}}},"/webhooks/{id}":{"parameters":[{"$ref":"#/components/parameters/WebhookId"}],"get":{"operationId":"getWebhook","tags":["Webhooks"],"summary":"Get one event endpoint with its delivery health (failure count, last success / failure).","x-credits":0,"responses":{"200":{"description":"The endpoint.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/WebhookEndpoint"}}}]}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"operationId":"updateWebhook","tags":["Webhooks"],"summary":"Change an endpoint's URL, event types or description, re-enable it, or rotate its signing secret.","x-credits":0,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"event_types":{"type":["array","null"],"items":{"$ref":"#/components/schemas/EventType"}},"description":{"type":["string","null"]},"active":{"type":"boolean"},"github_token":{"type":"string"},"rotate_secret":{"type":"boolean","description":"true = new secret, returned in this response only."}}}}}},"responses":{"200":{"description":"The updated endpoint.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/WebhookEndpoint"}}}]}}}},"400":{"$ref":"#/components/responses/InvalidParam"},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"operationId":"deleteWebhook","tags":["Webhooks"],"summary":"Delete an event endpoint and its delivery log.","x-credits":0,"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"object","properties":{"deleted":{"type":"boolean"}}}}}]}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/webhooks/{id}/test":{"post":{"operationId":"testWebhook","tags":["Webhooks"],"summary":"Send a `test` event to an endpoint now and see what it answered (status, body, latency).","x-credits":0,"parameters":[{"$ref":"#/components/parameters/WebhookId"}],"responses":{"200":{"description":"The attempt (`ok` false when the endpoint did not answer 2xx).","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"object","properties":{"delivery_id":{"type":"string"},"ok":{"type":"boolean"},"response_status":{"type":["integer","null"]},"response_body":{"type":["string","null"]},"error":{"type":["string","null"]},"duration_ms":{"type":"integer"},"event":{"$ref":"#/components/schemas/Event"}}}}}]}}}},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/webhooks/{id}/deliveries":{"get":{"operationId":"listWebhookDeliveries","tags":["Webhooks"],"summary":"List an endpoint's delivery log (every attempt's status, response and next retry), newest first.","x-credits":0,"parameters":[{"$ref":"#/components/parameters/WebhookId"},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","succeeded","failed"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"Deliveries.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}}}}]}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/connections":{"get":{"operationId":"listConnections","tags":["Connections"],"summary":"List the connected App Store Connect, Play Console and Apple Ads accounts (ids, linked apps, status; never secrets).","description":"Use the connection `id` in `POST /v1/actions` (or omit it when only one connection fits). `status: invalid`\nmeans the provider rejected the credentials since they were added (`last_error` says why); fix them and call\n`POST /v1/connections/{id}/verify`. `mode: read_only` connections can dry-run actions but not apply them.\n","x-credits":0,"parameters":[{"name":"provider","in":"query","schema":{"$ref":"#/components/schemas/Provider"}}],"responses":{"200":{"description":"The connections.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Connection"}}}}]}}}}}},"post":{"operationId":"createConnection","tags":["Connections"],"summary":"Connect an App Store Connect, Play Console or Apple Ads account (credentials are verified, then stored encrypted).","description":"Credentials per provider (all are verified with one cheap read before anything is stored; they are encrypted\nwith AES-256-GCM and never returned):\n- `asc`: `{ issuer_id, key_id, private_key, vendor_number? }` from App Store Connect → Users and Access →\n  Integrations → App Store Connect API (role App Manager; Sales too for downloads/proceeds sync with\n  `vendor_number` from Payments and Financial Reports). `apps` defaults to every app the key can see.\n- `play_console`: `{ service_account, reports_bucket? }` = the Google Cloud service account JSON key, invited in\n  Play Console → Users and permissions with View app information, Reply to reviews and Edit store listing.\n  `apps` (package names) is required. `reports_bucket` (pubsite_prod_…) enables install stats.\n- `apple_ads`: `{ client_id, team_id, key_id, private_key, ad_account_id? }` from Apple Ads → Account Settings →\n  API for an API user with the API Account Manager role (Apple Ads Platform API; `ad_account_id` is needed when\n  the user can access several ad accounts, the error lists them).\nEach linked app uses one of the plan's connected apps (`limits.connections`; Free 1, read-only). The default\nmode is `actions` (`read_only` on Free).\n","x-credits":0,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["provider","credentials"],"properties":{"provider":{"$ref":"#/components/schemas/Provider"},"label":{"type":"string","description":"Your name for it (default: provider + key / account)."},"mode":{"type":"string","enum":["actions","read_only"]},"credentials":{"type":"object","additionalProperties":true,"description":"See the description for the fields per provider."},"apps":{"type":"array","items":{"type":"string"},"description":"Apps to link: App Store ids / bundle ids (asc, apple_ads) or package names (play_console, required)."}}},"example":{"provider":"asc","label":"My ASC key","credentials":{"issuer_id":"57246542-96fe-1a63-e053-0824d011072a","key_id":"2X9R4HXF34","private_key":"-----BEGIN PRIVATE KEY-----\n…\n-----END PRIVATE KEY-----"},"apps":["1234567890"]}}}},"responses":{"201":{"description":"Connected and verified.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Connection"}}}]}}}},"400":{"$ref":"#/components/responses/InvalidParam"},"402":{"$ref":"#/components/responses/PaymentRequired"},"422":{"$ref":"#/components/responses/InvalidCredentials"},"502":{"$ref":"#/components/responses/ProviderError"}}}},"/connections/{id}":{"get":{"operationId":"getConnection","tags":["Connections"],"summary":"Get one connection (status, linked apps, non-secret account identifiers).","x-credits":0,"parameters":[{"$ref":"#/components/parameters/ConnectionId"}],"responses":{"200":{"description":"The connection.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Connection"}}}]}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"operationId":"updateConnection","tags":["Connections"],"summary":"Rename a connection, switch it between read_only and actions, or change which apps it links.","x-credits":0,"parameters":[{"$ref":"#/components/parameters/ConnectionId"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string"},"mode":{"type":"string","enum":["actions","read_only"]},"apps":{"type":"array","items":{"type":"string"},"description":"Replaces the linked apps (checked against what the credentials can access)."}}}}}},"responses":{"200":{"description":"Updated.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Connection"}}}]}}}},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"operationId":"deleteConnection","tags":["Connections"],"summary":"Disconnect an account; its credentials are erased and open (draft / pending) actions are rejected.","x-credits":0,"parameters":[{"$ref":"#/components/parameters/ConnectionId"}],"responses":{"200":{"description":"Deleted."},"404":{"$ref":"#/components/responses/NotFound"}}}},"/connections/{id}/verify":{"post":{"operationId":"verifyConnection","tags":["Connections"],"summary":"Re-check a connection's credentials with the provider (after fixing a role or key); lists every app it can access.","x-credits":0,"parameters":[{"$ref":"#/components/parameters/ConnectionId"}],"responses":{"200":{"description":"Verified; `data.available_apps` are the apps the credentials can see (link more with PATCH).","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Connection"}}}]}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/InvalidCredentials"}}}},"/connections/{id}/reviews":{"get":{"operationId":"listConnectionReviews","tags":["Connections"],"summary":"Read your own app's reviews from App Store Connect / Play Console with reply status; their ids feed review.reply.","description":"`unanswered=true` keeps reviews without a developer reply (the \"reply to every review\" playbook). Play only\nreturns reviews written or edited in the last 7 days (Google API limit); App Store Connect returns all.\n","x-credits":1,"parameters":[{"$ref":"#/components/parameters/ConnectionId"},{"name":"app","in":"query","required":true,"description":"A linked app (App Store id or package name).","schema":{"type":"string"}},{"name":"unanswered","in":"query","schema":{"type":"boolean","default":false}},{"name":"rating","in":"query","description":"`1`, `1,2` or `1-3`.","schema":{"type":"string"}},{"name":"country","in":"query","description":"App Store territory filter (ISO alpha-2).","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":100}},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"One page of reviews.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ProviderReview"}}}}]}}}},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/NotFound"},"502":{"$ref":"#/components/responses/ProviderError"}}}},"/connections/{id}/listings":{"get":{"operationId":"getConnectionListing","tags":["Connections"],"summary":"Read your app's current listing text for one locale and which fields can be edited right now.","description":"App Store name/subtitle/description/keywords/what's new need a version in Prepare for Submission; promotional text is editable on the live version. Play fields are always editable.","x-credits":1,"parameters":[{"$ref":"#/components/parameters/ConnectionId"},{"name":"app","in":"query","required":true,"schema":{"type":"string"}},{"name":"locale","in":"query","schema":{"type":"string","default":"en-US"}}],"responses":{"200":{"description":"The listing.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Listing"}}}]}}}},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/NotFound"},"502":{"$ref":"#/components/responses/ProviderError"}}}},"/connections/{id}/ads":{"get":{"operationId":"getConnectionAds","tags":["Connections"],"summary":"Read Apple Ads campaigns, ad groups, keywords (with bids), negatives, or a performance report.","description":"`view=campaigns` → `ad_groups` (campaign_id) → `keywords` (campaign_id, ad_group_id) gives the ids the ads.*\nactions take. `view=report&level=keywords|searchterms|adgroups|campaigns&campaign_id=` returns impressions,\ntaps, installs, spend, avg CPT / CPA for `start`..`end` (default the last 7 days, UTC).\n","x-credits":1,"parameters":[{"$ref":"#/components/parameters/ConnectionId"},{"name":"view","in":"query","schema":{"type":"string","enum":["campaigns","ad_groups","keywords","negatives","report"],"default":"campaigns"}},{"name":"campaign_id","in":"query","schema":{"type":"string"}},{"name":"ad_group_id","in":"query","schema":{"type":"string"}},{"name":"level","in":"query","schema":{"type":"string","enum":["campaigns","adgroups","keywords","searchterms"]}},{"name":"start","in":"query","schema":{"type":"string","format":"date"}},{"name":"end","in":"query","schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":1000,"default":200}}],"responses":{"200":{"description":"The requested view.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/NotFound"},"502":{"$ref":"#/components/responses/ProviderError"}}}},"/actions":{"get":{"operationId":"listActions","tags":["Actions"],"summary":"List proposed and applied actions (drafts, pending approval, applied, failed, rejected), newest first.","x-credits":0,"parameters":[{"name":"status","in":"query","description":"Comma list: draft, pending_approval, approved, applied, failed, rejected.","schema":{"type":"string"}},{"name":"type","in":"query","schema":{"$ref":"#/components/schemas/ActionType"}},{"name":"connection","in":"query","schema":{"type":"string"}},{"$ref":"#/components/parameters/Limit100"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"One page of actions.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Action"}}}}]}}}}}},"post":{"operationId":"createAction","tags":["Actions"],"summary":"Propose a write to a connected account (reply to a review, update a listing, set keywords, upload screenshots, change Apple Ads bids / keywords / negatives); always start with dry_run=true.","description":"Computes the before → after `diff` from the live account and runs guardrails (policy / tone / claims\nprobabilities for text, plus deterministic checks like character limits and bid jumps). Free.\n- `dry_run: true` → a `draft` (24 h) with the diff: show it to the user. To go ahead, call\n  `POST /v1/actions/{id}/approve`.\n- otherwise → `pending_approval` (a person approves it in the dashboard, link in `approve_url`), or `applied`\n  immediately when the org has an auto-apply rule for this type that the guardrail score clears (Studio,\n  1 credit).\nBlocking check failures (over a character limit, nothing to change, not editable) return 400 with `checks`\n(a dry run returns them in `guardrail.checks_failed` instead).\n\nParams per type (`app` = a linked App Store id or package name, `locale` like en-US):\n- `review.reply` (asc, play_console): `{ app, review_id, text }` — review ids from GET /v1/connections/{id}/reviews. Play replies ≤ 350 chars.\n- `listing.update` (asc, play_console): `{ app, locale, fields: { name|title, subtitle, description, promotional_text, whats_new, marketing_url, support_url, privacy_policy_url } }` (Play: title, short_description, full_description, video).\n- `keywords.set` (asc): `{ app, locale, keywords: [..] | \"a,b,c\", mode?: replace|add|remove }` — 100 bytes comma-joined.\n- `screenshots.upload` (asc, play_console): `{ app, locale, display_type: APP_IPHONE_67 … (asc) | image_type: phoneScreenshots … (play), images: [{ url }], replace?: true }`.\n- `ads.keyword.bid` (apple_ads): `{ campaign_id, ad_group_id, keywords: [{ id, bid?, status?: ENABLED|PAUSED }], max_increase?: 1 }`.\n- `ads.keyword.add` (apple_ads): `{ campaign_id, ad_group_id, keywords: [{ text, match_type?: EXACT|BROAD, bid? }] }`.\n- `ads.negative.add` (apple_ads): `{ campaign_id, ad_group_id?, keywords: [{ text, match_type? }] }`.\n","x-credits":"0 (dry run, pending approval) or 1 when auto-applied","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["type","params"],"properties":{"type":{"$ref":"#/components/schemas/ActionType"},"connection":{"type":"string","description":"Connection id; optional when exactly one active connection fits the type (and params.app)."},"params":{"type":"object","additionalProperties":true},"dry_run":{"type":"boolean","default":false},"source":{"type":"string","description":"Who proposes it: api, mcp or playbook:<name> (shown in the approvals list)."}}},"example":{"type":"review.reply","dry_run":true,"source":"playbook:reply-to-every-review","params":{"app":"1234567890","review_id":"00000043-a2fa-4f01-0000-000000000000","text":"Thanks for the detailed report! Version 2.4.1 fixes the login loop."}}}}},"responses":{"201":{"description":"The action (draft, pending_approval or applied).","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Action"}}}]}}}},"400":{"$ref":"#/components/responses/InvalidParam"},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"502":{"$ref":"#/components/responses/ProviderError"}}}},"/actions/{id}":{"get":{"operationId":"getAction","tags":["Actions"],"summary":"Get one action with its diff, guardrail scores, status, result or error, and audit trail.","x-credits":0,"parameters":[{"$ref":"#/components/parameters/ActionId"}],"responses":{"200":{"description":"The action.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Action"}}}]}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/actions/{id}/approve":{"post":{"operationId":"approveAction","tags":["Actions"],"summary":"Go ahead with a draft or pending action; applies it when a person approves (or a rule allows), else submits it for approval.","description":"From an API key / agent: a `draft` becomes `pending_approval` (a person approves at `approve_url`) unless an\nauto-apply rule clears it, in which case it is applied. A `pending_approval` action needs a person unless the\norg enabled agent approval (403 otherwise). From the dashboard: applies it. The diff is recomputed before\napplying; 409 conflict when the account changed since the dry run (`force: true` applies the new diff).\nThe result is `applied` (1 credit) or `failed` with `error` (free).\n","x-credits":"1 when applied, else 0","parameters":[{"$ref":"#/components/parameters/ActionId"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"force":{"type":"boolean","default":false}}}}}},"responses":{"200":{"description":"The action after approval (pending_approval, applied or failed).","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Action"}}}]}}}},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/actions/{id}/reject":{"post":{"operationId":"rejectAction","tags":["Actions"],"summary":"Discard a draft or pending action (nothing is written to the account).","x-credits":0,"parameters":[{"$ref":"#/components/parameters/ActionId"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string"}}}}}},"responses":{"200":{"description":"Rejected.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Action"}}}]}}}},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/opportunities":{"get":{"operationId":"listOpportunities","tags":["Opportunities"],"summary":"Find app ideas - niches ranked by opportunity score (demand, weak incumbents, competition, monetization, trend).","description":"Use this when a user wants to know what app to build, or how attractive a niche is. Every niche of the App\nStore and Google Play (an AI taxonomy of the catalog, e.g. \"ADHD habit tracker\") is scored weekly from 0 to\n100 per store and country:\n`demand` (30%: popularity of the niche's search keywords + ratings the niche holds),\n`supply_gap` (30%: incumbents' rating, apps not updated for a year, a fragmented market, unhappy reviews),\n`competition` (20%: ease, from keyword difficulty and the number of apps with 100k+ ratings),\n`monetization` (10%: incumbents selling IAP / paid, top-grossing chart presence) and\n`trend` (10%: ratings growth, share won by apps released in the last 2 years).\nEvery component lists its signals with the raw values; a signal without data is left out and `confidence`\n(0–1) drops. Each item has the niche's top keywords (popularity, difficulty), its incumbents and their\ncomplaints from AI-tagged reviews; the top 10 per store in the US also carry an analyst `headline` and\n`thesis`. Filter by `niche` (id, slug or words like `habit tracker`) or `category`; page with `cursor`.\nThen use `GET /v1/keywords` on `top_keywords` and `GET /v1/apps/{app}` on `incumbents` to dig deeper.\nA page with no results costs nothing.\n","x-credits":50,"parameters":[{"name":"niche","in":"query","description":"A niche id, slug (`health-fitness/adhd-habit-tracker`) or words matched against niche names (`habit tracker`).","schema":{"type":"string"}},{"name":"category","in":"query","description":"Store category: App Store name (`Health & Fitness`, or `health-fitness`) or Play category (`HEALTH_AND_FITNESS`).","schema":{"type":"string"}},{"name":"store","in":"query","description":"Default both stores.","schema":{"$ref":"#/components/schemas/Store"}},{"name":"country","in":"query","description":"ISO country code. Every niche is scored in `us`; other markets where its keywords are measured (gb, de, …).","schema":{"type":"string","default":"us"}},{"name":"min_score","in":"query","schema":{"type":"integer","minimum":0,"maximum":100}},{"name":"sort","in":"query","description":"Total score, one component, or confidence.","schema":{"type":"string","enum":["score","demand","supply_gap","competition","monetization","trend","confidence"],"default":"score"}},{"name":"week","in":"query","description":"The ranking as of this date (ISO; the latest weekly computation on or before it). Default the latest.","schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Fields"}],"responses":{"200":{"description":"Ranked niches (`meta.week` = the Monday of the computation).","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Opportunity"}}}}]}}}},"400":{"$ref":"#/components/responses/InvalidParam"},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/jobs/{id}":{"get":{"operationId":"getJob","tags":["Jobs"],"summary":"Poll a background store fetch started by a read that answered refreshing:true (free).","description":"Poll every few seconds until `status` is done / partial / failed, then repeat the original call.","x-credits":0,"parameters":[{"name":"id","in":"path","required":true,"description":"`meta.freshness.job_id`, e.g. `fetch_123`.","schema":{"type":"string"}}],"responses":{"200":{"description":"The job.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Envelope"},{"properties":{"data":{"$ref":"#/components/schemas/Job"}}}]}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/openapi.json":{"get":{"operationId":"getOpenapi","tags":["Account"],"summary":"This OpenAPI 3.1 document (no key needed, free).","security":[],"x-credits":0,"responses":{"200":{"description":"The spec.","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/me":{"get":{"operationId":"getMe","tags":["Account"],"summary":"Your plan, credits left this cycle and limits.","x-credits":0,"x-served-by":"gateway","responses":{"200":{"description":"The account.","content":{"application/json":{"schema":{"type":"object"}}}}}}}},"webhooks":{"event":{"post":{"operationId":"receiveEvent","summary":"What AppGoat POSTs to your `kind: webhook` endpoint for every event (and for test sends, type `test`).","description":"Verify `appgoat-signature: t=<unix seconds>,v1=<hex>` before trusting the body: compute\nHMAC-SHA256(secret, `<t>.<raw request body>`), compare in constant time, and reject timestamps older than\n5 minutes. Deduplicate on `appgoat-event-id` (a retry repeats it). Answer 2xx within 10 seconds; do the\nwork asynchronously.\n","parameters":[{"name":"appgoat-signature","in":"header","required":true,"schema":{"type":"string","example":"t=1792650000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd"}},{"name":"appgoat-event-id","in":"header","required":true,"schema":{"type":"string"}},{"name":"appgoat-event-type","in":"header","required":true,"schema":{"type":"string"}},{"name":"appgoat-delivery-id","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the delivery; anything else (or a timeout) is retried."}}}}},"components":{"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"x-api-key","description":"Create a key at https://dash.appgoat.ai."}},"parameters":{"App":{"name":"app","in":"path","required":true,"description":"Any app identifier: App Store id (`284882215`, `id284882215`), Play package (`com.spotify.music`), Apple bundle id (`com.spotify.client`), store URL (URL-encoded), `apple:<id>` / `play:<id>`, or a name (`spotify`).","schema":{"type":"string","example":"com.spotify.music"}},"StoreHint":{"name":"store","in":"query","description":"Disambiguates `{app}` (a bundle id vs a Play package, or a name).","schema":{"$ref":"#/components/schemas/Store"}},"Country":{"name":"country","in":"query","description":"ISO country code(s): `us` (default), a comma list (paid plans), or `all` (Studio).","schema":{"type":"string","default":"us","example":"us,de"}},"MaxAgeApp":{"name":"max_age","in":"query","description":"Refresh from the store when our data is older than this many seconds (0 = always). Default 604800 (7 days).","schema":{"type":"integer","minimum":0,"default":604800}},"MaxAgeReviews":{"name":"max_age","in":"query","description":"Refresh the latest US reviews when older than this many seconds. Default 86400 (1 day).","schema":{"type":"integer","minimum":0,"default":86400}},"Wait":{"name":"wait","in":"query","description":"Block up to ~25 s for a refresh (default). false = answer immediately from cache with a job id.","schema":{"type":"boolean","default":true}},"Since":{"name":"since","in":"query","description":"Only items at or after this ISO date / datetime.","schema":{"type":"string","format":"date-time","example":"2026-10-01"}},"Limit100":{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},"Cursor":{"name":"cursor","in":"query","description":"`meta.next_cursor` from the previous page.","schema":{"type":"string"}},"Fields":{"name":"fields","in":"query","description":"Comma list of top-level fields to return (identifiers are always kept), e.g. `title,rating,version`.","schema":{"type":"string"}},"ConnectionId":{"name":"id","in":"path","required":true,"description":"Connection id (`con_…`).","schema":{"type":"string"}},"ActionId":{"name":"id","in":"path","required":true,"description":"Action id (`act_…`).","schema":{"type":"string"}},"TrackedKeywordId":{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},"WatchId":{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},"WebhookId":{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}},"responses":{"Fetching":{"description":"Not in the catalog yet and still being fetched; poll `GET /v1/jobs/{meta.freshness.job_id}` and call again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"InvalidParam":{"description":"A parameter is missing or invalid (`error.param` names it).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_param","message":"limit must be ≤ 100","hint":"Fix the parameter and retry.","docs":"https://appgoat.ai/docs/errors#invalid_param","param":"limit"}}}}},"PaymentRequired":{"description":"`insufficient_credits` (the call costs more than you have left; nothing was done) or `plan_limit` (a feature of a higher plan).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"AppNotFound":{"description":"Nothing matches `{app}`, or the store does not have it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InvalidCredentials":{"description":"The provider rejected the credentials, or a field is missing; `hint` says where to find / fix it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ProviderError":{"description":"App Store Connect / Google Play / Apple Ads answered with an error (message passed through).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"The state does not allow this (already applied, expired, connection read-only or invalid, account changed since the dry run).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"Needs a person (approve in the dashboard at `error.approve_url`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Provider":{"type":"string","enum":["asc","play_console","apple_ads"],"description":"asc = App Store Connect, play_console = Google Play Console, apple_ads = Apple Ads (Search Ads)."},"LinkedApp":{"type":"object","properties":{"store":{"$ref":"#/components/schemas/Store"},"app_id":{"type":"string"},"external_id":{"type":["string","null"]},"title":{"type":["string","null"]},"bundle_id":{"type":["string","null"]}}},"Connection":{"type":"object","properties":{"id":{"type":"string","example":"con_x8Hq2mXc0aLpQwRtYb"},"provider":{"$ref":"#/components/schemas/Provider"},"label":{"type":"string"},"mode":{"type":"string","enum":["actions","read_only"]},"status":{"type":"string","enum":["active","invalid","deleted"]},"account":{"type":"object","additionalProperties":true,"description":"Non-secret identifiers (issuer_id, key_id, client_email, ad_account_id, ad_account_name, currency, …)."},"apps":{"type":"array","items":{"$ref":"#/components/schemas/LinkedApp"}},"last_verified_at":{"type":["string","null"],"format":"date-time"},"last_error":{"type":["string","null"]},"last_synced_at":{"type":["string","null"],"format":"date-time","description":"Last downloads / proceeds sync (ASC with vendor_number","Play with reports_bucket).":null},"created_at":{"type":"string","format":"date-time"},"available_apps":{"type":"array","items":{"$ref":"#/components/schemas/LinkedApp"},"description":"Only on verify."}}},"ActionType":{"type":"string","enum":["review.reply","listing.update","keywords.set","screenshots.upload","ads.keyword.bid","ads.keyword.add","ads.negative.add"]},"Diff":{"type":"object","properties":{"target":{"type":"object","additionalProperties":true,"description":"What changes: app, locale, review (rating, text), campaign / ad group …"},"changes":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"before":{},"after":{}}}},"summary":{"type":"string"},"notes":{"type":"array","items":{"type":"string"}}}},"Guardrail":{"type":"object","properties":{"status":{"type":"string","enum":["passed","flagged","unavailable","not_applicable"]},"score":{"type":"number","description":"Lowest AI check probability (1 when none apply). Auto-apply rules compare this."},"checks":{"type":"object","additionalProperties":{"type":"number"},"description":"Probability each holds: policy (store rules), tone (professional), claims (no risky promises), relevance (replies)."},"warnings":{"type":"array","items":{"type":"string"}},"checks_failed":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"severity":{"type":"string","enum":["block","warn"]},"message":{"type":"string"}}}},"model":{"type":["string","null"]}}},"Action":{"type":"object","properties":{"id":{"type":"string","example":"act_Qm3xXk2Lw9PaZr0cVb"},"type":{"$ref":"#/components/schemas/ActionType"},"connection_id":{"type":"string"},"status":{"type":"string","enum":["draft","pending_approval","approved","applied","failed","rejected"]},"params":{"type":"object","additionalProperties":true},"diff":{"$ref":"#/components/schemas/Diff"},"guardrail":{"$ref":"#/components/schemas/Guardrail"},"result":{"description":"What the provider returned when applied."},"error":{"type":["string","null"]},"created_by":{"type":"string","description":"api, mcp, playbook:<name> or dashboard."},"approved_by":{"type":["string","null"],"description":"user:<id>, auto (rule) or api."},"rejected_reason":{"type":["string","null"]},"credits":{"type":"integer"},"created_at":{"type":"string","format":"date-time"},"applied_at":{"type":["string","null"],"format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"},"approve_url":{"type":["string","null"],"description":"Dashboard page where a person approves it."},"audit":{"type":"array","description":"Only on GET /actions/{id}.","items":{"type":"object","properties":{"event":{"type":"string"},"actor":{"type":"string"},"at":{"type":"string","format":"date-time"},"detail":{"type":["object","null"],"additionalProperties":true}}}}}},"ProviderReview":{"type":"object","properties":{"id":{"type":"string","description":"The provider's review id (use in review.reply)."},"rating":{"type":["integer","null"]},"title":{"type":["string","null"]},"body":{"type":["string","null"]},"author":{"type":["string","null"]},"country":{"type":["string","null"]},"language":{"type":["string","null"]},"version":{"type":["string","null"]},"created_at":{"type":["string","null"],"format":"date-time"},"response":{"type":["object","null"],"properties":{"id":{"type":["string","null"]},"body":{"type":"string"},"updated_at":{"type":["string","null"],"format":"date-time"},"state":{"type":["string","null"],"description":"ASC: PENDING_PUBLISH or PUBLISHED."}}}}},"Listing":{"type":"object","properties":{"app":{"type":"string"},"locale":{"type":"string"},"fields":{"type":"object","additionalProperties":{"type":["string","null"]}},"editable":{"type":"array","items":{"type":"string"}},"notes":{"type":"array","items":{"type":"string"}},"version":{"type":["string","null"]},"version_state":{"type":["string","null"]}}},"Store":{"type":"string","enum":["apple","play"]},"Freshness":{"type":"object","properties":{"fetched_at":{"type":["string","null"],"format":"date-time","description":"When the oldest requested country was last fetched from the store."},"age_seconds":{"type":["integer","null"]},"stale":{"type":"boolean","description":"Older than max_age (or missing)."},"refreshing":{"type":"boolean","description":"A store fetch is still running; poll job_id."},"job_id":{"type":["string","null"]}}},"Meta":{"type":"object","properties":{"credits_used":{"type":"integer"},"credits_remaining":{"type":"integer","description":"Added by the gateway."},"request_id":{"type":"string","description":"Added by the gateway."},"freshness":{"$ref":"#/components/schemas/Freshness"},"next_cursor":{"type":["string","null"]},"store":{"$ref":"#/components/schemas/Store"},"warnings":{"type":"array","items":{"type":"string"},"description":"Things to know (e.g. \"resolved by name\"); safe to show to the user."}}},"Envelope":{"type":"object","required":["data","meta"],"properties":{"data":{},"meta":{"$ref":"#/components/schemas/Meta"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["invalid_param","invalid_credentials","unauthorized","forbidden","insufficient_credits","plan_limit","free_audit_used","not_found","app_not_found","developer_not_found","job_not_found","conflict","not_ready","rate_limited","provider_error","internal_error","not_configured"]},"message":{"type":"string"},"hint":{"type":"string","description":"What to do next."},"docs":{"type":"string","format":"uri"},"param":{"type":"string"}}}}},"AppCard":{"type":"object","properties":{"store":{"$ref":"#/components/schemas/Store"},"app_id":{"type":"string"},"title":{"type":["string","null"]},"developer_name":{"type":["string","null"]},"icon_url":{"type":["string","null"]},"category":{"type":["string","null"]},"rating":{"type":["number","null"]},"ratings_count":{"type":["integer","null"]},"installs_min":{"type":["integer","null"],"description":"Play install bucket lower bound."},"price":{"type":["number","null"]}}},"Market":{"type":"object","properties":{"country":{"type":"string"},"available":{"type":"boolean"},"title":{"type":["string","null"]},"price":{"type":["number","null"]},"currency":{"type":["string","null"]},"rating":{"type":["number","null"]},"ratings_count":{"type":["integer","null"]},"version":{"type":["string","null"]},"fetched_at":{"type":"string","format":"date-time"}}},"App":{"type":"object","properties":{"store":{"$ref":"#/components/schemas/Store"},"app_id":{"type":"string"},"bundle_id":{"type":["string","null"]},"url":{"type":"string"},"title":{"type":["string","null"]},"subtitle":{"type":["string","null"],"description":"App Store subtitle / Play short description."},"description":{"type":["string","null"]},"developer":{"type":"object","properties":{"id":{"type":["string","null"]},"name":{"type":["string","null"]}}},"category":{"type":["string","null"]},"genres":{"type":"array","items":{"type":"string"}},"content_rating":{"type":["string","null"]},"free":{"type":["boolean","null"]},"price":{"type":["number","null"]},"currency":{"type":["string","null"]},"has_iap":{"type":["boolean","null"]},"has_ads":{"type":["boolean","null"]},"rating":{"type":["number","null"]},"ratings_count":{"type":["integer","null"]},"reviews_count":{"type":["integer","null"]},"histogram":{"type":["array","null"],"items":{"type":"integer"},"description":"1★…5★ counts."},"installs_min":{"type":["integer","null"]},"installs_exact":{"type":["integer","null"]},"installs_text":{"type":["string","null"]},"version":{"type":["string","null"]},"release_notes":{"type":["string","null"]},"min_os":{"type":["string","null"]},"size_bytes":{"type":["integer","null"]},"released_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"icon_url":{"type":["string","null"]},"screenshots":{"type":"array","items":{"type":"string"}},"languages":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["pending","active","delisted","error"]},"first_seen_at":{"type":"string","format":"date-time"},"last_fetched_at":{"type":["string","null"],"format":"date-time"},"markets":{"type":"array","items":{"$ref":"#/components/schemas/Market"},"description":"The requested countries (all with include=markets)."},"linked":{"type":["object","null"],"description":"The same app in the other store.","properties":{"store":{"$ref":"#/components/schemas/Store"},"app_id":{"type":"string"},"title":{"type":["string","null"]},"icon_url":{"type":["string","null"]},"match":{"type":"string","enum":["bundle_id","developer"]}}},"iap":{"type":"object","description":"include=iap: items (App Store) or price_range (Play)."},"versions":{"type":"array","items":{"type":"object","properties":{"version":{"type":"string"},"first_seen_at":{"type":"string","format":"date-time"},"release_notes":{"type":["string","null"]}}}},"privacy":{"type":"object","description":"include=privacy: App Store privacy labels."},"estimates":{"type":"array","items":{"type":"object","properties":{"country":{"type":"string"},"month":{"type":"string"},"downloads":{"type":["integer","null"]},"revenue_usd":{"type":["integer","null"]},"confidence":{"type":["number","null"]}}}},"charts":{"type":"array","items":{"type":"object","properties":{"country":{"type":"string"},"chart":{"type":"string"},"category":{"type":"string"},"date":{"type":"string"},"rank":{"type":"integer"}}}}}},"Review":{"type":"object","properties":{"review_id":{"type":"string"},"country":{"type":"string"},"rating":{"type":"integer","minimum":1,"maximum":5},"title":{"type":["string","null"]},"body":{"type":["string","null"]},"author":{"type":["string","null"]},"version":{"type":["string","null"]},"thumbs_up":{"type":["integer","null"]},"reply":{"type":["string","null"],"description":"The developer's reply."},"replied_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":["string","null"],"format":"date-time"},"sentiment":{"type":["string","null"],"enum":["positive","neutral","negative",null],"description":"AI tag; null = not tagged yet."},"intent":{"type":["string","null"],"enum":["bug","crash","feature_request","pricing","ux","praise","spam","other",null],"description":"AI tag."},"severity":{"type":["integer","null"],"minimum":0,"maximum":3,"description":"0 none, 1 minor, 2 major, 3 critical."},"topic":{"type":["string","null"],"description":"AI topic label (one per review, per-app taxonomy)."},"topic_id":{"type":["integer","null"]},"confidence":{"type":["number","null"],"description":"Probability of the chosen intent (0–1)."}}},"HistoryPoint":{"type":"object","properties":{"country":{"type":"string"},"date":{"type":"string","format":"date"},"rating":{"type":["number","null"]},"ratings_count":{"type":["integer","null"]},"reviews_count":{"type":["integer","null"]},"installs_min":{"type":["integer","null"]},"installs_exact":{"type":["integer","null"]},"histogram":{"type":["array","null"],"items":{"type":"integer"}},"price":{"type":["number","null"]}}},"Change":{"type":"object","properties":{"id":{"type":"string"},"country":{"type":"string"},"field":{"type":"string","example":"version"},"old":{"description":"Previous value (null = absent)."},"new":{"description":"New value (null = removed)."},"detected_at":{"type":"string","format":"date-time"}}},"AppKeyword":{"type":"object","properties":{"term":{"type":"string"},"country":{"type":"string"},"rank":{"type":"integer"},"popularity":{"type":["integer","null"]},"popularity_source":{"type":["string","null"],"enum":["apple","proxy",null]},"difficulty":{"type":["integer","null"]},"results_count":{"type":["integer","null"]},"ranked_at":{"type":"string","format":"date-time"},"source":{"type":"string","enum":["universe","tracked"]},"tracked_keyword_id":{"type":"integer"}}},"Competitor":{"allOf":[{"$ref":"#/components/schemas/AppCard"},{"type":"object","properties":{"shared_keywords":{"type":"integer"},"best_shared_rank":{"type":["integer","null"]},"similar_position":{"type":["integer","null"],"description":"Position in the store's similar-apps list."},"score":{"type":"number"}}}]},"Chart":{"type":"object","properties":{"store":{"$ref":"#/components/schemas/Store"},"country":{"type":"string"},"chart":{"type":"string","enum":["free","paid","grossing"]},"category":{"type":"string"},"date":{"type":"string","format":"date"},"previous_date":{"type":["string","null"],"format":"date"},"entries":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/AppCard"},{"type":"object","properties":{"rank":{"type":"integer"},"delta":{"type":["integer","null"]},"is_new":{"type":"boolean"}}}]}},"dropped":{"type":"array","items":{"$ref":"#/components/schemas/AppCard"}}}},"KeywordMetrics":{"type":"object","properties":{"term":{"type":"string"},"store":{"$ref":"#/components/schemas/Store"},"country":{"type":"string"},"popularity":{"type":["integer","null"],"description":"5–100."},"popularity_source":{"type":["string","null"],"enum":["apple","proxy",null]},"difficulty":{"type":["integer","null"],"description":"0–100."},"difficulty_breakdown":{"type":["object","null"]},"results_count":{"type":["integer","null"]},"est_downloads_at_1":{"type":["integer","null"]},"measured_at":{"type":["string","null"],"format":"date-time"},"pending":{"type":"boolean","description":"Being measured; call again in a minute."}}},"Keyword":{"allOf":[{"$ref":"#/components/schemas/KeywordMetrics"},{"type":"object","properties":{"top_app_ids":{"type":"array","items":{"type":"string"}},"top_apps":{"type":"array","items":{"$ref":"#/components/schemas/AppCard"}},"related":{"type":"array","items":{"$ref":"#/components/schemas/KeywordMetrics"}},"suggestions":{"type":"array","items":{"type":"string"}},"app":{"type":"object","properties":{"store":{"$ref":"#/components/schemas/Store"},"app_id":{"type":"string"},"rank":{"type":["integer","null"]},"relevance":{"type":"number","description":"0–1: term coverage in title (1), subtitle (0.7), description (0.4)."}}}}}]},"TrackedKeyword":{"type":"object","properties":{"id":{"type":"integer"},"term":{"type":"string"},"store":{"$ref":"#/components/schemas/Store"},"country":{"type":"string"},"depth":{"type":"integer"},"cadence_minutes":{"type":"integer"},"tags":{"type":["array","null"],"items":{"type":"string"}},"popularity":{"type":["integer","null"]},"last_run_at":{"type":["string","null"],"format":"date-time"},"top10":{"type":["array","null"],"items":{"type":"string"}},"ranked_at":{"type":["string","null"],"format":"date-time"}}},"DeveloperLead":{"type":"object","properties":{"store":{"$ref":"#/components/schemas/Store"},"developer_id":{"type":"string"},"name":{"type":["string","null"]},"url":{"type":["string","null"],"description":"Developer page in the store."},"website":{"type":["string","null"]},"domain":{"type":["string","null"]},"country":{"type":["string","null"]},"support_url":{"type":["string","null"]},"app_count":{"type":["integer","null"]},"total_ratings":{"type":["integer","null"]},"total_installs":{"type":["integer","null"]},"top_category":{"type":["string","null"]},"last_app_update":{"type":["string","null"],"format":"date-time","description":"Most recent store update of any of their apps."},"email":{"type":["string","null"],"description":"Best scored business email (never personal","MX-failed or opted-out addresses).":null},"email_score":{"type":["integer","null"],"description":"0-100 (role","source and domain match).":null},"email_role":{"type":["string","null"],"description":"support, sales, press, legal, privacy or generic."},"email_mx_ok":{"type":["boolean","null"]}}},"Developer":{"type":"object","properties":{"store":{"$ref":"#/components/schemas/Store"},"developer_id":{"type":"string"},"name":{"type":["string","null"]},"url":{"type":["string","null"]},"website":{"type":["string","null"]},"domain":{"type":["string","null"]},"country":{"type":["string","null"]},"support_url":{"type":["string","null"]},"privacy_url":{"type":["string","null"]},"app_count":{"type":["integer","null"]},"total_ratings":{"type":["integer","null"]},"total_installs":{"type":["integer","null"]},"top_category":{"type":["string","null"]},"email":{"type":["string","null"],"description":"Studio+."},"contacts":{"type":"array","description":"Studio+: email, role, score, source.","items":{"type":"object"}},"apps":{"type":"array","items":{"$ref":"#/components/schemas/AppCard"}},"linked":{"type":"array","description":"The same company in the other store.","items":{"type":"object"}}}},"OpportunityComponent":{"type":"object","properties":{"score":{"type":["number","null"],"description":"0–100 (higher = better for a new app); null without data."},"weight":{"type":"number"},"coverage":{"type":"number","description":"Share (0–1) of this component's signals that had data."},"signals":{"type":"object","description":"signal → { score (0–100 or null), value (the raw input: a number or a short sentence) }","additionalProperties":{"type":"object","properties":{"score":{"type":["number","null"]},"value":{"type":["number","string","null"]}}}}}},"Opportunity":{"type":"object","properties":{"id":{"type":"integer"},"rank":{"type":"integer"},"niche":{"type":"object","properties":{"id":{"type":"integer"},"slug":{"type":"string","example":"health-fitness/adhd-habit-tracker"},"label":{"type":"string","example":"ADHD habit tracker"},"description":{"type":["string","null"]},"category":{"type":["string","null"]}}},"store":{"$ref":"#/components/schemas/Store"},"country":{"type":"string"},"week":{"type":"string","format":"date"},"score":{"type":"number","description":"0–100."},"confidence":{"type":"number","description":"0–1; low = few signals had data."},"app_count":{"type":"integer","description":"Apps in the niche."},"headline":{"type":["string","null"],"description":"Analyst headline (top 10 per store in the US)."},"thesis":{"type":["string","null"],"description":"One-paragraph analyst thesis (top 10 per store in the US)."},"components":{"type":"object","properties":{"demand":{"$ref":"#/components/schemas/OpportunityComponent"},"supply_gap":{"$ref":"#/components/schemas/OpportunityComponent"},"competition":{"$ref":"#/components/schemas/OpportunityComponent"},"monetization":{"$ref":"#/components/schemas/OpportunityComponent"},"trend":{"$ref":"#/components/schemas/OpportunityComponent"}}},"top_keywords":{"type":"array","items":{"type":"object","properties":{"term":{"type":"string"},"popularity":{"type":["integer","null"]},"difficulty":{"type":["integer","null"]},"source":{"type":"string","enum":["serp","seed"],"description":"serp = the niche holds ≥ 3 of its top 10; seed = a taxonomy search term."},"niche_share":{"type":"number"}}}},"incumbents":{"type":"array","items":{"type":"object","properties":{"app_id":{"type":"string"},"title":{"type":["string","null"]},"developer_name":{"type":["string","null"]},"icon_url":{"type":["string","null"]},"rating":{"type":["number","null"]},"ratings_count":{"type":["integer","null"]},"updated_at":{"type":["string","null"],"format":"date-time"},"days_since_update":{"type":["integer","null"]},"released_at":{"type":["string","null"],"format":"date-time"},"has_iap":{"type":["boolean","null"]},"iap_prices":{"type":"array","items":{"type":"string"},"description":"Up to 4 in-app purchases as \"name: price\" (App Store)."},"price":{"type":["number","null"]},"in_top_grossing":{"type":"boolean"}}}},"complaints":{"type":"array","description":"Topics / intents of the incumbents' negative AI-tagged reviews.","items":{"type":"object","properties":{"label":{"type":"string"},"reviews":{"type":"integer"}}}},"stats":{"type":"object","additionalProperties":true}}},"Finding":{"type":"object","description":"A deterministic check over the measured facts.","properties":{"id":{"type":"string"},"type":{"type":"string","example":"striking_distance"},"section":{"type":"string","enum":["metadata","keywords","reviews","ratings","localization","competitors","creative","maintenance"]},"severity":{"type":"string","enum":["high","medium","low"]},"title":{"type":"string","example":"#14 for \"habit tracker adhd\" (not in the title or subtitle)"},"evidence":{"type":"object","additionalProperties":true,"description":"The numbers the finding rests on."},"fix":{"type":"string"},"playbook":{"type":["string","null"],"description":"Playbook that automates the fix: https://appgoat.ai/playbooks/{playbook}"}}},"AuditReport":{"type":"object","properties":{"score":{"type":"integer","minimum":0,"maximum":100},"headline":{"type":"string"},"summary":{"type":"string"},"sections":{"type":"array","items":{"type":"object","properties":{"section":{"type":"string"},"title":{"type":"string"},"body":{"type":"string"},"finding_ids":{"type":"array","items":{"type":"string"}}}}},"actions":{"type":"array","description":"Prioritised, most impactful first.","items":{"type":"object","properties":{"title":{"type":"string"},"why":{"type":"string"},"how":{"type":"string"},"impact":{"type":"string","enum":["high","medium","low"]},"effort":{"type":"string","enum":["low","medium","high"]},"finding_ids":{"type":"array","items":{"type":"string"}},"playbook":{"type":["string","null"]}}}},"metadata":{"type":"array","description":"Listing rewrites within the store character limits.","items":{"type":"object","properties":{"field":{"type":"string","enum":["title","subtitle","short_description","keywords","description_first_line"]},"current":{"type":["string","null"]},"suggested":{"type":"string"},"chars":{"type":"integer"},"limit":{"type":"integer"},"rationale":{"type":"string"}}}},"findings":{"type":"array","items":{"$ref":"#/components/schemas/Finding"}},"narrative":{"type":"string","enum":["opus","deterministic"],"description":"deterministic = findings only (the AI step was unavailable)."},"model":{"type":["string","null"]},"generated_at":{"type":"string","format":"date-time"}}},"AuditSummary":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"url":{"type":"string","format":"uri"},"status":{"type":"string","enum":["queued","running","batched","done","failed"]},"store":{"$ref":"#/components/schemas/Store"},"app_id":{"type":"string"},"country":{"type":"string"},"mode":{"type":"string","enum":["full","lite"]},"title":{"type":["string","null"]},"icon_url":{"type":["string","null"]},"score":{"type":["integer","null"]},"white_label":{"type":"boolean","description":"The report page carries your branding."},"brand_name":{"type":["string","null"]},"label":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"}}},"ReportBranding":{"type":"object","properties":{"brand_name":{"type":["string","null"]},"logo_url":{"type":["string","null"],"format":"uri"},"accent_color":{"type":["string","null"],"example":"#1f6feb"},"cta_url":{"type":["string","null"]},"cta_text":{"type":["string","null"]},"footer":{"type":["string","null"]},"powered_by":{"type":"boolean","description":"Shows \"Powered by AppGoat\"."}}},"Audit":{"type":"object","properties":{"id":{"type":"string","example":"aud_3fK9aQ2mXc81LpRt"},"slug":{"type":"string"},"url":{"type":"string","format":"uri","description":"Shareable report page (not indexed by search engines)."},"status":{"type":"string","enum":["queued","running","batched","done","failed"]},"store":{"$ref":"#/components/schemas/Store"},"app_id":{"type":"string"},"country":{"type":"string"},"mode":{"type":"string","enum":["full","lite"]},"title":{"type":["string","null"]},"icon_url":{"type":["string","null"]},"score":{"type":["integer","null"]},"white_label":{"type":"boolean","description":"The report page carries your branding."},"branding":{"oneOf":[{"$ref":"#/components/schemas/ReportBranding"},{"type":"null"}]},"label":{"type":["string","null"]},"report":{"oneOf":[{"$ref":"#/components/schemas/AuditReport"},{"type":"null"}]},"findings":{"type":"array","items":{"$ref":"#/components/schemas/Finding"},"description":"Available as soon as the facts are gathered."},"facts":{"type":"object","description":"Only with include=facts: listing, ratings, reviews, keywords (probe), competitors, localization, changes, gaps."},"credits_charged":{"type":"integer"},"free":{"type":"boolean","description":"This was the organization's free first audit."},"error":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"}}},"Insights":{"type":"object","properties":{"window":{"type":"object","properties":{"since":{"type":"string","format":"date-time"},"until":{"type":"string","format":"date-time"}}},"reviews":{"type":"integer"},"tagged":{"type":"integer","description":"Reviews with AI tags (the breakdowns below cover these)."},"avg_rating":{"type":["number","null"]},"sentiment":{"type":"object","properties":{"positive":{"type":"integer"},"neutral":{"type":"integer"},"negative":{"type":"integer"}}},"intents":{"type":"object","additionalProperties":{"type":"integer"}},"topics":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"reviews":{"type":"integer"},"negative":{"type":"integer"},"avg_rating":{"type":["number","null"]}}}},"top_issues":{"type":"array","items":{"type":"object","properties":{"topic":{"type":"string"},"reviews":{"type":"integer"},"share":{"type":"number"},"avg_severity":{"type":["number","null"],"description":"0 none - 3 critical."},"intents":{"type":"object","additionalProperties":{"type":"integer"}},"last_30d":{"type":"integer"},"prev_30d":{"type":"integer"},"versions":{"type":"array","items":{"type":"string"}},"samples":{"type":"array","items":{"type":"object","properties":{"rating":{"type":["integer","null"]},"version":{"type":["string","null"]},"created_at":{"type":"string"},"text":{"type":"string"}}}}}}},"versions":{"type":"array","items":{"type":"object","properties":{"version":{"type":"string"},"first_review_at":{"type":"string","format":"date-time"},"reviews":{"type":"integer"},"avg_rating":{"type":["number","null"]},"sentiment":{"type":"object","additionalProperties":{"type":"integer"}},"intents":{"type":"object","additionalProperties":{"type":"integer"}},"topics":{"type":"array","items":{"type":"object","additionalProperties":true}}}}},"sentiment_over_time":{"type":"array","items":{"type":"object","properties":{"week":{"type":"string","format":"date"},"reviews":{"type":"integer"},"positive":{"type":"integer"},"neutral":{"type":"integer"},"negative":{"type":"integer"},"avg_rating":{"type":["number","null"]}}}}}},"Job":{"type":"object","properties":{"id":{"type":"string","example":"fetch_123"},"kind":{"type":"string","enum":["fetch"]},"status":{"type":"string","enum":["queued","running","done","partial","failed"]},"store":{"$ref":"#/components/schemas/Store"},"app_id":{"type":"string"},"countries":{"type":"array","items":{"type":"string"}},"progress":{"type":"object","additionalProperties":{"type":"string"},"description":"country → ok | unavailable | cached | error: …"},"done":{"type":"integer"},"total":{"type":"integer"},"error":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"}}},"WatchKind":{"type":"string","enum":["app","keyword","competitor_set"]},"EventType":{"type":"string","enum":["new_version","metadata_change","price_change","featured","in_app_event","installs_milestone","rating_drop","ratings_spike","review_spike","negative_review_spike","chart_enter","chart_leave","rank_change","keyword_entrant"],"description":"App / competitor_set watches: `new_version` (version + release notes), `metadata_change` (title, subtitle,\ndescription, screenshots, icon, category…; `payload.changes`), `price_change` (price or in-app purchases),\n`featured` (Editors' Choice, featuring, badges), `in_app_event`, `installs_milestone` (Play install bucket),\n`rating_drop` (7-day drop ≥ settings.rating_drop), `ratings_spike` / `review_spike` (day count ≥\nsettings.spike_factor × the 14-day average), `negative_review_spike` (negative reviews per topic),\n`chart_enter` / `chart_leave` (crossing the top settings.chart_top_n). Keyword watches: `rank_change` (the\nwatch's app moved ≥ settings.rank_move, or entered / left the ranking), `keyword_entrant` (new apps in the\ntop settings.keyword_top_n).\n"},"WatchSettings":{"type":"object","properties":{"significance":{"type":"number","minimum":0,"maximum":1,"default":0.5,"description":"Minimum significance for an event: Jev's probability that an analyst would want the alert (AI on), or a fixed per-type score."},"rank_move":{"type":"integer","default":5},"keyword_top_n":{"type":"integer","default":10},"chart_top_n":{"type":"integer","default":100},"rating_drop":{"type":"number","default":0.1,"description":"Stars over 7 days."},"spike_factor":{"type":"number","default":3},"email_digest":{"type":"boolean","default":true,"description":"Include in the daily email digest."},"depth":{"type":"integer","description":"Keyword watches: results kept per ranking (Apple ≤ 250, Play ≤ 30)."},"cadence_minutes":{"type":"integer","description":"Keyword watches: minutes between re-ranks (360…10080)."}}},"WatchInput":{"type":"object","required":["kind"],"properties":{"kind":{"$ref":"#/components/schemas/WatchKind"},"name":{"type":["string","null"]},"app":{"type":"string","description":"Any `{app}` input. app: required; competitor_set: your own app (optional); keyword: the app whose ranks to report (optional)."},"competitors":{"type":"array","items":{"type":"string"},"maxItems":50,"description":"competitor_set only."},"terms":{"type":"array","items":{"type":"string"},"maxItems":500,"description":"keyword only (or `term`)."},"term":{"type":"string"},"store":{"type":"string","enum":["apple","play","both"],"description":"keyword watches without app (default both); also disambiguates app inputs."},"countries":{"type":"array","items":{"type":"string"},"default":["us"]},"event_types":{"type":["array","null"],"items":{"$ref":"#/components/schemas/EventType"},"description":"null = every type of the kind."},"settings":{"$ref":"#/components/schemas/WatchSettings"},"active":{"type":"boolean","default":true}}},"WatchPatch":{"type":"object","properties":{"name":{"type":["string","null"]},"app":{"type":["string","null"]},"competitors":{"type":"array","items":{"type":"string"}},"terms":{"type":"array","items":{"type":"string"}},"store":{"type":"string","enum":["apple","play","both"]},"countries":{"type":"array","items":{"type":"string"}},"event_types":{"type":["array","null"],"items":{"$ref":"#/components/schemas/EventType"}},"settings":{"$ref":"#/components/schemas/WatchSettings"},"active":{"type":"boolean"}}},"WatchApp":{"type":"object","properties":{"store":{"$ref":"#/components/schemas/Store"},"app_id":{"type":"string"},"title":{"type":["string","null"]},"icon_url":{"type":["string","null"]},"developer_name":{"type":["string","null"]}}},"Watch":{"type":"object","properties":{"id":{"type":"integer"},"kind":{"$ref":"#/components/schemas/WatchKind"},"name":{"type":["string","null"]},"store":{"type":["string","null"],"enum":["apple","play","both",null]},"app":{"oneOf":[{"$ref":"#/components/schemas/WatchApp"},{"type":"null"}]},"competitors":{"type":"array","items":{"$ref":"#/components/schemas/WatchApp"},"description":"competitor_set only."},"terms":{"type":"array","items":{"type":"string"},"description":"keyword only."},"keywords":{"type":"array","description":"keyword only: one slot per store × country × term (id = the tracked-keyword id).","items":{"type":"object","properties":{"id":{"type":"integer"},"term":{"type":"string"},"store":{"$ref":"#/components/schemas/Store"},"country":{"type":"string"},"ranked_at":{"type":["string","null"],"format":"date-time"}}}},"countries":{"type":"array","items":{"type":"string"}},"event_types":{"type":"array","items":{"$ref":"#/components/schemas/EventType"}},"settings":{"$ref":"#/components/schemas/WatchSettings"},"active":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"Event":{"type":"object","description":"Also the body of webhook deliveries and the GitHub `client_payload` (10 top-level keys).","properties":{"id":{"type":"string"},"type":{"$ref":"#/components/schemas/EventType"},"created_at":{"type":"string","format":"date-time"},"watch_id":{"type":["integer","null"],"description":"null once the watch is deleted."},"app":{"oneOf":[{"type":"object","properties":{"store":{"$ref":"#/components/schemas/Store"},"app_id":{"type":"string"},"title":{"type":["string","null"]},"icon_url":{"type":["string","null"]}}},{"type":"null"}]},"country":{"type":["string","null"]},"title":{"type":"string","description":"Deterministic one-liner, e.g. \"Spotify released version 9.0.2 (was 9.0.1)\"."},"summary":{"type":["string","null"],"description":"AI one-line summary (null when AI is off or for low-significance events)."},"significance":{"type":["number","null"],"minimum":0,"maximum":1},"payload":{"type":"object","description":"Type-specific: version / release_notes, changes[{field, old, new}], rating / previous_rating / drop, keyword / rank / previous_rank, chart / category / rank, topic / sample…"}},"example":{"id":"4812","type":"new_version","created_at":"2026-10-22T08:15:02.000Z","watch_id":12,"app":{"store":"apple","app_id":"324684580","title":"Spotify","icon_url":null},"country":"us","title":"Spotify released version 9.0.2 (was 9.0.1)","summary":"Spotify 9.0.2 adds offline lyrics and fixes CarPlay crashes.","significance":0.81,"payload":{"version":"9.0.2","previous_version":"9.0.1","release_notes":"Offline lyrics. CarPlay fixes."}}},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"integer"},"kind":{"type":"string","enum":["webhook","slack","github"]},"url":{"type":"string","description":"github: owner/repo; slack: shortened (the URL is a credential)."},"description":{"type":["string","null"]},"event_types":{"type":["array","null"],"items":{"$ref":"#/components/schemas/EventType"}},"active":{"type":"boolean"},"disabled_reason":{"type":["string","null"]},"failure_count":{"type":"integer","description":"Consecutive failed attempts."},"last_success_at":{"type":["string","null"],"format":"date-time"},"last_failure_at":{"type":["string","null"],"format":"date-time"},"secret":{"type":"string","description":"kind webhook: the signing secret, only in the create / rotate response."},"secret_hint":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"string"},"endpoint_id":{"type":"integer"},"event_id":{"type":["string","null"],"description":"null for test sends."},"event_type":{"type":"string"},"status":{"type":"string","enum":["pending","succeeded","failed"]},"attempts":{"type":"integer"},"next_attempt_at":{"type":["string","null"],"format":"date-time"},"response_status":{"type":["integer","null"]},"response_body":{"type":["string","null"],"description":"First 1000 characters."},"error":{"type":["string","null"]},"duration_ms":{"type":["integer","null"]},"created_at":{"type":"string","format":"date-time"},"delivered_at":{"type":["string","null"],"format":"date-time"}}}}}}