API v1 · included in Pro and Agency
The SEOClave API
Real, current Google data (search volume, CPC, difficulty, intent, the top 10 and where each site ranks) inside your scripts, your spreadsheets, n8n, Make or your ChatGPT/Claude. What your AI can't make up: numbers with a date and a source.
- No extra cost: it uses the same credits as the website.
- Repeats are free for 30 days (the top 10, 7 days).
- If it fails or comes back empty, you're not charged.
- Caps that protect you from a script gone wrong.
OpenAPI specification: /api/v1/openapi.json
Start in 2 minutes
- Log in and open API (in the menu).
- Click Create key and copy it: it's shown only once.
- Try it (it doesn't use credits):
curl https://seoclave.com/api/v1/account/ \ -H "Authorization: Bearer sc_YOUR_KEY"
{
"plan": "Pro",
"balance": 150,
"plan_expires": "2026-12-02T14:00:00+00:00",
"limits": { "per_minute": 10, "requests_per_day": 1000, "credits_per_day": 50 },
"today": { "requests": 1, "credits": 0 }
}Authentication
Every request carries the header Authorization: Bearer sc_…. The key never goes in the URL (it would end up in histories and logs) and it doesn't work from the website session. Treat it like a password: whoever has it spends your credits. You can have up to 3 and revoke any of them instantly; when you create one, we email you.
Limits by plan
Per account, adding up all your keys. They're mandatory: they protect your credits and everyone's service.
| Pro | Agency | |
|---|---|---|
| Requests per minute | 10 | 20 |
| Requests per day | 1,000 | 2,000 |
| Credits per day through the API | 50 (you can lower it) | 100 (you can lower it) |
| Active keys | 3 | 3 |
Every response includes X-RateLimit-Limit and X-RateLimit-Remaining (this minute); go over and you get a 429 with Retry-After in seconds. Requests rejected by a limit aren't charged.
Endpoints
GET/account/free
POST/keywords/estimate/free
How many credits a query would cost, without running it. Same body as /keywords/.
POST/keywords/uses credits
The query. Fields:
| Field | What it is |
|---|---|
mode | ideas (keywords for a topic) · suggestions (long tail) · volume (measure your list) · serp (today's top 10) · ranked_keywords (keywords a domain ranks for) |
query | The keyword, topic, domain or your list (one per line) |
country | us, ca, es, mx, br, fr, be, ch… and all of Latin America (default us) |
language | es, en, pt (only with br) or fr (French-speaking countries). Default: the country's main language (en for us) |
limit | Maximum rows, up to 1,000 (default 200). More rows, more credits |
max_credits | The most you accept to spend on this query. If it would cost more, it isn't run or charged |
refresh | true = fresh data even if you already paid for it (charges again; ignored if you paid less than 24 h ago) |
curl https://seoclave.com/api/v1/keywords/ \
-H "Authorization: Bearer sc_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"mode": "ideas", "query": "immigration lawyer", "country": "us", "limit": 50, "max_credits": 1}'{
"id": 812, "mode": "ideas", "cached": false, "empty": false,
"result": { "rows": [
{ "keyword": "immigration lawyer near me", "volume": 9900, "cpc": 18.4,
"difficulty": 31, "intent": "commercial", "trend": [ … ] }
] },
"credits": 1, "balance": 149, "notices": []
}GET/keywords/{id}/free
GET/projects/free
GET/projects/{id}/free
GET/projects/{id}/tracking/free
What it costs
| Query | Credits |
|---|---|
| Top 10 for one keyword (serp) | 1 |
| ideas, suggestions or ranked_keywords with 50 rows | 1 |
| … with 200 rows | 2 |
| … with 500 rows | 4 |
| … with 1,000 rows | 7 |
| volume: list of up to 66 keywords | 1 |
| volume: up to 230 keywords | 2 |
| volume: 700 keywords | 5 |
| What you already paid for in the last 30 days | Free |
How not to burn credits
- Always set
max_credits. If your script builds a bad request, it won't spend more than that. - Ask only for the rows you'll use.
limit: 50costs 1 credit; 1,000 rows, 7. - Measure in batches. A 60-keyword list in
volumecosts 1 credit; 60 separate requests, 60. - Don't use
refreshin loops. Repeats are already free for 30 days; refresh within 24 h and we return what you have without charging. - Keep the
id. Reading/keywords/{id}/again is free. - Lower your daily cap in API while you test.
- On a 429, wait as long as
Retry-Aftersays: retrying right away doesn't help.
Errors
Always {"error": {"code": "…", "message": "…"}}. The code never changes: branch on it. The message is for people: it comes in the Accept-Language language (en, es, pt or fr) or, if you don't send it, in your account's language.
| HTTP | code | What happened |
|---|---|---|
| 401 | missing_key | You didn't send the Authorization header |
| 401 | invalid_key | The key doesn't exist or was revoked |
| 403 | plan_without_api | Your plan isn't active or doesn't include the API |
| 400 | invalid_request | The JSON or a field can't be understood |
| 402 | insufficient_credits | You don't have enough credits for this query |
| 402 | exceeds_max_credits | It would cost more than your max_credits: not run |
| 404 | not_found | That doesn't exist in your account |
| 413 | request_too_large | The request is over 32 KB |
| 429 | rate_limit_per_minute | Too many requests per minute (see Retry-After) |
| 429 | daily_request_limit | Too many requests today |
| 429 | daily_credit_limit | It would go over your daily credit cap |
| 429 | too_many_failed_keys | Too many wrong keys from your connection: wait 10 minutes |
| 429 | service_daily_cap | The service hit its daily cap; you weren't charged |
| 502 | provider_error | The data provider failed; you weren't charged |
| 503 | maintenance | Maintenance; you weren't charged |
If you used the Spanish names
Until November 11, 2026 the API had Spanish routes and fields. They keep working exactly the same, with Spanish responses and codes: you don't have to change anything. Their error mensaje follows the same rule as message: Accept-Language, else your account's language, else Spanish. For new code, use the English names.
| 2026-11-11 → | ← 2026-11-11 |
|---|---|
/account/ | /cuenta/ |
/keywords/ | /palabras/ |
/keywords/estimate/ | /palabras/presupuesto/ |
/keywords/{id}/ | /palabras/{id}/ |
/projects/ | /proyectos/ |
/projects/{id}/tracking/ | /proyectos/{id}/seguimiento/ |
mode · query · country · language | modo · texto · pais · idioma |
limit · max_credits · refresh | limite · max_creditos · refrescar |
suggestions · volume · ranked_keywords | sugerencias · volumen · nuestras |
MCP connector: Claude, Cursor and more
MCP is the open standard AI assistants use to call external tools. Connect SEOClave and your AI queries Google on its own when the conversation needs it: “how many people search for lawyer in Houston?”, “where do I rank for leather boots?”. It uses the same key, spends the same credits and follows the same limits (only queries count, not the handshake or the tool list). Only keyword research (50 rows = 1 credit; repeating it within 30 days is free) and the top 10 (1 credit) spend credits; the cost estimate, audit, robots.txt, DNS, redirects and your projects are free.
Connector URL: https://seoclave.com/api/v1/mcp
claude mcp add --transport http seoclave https://seoclave.com/api/v1/mcp \ --header "Authorization: Bearer sc_YOUR_KEY"
{
"mcpServers": {
"seoclave": {
"url": "https://seoclave.com/api/v1/mcp",
"headers": { "Authorization": "Bearer sc_YOUR_KEY" }
}
}
}| Tool | What it does | Credits |
|---|---|---|
| account | Your plan, balance, limits and today's usage | Free |
| estimate_cost | What a keyword query would cost, without running it | Free |
| keyword_research | Keyword research: volume, CPC, difficulty, intent and trend | 50 rows = 1 credit (repeat within 30 days, free) |
| google_top10 | Google's top 10 today, with the opportunity score | 1 credit |
| saved_search | Open a search you already paid for | Free |
| list_projects | Your projects | Free |
| get_project | A project with its keywords: volume, position and status | Free |
| rank_tracking | Weekly position history (1-30) | Free |
| site_audit · get_audit | SEO audit of a website and its report (AI crawlers too) | Free (daily audit limit) |
| check_robots_txt | Test robots.txt with Google's rules | Free |
| check_dns | DNS, email (SPF, DMARC) and www | Free |
| check_redirects | Redirects, loops and http/www variants | Free |
claude.ai (web and mobile) and Claude Desktop: one click
- In claude.ai, open Settings → Connectors → Add custom connector.
- Name: SEOClave. URL:
https://seoclave.com/api/v1/mcp. - Authentication: sign in with OAuth, using Claude's published identity or automatic registration (both work). No headers.
- Click Connect: we bring you to SEOClave, you log in and click Allow. No keys to copy.
ChatGPT
- Turn on developer mode in Settings → Apps & Connectors → Advanced (depending on your ChatGPT plan).
- Create a connector with the URL
https://seoclave.com/api/v1/mcpand OAuth authentication. - Connect it: we bring you to SEOClave, you log in and click Allow.
Other assistants that accept MCP connectors with sign-in (OAuth) connect the same way. You see it and disconnect it in API → Connections.
Connect it to your AI and your tools
- ChatGPT (custom GPT): under Actions, import the schema from
https://seoclave.com/api/v1/openapi.jsonand choose «API Key» authentication, type «Bearer», with your key. Your GPT can then measure keywords and check today's top 10 on its own. - n8n or Make: an HTTP Request node with the header
Authorization: Bearer sc_…. - Claude and other assistants: with the MCP connector, your AI queries SEOClave on its own.
import requests
r = requests.post("https://seoclave.com/api/v1/keywords/",
headers={"Authorization": "Bearer sc_YOUR_KEY"},
json={"mode": "volume", "query": "shoes\nleather boots\nsandals", "country": "us", "max_credits": 1},
timeout=60)
r.raise_for_status()
for row in r.json()["result"]["rows"]:
print(row["keyword"], row["volume"], row["cpc"])const r = await fetch("https://seoclave.com/api/v1/keywords/", {
method: "POST",
headers: { Authorization: "Bearer sc_YOUR_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ mode: "serp", query: "lawyer in houston", country: "us", max_credits: 1 }),
});
const data = await r.json();
if (!r.ok) throw new Error(data.error.code);
console.log(data.result.organic.slice(0, 3));Questions, or something missing? Write to us from the help center. By using the API you accept the terms.