Authentication
Zyntem uses API keys for authentication. The Cloud API sends the key as a Bearer token with every request. The Embedded Local SDKs exchange the key for a signed token once at initialization — see Embedded SDK authentication below.
API key format
API keys follow the format:
zyn_{environment}_{64 hex characters}
| Prefix | Environment | Usage |
|---|---|---|
zyn_test_ | Test | Development and testing |
zyn_live_ | Live | Production |
Using your API key (Cloud API)
Include the API key in the Authorization header:
curl https://api.zyntem.dev/v1/locations \
-H "Authorization: Bearer zyn_test_abc123def456..."
Key lifecycle
- Creation: An API key is generated when you create an account. The plaintext key is returned only once.
- Storage: Zyntem stores a SHA-256 hash of the key. The plaintext cannot be retrieved after creation.
- Revocation: Keys can be revoked, making them permanently unusable.
Store your API key securely immediately after account creation. If lost, you'll need to generate a new key.
Test vs live mode
The API key prefix determines the environment for each request:
zyn_test_keys route fiscalization to sandbox tax authority endpoints. Use these during development and testing.zyn_live_keys route fiscalization to production tax authority endpoints. Requires the server to have live mode enabled.
Transactions include an environment field ("test" or "live") reflecting which mode was used.
If live mode is not enabled on the server, requests with zyn_live_ keys return 403 Forbidden:
{
"error": "live mode is not enabled"
}
See the Sandbox routing guide for more details.
Public endpoints
The following endpoints do not require authentication:
| Endpoint | Description |
|---|---|
GET /health | Service health check |
GET /version | API version information |
POST /v1/accounts | Account creation |
Error responses
| Status | Error | Cause |
|---|---|---|
401 | missing or invalid Authorization header | No Authorization header provided |
401 | invalid API key format | Key doesn't match expected format |
401 | invalid API key | Key not found or hash mismatch |
401 | API key has been revoked | Key was revoked |
403 | account is not active | Account suspended or cancelled |
Example error response:
{
"error": "missing or invalid Authorization header"
}
Embedded SDK authentication
The Embedded Local SDKs use the same API keys as the Cloud API, but authentication works differently. Instead of sending the key with every request, the SDK exchanges it for a signed token once during initialization.
How token provisioning works
When you call init() or initWithConfig() with an api_key, the SDK makes a single HTTPS call to api.zyntem.com to exchange the key for a signed token. This is the only network call required at startup.
init(config with api_key)
│
▼
SDK calls api.zyntem.com ◄── one-time token exchange
│
▼
Signed token stored locally
│
▼
All future processTransaction() calls
work offline using the local token
The token is cached locally. Subsequent init() calls (e.g., after an app restart) reuse the cached token without a network call, unless the token has expired.
Providing the API key
Pass the api_key in your configuration:
# fiscalization.yaml
country: ES
tax_id: B12345678
environment: sandbox
api_key: zyn_test_abc123
Or inline via initWithConfig():
zyntem_fiscal.init_with_config({
"country": "ES",
"tax_id": "B12345678",
"environment": "sandbox",
"api_key": "zyn_test_abc123",
})
If api_key is omitted, the SDK falls back to the ZYNTEM_API_KEY environment variable. See the Configuration Reference for the full list of fields.
Test vs live keys in Embedded mode
The key prefix determines the environment, just like the Cloud API:
| Key prefix | environment config | Behavior |
|---|---|---|
zyn_test_ | "sandbox" | Transactions signed locally, queued for sandbox tax authority endpoints |
zyn_live_ | "production" | Transactions signed locally, queued for production tax authority endpoints |
The SDK validates that the key prefix matches the environment setting at init time. Mismatches are rejected:
- A
zyn_test_key with"environment": "production"→ init error - A
zyn_live_key with"environment": "sandbox"→ init error
This prevents accidental production submissions during development.
Token provisioning errors
If token provisioning fails during init(), the SDK returns an error and is not usable until init succeeds:
| Error | Cause |
|---|---|
token provisioning failed: HTTP 401 | Invalid or revoked API key |
token provisioning failed: HTTP 403 | Key doesn't have permission for this country |
token provisioning failed: connection refused | Can't reach api.zyntem.com |
Network errors (connection refused) are the only retryable init errors. See Embedded Error Handling for recovery patterns.
Best practices
- Use
zyn_test_keys for development; never usezyn_live_keys in test environments - Store keys in environment variables, not in code
- Rotate keys periodically by creating new ones and revoking old ones
- Use separate keys for different services or environments
- Embedded SDK: ensure network is available on first boot for token provisioning
- Embedded SDK: monitor
queueStatus()for failed submissions after going live