SEO Keyword Endpoints

Both operations are part of All tools. A start needs the relevant scope and enough credits, and the tool must be available in /v1/health. Free credits also follow the free limits. Accepted starts return 202 Accepted.

Both endpoints are preview. Preview means the contract may still evolve before stable release; returned data is live keyword data, not sample output.

POST/v1/seo/keywords/ideas

Generates related keyword ideas from one to five seed phrases.

Required Access

  • Access: Paid plans that include this family, or free credits (guest trial or verified account) within the free limits.
  • Operation family: SEO
  • Scope: api:seo:read
  • Credits: 10 credits reserved on acceptance
  • Idempotency: Idempotency-Key header required

Request

{
  "seeds": ["laravel queues", "api monitoring"],
  "engine": "google",
  "location": {
    "country": "US"
  },
  "language": "en-US",
  "metric_families": ["volume", "competition", "cpc", "difficulty", "trends"],
  "limit": 25
}

Fields:

  • seeds: required array of 1 to 5 unique strings. Each seed is trimmed and must be 1 to 100 characters.
  • engine: required. google is the supported engine.
  • location.country: required ISO 3166-1 alpha-2 country code. Region, city, and postal-code fields are rejected with validation_failed.
  • language: required BCP 47 language tag, such as en-US, en-GB, or de-DE.
  • metric_families: optional unique array containing volume, competition, cpc, difficulty, and/or trends. When omitted, all five families are returned.
  • limit: optional integer from 1 to 50; defaults to 25.
  • callback_url, callback_secret, callback_events, and callback_notify_on_expiration: optional one-off operation callback fields.

Unknown request fields are rejected. keywords and output_format are not accepted on this endpoint.

Async Response

{
  "operation": {
    "id": "op_01JZ7H0A1B2C3D4E5F6G7H8J9K",
    "status": "queued",
    "operation_key": "seo.keywords.ideas",
    "family": "seo",
    "status_url": "/v1/operations/op_01JZ7H0A1B2C3D4E5F6G7H8J9K",
    "result_url": "/v1/operations/op_01JZ7H0A1B2C3D4E5F6G7H8J9K/result",
    "estimated_credits": 10,
    "result_available": false,
    "warnings": []
  },
  "meta": {
    "request_id": "req_123",
    "credits": {
      "estimated": 10,
      "reserved": 10,
      "currency": "credit"
    }
  }
}

Succeeded Status

GET /v1/operations/{id} returns the operation status. Keyword operations are asynchronous Chab operations; there is no public provider task handle.

{
  "operation": {
    "id": "op_01JZ7H0A1B2C3D4E5F6G7H8J9K",
    "status": "succeeded",
    "operation_key": "seo.keywords.ideas",
    "family": "seo",
    "status_url": "/v1/operations/op_01JZ7H0A1B2C3D4E5F6G7H8J9K",
    "result_url": "/v1/operations/op_01JZ7H0A1B2C3D4E5F6G7H8J9K/result",
    "estimated_credits": 10,
    "result_available": true,
    "public_error_code": null,
    "warnings": [],
    "diagnostic_reference": null
  },
  "meta": {
    "request_id": "req_123"
  }
}

Result

GET /v1/operations/{id}/result returns keyword rows after success:

{
  "data": {
    "result": {
      "engine": "google",
      "location": {
        "country": "US"
      },
      "language": "en-US",
      "metric_families": ["volume", "competition", "cpc", "difficulty", "trends"],
      "fetched_at": "2026-06-28T12:00:05+00:00",
      "result_count": 1,
      "complete": true,
      "keywords": [
        {
          "keyword": "laravel queue best practices",
          "source_seed": null,
          "metrics": {
            "volume": {
              "monthly_searches": 1900
            },
            "competition": {
              "index": 42,
              "label": "medium"
            },
            "cpc": {
              "amount": 3.25,
              "currency": "USD"
            },
            "difficulty": {
              "score": 34
            },
            "trends": {
              "monthly": [
                {
                  "month": "2025-07",
                  "monthly_searches": 1700
                },
                {
                  "month": "2026-06",
                  "monthly_searches": 1900
                }
              ]
            }
          },
          "availability": {
            "metrics.volume.monthly_searches": "available",
            "metrics.competition.index": "available",
            "metrics.cpc.amount": "available",
            "metrics.cpc.currency": "available",
            "metrics.difficulty.score": "available",
            "metrics.trends.monthly": "available"
          },
          "confidence": {
            "score": null,
            "availability": "available",
            "source": "provider"
          },
          "observed_at": "2026-06-27T00:00:00+00:00",
          "warnings": []
        }
      ]
    },
    "artifacts": [],
    "warnings": [],
    "result_expires_at": "2026-07-01T12:00:05+00:00"
  },
  "meta": {
    "request_id": "req_123"
  }
}

Metric units:

  • volume.monthly_searches: integer monthly search volume, or null when unavailable.
  • competition.index: 0 to 100 competition score, with optional low, medium, or high label.
  • cpc.amount: cost-per-click amount in USD, or null when unavailable.
  • difficulty.score: 0 to 100 keyword difficulty score, or null.
  • trends.monthly: up to 12 monthly buckets in YYYY-MM format, oldest to newest.

Every metric path has an explicit availability state. Missing keyword data does not become numeric zero. A valid seed or keyword can return unavailable metric families with row-level field_unavailable warnings while the operation still succeeds. In that case, complete is false and the operation includes a partial_results warning.

POST/v1/seo/keywords/metrics

Returns metrics for an explicit list of one to fifty keywords. The result contains one row per requested keyword in request order.

Required Access

  • Access: Paid plans that include this family, or free credits (guest trial or verified account) within the free limits.
  • Operation family: SEO
  • Scope: api:seo:read
  • Credits: 8 credits reserved on acceptance
  • Idempotency: Idempotency-Key header required

Request

{
  "keywords": ["laravel queues", "api monitoring tools"],
  "engine": "google",
  "location": {
    "country": "US"
  },
  "language": "en-US",
  "metric_families": ["volume", "competition", "cpc", "difficulty", "trends"]
}

Fields:

  • keywords: required array of 1 to 50 unique strings. Each keyword is trimmed and must be 1 to 100 characters.
  • engine, location.country, language, metric_families, and callback fields match POST /v1/seo/keywords/ideas.

seeds, limit, and output_format are rejected on this endpoint.

Async Response

The create response has the same operation envelope shape as keyword ideas, with operation_key: "seo.keywords.metrics" and an 8 credit estimate/reservation.

Succeeded Status

The status response has the same operation envelope shape as keyword ideas, with operation_key: "seo.keywords.metrics".

Result

The result shape is the same keyword row format as keyword ideas. Differences:

  • source_seed is always null.
  • result_count equals the number of requested keywords.
  • Rows preserve request order, including rows where some or all metrics are unavailable.

Errors

Common errors include:

Code Meaning Retry
validation_failed Request fields, location, language, or keyword caps are invalid or unsupported. No
api_scope_missing The key does not have api:seo:read. No
paid_plan_required The team is not on a paid API plan. No
operation_family_not_included The plan does not include SEO operations. No
insufficient_credits The team does not have enough available credits for the estimate. No
rate_limited The operation-start rate limit was exceeded. Yes
quota_exceeded The plan quota was exceeded. No
concurrency_limit_exceeded Too many active operations are running. Yes
spend_threshold_exceeded Starting the operation would exceed the team's operation spend threshold. No
provider_unavailable Keyword data is temporarily unavailable. Yes
provider_temporarily_rate_limited Keyword data is temporarily throttled after retries. Yes
provider_response_invalid Chab could not use the returned keyword data. Yes
provider_error Keyword data could not be completed because of a provider-side failure. No

Provider errors stay provider-neutral. Responses never include provider task IDs, raw provider messages, or internal diagnostics.

Credit Notes

seo.keywords.ideas reserves 10 credits per accepted operation. seo.keywords.metrics reserves 8 credits per accepted operation. Pricing is flat per operation regardless of seed count, keyword count, or requested metric family count within the documented caps.

Successful keyword operations settle at the reserved amount. If no chargeable work starts, cancellation or failure releases the hold. If chargeable work has partially started, Chab may charge the actual partial amount up to the active hold and release the remainder.

Examples

curl -X POST https://www.chab.ai/v1/seo/keywords/ideas \
  -H "Authorization: Bearer CHAB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: keyword-ideas-001" \
  -d '{"seeds":["laravel queues","api monitoring"],"engine":"google","location":{"country":"US"},"language":"en-US","metric_families":["volume","competition","cpc","difficulty","trends"],"limit":25}'
curl -X POST https://www.chab.ai/v1/seo/keywords/metrics \
  -H "Authorization: Bearer CHAB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: keyword-metrics-001" \
  -d '{"keywords":["laravel queues","api monitoring tools"],"engine":"google","location":{"country":"US"},"language":"en-US","metric_families":["volume","competition","cpc","difficulty","trends"]}'