Overview
API keys are the primary authentication mechanism for the InstaView API. Each key is cryptographically secure, scoped to a specific company, and has granular permissions through scopes.
Key Architecture
Security Features
InstaView API keys are built with enterprise-grade security:
HMAC-SHA256 Hashing Keyed hashing with a strong server-side secret; plaintext keys are never
stored.
256-bit Entropy Cryptographically secure random key generation
Audit Logging Complete audit trail for all key lifecycle events
Company Isolation Keys are strictly scoped to prevent cross-company access
Key Components
Every API key contains:
Prefix : Identifies key type (sk_ for secret keys)
Environment : live for production, test for sandbox
Identifier : Unique 32-character string
Metadata : Name, scopes, creation date, etc.
Creating API Keys
Via Dashboard
Navigate to API Keys
Go to Settings → API Keys in your dashboard
Create New Key
Click Create API Key
Configure Details
{
"name" : "Production Integration" ,
"scopes" : [
"read:jobs" ,
"write:jobs" ,
"read:candidates" ,
"write:candidates" ,
"read:interviews" ,
"write:interviews"
],
"expiresAt" : "2025-12-31T23:59:59Z" , // Optional
"allowedIPs" : [ // Optional
"192.168.1.0/24" ,
"10.0.0.100"
]
}
Save the Key
Important : Copy your API key immediately - it will only be shown once!
Via API (Admin Only)
// Requires admin JWT authentication
const response = await fetch ( "https://api.instaview.sk/api-keys" , {
method: "POST" ,
headers: {
Authorization: "Bearer <admin-jwt>" ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({
companyId: "550e8400-e29b-41d4-a716-446655440000" ,
name: "Production Integration" ,
scopes: [ "read:jobs" , "write:jobs" , "read:candidates" , "write:candidates" ],
}),
});
const { data } = await response . json ();
console . log ( "API Key:" , data . key ); // Save this securely!
Scope Configuration
Choosing the Right Scopes
Apply the principle of least privilege:
Analytics Dashboard
Candidate Portal
Full Integration
Webhook Handler
{
"scopes" : [
"read:jobs" ,
"read:candidates" ,
"read:interviews" ,
"read:billing"
]
}
Read-only access for dashboards and reporting. {
"scopes" : [
"read:jobs" ,
"read:candidates" ,
"write:candidates" ,
"read:interviews"
]
}
Candidate management with limited interview access. {
"scopes" : [
"read:jobs" ,
"write:jobs" ,
"delete:jobs" ,
"read:candidates" ,
"write:candidates" ,
"delete:candidates" ,
"read:interviews" ,
"write:interviews" ,
"read:agents" ,
"write:agents" ,
"delete:agents"
]
}
Complete access for primary integrations. {
"scopes" : [
"read:interviews" ,
"read:candidates"
]
}
Minimal access for processing webhook events.
Scope Validation
When making API requests, scopes are validated:
// ✅ Success: Key has write:jobs scope
POST / jobs
Authorization : Bearer sk_live_xxx ( scopes : [ "write:jobs" ])
// ❌ Error: Key lacks write:jobs scope
POST / jobs
Authorization : Bearer sk_live_yyy ( scopes : [ "read:jobs" ])
// Response:
{
"success" : false ,
"error" : {
"code" : "INSUFFICIENT_PERMISSIONS" ,
"message" : "This API key does not have the required scope: write:jobs"
}
}
Key Types
Regular API Keys
Standard keys associated with a single company:
// Automatically scoped to the key's company
GET / jobs
Authorization : Bearer sk_live_company_a_key
// Returns only jobs for Company A
Use Cases :
Direct integrations
Internal tools
Customer-facing applications
ATS Integration Keys
Special keys for multi-tenant ATS platforms:
// Must specify companyId for resource access
GET / jobs ? companyId = company - b - uuid
Authorization : Bearer sk_live_ats_integration_key
// Can create new companies
POST / companies
Authorization : Bearer sk_live_ats_integration_key
Use Cases :
Greenhouse, Lever, or other ATS integrations
Multi-tenant recruitment platforms
White-label solutions
ATS keys can only be created by InstaView administrators. Contact
support to request ATS integration access.
Advanced Configuration
IP Allowlists
Restrict key usage to specific IP addresses or ranges:
{
"name" : "Production Integration" ,
"allowedIPs" : [
"192.168.1.100" , // Single IP
"10.0.0.0/8" , // CIDR notation
"172.16.0.0/12" // Private network range
]
}
Requests from non-allowlisted IPs will be rejected:
{
"success" : false ,
"error" : {
"code" : "IP_NOT_ALLOWED" ,
"message" : "Request IP address not in allowlist"
}
}
Expiration Dates
Set automatic key expiration for temporary access:
{
"name" : "Contractor Access" ,
"expiresAt" : "2025-03-31T23:59:59Z" ,
"scopes" : [ "read:candidates" ]
}
Best Practices :
Use expiration for contractor/temporary access
Set 90-day expiration for high-privilege keys
Receive email notifications 7 days before expiry
Add custom metadata for organization:
{
"name" : "Production Integration" ,
"metadata" : {
"tags" : [ "production" , "primary" ],
"environment" : "us-east-1" ,
"owner" : "engineering@company.com" ,
"project" : "candidate-sync"
}
}
Key Lifecycle Management
Monitoring Usage
Track key usage in the dashboard:
Last Used : Timestamp of most recent request
Request Count : Total API calls made
Error Rate : Failed requests percentage
Top Endpoints : Most frequently accessed endpoints
Rotating Keys
Regular rotation improves security:
Create New Key
Generate a replacement key with the same scopes
Update Applications
Deploy the new key to all applications
Monitor Old Key
Verify traffic has moved to the new key
Revoke Old Key
Once traffic has fully migrated, revoke the old key
Recommended Rotation Schedule :
High-privilege keys: Every 90 days
Read-only keys: Every 180 days
Compromised keys: Immediately
Suspending Keys
Temporarily disable a key without deletion:
// Via dashboard or API
PATCH / api - keys / { keyId }
{
"suspended" : true ,
"suspensionReason" : "Temporary maintenance"
}
Use Cases :
Investigating suspicious activity
Temporary service maintenance
Debugging integration issues
Revoking Keys
Permanently revoke a compromised key:
Revocation is permanent! Revoked keys cannot be restored. Create a new key
if needed.
DELETE / api - keys / { keyId }
{
"revocationReason" : "Key compromised in security incident"
}
All subsequent requests with the revoked key will fail:
{
"success" : false ,
"error" : {
"code" : "API_KEY_REVOKED" ,
"message" : "This API key has been revoked"
}
}
Security Best Practices
Never Expose Keys in Code
❌ Don’t do this: const apiKey = 'sk_live_1234567890abcdef' ; // Hardcoded!
✅ Do this instead: const apiKey = process . env . INSTAVIEW_API_KEY ;
Use Separate Keys per Environment
Production : sk_live_xxx - Staging : sk_test_xxx -
Development : sk_test_yyy Never use production keys in non-production
environments.
// Graceful key rotation
const primaryKey = process . env . INSTAVIEW_PRIMARY_KEY ;
const fallbackKey = process . env . INSTAVIEW_FALLBACK_KEY ;
async function makeRequest ( url , options ) {
try {
return await fetch ( url , {
... options ,
headers: {
... options . headers ,
'Authorization' : `Bearer ${ primaryKey } `
}
});
} catch ( error ) {
if ( error . status === 401 ) {
// Primary key failed, try fallback
return await fetch ( url , {
... options ,
headers: {
... options . headers ,
'Authorization' : `Bearer ${ fallbackKey } `
}
});
}
throw error ;
}
}
Set up alerts for: - Unusual request volumes - Requests from unexpected IPs -
High error rates - After-hours usage (if unexpected)
When your application runs from fixed infrastructure: {
"allowedIPs" : [
"52.1.2.3" , // Production server 1
"52.1.2.4" , // Production server 2
"10.0.0.0/16" // VPC network
]
}
Note: All API requests must use the Authorization: Bearer header with your API key.
Audit Logs
All API key events are logged for security and compliance:
Logged Events
Key Creation : Who created it, when, and with what scopes
Authentication : Every successful and failed authentication
Scope Changes : Modifications to key permissions
Suspension/Revocation : Status changes with reasons
Configuration Changes : IP allowlist, expiration date updates
Accessing Audit Logs
// Via dashboard: Security → Audit Logs
// Filter by key ID
GET / api - keys / { keyId } / audit - logs
// Filter by event type
GET / api - keys / { keyId } / audit - logs ? eventType = authentication_failed
// Date range
GET / api - keys / { keyId } / audit - logs ? from = 2024 - 01 - 01 & to = 2024 - 01 - 31
Example Audit Log Entry
{
"id" : "log_1234567890" ,
"eventType" : "authentication_success" ,
"apiKeyId" : "key_xxx" ,
"timestamp" : "2024-01-15T10:30:00Z" ,
"ipAddress" : "192.168.1.100" ,
"userAgent" : "MyApp/1.0" ,
"endpoint" : "/jobs" ,
"metadata" : {
"companyId" : "550e8400-e29b-41d4-a716-446655440000" ,
"scopes" : [ "read:jobs" , "write:jobs" ]
}
}
Troubleshooting
Possible Causes :
Invalid API key format
Revoked or expired key
Suspended key
Key not properly set in headers
Solutions :
Verify key format: sk_live_xxx or sk_test_xxx
Check key status in dashboard
Ensure header is Authorization: Bearer sk_xxx
Possible Causes : - Insufficient scopes - IP not in allowlist - Attempting
cross-company access Solutions : - Check required scope in error message -
Verify your IP is allowlisted - Confirm you’re accessing resources in your
company
Possible Causes :
Exceeded rate limit
Too many requests in short time
Solutions :
Next Steps