Keyword Analysis API MCP Server

Agent-first keyword analysis API for live SERP research, page scraping, and SEO keyword synthesis.

Documentation

keyword-analysis-api

Agent-first keyword analysis API for live SERP research, page scraping, and keyword synthesis.

Summary

This service is designed for LLMs and MCP-style agents that need to:

  • create an account without a traditional website flow
  • verify ownership of an email with a one-time code
  • run live keyword analysis against Google results
  • receive structured SEO-oriented output focused on word count and keyword density
  • defer billing setup until after free usage is exhausted

The product is mostly headless. Human interaction is only required for:

  • reading the email verification code
  • completing hosted Stripe billing setup when free usage is exhausted

Authentication Flow

  1. POST /auth/create-accountCreate or resume a pending account for an email address.
  2. POST /auth/verify-accountSubmit the one-time code sent by email. On success this returns an API token.
  3. Use the API token as either:
  • Authorization: Bearer <token>
  • X-API-Key: <token>

MCP Connector

  • MCP endpoint: GET/POST /mcp
  • OAuth metadata: GET /.well-known/oauth-authorization-server
  • OAuth authorize: GET /oauth/authorize
  • OAuth token exchange: POST /oauth/token
  • Dynamic client registration: POST /oauth/register

The MCP server exposes tool wrappers for:

  • account status
  • usage summary
  • queued keyword analysis
  • job lookup and listing
  • billing setup

Primary Endpoint

POST /keyword-analysis/analyze

Queue a keyword analysis job that will:

  • fetch live SERP results from Bright Data
  • scrape the top results with Jina Reader
  • calculate suggested target word count
  • score primary and supporting keyword candidates from the ranking-page corpus
  • recommend the closest ranking-backed primary keyword for the user's original query
  • use a constrained LLM cleanup pass to choose the strongest supporting keywords from those candidates
  • calculate primary and secondary keyword density targets from the ranking-page corpus

Input

{
  "keyword": "ai teaching assistant",
  "top_n_results": 5,
  "include_page_content": false
}

Output

Returns:

  • keyword
  • suggested_word_count
  • total_results_analyzed
  • results
  • analysis.primary_keyword
  • analysis.primary_keyword_density
  • analysis.secondary_keywords

Notes:

  • keyword is the user's original query
  • analysis.primary_keyword is the recommended ranking-backed primary keyword target
  • results contains only the pages actually used in the analysis and each item includes analysis_rank

OpenAPI Summary

Auth

  • POST /auth/create-account
  • POST /auth/verify-account
  • GET /auth/account-status
  • GET /auth/usage-summary

Billing

  • POST /billing/start-billing-setup
  • POST /billing/stripe/webhooks
  • GET /billing/setup/success
  • GET /billing/setup/cancel

Keyword Analysis

  • POST /keyword-analysis/analyze

Discovery

  • GET /
  • GET /mcp
  • GET /.well-known/oauth-authorization-server
  • GET /llms.txt
  • GET /.well-known/llms.txt
  • GET /openapi.json

Account and Billing Endpoints

GET /auth/account-status

Get verified status, billing status, and free-search availability.

GET /auth/usage-summary

Get free usage, paid usage, successful searches, and failed searches.

POST /billing/start-billing-setup

Return a hosted Stripe URL for payment-method setup or billing management.

POST /billing/stripe/webhooks

Stripe webhook endpoint for billing state updates.

Example Flows

1. Create Account

Request:

{
  "email": "[email protected]"
}

Response:

{
  "pending_user_id": "pending_abcd1234",
  "verification_required": true,
  "expires_in_seconds": 600,
  "delivery_method": "smtp"
}

In development, delivery_method may be console and verification_code may be included directly.

2. Verify Account

Request:

{
  "pending_user_id": "pending_abcd1234",
  "code": "123456"
}

Response:

{
  "account_id": 1,
  "email": "[email protected]",
  "api_token": "kaa_xxxxx",
  "billing_status": "unconfigured",
  "free_searches_remaining": 25
}

3. Check Account Status

Response:

{
  "account_id": 1,
  "email": "[email protected]",
  "email_verified": true,
  "billing_configured": false,
  "billing_status": "unconfigured",
  "free_searches_remaining": 25,
  "paid_usage_enabled": false,
  "usage_this_month": 0
}

4. Run Keyword Analysis

Request:


Response shape:

{ "keyword": "auto body repair pearland tx", "suggested_word_count": 550, "total_results_analyzed": 4, "results": [ { "analysis_rank": 1, "title": "Collision Repair in Pearland", "url": "https://example.com/pearland-collision-repair", "rank": 1, "word_count": 612, "scrape_error": null } ], "analysis": { "primary_keyword": "collision repair pearland", "primary_keyword_density": { "keyword": "collision repair pearland", "occurrence_count": 4, "occurrences_per_result": 1.0, "total_word_count": 2287, "density_percentage": 0.17 }, "secondary_keywords": [ { "keyword": "collision repair", "occurrence_count": 13, "occurrences_per_result": 3.25, "total_word_count": 2287, "density_percentage": 0.57 } ] } }


### 5\. Start Billing Setup

Response:

{ "billing_status": "unconfigured", "url": "https://checkout.stripe.com/...", "mode": "checkout_setup", "stripe_customer_id": "cus_123" }


## Billing-Required Response Pattern

When free usage is exhausted and billing is not configured, the API may return HTTP `402` with a detail object like:

{ "message": "Billing setup required", "billing_url": "https://checkout.stripe.com/..." }


## Billing Model

* First 25 successful searches are free
* Billing is only required after free usage is exhausted
* Failed searches should not be billed
* Successful searches are metered per completed keyword-analysis request

## Agent Guidance

* If account creation returns a verification code in development, use it directly
* In production, ask the human to check email for the code
* If analysis returns a billing-required response, show the hosted billing URL to the user
* Prefer `top_n_results=5` unless a larger competitive sample is necessary
* Use `include_page_content=false` by default to minimize payload size

## Best Practices For Agents

* Treat `create-account` and `verify-account` as a two-step handshake
* Do not retry verification blindly after a wrong code; ask the user to re-check email
* Store the returned API token securely for future calls
* On HTTP `402`, pause analysis flow and present the hosted billing URL to the human
* Retry transient upstream failures conservatively; avoid repeated search bursts
* Do not assume every SERP request will return the same ranking set across time and geography
* Treat `analysis.primary_keyword` as the recommended target and `keyword` as the user's original query
* Use `account-status` before prompting the user for billing if you are unsure whether free usage remains
* Consider `usage-summary` the source of truth for agent-side quota messaging
* Default to 5 results for speed and cost unless the user explicitly asks for deeper analysis
* If partial scraping occurs but a valid analysis returns, treat the request as successful unless the API says otherwise

## Discovery Endpoints

* `GET /`
* `GET /llms.txt`
* `GET /.well-known/llms.txt`
* `GET /openapi.json`

## Notes

* This service is optimized for fast, structured keyword analysis rather than broad SEO suite workflows
* It is intended to be easier and cheaper to use than a full SEO platform when the only need is quick live keyword research