Skip to main content

Quick Start Guide

Get your first interview running in under 5 minutes with this step-by-step guide.
1

Get Your API Key

  1. Sign up at app.jobhive.ai if you haven’t already
  2. Navigate to SettingsAPI Keys
  3. Click “Generate API Key” and copy it securely
export JOBHIVE_API_KEY="jh_live_your_api_key_here"
2

Create Your First Interview

Use our API to schedule an AI-powered interview:
cURL
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
  }'
You’ll get a response like this:
{
  "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
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

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

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:
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:
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

Problem: API key missing or invalidSolution:
// 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_');
}
Problem: Too many requests per minuteSolution:
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');
}
Problem: Invalid request parametersSolution:
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

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.