Quick Start Guide
Get your first interview running in under 5 minutes with this step-by-step guide.1
Get Your API Key
- Sign up at app.jobhive.ai if you haven’t already
- Navigate to Settings → API Keys
- Click “Generate API Key” and copy it securely
Copy
export JOBHIVE_API_KEY="jh_live_your_api_key_here"
2
Create Your First Interview
Use our API to schedule an AI-powered interview:You’ll get a response like this:
cURL
Copy
curl -X POST "https://backend.jobhive.ai/v1/interviews" \
-H "Authorization: Bearer $JOBHIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"candidate_email": "[email protected]",
"position": "Software Engineer",
"skills": ["JavaScript", "React", "Node.js"],
"duration_minutes": 30
}'
Copy
{
"success": true,
"data": {
"id": "int_abc123def456",
"interview_url": "https://app.jobhive.ai/interview/int_abc123def456",
"status": "scheduled",
"candidate_email": "[email protected]"
}
}
3
Share Interview Link
Send the
interview_url to your candidate. They can start the interview immediately - no account required!4
Get Results
Once completed, fetch the results:
cURL
Copy
curl -X GET "https://backend.jobhive.ai/v1/interviews/int_abc123def456?include_results=true" \
-H "Authorization: Bearer $JOBHIVE_API_KEY"
Complete Code Examples
JavaScript/Node.js
Copy
const fetch = require('node-fetch');
const JOBHIVE_API_KEY = process.env.JOBHIVE_API_KEY;
const BASE_URL = 'https://backend.jobhive.ai/v1';
async function createInterview() {
const response = await fetch(`${BASE_URL}/interviews`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${JOBHIVE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
candidate_email: '[email protected]',
position: 'Full Stack Developer',
skills: ['JavaScript', 'React', 'Python', 'Django'],
duration_minutes: 45,
difficulty: 'intermediate'
})
});
const interview = await response.json();
console.log('Interview created:', interview.data.id);
console.log('Share this link:', interview.data.interview_url);
return interview.data;
}
async function getResults(interviewId) {
const response = await fetch(`${BASE_URL}/interviews/${interviewId}?include_results=true`, {
headers: {
'Authorization': `Bearer ${JOBHIVE_API_KEY}`
}
});
const interview = await response.json();
if (interview.data.status === 'completed') {
console.log('Overall Score:', interview.data.results.overall_score);
console.log('Recommendation:', interview.data.results.recommendation);
console.log('Strengths:', interview.data.results.strengths);
}
return interview.data;
}
// Usage
createInterview()
.then(interview => {
console.log('Waiting for interview completion...');
// In practice, use webhooks for real-time updates
setTimeout(() => getResults(interview.id), 60000); // Check after 1 minute
})
.catch(console.error);
Python
Copy
import requests
import os
import time
JOBHIVE_API_KEY = os.environ['JOBHIVE_API_KEY']
BASE_URL = 'https://backend.jobhive.ai/v1'
def create_interview():
response = requests.post(f'{BASE_URL}/interviews',
headers={
'Authorization': f'Bearer {JOBHIVE_API_KEY}',
'Content-Type': 'application/json'
},
json={
'candidate_email': '[email protected]',
'position': 'Data Scientist',
'skills': ['Python', 'Machine Learning', 'SQL', 'Pandas'],
'duration_minutes': 60,
'difficulty': 'senior'
}
)
interview = response.json()
print(f"Interview created: {interview['data']['id']}")
print(f"Share this link: {interview['data']['interview_url']}")
return interview['data']
def get_results(interview_id):
response = requests.get(f'{BASE_URL}/interviews/{interview_id}?include_results=true',
headers={'Authorization': f'Bearer {JOBHIVE_API_KEY}'}
)
interview = response.json()
if interview['data']['status'] == 'completed':
results = interview['data']['results']
print(f"Overall Score: {results['overall_score']}")
print(f"Technical Score: {results['technical_score']}")
print(f"Communication Score: {results['communication_score']}")
print(f"Recommendation: {results['recommendation']}")
print("\nStrengths:")
for strength in results['strengths']:
print(f" ✅ {strength}")
print("\nAreas for Improvement:")
for area in results['areas_for_improvement']:
print(f" 📈 {area}")
return interview['data']
# Usage
if __name__ == "__main__":
interview = create_interview()
print("Waiting for interview completion...")
# In practice, use webhooks for real-time updates
time.sleep(60) # Wait 1 minute then check
get_results(interview['id'])
Common Use Cases
Bulk Interview Creation
Create multiple interviews efficiently:Copy
async function createBulkInterviews(candidates) {
const interviews = [];
for (const candidate of candidates) {
const interview = await fetch(`${BASE_URL}/interviews`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${JOBHIVE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
candidate_email: candidate.email,
position: candidate.position,
skills: candidate.skills,
duration_minutes: 30
})
});
interviews.push(await interview.json());
}
return interviews;
}
// Usage
const candidates = [
{ email: '[email protected]', position: 'Frontend Developer', skills: ['React', 'TypeScript'] },
{ email: '[email protected]', position: 'Backend Developer', skills: ['Node.js', 'PostgreSQL'] },
{ email: '[email protected]', position: 'Full Stack Developer', skills: ['React', 'Node.js'] }
];
createBulkInterviews(candidates)
.then(results => console.log(`Created ${results.length} interviews`))
.catch(console.error);
Real-time Interview Monitoring
Set up webhooks to monitor interview progress:Copy
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use(express.json());
function verifyWebhook(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(`sha256=${expectedSignature}`)
);
}
app.post('/webhooks/jobhive', (req, res) => {
const signature = req.headers['x-jobhive-signature'];
const payload = JSON.stringify(req.body);
if (!verifyWebhook(payload, signature, process.env.JOBHIVE_WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const { event, data } = req.body;
switch(event) {
case 'interview.started':
console.log(`🎬 Interview ${data.id} started by ${data.candidate.email}`);
// Notify hiring team
break;
case 'interview.completed':
console.log(`✅ Interview ${data.id} completed`);
console.log(`📊 Score: ${data.results.overall_score}`);
console.log(`💡 Recommendation: ${data.results.recommendation}`);
// Auto-schedule next round for strong candidates
if (data.results.overall_score >= 80) {
scheduleHumanInterview(data);
}
break;
case 'candidate.no_show':
console.log(`❌ Candidate ${data.candidate_email} didn't show for interview ${data.interview_id}`);
// Send follow-up email
break;
}
res.status(200).send('OK');
});
app.listen(3000, () => {
console.log('Webhook server running on port 3000');
});
Error Handling
Common Errors and Solutions
401 Unauthorized
401 Unauthorized
Problem: API key missing or invalidSolution:
Copy
// Check your API key format and environment variable
if (!process.env.JOBHIVE_API_KEY) {
throw new Error('JOBHIVE_API_KEY environment variable is required');
}
if (!process.env.JOBHIVE_API_KEY.startsWith('jh_')) {
throw new Error('Invalid API key format. Should start with jh_');
}
429 Rate Limit Exceeded
429 Rate Limit Exceeded
Problem: Too many requests per minuteSolution:
Copy
async function makeRequestWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = response.headers.get('X-RateLimit-Retry-After');
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
continue;
}
return response;
}
throw new Error('Max retries exceeded');
}
400 Validation Error
400 Validation Error
Problem: Invalid request parametersSolution:
Copy
function validateInterviewData(data) {
const errors = [];
if (!data.candidate_email || !data.candidate_email.includes('@')) {
errors.push('Valid candidate_email is required');
}
if (!data.position || data.position.length < 2) {
errors.push('Position must be at least 2 characters');
}
if (!data.skills || data.skills.length === 0) {
errors.push('At least one skill is required');
}
if (data.duration_minutes < 15 || data.duration_minutes > 90) {
errors.push('Duration must be between 15 and 90 minutes');
}
if (errors.length > 0) {
throw new Error(`Validation errors: ${errors.join(', ')}`);
}
}
Next Steps
Explore Full API Reference
Complete documentation for all endpoints and features
Set Up Webhooks
Real-time notifications for interview events
JavaScript SDK
Official SDK for Node.js and browser applications
Python SDK
Official SDK for Python applications
Development Tip: Start with test mode interviews to familiarize yourself with the API without consuming production credits. Add
"test_mode": true to any interview creation request.Pro Tip: Use webhooks instead of polling for real-time updates. They’re more efficient and provide better user experience.
