Authentication

How to authenticate Ziptax API requests using an API key, including where to send the key and which entitlements gate specific features.

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

Sending the key

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

$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

$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

EndpointAuth required
GET /request/v10GET /request/v60Yes
GET /account/metrics and /account/v{N}/metricsYes
POST /search/ticYes
POST /calculate/cartYes (header only)
GET /data/ticNo, public
GET /system/healthNo, public
GET /system/metadataNo, public

Entitlements

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

EntitlementControlsError code if missing
request_rateRequests per minute, default 10,000108
geo_enabledAddress and lat/lng lookups (postal code lookups don’t require it)Returned per endpoint
rate_loc_cancountryCode=CAN for Canadian rates112
product_ratestaxabilityCode for product-specific rules113
core_request_limitPer-period quota on base rate lookups107
geo_request_limitPer-period quota on geocoded lookups107

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

Read current usage against core_request_limit and geo_request_limit from the Account Metrics endpoint.

Invalid or missing keys

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

1{
2 "metadata": {
3 "version": "v60",
4 "response": {
5 "code": 101,
6 "name": "RESPONSE_CODE_INVALID_KEY",
7 "message": "Key format is not valid or key not found."
8 }
9 }
10}

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. Default is 10,000 requests per minute, controlled by request_rate. Every response includes:

X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 9847

Exceeding the limit returns HTTP 429 with response code 108. See 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:

1import os
2from ziptax import Ziptax
3
4client = Ziptax(api_key=os.environ["ZIPTAX_API_KEY"])
5rate = client.by_address(address="200 Spectrum Center Dr, Irvine CA")