> ## Documentation Index
> Fetch the complete documentation index at: https://gtmapis.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Learn how to authenticate with the GTMAPIs API

## API Key Format

GTMAPIs uses API keys for authentication. All API requests must include your API key in the `X-API-Key` header.

### Key Types

<CodeGroup>
  ```text Test Keys theme={null}
  gtm_test_1234567890abcdef1234567890abcdef
  ```

  ```text Live Keys theme={null}
  gtm_live_1234567890abcdef1234567890abcdef
  ```
</CodeGroup>

* **Test keys** (`gtm_test_*`) - For development and test integrations
* **Live keys** (`gtm_live_*`) - For production integrations

Test and live prefixes identify intended usage. Both must be valid account keys and both follow the normal access, rate-limit, and credit policy unless product docs state otherwise.

<Warning>
  Never commit API keys to version control or expose them in client-side code. Store them as environment variables.
</Warning>

## Making Authenticated Requests

Include your API key in the `X-API-Key` header with every request:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.gtmapis.com/v1/validate \
    -H "Content-Type: application/json" \
    -H "X-API-Key: gtm_test_1234567890abcdef1234567890abcdef" \
    -d '{"email":"test@example.com"}'
  ```

  ```javascript JavaScript theme={null}
  const headers = {
    'Content-Type': 'application/json',
    'X-API-Key': 'gtm_test_1234567890abcdef1234567890abcdef'
  };

  const response = await fetch('https://api.gtmapis.com/v1/validate', {
    method: 'POST',
    headers: headers,
    body: JSON.stringify({ email: 'test@example.com' })
  });
  ```

  ```python Python theme={null}
  headers = {
      'Content-Type': 'application/json',
      'X-API-Key': 'gtm_test_1234567890abcdef1234567890abcdef'
  }

  response = requests.post(
      'https://api.gtmapis.com/v1/validate',
      headers=headers,
      json={'email': 'test@example.com'}
  )
  ```
</CodeGroup>

## Generating API Keys

<Steps>
  <Step title="Login to Dashboard">
    Go to [gtmapis.com/dashboard](https://www.gtmapis.com/dashboard)
  </Step>

  <Step title="Navigate to API Keys">
    Click on **API Keys** in the sidebar
  </Step>

  <Step title="Create New Key">
    Click **Generate New Key** and choose test or live mode
  </Step>

  <Step title="Save Your Key">
    Copy the full key immediately - it's only shown once!
  </Step>
</Steps>

<Info>
  API keys are stored as SHA-256 hashes for security. You'll only see the full key once during creation.
</Info>

## Scoped Keys for Agents and Automations

Create restricted keys for integrations, contractors, automations, and MCP-enabled agents instead of sharing an unrestricted live key.

Current public scopes:

| Scope                   | Permits                                                                                                                                                                                                                                                                   |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `credits:read`          | Credit balance inspection through `GET /v1/credits` and the `gtmapis_get_credits` MCP tool.                                                                                                                                                                               |
| `email:validate:single` | Single-email validation through `POST /v1/validate` and the `gtmapis_validate_email` MCP tool.                                                                                                                                                                            |
| `email:validate:bulk`   | Synchronous bulk validation through `POST /v1/validate/bulk`, async validation jobs through `POST /v1/validate/batch`, signed CSV upload through `/v1/csv/prepare-upload` and `/v1/csv/start-processing`, job reads through `/v1/csv/jobs/*`, and the bulk/job MCP tools. |

For an agent that only needs to inspect docs, do not provide a key. For an agent that only checks balances, grant only `credits:read`. For an agent that validates one-off emails, grant only `email:validate:single`. For an agent that validates lists, grant `email:validate:bulk` and prefer `/v1/validate/bulk` over many single-email calls.

<Tip>
  See [MCP and Agent Tools](/guides/mcp-agent-tools) for Claude Desktop and generic MCP client configuration.
</Tip>

## Hosted MCP Authentication

Hosted MCP uses a different credential model from the public API. Remote MCP clients connect to `https://www.gtmapis.com/api/mcp` and complete an OAuth-style PKCE flow. GTMAPIs issues bearer tokens scoped to hosted MCP, with expiry and revocation support.

Do not paste public API keys into hosted MCP clients, and do not use hosted MCP bearer tokens for public API calls. Public API requests continue to use `X-API-Key`.

## API Key Security

### Best Practices

✅ **Do:**

* Store API keys as environment variables
* Use test keys for development
* Rotate keys regularly
* Use separate keys for different environments
* Revoke compromised keys immediately

❌ **Don't:**

* Commit keys to version control
* Share keys in public forums or Slack
* Use live keys in development
* Expose keys in client-side JavaScript
* Hardcode keys in your source code

### Key Storage Example

<CodeGroup>
  ```bash .env theme={null}
  # Store in .env file (never commit this!)
  GTMAPIS_API_KEY=gtm_test_1234567890abcdef1234567890abcdef
  ```

  ```javascript Node.js theme={null}
  // Load from environment
  const apiKey = process.env.GTMAPIS_API_KEY;

  const response = await fetch('https://api.gtmapis.com/v1/validate', {
    headers: {
      'X-API-Key': apiKey
    }
  });
  ```

  ```python Python theme={null}
  # Load from environment
  import os
  api_key = os.environ.get('GTMAPIS_API_KEY')

  response = requests.post(
      'https://api.gtmapis.com/v1/validate',
      headers={'X-API-Key': api_key}
  )
  ```
</CodeGroup>

## Rate Limits

Each API key has a public API rate limit of **10,000 requests per minute**. IP-based abuse protection may also apply at **1,000 requests per minute per IP address**.

If you exceed this limit, you'll receive a `429 Too Many Requests` response:

```json theme={null}
{
  "error": "Rate limit exceeded",
  "message": "You have exceeded the rate limit of 10000 requests per minute",
  "retry_after": 60
}
```

<Tip>
  For higher rate limits, contact us at [matt@closedwonleads.com](mailto:matt@closedwonleads.com)
</Tip>

## Error Responses

### Invalid API Key

```json theme={null}
{
  "error": "Unauthorized",
  "message": "Invalid API key"
}
```

### Missing API Key

```json theme={null}
{
  "error": "Unauthorized",
  "message": "X-API-Key header is required"
}
```

### Expired or Revoked Key

```json theme={null}
{
  "error": "Unauthorized",
  "message": "API key has been revoked"
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Make Your First Request" icon="rocket" href="/quickstart">
    Try the API with your new key
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/overview">
    Explore all available endpoints
  </Card>
</CardGroup>
