API Authentication
Learn how to authenticate with the ZenSearch API.
API Key Pairs
ZenSearch uses a key pair model with two types of keys for different use cases:
| Key Type | Prefix | Use Case | Security Level |
|---|---|---|---|
| Publishable Key | zsk_pk_ | Client-side (browsers, mobile) | Public-safe |
| Secret Key | zsk_sk_ | Server-side only | Confidential |
Getting API Keys
- Go to Settings → API Keys in ZenSearch
- Click Create API Key
- Configure collection access and security settings
- Copy and securely store both keys
API keys are only shown once at creation. Store them securely immediately.
Authentication Methods
Header Authentication
Include your API key in the X-ZenSearch-Key header:
# Client-side: use publishable key
curl -X POST https://your-domain.com/v1/docs/search \
-H "X-ZenSearch-Key: zsk_pk_xxx..." \
-H "Content-Type: application/json" \
-d '{"query": "authentication"}'
# Server-side: use secret key
curl -X POST https://your-domain.com/v1/docs/search \
-H "X-ZenSearch-Key: zsk_sk_xxx..." \
-H "Content-Type: application/json" \
-d '{"query": "authentication"}'
HMAC Request Signing (Server-Side)
For enhanced security, enable HMAC signing for server-side requests:
# Generate signature
TIMESTAMP=$(date +%s)000
PAYLOAD='{"query":"authentication"}'
SIGNATURE=$(echo -n "${TIMESTAMP}.${PAYLOAD}" | openssl dgst -sha256 -hmac "zsk_sk_xxx..." | cut -d' ' -f2)
curl -X POST https://your-domain.com/v1/docs/search \
-H "X-ZenSearch-Key: zsk_sk_xxx..." \
-H "X-ZenSearch-Timestamp: $TIMESTAMP" \
-H "X-ZenSearch-Signature: $SIGNATURE" \
-H "Content-Type: application/json" \
-d "$PAYLOAD"
Signature requirements:
- Timestamp: Unix timestamp in milliseconds
- Payload: Request body as JSON string
- Signature: HMAC-SHA256 of
{timestamp}.{payload} - Replay protection: Timestamp must be within 5 minutes of server time
SDK Authentication
Documentation Search SDK (JavaScript/TypeScript)
import { ZenSearchDocs } from '@zensearch/docs-sdk';
// Client-side: use publishable key
const client = new ZenSearchDocs({
apiKey: 'zsk_pk_xxx...',
defaultCollection: 'your-collection-id',
});
// Search documentation
const results = await client.search('authentication');
// Server-side: use secret key
import { ZenSearchDocs } from '@zensearch/docs-sdk';
const serverClient = new ZenSearchDocs({
apiKey: process.env.ZENSEARCH_SECRET_KEY, // zsk_sk_xxx...
});
Docusaurus Plugin
// docusaurus.config.js
module.exports = {
themes: [
[
'docusaurus-search-zensearch',
{
apiKey: 'zsk_pk_xxx...', // Publishable key
collectionId: 'your-collection-id',
},
],
],
};
Publishable vs Secret Keys
When to Use Publishable Keys (zsk_pk_)
Use publishable keys when:
- Embedding in frontend JavaScript
- Building mobile applications
- Creating browser extensions
- Any client-side code that users can inspect
Publishable keys are protected by:
- Allowed hosts: Only work from specified domains
- Allowed referers: Validate HTTP Referer header
- IP rate limiting: Per-IP request limits
- Read-only operations: Cannot modify data
When to Use Secret Keys (zsk_sk_)
Use secret keys when:
- Making requests from your backend server
- Running in serverless functions (Lambda, Cloud Functions)
- Building internal tools
- Any environment where the key is not exposed to users
Secret keys provide:
- Full API access: All permitted operations
- HMAC signing support: Enhanced request security
- Higher rate limits: Not subject to per-IP limits
- Analytics write access: Can track events server-side
Never expose secret keys in client-side code. If a secret key is compromised, revoke it immediately and create a new key pair.
Collection-Scoped Access
API key pairs can be restricted to specific collections:
{
"allow_all_collections": false,
"allowed_collections": [
"collection-uuid-1",
"collection-uuid-2"
]
}
Requests to unauthorized collections return:
{
"error": {
"code": "forbidden",
"message": "Collection access denied"
}
}
Security Best Practices
Do
- Use publishable keys for all client-side code
- Store secret keys in environment variables or secret managers
- Restrict collections to only what's needed
- Set allowed hosts for publishable keys to your domains
- Enable HMAC signing for sensitive server operations
- Rotate keys every 90 days
- Monitor usage for unusual patterns
Don't
- Commit keys to version control
- Share keys in plain text (Slack, email)
- Use secret keys in client-side code
- Use production keys in development
- Share key pairs between applications
Error Responses
Invalid API Key
{
"error": {
"code": "invalid_key",
"message": "Invalid API key"
}
}
HTTP Status: 401 Unauthorized
Missing API Key
{
"error": {
"code": "unauthorized",
"message": "API key required"
}
}
HTTP Status: 401 Unauthorized
Expired API Key
{
"error": {
"code": "key_expired",
"message": "API key has expired"
}
}
HTTP Status: 401 Unauthorized
Collection Access Denied
{
"error": {
"code": "forbidden",
"message": "Collection access denied"
}
}
HTTP Status: 403 Forbidden
Host Not Allowed
{
"error": {
"code": "forbidden",
"message": "Host not allowed"
}
}
HTTP Status: 403 Forbidden
Invalid HMAC Signature
{
"error": {
"code": "invalid_signature",
"message": "Invalid request signature"
}
}
HTTP Status: 401 Unauthorized
Rate Limited
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded"
}
}
HTTP Status: 429 Too Many Requests
Headers:
Retry-After: 60
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1609459200
Next Steps
- API Keys Settings - Manage your API keys
- Docs SDK - JavaScript/TypeScript SDK reference
- Rate Limits - Usage limits and quotas
- Search API - Search endpoints