Watches
A watch follows an app or a niche in the markets you choose and tells you when something changes. Detection runs in the ingest worker over listing history, chart snapshots and collected ads, so a watch sees changes at the rate the library refreshes them (weekly for listings and charts by default; see Data and freshness).
Events
| Event | Fires when | Payload highlights |
|---|---|---|
listing.changed | A storefront's title, description, screenshots or price changes | changes.title (from, to), changes.description, changes.screenshots (from and to counts), changes.price (from, to), market_code, store, captured_at |
rank.moved | A chart rank moves by at least threshold places (default 5) | previous_rank, current_rank, movement, niche_slug, market_code, store, captured_on |
ad.new | A new ad is collected for the watched app (or, for a niche watch, the niche) | creative_id, source, headline, first_seen_on, delivery_start. Needs Paid data, which arrives as ad-library connections go live. |
Each event is delivered once per change, to every destination on the watch. A webhook body has this shape:
{
"event": "rank.moved",
"event_id": <uuid>,
"watch_id": <uuid>,
"target_type": "app",
"target_id": "529479190",
"market": "es",
"occurred_at": <timestamp>,
"data": { "previous_rank": <int>, "current_rank": <int>, "movement": <int>, ... }
}
Create
curl -X POST https://api.threefold.eco/api/watches \
-H "Authorization: Bearer tf_live_your_key" \
-H "Content-Type: application/json" \
-d '{"target_type":"app","target_id":"529479190","markets":["es","de"],"events":["listing","rank","ad"],"threshold":5,"webhook_url":"https://example.com/threefold-hook","webhook_secret":"your-secret","email":"alerts@example.com"}'
| Field | Required | Meaning |
|---|---|---|
target_type | yes | app or niche |
target_id | yes | App Store id (for example 529479190) or niche slug (for example games) |
markets | Markets to watch. Default: all. | |
events | Any of listing, rank, ad. Default: all three. | |
threshold | Rank movement that counts as a move. Default 5. | |
webhook_url, webhook_secret | Where to POST events, and the secret to sign them with | |
email | Where to email events |
Manage
Over MCP
Watching and competitor monitoring over MCP are unified inside the workspace tool (docs/agent-tools.md):
- Start watching:
workspacewith{ "action": "watch", "apps": ["<app-id-or-name>"], "markets": ["es", "de"] }. - Review changes:
workspacewith{ "action": "changes", "since": "YYYY-MM-DD" }. - Stop watching:
workspacewith{ "action": "unwatch", "apps": ["<app-id-or-name>"] }.
Over REST
| REST Route | What |
|---|---|
POST /api/watches | Create a watch |
GET /api/watches | Your workspace's watches |
GET /api/watches/:id/events | Detected events and each delivery attempt |
POST /api/watches/:id/delete | Stop a watch |
Verifying webhooks
Each webhook is a JSON POST signed with HMAC-SHA256 of the body using your webhook_secret, sent as X-Threefold-Signature: sha256=<hex>. Compute the same HMAC over the raw body and compare in constant time. Webhook URLs are checked when you create the watch and again when sending: they must resolve to public addresses.
Plans
Watches are available on Team (up to 10) and Enterprise (no set limit). Each watch carries a monthly charge recorded through the meter; the amount is a beta figure. See Pricing.