Documentation Index Fetch the complete documentation index at: https://docs.instaview.sk/llms.txt
Use this file to discover all available pages before exploring further.
Authentication & Security
// ✅ Good
const apiKey = process . env . INSTAVIEW_API_KEY ;
// ❌ Bad
const apiKey = 'sk_live_abc123' ; // Hardcoded!
Separate Keys per Environment
Production : sk_live_xxx
Staging : sk_test_xxx
Development : sk_test_yyy
// ✅ Good: Only what's needed
scopes : [ 'read:jobs' , 'read:candidates' ]
// ❌ Bad: Unnecessary permissions
scopes : [ 'read:*' , 'write:*' , 'delete:*' ]
Rotate high-privilege keys every 90 days
Implement graceful key rotation with fallback
Monitor key usage after rotation
Error Handling
Comprehensive Error Handler
class InstaViewAPI {
async request ( method , path , data ) {
try {
const response = await fetch ( ` ${ this . baseURL }${ path } ` , {
method ,
headers: this . headers ,
body: data ? JSON . stringify ( data ) : null
});
const result = await response . json ();
if ( ! result . success ) {
throw this . createError ( result . error , response . status );
}
return result . data ;
} catch ( error ) {
if ( error . name === 'FetchError' ) {
// Network error - retry
return this . retryRequest ( method , path , data );
}
throw error ;
}
}
createError ( errorData , statusCode ) {
const error = new Error ( errorData . message );
error . code = errorData . code ;
error . details = errorData . details ;
error . statusCode = statusCode ;
return error ;
}
}
Rate Limiting
Request Queue
class RateLimitedQueue {
constructor ( requestsPerSecond = 5 ) {
this . queue = [];
this . processing = false ;
this . interval = 1000 / requestsPerSecond ;
}
async add ( fn ) {
return new Promise (( resolve , reject ) => {
this . queue . push ({ fn , resolve , reject });
if ( ! this . processing ) {
this . process ();
}
});
}
async process () {
this . processing = true ;
while ( this . queue . length > 0 ) {
const { fn , resolve , reject } = this . queue . shift ();
try {
const result = await fn ();
resolve ( result );
} catch ( error ) {
reject ( error );
}
if ( this . queue . length > 0 ) {
await this . sleep ( this . interval );
}
}
this . processing = false ;
}
sleep ( ms ) {
return new Promise ( resolve => setTimeout ( resolve , ms ));
}
}
// Usage
const queue = new RateLimitedQueue ( 5 ); // 5 requests/second
await queue . add (() => createJob ( jobData ));
await queue . add (() => createCandidate ( candidateData ));
Efficient Iteration
async function* paginateAll ( endpoint ) {
let page = 1 ;
let hasMore = true ;
while ( hasMore ) {
const response = await fetch (
` ${ endpoint } ?page= ${ page } &limit=100` ,
{ headers: { 'Authorization' : `Bearer ${ apiKey } ` } }
);
const result = await response . json ();
yield * result . data . items ;
hasMore = result . data . pagination . hasNextPage ;
page ++ ;
}
}
// Process items as they arrive
for await ( const candidate of paginateAll ( '/candidates' )) {
await processCandidate ( candidate );
}
Data Validation
Pre-Request Validation
function validateCandidateData ( data ) {
const errors = [];
if ( ! data . firstName || data . firstName . length < 1 ) {
errors . push ( 'firstName is required' );
}
if ( ! / ^ [ ^ \s@ ] + @ [ ^ \s@ ] + \. [ ^ \s@ ] + $ / . test ( data . email )) {
errors . push ( 'Invalid email format' );
}
if ( ! / ^ \+ \d {10,15} $ / . test ( data . phoneNumber )) {
errors . push ( 'Phone must be in E.164 format (+1234567890)' );
}
if ( errors . length > 0 ) {
throw new ValidationError ( errors );
}
}
// Use before API call
try {
validateCandidateData ( candidateData );
await createCandidate ( candidateData );
} catch ( error ) {
if ( error instanceof ValidationError ) {
showUserErrors ( error . errors );
}
}
Caching
Smart Caching Strategy
class CachedAPI {
constructor ( apiKey ) {
this . cache = new Map ();
this . ttl = {
jobs: 300000 , // 5 minutes
candidates: 60000 , // 1 minute
interviews: 30000 // 30 seconds
};
}
async get ( resource , id ) {
const cacheKey = ` ${ resource } : ${ id } ` ;
const cached = this . cache . get ( cacheKey );
if ( cached && Date . now () - cached . timestamp < this . ttl [ resource ]) {
return cached . data ;
}
const data = await this . fetchFromAPI ( resource , id );
this . cache . set ( cacheKey , {
data ,
timestamp: Date . now ()
});
return data ;
}
invalidate ( resource , id ) {
this . cache . delete ( ` ${ resource } : ${ id } ` );
}
}
Monitoring & Logging
Structured Logging
class APILogger {
static log ( level , message , context = {}) {
const log = {
timestamp: new Date (). toISOString (),
level ,
message ,
... context ,
service: 'instaview-api'
};
console . log ( JSON . stringify ( log ));
// Send to monitoring service
if ( process . env . NODE_ENV === 'production' ) {
monitoring . track ( log );
}
}
static info ( message , context ) {
this . log ( 'info' , message , context );
}
static error ( message , error , context ) {
this . log ( 'error' , message , {
... context ,
error: {
message: error . message ,
code: error . code ,
stack: error . stack
}
});
}
}
// Usage
APILogger . info ( 'Creating candidate' , {
jobId: 'job-uuid' ,
candidateEmail: 'jane@example.com'
});
Testing
Integration Tests
describe ( 'InstaView API Integration' , () => {
let testJobId ;
let testCandidateId ;
beforeAll ( async () => {
// Create test job
const job = await createJob ({
title: 'Test Job' ,
status: 'OPEN'
});
testJobId = job . id ;
});
afterAll ( async () => {
// Cleanup
await deleteJob ( testJobId );
});
test ( 'should create and retrieve candidate' , async () => {
// Create candidate
const candidate = await createCandidate ({
jobId: testJobId ,
firstName: 'Test' ,
lastName: 'User' ,
email: 'test@example.com' ,
phoneNumber: '+1234567890'
});
testCandidateId = candidate . id ;
expect ( candidate . firstName ). toBe ( 'Test' );
// Retrieve candidate
const retrieved = await getCandidate ( testCandidateId );
expect ( retrieved . id ). toBe ( testCandidateId );
expect ( retrieved . email ). toBe ( 'test@example.com' );
});
});
Batch Operations Group related API calls together
Parallel Requests Use Promise.all() for independent calls
Connection Pooling Reuse HTTP connections
Compression Enable gzip compression
Deployment Checklist
Environment Variables
✓ API keys in environment variables
✓ Different keys for each environment
✓ Secrets not in version control
Error Handling
✓ Comprehensive error handling
✓ Retry logic with exponential backoff
✓ Circuit breakers for failures
Monitoring
✓ Logging for all API calls
✓ Error tracking (Sentry, etc.)
✓ Performance monitoring
✓ Alert on rate limit hits
Security
✓ API key rotation schedule
✓ IP allowlists configured
✓ HTTPS only
✓ Webhook signature verification
Next Steps
Error Handling Handle errors gracefully
Rate Limiting Optimize API usage
Webhooks Real-time event notifications
API Reference Complete API documentation