> This page is for version v6.0 (default).
> For other versions, use one of these documentation indexes:
> - v6.0 (default): https://docs.zip.tax/v-6-0/llms.txt
> - v5.0: https://docs.zip.tax/v-5-0/llms.txt

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

# Authentication

Every Ziptax request is authenticated with an API key. The same key works across every API version (`/request/v10` through `/request/v60`) and against the account metrics, TIC search, and cart calculation endpoints.

## Get an API key

1. Sign in to [platform.zip.tax](https://platform.zip.tax).
2. Navigate to `Develop > API Keys` using the side navigation menu.
3. Generate a new key and copy the value. Keys are opaque strings; keep them out of client-side code and source control.

For a step-by-step walkthrough with screenshots, see [How to create an API key](../tutorials/how-to-create-an-api-key).

## Sending the key

Two options. The header form is recommended for production; the query form is fine for quick tests.

### Option 1: `X-API-KEY` header (recommended)

```bash
curl -H "X-API-KEY: YOUR_API_KEY" \
  "https://api.zip-tax.com/request/v60?address=200+Spectrum+Center+Dr+Irvine+CA"
```

### Option 2: `key` query parameter

```bash
curl "https://api.zip-tax.com/request/v60?key=YOUR_API_KEY&address=200+Spectrum+Center+Dr+Irvine+CA"
```

If both are set, the header wins and the query parameter is ignored.

## Which endpoints need a key

| Endpoint                                  | Auth required     |
| ----------------------------------------- | ----------------- |
| `GET /request/v10` ... `GET /request/v60` | Yes               |
| `GET /account/v{N}/metrics`               | Yes               |
| `POST /search/tic`                        | Yes               |
| `POST /calculate/cart`                    | Yes (header only) |
| `GET /data/tic`                           | No, public        |
| `GET /system/health`                      | No, public        |
| `GET /system/metadata`                    | No, public        |

## Entitlements

Each key carries entitlements that gate specific features and quotas. When a key is missing one, Ziptax returns a specific response code.

| Entitlement          | Controls                                                                                   | Error code if missing                               |
| -------------------- | ------------------------------------------------------------------------------------------ | --------------------------------------------------- |
| `request_rate`       | Requests per minute, set by your plan — see [Rate Limiting & Errors](rate-limiting-errors) | [108](response-codes#108-rate-limit)                |
| `geo_enabled`        | Address and lat/lng lookups (postal code lookups don't require it)                         | Returned per endpoint                               |
| `rate_loc_can`       | `countryCode=CAN` for Canadian rates                                                       | [112](response-codes#112-international-not-enabled) |
| `product_rates`      | `taxabilityCode` for product-specific rules                                                | [113](response-codes#113-product-rules-not-enabled) |
| `core_request_limit` | Per-period quota on base rate lookups                                                      | [107](response-codes#107-feature-not-enabled)       |
| `geo_request_limit`  | Per-period quota on geocoded lookups                                                       | [107](response-codes#107-feature-not-enabled)       |

Plan upgrades update entitlements on the existing key. No rotation required.

> **Info**
>
> Read current usage against `core_request_limit` and `geo_request_limit` from the [Account Metrics endpoint](account-metrics).

## Invalid or missing keys

A malformed, unknown, or deactivated key returns response code **101** with HTTP 401.

```json
{
  "metadata": {
    "version": "v60",
    "response": {
      "code": 101,
      "name": "RESPONSE_CODE_INVALID_KEY",
      "message": "Key format is not valid or key not found."
    }
  }
}
```

Common causes:

* Trailing whitespace or wrapping quotes after copy-paste.
* A deactivated key (regenerate from the platform).
* Wrong environment.
* Using `apiKey` or `api_key` as the query parameter name. Only lowercase `key` is accepted.

## Rate limiting

Per-key, 60-second sliding window. Your plan sets the ceiling: 10 requests per minute on Starter, 100 on Growth, 500 on Pro, and an account-defined limit on Enterprise. Every response includes:

```
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 487
```

Exceeding the limit returns HTTP 429 with response code 108. See [Rate Limiting & Errors](rate-limiting-errors) for backoff guidance.

## Key hygiene

* Store keys as environment variables. Never check them into source control or front-end bundles.
* Use a separate key per environment so you can rotate without affecting others.
* Rotate after a suspected leak: generate a new key, deploy it, then deactivate the old one.
* Never expose keys to the client. Ziptax is server-to-server; route browser and mobile calls through your backend.
* Don't log raw keys. Ziptax internal logs mask all but the first 8 and last 4 characters; mirror that pattern.

## Using keys with the SDKs

Each SDK accepts the key in the constructor and sets the header on every request:

#### Python

```python
import os
from ziptax import Ziptax

client = Ziptax(api_key=os.environ["ZIPTAX_API_KEY"])
rate = client.by_address(address="200 Spectrum Center Dr, Irvine CA")
```

#### Node.js

```javascript
import { Ziptax } from "ziptax";

const client = new Ziptax({ apiKey: process.env.ZIPTAX_API_KEY });
const rate = await client.byAddress({
  address: "200 Spectrum Center Dr, Irvine CA",
});
```

#### Go

```go
client := ziptax.New(os.Getenv("ZIPTAX_API_KEY"))

rate, err := client.ByAddress(ctx, ziptax.ByAddressRequest{
    Address: "200 Spectrum Center Dr, Irvine CA",
})
```

## Related

#### [Response Codes](response-codes)

Every application-level code Ziptax can return.

#### [Rate Limiting & Errors](rate-limiting-errors)

How `request_rate` is enforced and how to back off.

#### [Account Metrics](account-metrics)

Check usage against your plan's quotas.