Error Reference

Every GTM Tools API error, what it means, and how to fix it.

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 tokens.

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 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 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.

Insufficient Tokens (402)

insufficient_tokens

Insufficient tokens. This tool costs 5 tokens but you only have 2. Use buy_tokens 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_tokens 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 Tokens.

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 list or the 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)

Both cases below carry a Retry-After header when a wait is known.

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.

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

try_again_later

1{ "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 tokens, 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, LinkedIn for the socials 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.

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 with the tool name and the exact arguments.