Troubleshooting

Symptom → cause → fix recipes for the issues we see most often, grouped by client surface.

If something's not working, start here. Each entry below is a real symptom we've seen, with the most likely cause and the fix. If your issue isn't listed, the most actionable thing you can include in a support email is the x-request-id (or the requestId field in the response body) — that's how we find your specific call in our logs.

Authentication issues

These show up the same way across REST, MCP, and any other client.

401 unauthenticated on every call

The Authorization header is missing, malformed, or the key is no longer valid. Check, in order:

  1. The header reads exactly Authorization: Bearer rk_… — single space, exact prefix rk_, no ry9_… (that's an old format).
  2. The key isn't revoked or expired in Settings → API keys.
  3. You're calling https://api.ray9.ai/... (production), not a stale base URL or a dev URL with no key issued for it.
  4. You're not double-encoding the key (e.g. shell-escaping issues if you have special characters).

Ray9 deliberately doesn't tell you why the key is bad — unknown / expired / revoked all collapse to the same response. That's intentional; surfacing the reason would turn the API into a credential-validation oracle.

unauthenticated from MCP only, REST works

You authenticated REST with an env var or hardcoded header, but the MCP client config doesn't have the key wired into its server entry. See the per-client config in MCP server; the Authorization header (or its equivalent in your client's config) needs to be set.

MCP issues

Tools don't appear in your client

After editing the MCP config, fully quit and relaunch your client — most clients only read MCP config at startup. "Quit" means dock-quit / process-exit, not just close the window. Cmd+Q on macOS, right-click the system tray on Windows.

Connection refused or no response

  • Confirm the URL is https://api.ray9.ai/mcp exactly — no trailing slash, no /v1 prefix. The MCP endpoint sits at the root of the API host.
  • Confirm your client supports streamable-HTTP MCP. Some older clients only support stdio. See the Stdio shim section.
  • Check your network — corporate proxies sometimes block server-sent events.

Sessions drop after a few minutes

Ray9's MCP session TTL is 30 minutes (sliding, refreshed on each event). If your client goes idle for 30+ minutes, you'll start a new session on the next call. This is by design — long-idle sessions waste server resources.

Rate-limit errors when nothing else is using the key

The per-org rate limit (60/min) is shared across all callers — REST, MCP, CLI, web sessions. Background CI or another agent may be eating into the quota. See Rate limits.

HTTP API issues

400 bad_request on a request that looks correct

The request body failed JSON-schema validation. Common causes:

  • Missing a required field — typically keyword on SERP.
  • A field is the wrong type (e.g. depth: "10" instead of depth: 10).
  • A field is out of range — depth must be 1–100, keyword 1–700 characters.
  • The Content-Type: application/json header is missing, so Fastify never parses the body.

The error envelope's details payload usually points at the offending field — read it carefully before re-sending.

429 rate_limited immediately on first request

You've shared the per-org bucket with another client. Backoff per Retry-After (seconds) or details.retryAfterMs (milliseconds, takes precedence). If this happens consistently, run noisy workloads against a separate org. See Rate limits.

5xx during a known incident

For repeated 5xx that doesn't seem to be your fault, email contact@ray9.ai with a recent x-request-id — that's enough for us to pivot in our logs.

Billing and credits

402 out_of_credits mid-session

Your balance dropped below the next request's cost. Top up at Settings → Billing; the response's details.topup_url carries the same link. There's no auto-recharge or overage billing — once you're at zero, everything billable returns 402 until you top up. See Billing.

402 plan_required on a non-SERP endpoint

Free covers SERP only. A top-up of any amount ≥ $5.00 flips the org to PayG and unlocks the rest of the surface in one shot. The error response's details payload carries required_plan, current_plan, and topup_url so your client can build the right CTA.

Balance shows correctly in dashboard but the API says 402

Browser cache or a stale tab. Refresh the dashboard. If it still doesn't match the API, the API is right — credits are debited atomically server-side; the dashboard is a periodically-refreshed view.

Performance

Calls feel slow

SERP queries typically take 4–8 seconds; longer at high depth (near the 100 ceiling). This is the expected end-to-end latency — set client timeouts to 60s+ for anything that calls SERP.

Occasional timeouts (504 service_timeout)

The end-to-end budget for any single call is 130 seconds. If you're consistently hitting 504, the query is too heavy — narrow it (lower depth, more specific keyword, more specific location).

Getting help

When emailing contact@ray9.ai:

  • Your account email.
  • A recent x-request-id (response header) or requestId (response body field) for the failing call.
  • The exact request you sent, with the API key redacted.
  • The response you got back (status + body).

That's enough for us to find the call in our logs without back-and-forth.

On this page