401 Unauthorized

A 401 Unauthorized response means the request reached the server, but the auth layer couldn’t resolve the bearer token to an org.

Common causes

1. Missing Authorization header

Every paid tool requires the header. The exceptions are get_api_key (boots a new account) and ping (no auth required).

$# Wrong
$curl -X POST https://api.gtm-tools.sh/api/v0/get_linkedin_company_url \
> -H "Content-Type: application/json" \
> -d '{"domain": "siena.cx"}'
$
$# Right
$curl -X POST https://api.gtm-tools.sh/api/v0/get_linkedin_company_url \
> -H "Authorization: Bearer $GTM_TOOLS_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{"domain": "siena.cx"}'

2. Wrong header format

The format is Bearer <key>, with one space. Token <key> and bare <key> both fail.

3. Stale or revoked key

If you provisioned multiple keys, only the most recent verified one is guaranteed to work; older keys may have been revoked. Run get_token_balance with the key you’re using to confirm it resolves:

$curl https://api.gtm-tools.sh/api/v0/get_token_balance \
> -H "Authorization: Bearer $GTM_TOOLS_API_KEY"

If that returns 401, provision a new key with get_api_key.

4. MCP client sent no headers

Some MCP clients drop custom headers when configured incorrectly. For Claude Desktop, the headers field must live inside the server entry:

1{
2 "mcpServers": {
3 "gtm-tools": {
4 "url": "https://api.gtm-tools.sh/mcp",
5 "headers": { "Authorization": "Bearer YOUR_KEY" }
6 }
7 }
8}

A common mistake is putting headers at the top level — it’s silently ignored.

Verifying it works

$curl https://api.gtm-tools.sh/api/v0/ping \
> -H "Authorization: Bearer $GTM_TOOLS_API_KEY" -i

200 OK with a small JSON body confirms the auth chain. Anything else points to a different layer of the problem.

Still stuck

Open an issue on GitHub with the request URL, the -i output (redact your key), and the rough timestamp.