MCP & API
MCP Server & API
Bring your ASO data into Claude, Cursor, and any agent. Ask "what should I optimize this week?" and get an answer grounded in your real keyword ranks, page-one opportunities, and weekly action plan — then let it act: optimize toward a keyword, generate metadata, translate it. Through the MCP server or the REST API.
Building a platform that ships apps for your customers? See the Store-Ops API for platforms →
Score any App Store / Google Play keyword — difficulty + popularity.
Read an app's tracked keywords and their latest store rank.
Keywords ranked 11–30, ordered easiest-to-move first.
This week's prioritized ASO actions across all your apps.
AI-rewrite title/subtitle/keywords toward a target keyword — with an apply step.
ASO metadata generation and 40-language translation, from your agent.
1. Get an API key
Create a key in the Developers area of your dashboard. Keys look like ad_live_… and are shown in full exactly once — store it safely, we only keep a hash. API access is available on every paid plan (7-day free trial).
2a. MCP server (Claude, Cursor)
Add AppDrift to your MCP client config, drop in your key, and restart the client. Claude Desktop config lives in claude_desktop_config.json:
{
"mcpServers": {
"appdrift": {
"command": "npx",
"args": ["-y", "appdrift-mcp"],
"env": { "APPDRIFT_API_KEY": "ad_live_your_key_here" }
}
}
}appdrift-mcp package is open source and rolling out to npm. Until it lands, clone the repo and point command at node with the absolute path to mcp-server/index.js — see the server README.Tools exposed to the agent:
| Tool | What it does |
|---|---|
| keyword_difficulty | Score any keyword (difficulty + popularity). Free. |
| list_apps | List apps connected to your account. Free. |
| app_keywords | An app's tracked keywords with latest rank. Free. |
| app_opportunities | Page-one push candidates (rank 11–30). Free. |
| action_plan | This week's prioritized ASO actions. Free. |
| account_status | Plan + remaining token balance. Free. |
| optimize_for_keyword | AI-rewrite toward a target keyword. 3 tokens, charged on success. |
| apply_optimization | Write accepted fields to the app's draft version. Free. |
| generate_metadata | Generate ASO metadata from a brief. 1 token/field (2 for long fields). |
| translate_metadata | Translate a field into up to 15 languages. 1 token/language (3–5 for long fields). |
2b. REST API
Prefer to call it directly? Every endpoint takes your key as a bearer token; reads are GET, AI actions are POST with a JSON body. A machine-readable OpenAPI spec lives at /.well-known/openapi.json. Base URL:
https://appdrift-backend-1fabfc95f592.herokuapp.comcurl -H "Authorization: Bearer ad_live_your_key_here" \
"https://appdrift-backend-1fabfc95f592.herokuapp.com/v1/apps"Endpoints
keyword (required), platform (ios|android, default ios), country (default us).curl -H "Authorization: Bearer ad_live_..." \
"https://appdrift-backend-1fabfc95f592.herokuapp.com/v1/keyword-difficulty?keyword=meditation&platform=ios&country=us"{
"data": {
"keyword": "meditation",
"platform": "ios",
"country": "us",
"difficulty": 63,
"popularity": 41,
"source": "live"
}
}id below with the app-scoped endpoints.null = outside the tracked range).AI endpoints (charge tokens on success)
These consume plan tokens at the same prices as the dashboard, and only charge when the call succeeds. A failed call never charges.
keyword (required), country. Costs 3 tokens.curl -X POST -H "Authorization: Bearer ad_live_..." -H "Content-Type: application/json" \
-d '{"keyword": "habit tracker"}' \
"https://appdrift-backend-1fabfc95f592.herokuapp.com/v1/apps/123/optimize"fields (object from the optimize response's proposed).platform, app_name, app_description, optional fields, language, keywords. iOS fields: name, subtitle, promotional_text, description, keywords. Android: title, short_description, full_description. Costs 1 token per short field, 2 per long field.curl -X POST -H "Authorization: Bearer ad_live_..." -H "Content-Type: application/json" \
-d '{"platform": "ios", "app_name": "Drift", "app_description": "A minimalist habit tracker with streaks and reminders.", "fields": ["subtitle", "keywords"]}' \
"https://appdrift-backend-1fabfc95f592.herokuapp.com/v1/generate-metadata"field (title, subtitle, description, whats_new, promotional_text, android_title, short_description, full_description, recent_changes), text, target_languages. Costs 1 token per language (3 for description, 5 for full_description).curl -X POST -H "Authorization: Bearer ad_live_..." -H "Content-Type: application/json" \
-d '{"field": "subtitle", "text": "Build habits that stick", "target_languages": ["de-DE", "ja", "es-MX"]}' \
"https://appdrift-backend-1fabfc95f592.herokuapp.com/v1/translate"Rate limits
Per API key: 300 requests / 15 min overall, and 30 / 15 min on the AI endpoints. Standard RateLimit-* headers tell you where you stand.
3. Webhooks
Don't want to poll? AppDrift can push events to your own endpoints as they happen. Add up to 5 endpoints from the Developers area of your dashboard — available on every paid plan.
Events
| Event | Fires when |
|---|---|
| keyword.rank_change | Keyword rank threshold crossed |
| monitoring.alert | Store monitoring alert |
| action_plan.ready | Weekly Autopilot plan ready |
Payload
Every delivery is a POST with a JSON envelope:
{
"id": "evt_9f2c1a7d3b",
"type": "keyword.rank_change",
"created_at": "2026-08-03T09:00:00.000Z",
"data": { /* event-specific payload */ }
}Verifying signatures
Each endpoint gets a signing secret (whsec_…) shown exactly once at creation. Every delivery carries an X-AppDrift-Signature header in the form t=<unix>,v1=<hex>. Recompute the HMAC-SHA256 of `${t}.${rawBody}` with your secret, compare with a timing-safe compare, and reject anything whose timestamp is more than 5 minutes old:
const crypto = require("crypto");
// signatureHeader = req.headers["x-appdrift-signature"] → "t=1722672000,v1=abc123…"
// rawBody must be the exact raw request body string, not re-serialized JSON.
function verifyAppDriftSignature(rawBody, signatureHeader, secret) {
const parts = Object.fromEntries(
signatureHeader.split(",").map((kv) => kv.split("="))
);
const t = Number(parts.t);
// Reject stale timestamps (replay protection): older than 5 minutes.
if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false;
const expected = crypto
.createHmac("sha256", secret)
.update(`${t}.${rawBody}`)
.digest("hex");
const provided = parts.v1 || "";
// Compare decoded bytes; malformed hex would otherwise truncate or throw.
const a = Buffer.from(expected, "hex");
const b = Buffer.from(provided, "hex");
if (a.length !== b.length) return false;
try {
return crypto.timingSafeEqual(a, b);
} catch {
return false;
}
}Retries & auto-disable
- 4 attempts per event: immediate, then +1 minute, +10 minutes, and +60 minutes. A 2xx response counts as delivered; anything else (or a timeout) schedules the next retry.
- Auto-disable: after 20 consecutive failed deliveries the endpoint is disabled. Fix your receiver, then re-enable it from the Developers page — a “Send test” button lets you verify before real events flow again.
- Limits: up to 5 endpoints per account, each subscribed to any subset of the events above.
Notes
- Never store-direct. AI endpoints return proposals or write to your app's draft version inside AppDrift — nothing reaches the App Store or Play Store without your normal review → publish flow.
- Charge on success. AI endpoints check your token balance up front and only consume tokens when the call returns a result. Failed calls never charge.
- Tenant-scoped. A key only ever sees the account it was created in. Revoke a key any time from the Developers page.
- Cached where it helps. Keyword difficulty is served from a shared cache when fresh and computed live otherwise — the
sourcefield tells you which.
Ready to build?
Grab a key and wire AppDrift into your agent in a couple of minutes.
Create an API key