> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://gtm-tools.sh/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://gtm-tools.sh/_mcp/server.

# Error Reference

> Every GTM Tools HTTP error code (400, 401, 402, 404, 405, 429, 5xx), what it means, and how to recover.

Every failure is a standard HTTP status code with a JSON body of the shape `{ "error": "<message>" }`. Branch on the status, not the message text: the status is stable, the message may change. The named sub-sections below are the distinct conditions behind each status. They describe the cause; they are not a machine-readable field in the response.

Over MCP the same conditions arrive as tool results with `isError: true` carrying the same message text, since MCP has no HTTP status to branch on.

Errors raised before the metering gate (validation, authentication, insufficient balance, unknown tool) never charge credits.

## Validation (400)

### invalid_arguments

```
Invalid arguments for get_email: domain: Required
```

A required parameter is missing, or a parameter has the wrong type. Arguments are validated against the tool's schema before the tool runs, so nothing was charged and no upstream call was made. The message lists every offending field as `<path>: <reason>`.

**Fix:** Correct the body against the tool's parameters in the [API Reference](/api-reference) and retry.

### empty_or_malformed_body

An unparseable request body is treated as an empty object rather than rejected on its own, so malformed JSON surfaces as `invalid_arguments` listing every required field as missing.

**Fix:** If every field is reported missing at once, suspect the body serialization (unescaped quotes in a shell heredoc, a missing `-d`, a double-encoded string) before you suspect the fields.

## Authentication (401)

Every 401 carries a `WWW-Authenticate: Bearer resource_metadata="..."` header pointing at the OAuth discovery document, so an agent can bootstrap registration from the response alone. See [401 Unauthorized](/knowledge-base/troubleshooting/unauthorized) for the full walkthrough.

### missing_authorization

```
Unauthorized (401): Missing or malformed Authorization header. Use get_api_key to obtain an API key.
```

No `Authorization` header, or a header that isn't `Bearer <key>`, most often an unset shell variable expanding to `Bearer` followed by nothing.

**Fix:** Send `Authorization: Bearer sk_...`. Confirm the variable is actually populated (`echo ${GTM_TOOLS_API_KEY:0:6}`) before blaming the key.

### invalid_api_key

```
Unauthorized (401): Invalid API key.
```

The header was well-formed but the key isn't recognized. Common causes:

* A typo, or a truncated copy-paste (keys are long).
* The key was revoked with `revoke_api_key` / `gtm-tools admin keys revoke`.
* Someone re-ran `gtm-tools admin login`, which revokes the workspace's previous `CLI (...)`-named keys before minting a new one. A key hard-coded into a script or CI job stops working at that moment.

**Fix:** Get a fresh key with `get_api_key` or `gtm-tools admin login`. Run `gtm-tools admin keys list` to see which keys the workspace still has. Autonomous agents can self-register through [auth.md](/integrations/agent-onboarding).

## Insufficient Credits (402)

### insufficient_tokens

```
Insufficient credits. This tool costs 5 credits but you only have 2. Use buy_credits to purchase more.
```

The workspace balance doesn't cover the tool's cost. The balance check runs before any work, so nothing was done and nothing was charged. Free tools (cost `0`) are never gated this way.

**Fix:** Top up with `buy_credits` for a one-off, or set `set_auto_reload` so the saved card is charged automatically when the balance drops below your threshold. See [402 Insufficient Credits](/knowledge-base/troubleshooting/insufficient-credits).

## Not Found (404)

### unknown_tool

```
Unknown tool: get_linkedin_profil
```

The tool name in the path doesn't exist: a typo, or a name from a namespace that isn't yours to call.

**Fix:** Check the name against the [Pricing](/pricing) list or the [API Reference](/api-reference). Tool names are strict `<verb>_<noun>`, always lowercase snake_case.

## Method Not Allowed (405)

### wrong_host

The request went to `gtm-tools.sh`, which serves this documentation site and accepts no POSTs. The API lives on the `api.` subdomain.

**Fix:** POST to `https://api.gtm-tools.sh/api/v0/{tool_name}`. A 405 on a request you believe is well-formed is nearly always the host, not the payload.

## Rate Limited (429)

All three cases below carry a `Retry-After` header when a wait is known, and a `reason` field naming which one it is.

### rate_limited

An upstream provider throttled the call. We don't rate-limit per workspace, so this never means you've used a quota of ours. See [Rate Limits](/knowledge-base/getting-started/rate-limits).

**Fix:** Back off and honor `Retry-After`. For batch jobs keep concurrency around 5 to 10, which stays clear of provider-side limits.

### spend_limit_reached

Your workspace's own monthly spending ceiling — the one you set with `set_spend_controls`, not a quota of ours. The wallet may be full; this is the cap you asked us to enforce on it.

This is a **429 and not a 402** for a reason worth knowing: buying credits does not lift it. A 402 says "pay and continue", and paying here changes nothing until the ceiling is raised or the month rolls over, which is what `Retry-After` tells you.

**Fix:** Raise it with `set_spend_controls`, or wait for the reset. Check where you stand with `get_spend_controls`.

### try_again_later

```json
{ "status": "try_again_later", "retry_after_seconds": 60 }
```

Nothing is wrong with the request: a provider was busy, cooling down, or timed out, and the tool is telling you so explicitly rather than returning a misleading empty result. This is distinct from a `not_found` result, which means the tool did the work and there's genuinely nothing to return, so don't retry those.

Because the tool passed the metering gate before reaching the provider, this outcome costs its credits, and retrying costs them again. Space retries out by `retry_after_seconds` instead of hammering.

**Fix:** Retry once after `retry_after_seconds`. If a tool returns this persistently for the same input, it's an upstream outage, not your call pattern.

## Session Required (5xx)

### session_required

```
No Google session is connected for this workspace, so email verification can't run.
```

The tool needs a live browser session pooled through the [GTM Tools extension](/extension), LinkedIn for the LinkedIn tools and Google for `get_email`, and the workspace has none connected, or the pooled session went stale. The message includes the install and Connect steps.

**Fix:** Install the extension, click Connect, and stay signed into the service in that browser. Verify with `list_connected_linkedin_accounts` / `list_connected_reddit_accounts`. See [LinkedIn session errors](/knowledge-base/troubleshooting/linkedin-session).

## Upstream Error (5xx)

### upstream_error

An upstream provider (LinkedIn proxy, email verifier, geocoder, Reddit) returned an error or timed out in a way the tool couldn't classify as transient.

**Fix:** Retry with exponential backoff. If it persists for the same input across several minutes, it's an outage on the provider side. [Contact support](/support) with the tool name and the exact arguments.