> ## Documentation Index
> Fetch the complete documentation index at: https://docs.jobhive.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# API Quickstart

> Get up and running with JobHive API in 5 minutes

## Quick Start Guide

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

<Steps>
  <Step title="Get Your API Key">
    1. Sign up at [app.jobhive.ai](https://app.jobhive.ai/register) if you haven't already
    2. Navigate to **Settings** → **API Keys**
    3. Click **"Generate API Key"** and copy it securely

    ```bash theme={null}
    export JOBHIVE_API_KEY="jh_live_your_api_key_here"
    ```
  </Step>

  <Step title="Create Your First Interview">
    Use our API to schedule an AI-powered interview:

    ```bash cURL theme={null}
    curl -X POST "https://backend.jobhive.ai/v1/interviews" \
      -H "Authorization: Bearer $JOBHIVE_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "candidate_email": "candidate@example.com",
        "position": "Software Engineer", 
        "skills": ["JavaScript", "React", "Node.js"],
        "duration_minutes": 30
      }'
    ```

    You'll get a response like this:

    ```json theme={null}
    {
      "success": true,
      "data": {
        "id": "int_abc123def456",
        "interview_url": "https://app.jobhive.ai/interview/int_abc123def456",
        "status": "scheduled",
        "candidate_email": "candidate@example.com"
      }
    }
    ```
  </Step>

  <Step title="Share Interview Link">
    Send the `interview_url` to your candidate. They can start the interview immediately - no account required!
  </Step>

  <Step title="Get Results">
    Once completed, fetch the results:

    ```bash cURL theme={null}
    curl -X GET "https://backend.jobhive.ai/v1/interviews/int_abc123def456?include_results=true" \
      -H "Authorization: Bearer $JOBHIVE_API_KEY"
    ```
  </Step>
</Steps>

## Complete Code Examples

### JavaScript/Node.js

<CodeGroup>
  ```javascript Basic Example theme={null}
  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: 'john.doe@example.com',
        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);
  ```

  ```javascript With SDK theme={null}
  const { JobHive } = require('@jobhive/sdk');

  const client = new JobHive({
    apiKey: process.env.JOBHIVE_API_KEY
  });

  async function quickInterview() {
    try {
      // Create interview
      const interview = await client.interviews.create({
        candidate_email: 'jane.smith@example.com',
        position: 'Frontend Developer',
        skills: ['React', 'TypeScript', 'CSS'],
        duration_minutes: 30,
        send_invitation: true // Automatically email candidate
      });

      console.log('✅ Interview scheduled:', interview.id);
      console.log('📧 Invitation sent to:', interview.candidate_email);
      console.log('🔗 Interview URL:', interview.interview_url);

      // Set up webhook listener (in practice)
      client.on('interview.completed', (data) => {
        console.log('🎉 Interview completed!');
        console.log('📊 Score:', data.results.overall_score);
        console.log('💡 Recommendation:', data.results.recommendation);
      });

      return interview;
    } catch (error) {
      console.error('❌ Error creating interview:', error.message);
    }
  }

  quickInterview();
  ```
</CodeGroup>

### Python

<CodeGroup>
  ```python Basic Example theme={null}
  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': 'alice.johnson@example.com',
              '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'])
  ```

  ```python With SDK theme={null}
  import jobhive
  import os

  client = jobhive.JobHive(api_key=os.environ['JOBHIVE_API_KEY'])

  def quick_interview():
      try:
          # Create interview
          interview = client.interviews.create(
              candidate_email='bob.wilson@example.com',
              position='Backend Engineer',
              skills=['Python', 'Django', 'PostgreSQL', 'Redis'],
              duration_minutes=45,
              company_name='TechCorp',
              instructions='Focus on database design and API architecture'
          )

          print(f"✅ Interview scheduled: {interview.id}")
          print(f"📧 Candidate: {interview.candidate_email}")
          print(f"🔗 Interview URL: {interview.interview_url}")

          # Monitor interview status
          @client.webhooks.on('interview.completed')
          def handle_completion(event):
              print("🎉 Interview completed!")
              results = event.data.results
              
              print(f"📊 Overall Score: {results.overall_score}/100")
              print(f"🧠 Technical Score: {results.technical_score}/100")
              print(f"💬 Communication Score: {results.communication_score}/100")
              print(f"💡 Recommendation: {results.recommendation}")
              
              if results.recommendation == 'hire':
                  print("🎯 Strong candidate - recommend moving forward!")

          return interview
          
      except jobhive.APIError as e:
          print(f"❌ API Error: {e.message}")
      except Exception as e:
          print(f"❌ Error: {e}")

  if __name__ == "__main__":
      quick_interview()
  ```
</CodeGroup>

## Common Use Cases

### Bulk Interview Creation

Create multiple interviews efficiently:

<CodeGroup>
  ```javascript Bulk Creation theme={null}
  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: 'dev1@example.com', position: 'Frontend Developer', skills: ['React', 'TypeScript'] },
    { email: 'dev2@example.com', position: 'Backend Developer', skills: ['Node.js', 'PostgreSQL'] },
    { email: 'dev3@example.com', position: 'Full Stack Developer', skills: ['React', 'Node.js'] }
  ];

  createBulkInterviews(candidates)
    .then(results => console.log(`Created ${results.length} interviews`))
    .catch(console.error);
  ```

  ```python Parallel Processing theme={null}
  import concurrent.futures
  import requests

  def create_single_interview(candidate):
      response = requests.post(f'{BASE_URL}/interviews',
          headers={
              'Authorization': f'Bearer {JOBHIVE_API_KEY}',
              'Content-Type': 'application/json'
          },
          json={
              'candidate_email': candidate['email'],
              'position': candidate['position'],
              'skills': candidate['skills'],
              'duration_minutes': 30
          }
      )
      return response.json()

  def create_bulk_interviews(candidates):
      with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
          futures = [executor.submit(create_single_interview, candidate) 
                    for candidate in candidates]
          
          results = []
          for future in concurrent.futures.as_completed(futures):
              results.append(future.result())
          
          return results

  # Usage
  candidates = [
      {'email': 'eng1@example.com', 'position': 'Software Engineer', 'skills': ['Python', 'Django']},
      {'email': 'eng2@example.com', 'position': 'DevOps Engineer', 'skills': ['Docker', 'Kubernetes']},
      {'email': 'eng3@example.com', 'position': 'Data Engineer', 'skills': ['Spark', 'Airflow']}
  ]

  interviews = create_bulk_interviews(candidates)
  print(f"Created {len(interviews)} interviews successfully")
  ```
</CodeGroup>

### Real-time Interview Monitoring

Set up webhooks to monitor interview progress:

<CodeGroup>
  ```javascript Webhook Handler theme={null}
  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');
  });
  ```

  ```python Flask Webhook theme={null}
  from flask import Flask, request, jsonify
  import hmac
  import hashlib

  app = Flask(__name__)

  def verify_webhook(payload, signature, secret):
      expected_signature = hmac.new(
          secret.encode('utf-8'),
          payload.encode('utf-8'),
          hashlib.sha256
      ).hexdigest()
      
      return hmac.compare_digest(signature, f"sha256={expected_signature}")

  @app.route('/webhooks/jobhive', methods=['POST'])
  def handle_webhook():
      signature = request.headers.get('X-JobHive-Signature')
      payload = request.get_data(as_text=True)
      
      if not verify_webhook(payload, signature, os.environ['JOBHIVE_WEBHOOK_SECRET']):
          return 'Invalid signature', 401
      
      data = request.get_json()
      event = data.get('event')
      event_data = data.get('data')
      
      if event == 'interview.completed':
          process_interview_results(event_data)
      elif event == 'interview.started':
          notify_hiring_team(event_data)
      elif event == 'results.analyzed':
          update_candidate_record(event_data)
      
      return jsonify({'status': 'success'}), 200

  def process_interview_results(data):
      interview_id = data['id']
      score = data['results']['overall_score']
      recommendation = data['results']['recommendation']
      
      print(f"Interview {interview_id} completed with score {score}")
      
      # Auto-advance strong candidates
      if recommendation == 'hire':
          schedule_next_round(data['candidate_email'])

  if __name__ == '__main__':
      app.run(port=5000)
  ```
</CodeGroup>

## Error Handling

### Common Errors and Solutions

<AccordionGroup>
  <Accordion title="401 Unauthorized">
    **Problem**: API key missing or invalid

    **Solution**:

    ```javascript theme={null}
    // 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_');
    }
    ```
  </Accordion>

  <Accordion title="429 Rate Limit Exceeded">
    **Problem**: Too many requests per minute

    **Solution**:

    ```javascript theme={null}
    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');
    }
    ```
  </Accordion>

  <Accordion title="400 Validation Error">
    **Problem**: Invalid request parameters

    **Solution**:

    ```javascript theme={null}
    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(', ')}`);
      }
    }
    ```
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Explore Full API Reference" icon="book" href="/api-reference/introduction">
    Complete documentation for all endpoints and features
  </Card>

  <Card title="Set Up Webhooks" icon="webhook" href="/api-reference/endpoint/webhook">
    Real-time notifications for interview events
  </Card>

  <Card title="JavaScript SDK" icon="js" href="/api-reference/javascript-sdk">
    Official SDK for Node.js and browser applications
  </Card>

  <Card title="Python SDK" icon="python" href="/api-reference/python-sdk">
    Official SDK for Python applications
  </Card>
</CardGroup>

<Note>
  **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.
</Note>

<Tip>
  **Pro Tip**: Use webhooks instead of polling for real-time updates. They're more efficient and provide better user experience.
</Tip>
