Troubleshooting
API and MCP: 401, 402, 403, 429, or a missing tool
What each response means when a key or an MCP client is refused, and the one fix that usually applies: mint a key with the right scope on the right plan.
Updated · 2 min read
401 Unauthorized
No Authorization: Bearer nhm_… header, a revoked or expired key, or a plan below Pro. Keys are re-checked on every request, so a key that worked last month stops the day the plan lapses.
Fix: create a key under Settings, API Keys on a Pro or Enterprise account, and send it as a bearer token.
402 plan_upgrade_required
The endpoint needs a capability the plan does not have: DMARC reports or SEO on Free, Local SEO on Starter, scanner issue reports below Enterprise. The body names required_plan.
Fix: upgrade, or use the read that the plan allows (GET /api/seo-results/policy is open on every plan so you can see what is allowed).
403 Forbidden
One of three things: the key lacks the resource scope for the route; the request mutates state and the key has no write scope (Enterprise only); or the resource belongs to another account.
Fix: mint a key with the scope. A key's scopes cannot be edited after creation.
429 Too Many Requests
The key's hourly rate limit (1,000 by default, up to 10,000 at creation), or a per-plan manual-scan allowance. Retry-After and the body say which and when.
409 idempotency_mismatch
A request_key was reused for a different paid request. Generate a fresh key for a new run, and use get_local_seo_operation to read back the earlier one.
A tool is missing from tools/list
The list is filtered to the key's scopes and the account's plan. A missing tool means a missing scope (or, for write tools, a Pro key or no write). Mint a new key with the scope rather than rewording the prompt.
isError: "read-only"
The tool changes state and the key has no write scope. Live-scan tools count as writes even when they do not modify the target, because they spend allowances and contact upstream providers.
The connection works but Claude says the server has no tools
Check the header is sent exactly as Authorization: Bearer nhm_… (a stray space or a missing Bearer is the usual cause), and that the URL is https://nhmohio.com/api/mcp. Confirm with the tools/list curl in Connecting the MCP server.
Related
Keep reading
Related articles
- The REST APIBase URL, bearer authentication with an nhm_ key, the domain check endpoint, the resource endpoints behind the dashboard, and the 401, 402, 403 and 429 replies.API and MCP ·Updated
- "Needs an account" and "Ownership proof needed"The two gates on scanning: a session for any server-side check, and account-level ownership proof for anything that probes. What each message means and the fix.Troubleshooting ·Updated
- Connecting the MCP serverAdd https://nhmohio.com/api/mcp to Claude Code, Claude Desktop or any HTTP MCP client with an nhm_ key, confirm what the key can reach, and use the prompts.API and MCP ·Updated
