SearchChampSearchChamp
API Documentation

Errors, limits, and usage

Handle SearchChamp API errors, throttling, plan gates, and usage metering safely.

Response envelope

Successes and handler-generated errors share one JSON shape:

{
  "data": null,
  "meta": {},
  "errors": [
    {
      "code": "BAD_REQUEST",
      "message": "A \"site\" query parameter (domain or slug) is required."
    }
  ]
}

errors is empty on success. Do not branch on error-message text; use the HTTP status and errors[].code. Authentication failures rejected at the API Gateway authorizer can be shorter gateway responses rather than this handler envelope.

Status reference

StatusCommon causeWhat to do
200Successful read, including setup_required statesRead data; treat setup_required as an actionable empty state.
400Missing/ambiguous site, unknown route, invalid requestCorrect the request. Do not retry unchanged.
401Missing, expired, revoked, or unknown API keyReplace or rotate the key.
403Below-Pro plan, wrong credential type, missing permission, or organization usage ceilingCheck plan, key permissions, and billing/usage.
404Site not found inside the key's organizationCall with the exact domain or verify the site belongs to the organization.
429The API key exceeded its per-minute plan allowanceHonor Retry-After when present and retry with backoff.
503Rate limiting or another required guard could not be evaluatedRetry later with bounded exponential backoff. SearchChamp denies the request rather than serving it without protection.

Rate limits

Public /v1/api/* traffic is counted per API key, per minute. One noisy integration therefore does not consume another key's bucket.

PlanRequests per minute per key
Pro300
Agency600
Scale900
Enterprise1,200

The public API is unavailable below Pro even though lower plans have limits for internal application traffic.

On 429, pause new work, honor Retry-After if returned, and retry with jitter. Do not create extra API keys to distribute one integration's traffic; use caching, batching in your own system, and separate keys for operational isolation.

Credits and usage ceilings

Each successful REST call is metered at the same non-zero credit cost as its equivalent MCP read tool:

REST routeEquivalent MCP toolCredits per successful call
/v1/api/rankingsget_rankings1
/v1/api/ai-visibility/summaryget_ai_visibility1
/v1/api/keywordsget_tracked_keywords1
/v1/api/audit-issuesget_audit_issues1

Denied and invalid calls do not run the underlying read and are not debited as successful tool work. The organization-wide monthly usage ceiling also applies; once reached, requests receive 403 until usage becomes available again.

Retry pattern

async function searchChampGet(path, params, apiKey) {
  const url = new URL(path, 'https://api.searchchamp.com');
  for (const [key, value] of Object.entries(params)) url.searchParams.set(key, value);

  for (let attempt = 0; attempt < 4; attempt += 1) {
    const response = await fetch(url, {
      headers: { Authorization: `Bearer ${apiKey}` },
    });

    if (response.ok) return response.json();
    if (![429, 503].includes(response.status)) throw new Error(`SearchChamp API ${response.status}`);

    const retryAfter = Number(response.headers.get('retry-after'));
    const delayMs = Number.isFinite(retryAfter)
      ? retryAfter * 1000
      : (2 ** attempt) * 500 + Math.random() * 250;
    await new Promise((resolve) => setTimeout(resolve, delayMs));
  }

  throw new Error('SearchChamp API retry budget exhausted');
}

Version and compatibility boundary

The route prefix is /v1. SearchChamp has not published a broader deprecation schedule yet. Build only against fields documented in the endpoint reference, tolerate additive fields, and do not infer public support from the web app's internal network calls.

On this page