For developers
API reference
Plug DEXUN AdWhiz's three-platform AI optimization into your own tools, scripts, or backend via REST.
Base URL
All API requests go to this root:
https://www.7275.com/api/v1HTTPS is required. HTTP requests are rejected (not redirected).
Authentication
All requests need a Bearer token in the Authorization header. Generate one in dashboard → Settings → API Keys. Keys come in live and test flavors and can only access their own environment.
curl https://www.7275.com/api/v1/accounts \
-H "Authorization: Bearer dxk_live_...your-key..."- live key format: starts with dxk_live_, 64 characters
- test key format: starts with dxk_test_, scoped to the sandbox account
- Never use keys in front-end code — proxy through your own backend
- If leaked, immediately revoke and regenerate in dashboard
Use directly from Claude Desktop / Cursor (MCP server)
We ship a zero-dependency Model Context Protocol server so MCP clients like Claude Desktop and Cursor can read your AdWhiz state directly. No code to write — copy a config block, paste your API key, restart the client.
- Five read-only tools: list ad accounts, surface AI recommendations, get this-month savings, view recent activity, check API quota
- Mutation tools (apply / pause) deliberately not exposed yet — they wait until the optimizer exits shadow mode and we have calibration evidence to gate them
- Single Node 18+ script. Zero npm install. Runs on offline / airgapped machines just fine
- Your API key never leaves your machine. All requests HTTPS-direct to www.7275.com
Add this to Claude Desktop's claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\):
{
"mcpServers": {
"adwhiz": {
"command": "node",
"args": ["/path/to/mcp-server/src/index.mjs"],
"env": {
"ADWHIZ_API_KEY": "dxk_live_..."
}
}
}
}Full install guide, Cursor config and troubleshooting on GitHub: github.com/dexun-inc/adwhiz/mcp-server.
Endpoints
The v1 API exposes 13 core endpoints covering identity, account reads, recommendation generation (applying one is not available yet), audit logs, API key management, quota introspection, and the changelog feed.
| Method | Path | Description |
|---|---|---|
| GET | /me | Returns the calling token owner + remaining rate-limit quota (whoami) |
| GET | /accounts | List all ad accounts the current user has connected (across all three platforms) |
| GET | /accounts/{id}/campaigns | List campaigns, ad groups, keywords, and 7/30-day metrics for one account |
| POST | /recommendations/generate | Have the AI generate a fresh batch of optimization recommendations |
| GET | /recommendations | List all pending / applied / dismissed recommendations |
| POST | /recommendations/{id}/apply | Apply one recommendation — not available yet: returns 501 not_supported and changes nothing |
| POST | /recommendations/{id}/dismiss | Dismiss one recommendation — not available yet: returns 501 not_supported and changes nothing |
| POST | /changes/{id}/rollback | Roll back an applied change — not available yet: returns 501 not_supported and changes nothing |
| GET | /audit-log | (Deprecated, sunset 2027-05-23) Full audit log. Use /audit-events instead — backed by the real audit_events table with ?kind filtering |
| GET | /audit-events | Security audit-events stream (sign-in / password / OAuth / subscription), with ?since + ?kind filters |
| GET | /api-keys | List the caller's API keys (incl. lastUsedAt + active); hashedKey is never returned |
| GET | /usage | Read the current tier, RPM limit, remaining, and reset_at without a probe request |
| GET | /changelog | Product changelog JSON feed (public, no auth) with ETag + ?lang + ?limit (1..50) + ?since=YYYY-MM-DD — canonical incremental-poll shape |
Example request
Generate fresh three-platform optimization recommendations:
curl -X POST https://www.7275.com/api/v1/recommendations/generate \
-H "Authorization: Bearer dxk_live_..." \
-H "Content-Type: application/json" \
-d '{
"account_id": "ga-548-203-7184",
"platforms": ["google_ads", "meta_ads", "tiktok_ads"],
"window": "7d"
}'Example response:
{
"summary": "Pausing 3 high-CPA keywords and reallocating budget...",
"recommendations": [
{
"id": "rec_001",
"type": "pause_keyword",
"target": { "accountId": "ga-548-203-7184", "keywordText": "wool socks" },
"title": "Pause broad-match 'wool socks'",
"reason": "7-day CPA $45.82 vs target $8",
"expectedImpact": "Save ~$412/week",
"confidence": "high"
}
]
}Incrementally polling /changelog
/api/v1/changelog is a public endpoint (no API key required) with four bandwidth-saving knobs: ETag + If-None-Match, Last-Modified + If-Modified-Since (curl -z), ?since=YYYY-MM-DD for date-filtered fetches, and ?limit=N for size-capped fetches. SDKs and cron scripts can combine these to poll frequently without re-downloading the same JSON.
# 1. First call — store the ETag (or Last-Modified) you get back.
curl -i 'https://www.7275.com/api/v1/changelog?limit=10'
# 2. Subsequent calls — pass the stored ETag.
# Server returns 304 with empty body if nothing has shipped.
curl -i 'https://www.7275.com/api/v1/changelog?limit=10' \
-H 'If-None-Match: "abc123..."'
# 3. Or anchor on a date instead of an ETag.
# Only entries whose `date >= since` come back; pair with ?limit
# to cap the response size.
curl 'https://www.7275.com/api/v1/changelog?since=2026-01-01&limit=20'
# 4. curl -z for Last-Modified-style conditional GET (no ETag needed):
curl -z 'Mon, 20 May 2026 00:00:00 GMT' \
'https://www.7275.com/api/v1/changelog'Rate limits
Tiered by subscription plan to avoid hammering upstream Google / Meta / TikTok quotas:
- Professional: 120 requests/minute
- Business: 600 requests/minute
- Enterprise: custom (typically 3,000 requests/minute)
- Over the limit returns 429 + retry-after header — exponential backoff recommended
Error codes
All errors return JSON with error.code, error.message, and error.request_id:
| HTTP status | Meaning |
|---|---|
401 | Missing or invalid API key |
403 | Account not authorized for this resource (insufficient OAuth scope) |
404 | Resource not found or deleted |
422 | Invalid request parameters |
429 | Rate limit exceeded — wait for retry-after header |
500 | Server error — automatically reported |
503 | Upstream platform API temporarily unavailable (Google / Meta / TikTok) |