Watch an app, a set of competitors or a set of keywords and get events when something significant changes.

POSThttps://api.appgoat.ai/v1/watches
FreeMCP tool watchoperationId createWatch

Use this when the user wants to be told about changes ("tell me when a competitor updates", "alert me when my rating drops", "track my ranks for these keywords"). Kinds:

  • app { app }: new versions, metadata / price changes, featuring, rating drops, review and ratings spikes, chart entries for that app.
  • competitor_set { app?, competitors[] }: the same for every app in the set (your own app optional).
  • keyword { terms[], store, app? }: search-rank moves of app for each term (rank_change) and new apps in the top N (keyword_entrant). Watched apps (competitors included) count against limits.watches; keyword watches use one keyword slot per term × store × country (limits.keywords). Exceeding either returns 402 plan_limit and changes nothing. Watched apps are refreshed daily. Events appear at GET /v1/events and go to your webhooks.

Request

curl -X POST "https://api.appgoat.ai/v1/watches" \
  -H "x-api-key: $APPGOAT_API_KEY" \
  -H "content-type: application/json" \
  -d '{"kind":"app","name":"string","app":"string","competitors":["string"],"terms":["string"],"term":"photo editor","store":"apple","countries":["us"],"event_types":["new_version"],"settings":{"significance":0.5,"rank_move":5,"keyword_top_n":10,"chart_top_n":100,"rating_drop":0.1,"spike_factor":3,"email_digest":true,"depth":1,"cadence_minutes":1},"active":true}'

Request body

JSON, required.

kindWatchKind
namestring | null
appstring
Any {app} input. app: required; competitor_set: your own app (optional); keyword: the app whose ranks to report (optional).
competitorsstring[]
competitor_set only.
termsstring[]
keyword only (or term).
termstring
store"apple" | "play" | "both"
keyword watches without app (default both); also disambiguates app inputs.
countriesstring[]
event_typesEventType[] | null
null = every type of the kind.
settingsWatchSettings
activeboolean

Response

201 with data: Watch. See the envelope for meta.

idinteger
kindWatchKind
namestring | null
store"apple" | "play" | "both" | null
appany
competitorsWatchApp[]
competitor_set only.
termsstring[]
keyword only.
keywordsobject[]
keyword only: one slot per store × country × term (id = the tracked-keyword id).
keywords[].idinteger
keywords[].termstring
keywords[].storeStore
keywords[].countrystring
keywords[].ranked_atstring | null
countriesstring[]
event_typesEventType[]
settingsWatchSettings
activeboolean
created_atstring
updated_atstring
Example
{
  "data": {
    "id": 1,
    "kind": "app",
    "name": "string",
    "store": "apple",
    "app": null,
    "competitors": [
      {
        "store": "apple",
        "app_id": "324684580",
        "title": "Spotify: Music and Podcasts",
        "icon_url": "string",
        "developer_name": "string"
      }
    ],
    "terms": [
      "string"
    ],
    "keywords": [
      {
        "id": 1,
        "term": "photo editor",
        "store": "apple",
        "country": "us",
        "ranked_at": "2026-10-22T10:00:00Z"
      }
    ],
    "countries": [
      "string"
    ],
    "event_types": [
      "new_version"
    ],
    "settings": {
      "significance": 0.5,
      "rank_move": 5,
      "keyword_top_n": 10,
      "chart_top_n": 100,
      "rating_drop": 0.1,
      "spike_factor": 3,
      "email_digest": true,
      "depth": 1,
      "cadence_minutes": 1
    },
    "active": false,
    "created_at": "2026-10-22T10:00:00Z",
    "updated_at": "2026-10-22T10:00:00Z"
  },
  "meta": {
    "credits_used": 0,
    "credits_remaining": 9981,
    "request_id": "req_123"
  }
}

Status codes

201
The watch.
A parameter is missing or invalid (error.param names it).
Missing or invalid API key.
insufficient_credits (the call costs more than you have left; nothing was done) or plan_limit (a feature of a higher plan).
Nothing matches {app}, or the store does not have it.
Too many requests per second for your plan.