Public API
Pull the same keyword, rank, and opportunity data the dashboard shows you, straight from your own scripts and CI pipelines. Available on the Pro plan. See plans.
Authentication
Every request needs an Authorization: Bearer <key> header. Create a key from Settings → API keys -- keys look like psk_live_... and are shown exactly once, at creation. We store only a SHA-256 hash of your key, never the raw value, so if you lose it there's no way to retrieve it -- revoke it and create a new one instead.
A key created while you're on the Pro plan stops working immediately if you later downgrade -- every request re-checks your current plan, not whatever plan was active when the key was created.
curl "https://api.sonartree.com/v1/external/user/keywords?appId=123" \
-H "Authorization: Bearer psk_live_5f3a9c1e7b2d4a6f8e0c9b1d3a5f7e9c1b3d5f7e9c1b3d5f7e9c1b3d5f7e9c1b"Base URL
Every path below is relative to:
https://api.sonartree.comRate limit
600 requests per hour, per API key -- not per account and not per IP, so multiple keys on the same account each get their own 600/h budget, and the same key used from different machines shares one budget. Exceeding it returns 429:
{ "error": "rate_limited", "details": { "limit": 600, "used": 600 } }Endpoints
These four endpoints mirror the exact same data and access rules as the dashboard -- an appId/appleId must be one of YOUR connected apps (own or competitor); an unconnected or unknown app id returns 403 or 404, the same as it would in the app.
/v1/external/user/keywordsList tracked keywords
Your tracked keywords for one connected app, with each keyword's current popularity, difficulty, opportunity score, and this app's own rank.
Request
curl "https://api.sonartree.com/v1/external/user/keywords?appId=123" \
-H "Authorization: Bearer psk_live_5f3a9c1e7b2d4a6f8e0c9b1d3a5f7e9c1b3d5f7e9c1b3d5f7e9c1b3d5f7e9c1b"Response
{
"keywords": [
{
"id": 4821,
"keywordId": 42,
"term": "habit tracker",
"storefront": "US",
"createdAt": "2026-06-01T00:00:00.000Z",
"crawlTier": "tracked",
"popularity": 54,
"difficulty": 38,
"opportunity": 16.2,
"rank": 12
}
]
}/v1/external/keywords/:keywordId/ranksRank history
Daily rank history for one keyword, one storefront, one connected app. Depth follows your plan's history limit (Pro: unlimited, capped at 730 days per request).
Request
curl "https://api.sonartree.com/v1/external/keywords/42/ranks?storefront=US&appId=123&days=30" \
-H "Authorization: Bearer psk_live_5f3a9c1e7b2d4a6f8e0c9b1d3a5f7e9c1b3d5f7e9c1b3d5f7e9c1b3d5f7e9c1b"Response
{
"ranks": [
{ "date": "2026-06-30", "rank": 14, "source": "storefront" },
{ "date": "2026-07-01", "rank": 12, "source": "storefront" }
],
"upgradeRequired": false
}/v1/external/apps/:appId/opportunitiesOpportunities
Corpus-wide keywords at popularity >= 20 for one storefront, ranked by opportunity score, annotated with this app's own current rank and a defend/push/target label.
Request
curl "https://api.sonartree.com/v1/external/apps/123/opportunities?storefront=US" \
-H "Authorization: Bearer psk_live_5f3a9c1e7b2d4a6f8e0c9b1d3a5f7e9c1b3d5f7e9c1b3d5f7e9c1b3d5f7e9c1b"Response
{
"opportunities": [
{
"keywordId": 42,
"term": "habit tracker",
"popularity": 54,
"difficulty": 38,
"opportunity": 16.2,
"rank": 12,
"label": "defend"
}
]
}/v1/external/apps/:appleId/reverseReverse keyword lookup
Every keyword a connected app ranks for, on its most recent crawl date, for one storefront. Takes the app's raw Apple id (the numeric id in its App Store URL), not the internal app id the other endpoints use.
Request
curl "https://api.sonartree.com/v1/external/apps/6446901087/reverse?storefront=US" \
-H "Authorization: Bearer psk_live_5f3a9c1e7b2d4a6f8e0c9b1d3a5f7e9c1b3d5f7e9c1b3d5f7e9c1b3d5f7e9c1b"Response
{
"date": "2026-07-01",
"keywords": [
{ "keywordId": 42, "term": "habit tracker", "rank": 12, "popularity": 54, "difficulty": 38 }
]
}Errors
Every error is JSON: { "error": string, "details"?: unknown }.
| Status | error | Meaning |
|---|---|---|
| 401 | unauthenticated | No Authorization header was sent. |
| 401 | invalid_api_key | The key is unrecognized or has been revoked. |
| 403 | upgrade_required | The key's account isn't on the Pro plan. |
| 403 | forbidden | The requested app isn't one of your connected apps. |
| 404 | app_not_found | That appleId (reverse lookup only) has never been seen. |
| 400 | validation_failed | A required or malformed query parameter. |
| 429 | rate_limited | More than 600 requests in the trailing hour. |
Questions? [email protected]