GG Keywords API

v1Stable

Programmatic access to Google Ads keyword research data and AI-powered keyword grouping. Built for agents, automation scripts, and third-party integrations.

Overview

Base URL

https://gg-keywords-workers-production.dongpt.workers.dev

7

Endpoints

31

Locations

19

Languages

5,000

Max keywords/batch

Endpoints

MethodEndpointDescription
POST/api/v1/keywords/researchGenerate keyword ideas with metrics from Google Ads
POST/api/v1/keywords/groupAI-powered keyword grouping (intent / topic / SEO)
GET/api/v1/keywords/locationsList 31 supported geographic locations
GET/api/v1/keywords/languagesList 19 supported languages
GET/api/v1/quotaCheck daily quota usage
GET/api/v1/healthHealth check with capabilities & rate limit info

Quick Start

Get up and running in 3 steps:

1. Create an account

Register
curl -X POST https://gg-keywords-workers-production.dongpt.workers.dev/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]", "password": "your-password"}'

2. Get an API key

Login + Create key
# Login (saves auth cookie)
curl -c cookies.txt -X POST https://gg-keywords-workers-production.dongpt.workers.dev/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]", "password": "your-password"}'

# Create API key
curl -b cookies.txt -X POST https://gg-keywords-workers-production.dongpt.workers.dev/api/keys \
  -H "Content-Type: application/json" \
  -d '{"name": "my-integration", "rateLimit": 30}'
Save your key immediately. The full API key (kkp_...) is shown only once at creation time and cannot be retrieved later.

3. Make your first call

Keyword Research
curl -X POST https://gg-keywords-workers-production.dongpt.workers.dev/api/v1/keywords/research \
  -H "Authorization: Bearer kkp_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"keywords": ["email marketing"], "location": "US"}'

Authentication

All /api/v1/* endpoints require an API key via the Authorization header:

Authorization: Bearer kkp_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2

Key Format

API keys use the kkp_ prefix followed by 40 random hex characters (160 bits of entropy).

Key Management Endpoints

These require JWT cookie auth (login via browser or curl first):

MethodEndpointDescription
POST/api/keysCreate a new API key (max 5 per account)
GET/api/keysList active keys (prefix only, no full key)
DELETE/api/keys/:idRevoke a key (immediate, irreversible)
Create Key — Request
curl -b cookies.txt -X POST https://gg-keywords-workers-production.dongpt.workers.dev/api/keys \
  -H "Content-Type: application/json" \
  -d '{"name": "production-agent", "rateLimit": 60}'
Create Key — Response (201)
{
  "key": "kkp_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
  "prefix": "kkp_a1b2",
  "name": "production-agent",
  "rateLimit": 60,
  "message": "Store this key securely. It will not be shown again."
}

Security

The GG Keywords API is designed with multiple layers of security to protect your data and prevent abuse.

API Key Security

SHA-256 Key Hashing

API keys are hashed with SHA-256 before storage. We never store plaintext keys — even if our database is compromised, your key cannot be extracted.

One-Time Key Display

The full API key is returned exactly once at creation. It cannot be viewed again through the API or dashboard.

160-bit Entropy

Keys are generated using cryptographically secure random bytes (20 bytes = 160 bits), making brute-force attacks infeasible.

Instant Revocation

Compromised keys can be revoked immediately via DELETE /api/keys/:id. Revoked keys are rejected on the next request.

Key Limit

Maximum 5 active keys per account to minimize surface area. Rotate keys regularly by creating a new one and revoking the old.

Transport Security

HTTPS Only

All API traffic is served over HTTPS (TLS 1.2+) via Cloudflare's global edge network. HTTP requests are automatically redirected.

Cloudflare Edge Protection

Deployed on Cloudflare Workers with built-in DDoS protection, WAF, and bot management at the edge.

Rate Limiting & Abuse Prevention

Per-Key Rate Limiting

Each API key has its own sliding-window rate limit (configurable 1-120 requests/minute). One key cannot exhaust another's quota.

Per-IP Rate Limiting

Additional IP-based rate limiting (10 req/min) on management endpoints to prevent credential stuffing and brute-force attacks.

Daily Quota

1,000 keyword research requests per day to manage upstream Google Ads API costs. Cached results are free.

CORS Policy

Whitelist-Based CORS

Cross-origin requests are restricted to explicitly approved domains only. No wildcard * origins.

Data Security

No Data Sharing

Your keyword research data is isolated per account. We do not share, sell, or aggregate your research queries.

Cache Isolation

Cached keyword results are shared only when the exact same search parameters are used, reducing API costs for common queries.

Request Tracing

Every API response includes a unique requestId for debugging and audit purposes.

Reporting security issues: If you discover a security vulnerability, please contact us privately before disclosing publicly. Do not submit security issues via public channels.

Keyword Research

POST/api/v1/keywords/research

Generate keyword ideas with search volume, competition score, and CPC data from Google Ads API. Results are cached for 7 days.

ParameterTypeRequiredDescription
keywordsstring[]RequiredSeed keywords (1+). Required if no url provided.
urlstringOptionalSeed URL (alternative to keywords). Takes precedence if both provided.
locationstringOptional ("US")Country code, name, or Google Ads ID (e.g. "US", "United States", "2840")
languagestringOptional ("EN")Language code, name, or Google Ads ID (e.g. "EN", "English", "1000")
includeAdultKeywordsbooleanOptional (false)Include adult-oriented keywords in results
Request
curl -X POST https://gg-keywords-workers-production.dongpt.workers.dev/api/v1/keywords/research \
  -H "Authorization: Bearer kkp_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "keywords": ["email marketing", "newsletter tools"],
    "location": "US",
    "language": "EN"
  }'
Response (200)
{
  "success": true,
  "data": {
    "keywords": [
      {
        "keyword": "email marketing software",
        "avgMonthlySearches": 22000,
        "competition": "HIGH",
        "competitionIndex": 87,
        "lowTopOfPageBid": 5200000,
        "highTopOfPageBid": 18500000
      }
    ],
    "totalResults": 150
  },
  "meta": {
    "requestId": "a1b2c3d4e5f6a1b2",
    "durationMs": 1842,
    "fromCache": false,
    "apiVersion": "v1"
  },
  "timestamp": "2026-02-25T12:00:00.000Z"
}

Keyword Metrics Fields

FieldTypeDescription
keywordstringThe keyword text
avgMonthlySearchesintegerAverage monthly search volume
competitionstringLOW, MEDIUM, HIGH, or UNSPECIFIED
competitionIndexinteger0-100 competition score
lowTopOfPageBidintegerLow-range CPC in micros ($1 = 1,000,000)
highTopOfPageBidintegerHigh-range CPC in micros ($1 = 1,000,000)
CPC values are in micros ($1 = 1,000,000). Divide by 1,000,000 to get dollar amounts. Cached results return "fromCache": true and do not count toward daily quota.

Keyword Grouping

POST/api/v1/keywords/group

AI-powered keyword grouping with three modes. Powered by Claude AI.

ParameterTypeRequiredDescription
keywordsstring[]RequiredKeywords to group (1-5,000)
modestringRequired"intent", "topic", or "seo"
keywordMetricsKeywordMetrics[]OptionalRequired for SEO mode. Pass metrics from the research endpoint.

intent Intent Mode

Classifies keywords by search intent: informational, transactional, navigational, commercial.

Request
curl -X POST https://gg-keywords-workers-production.dongpt.workers.dev/api/v1/keywords/group \
  -H "Authorization: Bearer kkp_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "keywords": ["buy running shoes", "how to start running", "nike store"],
    "mode": "intent"
  }'
Response
{
  "success": true,
  "data": {
    "mode": "intent",
    "groups": [
      { "keyword": "buy running shoes", "group": "transactional" },
      { "keyword": "how to start running", "group": "informational" },
      { "keyword": "nike store", "group": "navigational" }
    ],
    "groupNames": ["transactional", "informational", "navigational"]
  }
}

topic Topic Mode

Groups keywords into semantic topic clusters.

Request
curl -X POST https://gg-keywords-workers-production.dongpt.workers.dev/api/v1/keywords/group \
  -H "Authorization: Bearer kkp_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "keywords": ["running shoes", "trail running gear", "marathon training plan", "5k race tips"],
    "mode": "topic"
  }'
Response
{
  "success": true,
  "data": {
    "mode": "topic",
    "groups": [
      { "keyword": "running shoes", "group": "Running Gear" },
      { "keyword": "trail running gear", "group": "Running Gear" },
      { "keyword": "marathon training plan", "group": "Race Training" },
      { "keyword": "5k race tips", "group": "Race Training" }
    ],
    "groupNames": ["Running Gear", "Race Training"]
  }
}

seo SEO Mode

Maps keywords to URL clusters with intent, page type, and priority scoring. Requires keywordMetrics from the research endpoint.

Request
curl -X POST https://gg-keywords-workers-production.dongpt.workers.dev/api/v1/keywords/group \
  -H "Authorization: Bearer kkp_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "keywords": ["best running shoes 2026", "running shoe reviews"],
    "mode": "seo",
    "keywordMetrics": [
      {
        "keyword": "best running shoes 2026",
        "avgMonthlySearches": 18000,
        "competition": "HIGH",
        "competitionIndex": 82,
        "lowTopOfPageBid": 1200000,
        "highTopOfPageBid": 3500000
      },
      {
        "keyword": "running shoe reviews",
        "avgMonthlySearches": 12000,
        "competition": "MEDIUM",
        "competitionIndex": 55,
        "lowTopOfPageBid": 800000,
        "highTopOfPageBid": 2100000
      }
    ]
  }'
Response
{
  "success": true,
  "data": {
    "mode": "seo",
    "assignments": [
      {
        "keyword": "best running shoes 2026",
        "intent": "commercial",
        "topic": "Running Shoes",
        "urlCluster": "/best-running-shoes",
        "pageType": "listicle"
      },
      {
        "keyword": "running shoe reviews",
        "intent": "informational",
        "topic": "Running Shoes",
        "urlCluster": "/best-running-shoes",
        "pageType": "listicle"
      }
    ],
    "clusters": [
      {
        "urlCluster": "/best-running-shoes",
        "intent": "commercial",
        "topic": "Running Shoes",
        "pageType": "listicle",
        "suggestedSlug": "/best-running-shoes",
        "keywords": ["best running shoes 2026", "running shoe reviews"],
        "combinedVolume": 30000,
        "avgCpc": 1.9,
        "priority": 85
      }
    ]
  }
}

Locations & Languages

GET/api/v1/keywords/locations

List all 31 supported geographic locations.

Request
curl https://gg-keywords-workers-production.dongpt.workers.dev/api/v1/keywords/locations \
  -H "Authorization: Bearer kkp_your_key"
Response (partial)
{
  "success": true,
  "data": {
    "locations": [
      { "code": "US", "id": "2840", "name": "United States" },
      { "code": "UK", "id": "2826", "name": "United Kingdom" },
      { "code": "DE", "id": "2276", "name": "Germany" },
      { "code": "JP", "id": "2392", "name": "Japan" },
      { "code": "VN", "id": "2704", "name": "Vietnam" }
    ],
    "count": 31
  }
}
GET/api/v1/keywords/languages

List all 19 supported languages.

Request
curl https://gg-keywords-workers-production.dongpt.workers.dev/api/v1/keywords/languages \
  -H "Authorization: Bearer kkp_your_key"
Response (partial)
{
  "success": true,
  "data": {
    "languages": [
      { "code": "EN", "id": "1000", "name": "English" },
      { "code": "ES", "id": "1003", "name": "Spanish" },
      { "code": "JA", "id": "1005", "name": "Japanese" },
      { "code": "VI", "id": "1040", "name": "Vietnamese" }
    ],
    "count": 19
  }
}
Flexible input: Location and language parameters accept any of three formats — code ("US"), name ("United States"), or Google Ads ID ("2840").

Quota & Rate Limits

Rate Limiting

Each API key has a configurable per-minute rate limit (1-120, default 30). Rate limit headers are included on every response:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per minute
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp (seconds) when window resets
Retry-AfterSeconds to wait before retrying (only on 429)

Daily Quota

Keyword research calls are limited to 1,000 requests per day. Quota resets at midnight UTC. Cached results do not count toward quota.

GET/api/v1/quota

Check current daily quota usage.

Request
curl https://gg-keywords-workers-production.dongpt.workers.dev/api/v1/quota \
  -H "Authorization: Bearer kkp_your_key"
Response
{
  "success": true,
  "data": {
    "date": "2026-03-16",
    "used": 42,
    "limit": 1000,
    "remaining": 958,
    "resetAt": "2026-03-17T00:00:00.000Z",
    "percentageUsed": 4.2
  }
}
GET/api/v1/health

Health check with API capabilities and your key's rate limit config.

Request
curl https://gg-keywords-workers-production.dongpt.workers.dev/api/v1/health \
  -H "Authorization: Bearer kkp_your_key"
Response
{
  "success": true,
  "data": {
    "status": "operational",
    "capabilities": [
      "keyword-research",
      "keyword-grouping-intent",
      "keyword-grouping-topic",
      "keyword-grouping-seo",
      "location-discovery",
      "language-discovery",
      "quota-check"
    ],
    "rateLimit": {
      "requestsPerMinute": 30,
      "window": "60s"
    },
    "version": "1.0.0"
  }
}

Error Reference

Response Envelope

All responses follow a consistent envelope format:

Success Envelope
{
  "success": true,
  "data": { ... },
  "meta": {
    "requestId": "a1b2c3d4e5f6a1b2",
    "durationMs": 142,
    "fromCache": false,
    "apiVersion": "v1"
  },
  "timestamp": "2026-03-16T12:00:00.000Z"
}
Error Envelope
{
  "success": false,
  "data": null,
  "error": "Human-readable error description",
  "meta": {
    "requestId": "a1b2c3d4e5f6a1b2",
    "durationMs": 3,
    "apiVersion": "v1"
  },
  "timestamp": "2026-03-16T12:00:00.000Z"
}

HTTP Status Codes

StatusMeaningWhen
200OKSuccessful request
201CreatedAPI key created
401UnauthorizedMissing, invalid, or revoked API key
404Not FoundUnknown endpoint
422Validation ErrorBad params, unknown location/language
429Too Many RequestsRate limit or daily quota exceeded
500Internal ErrorUnexpected server error
502Bad GatewayAI service (Claude) upstream failure
503Service UnavailableAI service not configured

Error Codes

CodeHTTPDescription
UNAUTHORIZED401Missing, invalid, or revoked API key
NOT_FOUND404Endpoint does not exist
VALIDATION_ERROR422Invalid request body or parameters
RATE_LIMITED429Per-minute rate limit exceeded
QUOTA_EXCEEDED429Daily quota limit reached
AI_SERVICE_ERROR502Claude AI call failed
INTERNAL_ERROR500Unhandled server error
Example: Rate Limited (429)
{
  "success": false,
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded: 60 requests per minute",
    "details": {
      "limit": 60,
      "retryAfter": 12
    }
  }
}
Example: Quota Exceeded (429)
{
  "success": false,
  "error": {
    "code": "QUOTA_EXCEEDED",
    "message": "Daily quota exceeded: 1000/1000 requests used",
    "details": {
      "used": 1000,
      "limit": 1000,
      "resetAt": "2026-03-17T00:00:00.000Z"
    }
  }
}

Best Practices

1. Store your API key securely

Use environment variables or a secrets manager. Never commit API keys to version control or expose them in client-side code.

2. Handle rate limits gracefully

Check X-RateLimit-Remaining headers. When you receive a 429, wait for the duration specified in the Retry-After header before retrying. Use exponential backoff for retries.

3. Leverage caching

Repeated requests with the same keywords + location + language return cached results instantly at no quota cost. Design your integration to benefit from this by batching similar queries.

4. Monitor quota usage

Call GET /api/v1/quota periodically to track your daily usage. Quota resets at midnight UTC.

5. Use specific locations & languages

Always specify location and language for the most relevant results. Use the discovery endpoints to find supported values.

6. Rotate API keys periodically

Create a new key, update your integration, then revoke the old key. You can have up to 5 active keys to enable zero-downtime rotation.

7. Batch keyword grouping

The grouping endpoint supports up to 5,000 keywords per request. Send larger batches to reduce the number of API calls.

8. Use requestId for debugging

Every response includes a unique meta.requestId. Include this when reporting issues for faster troubleshooting.

GG Keywords API v1 — Powered by Google Ads API & Claude AI

Deployed on Cloudflare Workers global edge network