Understanding and managing API keys for Quotient
API keys are the primary authentication mechanism for accessing the Quotient API. This guide covers the different key types, their use cases, and how to set them up correctly.
Quotient uses a two-tier API key system designed for different security contexts:
pk_*
)Public keys are designed for client-side applications where the key is exposed in browser code or mobile apps.
Characteristics:
pk_
Allowed Endpoints:
POST /api/v0/analytics
- Track events originating from your websitePOST /api/v0/people
- Upsert people you gather from your websiteGET /api/v0/whoami
- Verify key configuration and get client contextUse Cases:
sk_*
)Private keys are for server-side applications where the key can be kept secret.
Characteristics:
sk_
Use Cases:
Security Warning: Never expose private keys in client-side code, version control, or public repositories.
Public keys can be restricted to specific origins to prevent unauthorized use if the key is stolen.
How it works:
Origin
header of incoming requestsOrigin formats supported:
*
- Allow any origin (not recommended for production)example.com
- Matches example.com and all subdomainsapp.example.com
- Matches only this specific subdomainhttps://app.example.com
- Matches exact protocol and domainlocalhost:3000
- Matches localhost on specific portExamples:
✅ Valid origins:
- example.com
- app.example.com
- subdomain.example.com
- localhost:3000
- https://app.example.com:8080
❌ Invalid origins:
- http:// (protocol only)
- :3000 (port only)
- .com (TLD only)
Matching rules:
example.com
matches:
https://example.com
https://www.example.com
https://app.example.com
app.example.com
matches only:
https://app.example.com
http://app.example.com
API keys will support granular permission scopes:
ALL
- Full access (current default)Keys can have optional expiration dates for temporary access:
Each key tracks:
For now, you can only create public keys via the dashboard.
Principle of Least Privilege
Origin Restrictions
*
(wildcard) in productionInclude the API key in the Authorization
header:
curl -X POST https://api.quotient.com/api/v0/analytics \
-H "Authorization: Bearer pk_test_1234567890abcdef" \
-H "Content-Type: application/json" \
-d '{"eventType": "pageView"}'
// JavaScript SDK
const quotient = await QuotientClient.init({
apiKey: 'pk_test_1234567890abcdef'
});
// React SDK
<QuotientProvider clientOptions={{
apiKey: 'pk_test_1234567890abcdef'
}}>
Store keys in environment variables:
# .env.local
NEXT_PUBLIC_QUOTIENT_API_KEY=pk_1234567890abcdef
QUOTIENT_PRIVATE_KEY=sk_1234567890abcdef # Server-side only
Framework examples:
// Next.js (client-side)
const apiKey = process.env.NEXT_PUBLIC_QUOTIENT_API_KEY;
// Node.js (server-side)
const apiKey = process.env.QUOTIENT_PRIVATE_KEY;
// Vite/React
const apiKey = import.meta.env.VITE_QUOTIENT_API_KEY;
Origin
header matches allowed originshttp
vs https
)Use the whoami
endpoint to debug:
const info = await quotient.auth.whoami({});
console.log({
businessId: info.businessId,
keyType: info.keyType,
origin: info.origin,
allowedOrigins: info.allowedOrigins
});