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.
Overview
The InstaView API uses standard HTTP status codes and returns structured error responses to help you diagnose and handle issues in your integration.
Response Structure
All API responses follow a consistent format:
{
"success" : boolean ,
"data" : object | array | null ,
"error" : {
"code" : string ,
"message" : string ,
"details" : object
} | null ,
"timestamp" : string
}
Success Response
{
"success" : true ,
"data" : {
"id" : "550e8400-e29b-41d4-a716-446655440000" ,
"title" : "Senior Engineer"
},
"error" : null ,
"timestamp" : "2024-01-15T10:30:00Z"
}
Error Response
{
"success" : false ,
"data" : null ,
"error" : {
"code" : "RESOURCE_NOT_FOUND" ,
"message" : "Job with ID 550e8400-e29b-41d4-a716-446655440000 not found" ,
"details" : {
"resourceType" : "Job" ,
"resourceId" : "550e8400-e29b-41d4-a716-446655440000"
}
},
"timestamp" : "2024-01-15T10:30:00Z"
}
HTTP Status Codes
2xx Success
4xx Client Errors
5xx Server Errors
Code Meaning Usage 200 OK Successful GET, PATCH, DELETE requests 201 Created Successful POST request creating a resource
Code Meaning Common Causes 400 Bad Request Invalid request body, validation errors 401 Unauthorized Missing or invalid API key 403 Forbidden Insufficient permissions, wrong company 404 Not Found Resource doesn’t exist 409 Conflict Duplicate resource, state conflict 422 Unprocessable Valid JSON but semantic errors 429 Too Many Requests Rate limit exceeded
Code Meaning Action 500 Internal Server Error Retry with exponential backoff 502 Bad Gateway Temporary issue, retry 503 Service Unavailable Maintenance, retry later 504 Gateway Timeout Request timeout, retry
Error Codes
Authentication Errors
The provided API key is invalid, revoked, or expired {
"error" : {
"code" : "INVALID_API_KEY" ,
"message" : "The provided API key is invalid or has been revoked"
}
}
Solutions :
Verify API key format
Check if key was revoked in dashboard
Ensure key hasn’t expired
The API key has been temporarily suspended {
"error" : {
"code" : "API_KEY_SUSPENDED" ,
"message" : "This API key has been suspended" ,
"details" : {
"suspendedAt" : "2024-01-10T00:00:00Z" ,
"reason" : "Unusual activity detected"
}
}
}
Solution : Contact support or check dashboard for details
Permission Errors
API key lacks required scope {
"error" : {
"code" : "INSUFFICIENT_PERMISSIONS" ,
"message" : "This API key does not have the required scope: write:jobs" ,
"details" : {
"required" : "write:jobs" ,
"available" : [ "read:jobs" , "read:candidates" ]
}
}
}
Solution : Add required scope to API key or create new key
Resource belongs to different company {
"error" : {
"code" : "RESOURCE_ACCESS_DENIED" ,
"message" : "Access denied to this resource"
}
}
Solutions :
Verify resource belongs to your company
Check if using correct companyId (ATS keys)
Ensure resource hasn’t been deleted
Validation Errors
Request validation failed {
"error" : {
"code" : "VALIDATION_ERROR" ,
"message" : "Request validation failed" ,
"details" : {
"fields" : {
"email" : "Invalid email format" ,
"phoneNumber" : "Phone number is required" ,
"jobId" : "Must be a valid UUID"
}
}
}
}
Solution : Fix validation errors in request body
Required field not provided {
"error" : {
"code" : "MISSING_REQUIRED_FIELD" ,
"message" : "Missing required field: jobId" ,
"details" : {
"field" : "jobId" ,
"type" : "string (UUID)"
}
}
}
Resource Errors
Requested resource doesn’t exist {
"error" : {
"code" : "RESOURCE_NOT_FOUND" ,
"message" : "Job not found" ,
"details" : {
"resourceType" : "Job" ,
"resourceId" : "550e8400-e29b-41d4-a716-446655440000"
}
}
}
Resource already exists or state conflict {
"error" : {
"code" : "RESOURCE_CONFLICT" ,
"message" : "A candidate with this email already exists for this job" ,
"details" : {
"conflictingField" : "email" ,
"existingResourceId" : "candidate-uuid"
}
}
}
Rate Limiting
Too many requests {
"error" : {
"code" : "RATE_LIMIT_EXCEEDED" ,
"message" : "Rate limit exceeded. Please retry after 45 seconds" ,
"details" : {
"retryAfter" : 45 ,
"limit" : 300 ,
"window" : "minute"
}
}
}
Solution : Wait for retryAfter seconds, implement exponential backoff
Business Logic Errors
Company billing limit reached {
"error" : {
"code" : "BILLING_LIMIT_EXCEEDED" ,
"message" : "Monthly interview limit exceeded" ,
"details" : {
"limit" : 100 ,
"used" : 100 ,
"resetDate" : "2024-02-01T00:00:00Z"
}
}
}
Solution : Upgrade plan or wait for monthly reset
Invalid resource state change {
"error" : {
"code" : "INVALID_STATE_TRANSITION" ,
"message" : "Cannot delete job with active candidates" ,
"details" : {
"currentState" : "active" ,
"attemptedAction" : "delete" ,
"reason" : "Job has 5 active candidates"
}
}
}
Error Handling Patterns
Basic Error Handling
async function createJob ( jobData ) {
try {
const response = await fetch ( 'https://api.instaview.sk/jobs' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ process . env . INSTAVIEW_API_KEY } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ( jobData )
});
const result = await response . json ();
if ( ! result . success ) {
throw new InstaViewError ( result . error );
}
return result . data ;
} catch ( error ) {
console . error ( 'Failed to create job:' , error . message );
throw error ;
}
}
class InstaViewError extends Error {
constructor ( errorData ) {
super ( errorData . message );
this . code = errorData . code ;
this . details = errorData . details ;
this . name = 'InstaViewError' ;
}
}
Comprehensive Error Handler
class InstaViewClient {
constructor ( apiKey ) {
this . apiKey = apiKey ;
this . baseURL = 'https://api.instaview.sk/v1' ;
}
async request ( method , path , data = null ) {
try {
const response = await fetch ( ` ${ this . baseURL }${ path } ` , {
method ,
headers: {
'Authorization' : `Bearer ${ this . apiKey } ` ,
'Content-Type' : 'application/json'
},
body: data ? JSON . stringify ( data ) : null
});
const result = await response . json ();
if ( ! result . success ) {
return this . handleError ( result . error , response . status );
}
return result . data ;
} catch ( error ) {
console . error ( 'Network error:' , error );
throw error ;
}
}
handleError ( error , statusCode ) {
switch ( error . code ) {
case 'INVALID_API_KEY' :
case 'API_KEY_SUSPENDED' :
console . error ( 'Authentication error:' , error . message );
// Notify admin, stop operations
throw new AuthenticationError ( error );
case 'INSUFFICIENT_PERMISSIONS' :
console . error ( 'Permission denied:' , error . message );
console . error ( 'Required:' , error . details . required );
console . error ( 'Available:' , error . details . available );
throw new PermissionError ( error );
case 'VALIDATION_ERROR' :
console . error ( 'Validation failed:' , error . details . fields );
// Show user-friendly messages
throw new ValidationError ( error );
case 'RATE_LIMIT_EXCEEDED' :
console . log ( `Rate limited. Retry after ${ error . details . retryAfter } s` );
// Implement retry logic
throw new RateLimitError ( error );
case 'RESOURCE_NOT_FOUND' :
console . warn ( 'Resource not found:' , error . details );
return null ; // Handle gracefully
case 'BILLING_LIMIT_EXCEEDED' :
console . error ( 'Billing limit exceeded:' , error . message );
// Notify admin, show upgrade prompt
throw new BillingError ( error );
default :
console . error ( 'Unknown error:' , error );
throw new InstaViewError ( error );
}
}
}
Retry with Exponential Backoff
async function retryWithBackoff ( fn , maxRetries = 3 , baseDelay = 1000 ) {
let lastError ;
for ( let attempt = 0 ; attempt < maxRetries ; attempt ++ ) {
try {
return await fn ();
} catch ( error ) {
lastError = error ;
// Don't retry client errors (except rate limits)
if ( error . statusCode >= 400 && error . statusCode < 500 ) {
if ( error . code === 'RATE_LIMIT_EXCEEDED' ) {
const delay = error . details . retryAfter * 1000 || baseDelay ;
await sleep ( delay );
continue ;
}
throw error ; // Don't retry other client errors
}
// Retry server errors with exponential backoff
if ( error . statusCode >= 500 ) {
const delay = baseDelay * Math . pow ( 2 , attempt );
console . log ( `Attempt ${ attempt + 1 } failed. Retrying in ${ delay } ms...` );
await sleep ( delay );
continue ;
}
throw error ;
}
}
throw lastError ;
}
// Usage
const job = await retryWithBackoff ( async () => {
return await client . createJob ( jobData );
});
Validation Error Handling
Handle field-level validation errors:
async function createCandidateWithValidation ( candidateData ) {
try {
return await client . createCandidate ( candidateData );
} catch ( error ) {
if ( error . code === 'VALIDATION_ERROR' ) {
const fieldErrors = error . details . fields ;
// Display user-friendly errors
for ( const [ field , message ] of Object . entries ( fieldErrors )) {
showFieldError ( field , message );
}
// Or collect all errors
const errors = Object . entries ( fieldErrors ). map (([ field , msg ]) => ({
field ,
message: msg
}));
return { success: false , errors };
}
throw error ;
}
}
function showFieldError ( field , message ) {
// Display error next to form field
document . getElementById ( ` ${ field } -error` ). textContent = message ;
}
Idempotency
Implement idempotency for safe retries:
async function createJobIdempotent ( jobData , idempotencyKey ) {
try {
return await fetch ( 'https://api.instaview.sk/jobs' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ apiKey } ` ,
'Content-Type' : 'application/json' ,
'Idempotency-Key' : idempotencyKey // Use same key for retries
},
body: JSON . stringify ( jobData )
});
} catch ( error ) {
// Safe to retry with same idempotency key
return await fetch ( /* same request */ );
}
}
// Generate idempotency key
const idempotencyKey = `job-create- ${ Date . now () } - ${ Math . random () } ` ;
await createJobIdempotent ( jobData , idempotencyKey );
Logging and Monitoring
Log errors for debugging and monitoring:
class ErrorLogger {
static log ( error , context = {}) {
const errorLog = {
timestamp: new Date (). toISOString (),
code: error . code ,
message: error . message ,
details: error . details ,
statusCode: error . statusCode ,
context: context ,
stack: error . stack
};
// Send to logging service
console . error ( JSON . stringify ( errorLog ));
// Send to error tracking (Sentry, etc.)
if ( process . env . NODE_ENV === 'production' ) {
Sentry . captureException ( error , {
extra: errorLog
});
}
}
}
// Usage
try {
await createJob ( jobData );
} catch ( error ) {
ErrorLogger . log ( error , {
operation: 'createJob' ,
jobData: jobData ,
userId: currentUser . id
});
throw error ;
}
Best Practices
Always Check success Field
const response = await fetch ( url );
const result = await response . json ();
if ( ! result . success ) {
// Handle error
throw new Error ( result . error . message );
}
return result . data ;
Provide Context in Errors
class DetailedError extends Error {
constructor ( error , context ) {
super ( error . message );
this . code = error . code ;
this . details = error . details ;
this . context = context ; // Add operation context
}
}
throw new DetailedError ( apiError , {
operation: 'createCandidate' ,
candidateEmail: data . email ,
jobId: data . jobId
});
Don't Expose Sensitive Data
// ❌ Don't expose sensitive data in logs
console . error ( 'Failed:' , error , apiKey );
// ✅ Log safely
console . error ( 'Failed:' , error . code , error . message );
Implement Circuit Breakers
class CircuitBreaker {
constructor ( threshold = 5 , timeout = 60000 ) {
this . failureCount = 0 ;
this . threshold = threshold ;
this . timeout = timeout ;
this . state = 'CLOSED' ;
this . nextAttempt = Date . now ();
}
async execute ( fn ) {
if ( this . state === 'OPEN' ) {
if ( Date . now () < this . nextAttempt ) {
throw new Error ( 'Circuit breaker is OPEN' );
}
this . state = 'HALF_OPEN' ;
}
try {
const result = await fn ();
this . onSuccess ();
return result ;
} catch ( error ) {
this . onFailure ();
throw error ;
}
}
onSuccess () {
this . failureCount = 0 ;
this . state = 'CLOSED' ;
}
onFailure () {
this . failureCount ++ ;
if ( this . failureCount >= this . threshold ) {
this . state = 'OPEN' ;
this . nextAttempt = Date . now () + this . timeout ;
}
}
}
Next Steps
Rate Limiting Handle rate limits properly
Best Practices Production-ready patterns
Authentication Fix authentication errors
API Reference See all error codes per endpoint