Skip to content

Authentication

All public-API endpoints under /api/public/v1/* use bearer tokens:

Authorization: Bearer zk_live_<prefix>_<secret>

A workspace API key carries workspace + tenant scope automatically. You never pass tenant_id or workspace_id in the URL on public-API calls — those come from the key itself.

To verify a key is configured correctly before issuing real calls:

Terminal window
curl -sS https://api.getzutax.com/api/public/v1/_introspect \
-H "Authorization: Bearer zk_live_<prefix>_<secret>"

The response returns workspace_id, tenant_id, api_key_id, and the granted scopes for the key. See _introspect guide.

API keys are created from the ZUTAX dashboard under Workspace Settings → API Keys. Each key is shown once at creation; store it in your secret manager — it cannot be retrieved later. Keys can be scoped, rate-limited, and revoked at any time without affecting other keys in the workspace.

Each public-API endpoint declares the scopes it requires. Common scopes:

  • parties:read, parties:write
  • products:read, products:write
  • invoices:read, invoices:write, invoices:transmit
  • credit_notes:read, credit_notes:write, credit_notes:transmit
  • payments:write
  • imports:write

A request is allowed when an exact scope (e.g., invoices:read) or a wildcard for the resource (e.g., invoices:*) is granted. Otherwise the API returns 403.

Each API key is rate-limited based on your subscription tier:

| Tier | Requests / minute | |--------------|-------------------| | Starter | 60 | | Professional | 300 | | Enterprise | 1,000 |

Exceeding the limit returns 429 Too Many Requests with a Retry-After: 60 header. You can override the tier default by setting a per-key rate_limit_per_minute at creation.

| You sent | Result | |---|---| | X-API-Key: <key> instead of Authorization: Bearer <key> | 401 — only Authorization: Bearer is supported | | Passed tenant_id or workspace_id in the URL | 404 — those are derived from the API key, not the path | | Used a key from a different workspace | 401 / 404 — keys are workspace-scoped |

If you’re seeing 401s during integration, the most common cause is a malformed or wrong-environment key. Run _introspect (above) to confirm.