# How to Automate Interview Scheduling with the Hiring Agent: A Config-Driven Guide

> Automate interview scheduling with Hiring Agent by configuring providers.json and config.py. Streamline your hiring process and save time with this practical guide.

- Repository: [HackerRank/hiring-agent](https://github.com/interviewstreet/hiring-agent)
- Tags: how-to-guide
- Published: 2026-07-24

---

**To automate interview scheduling with the hiring agent, configure the `interview_scheduler` provider in [`providers.json`](https://github.com/interviewstreet/hiring-agent/blob/main/providers.json), set your timing constraints in [`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py), and implement the calendar provider using the `INTERVIEW_SCHEDULE_CONFIG` parameters to generate slots and create events.**

The **interviewstreet/hiring-agent** repository is a lightweight AI-driven framework that automates end-to-end hiring workflows for software engineers. Beyond parsing resumes and evaluating candidates, the system supports fully automated interview scheduling through a provider-based architecture that externalizes calendar integration logic into configuration files and modular Python components.

## Configure the Interview Scheduler Provider

The Hiring Agent uses a provider-mapping pattern to delegate scheduling operations to external calendar services. According to [`providers.json`](https://github.com/interviewstreet/hiring-agent/blob/main/providers.json) (lines 1–5), the `interview_scheduler` key determines which backend handles calendar operations:

```json
{
  "resume_parser": "openai",
  "interview_scheduler": "google_calendar",
  "candidate_evaluator": "ml_model"
}

```

Setting `"interview_scheduler": "google_calendar"` instructs the system to route all scheduling requests through the Google Calendar provider implementation. This decouples the scheduling logic from the core workflow, allowing you to swap providers (e.g., to Outlook or Calendly) by changing this single value and implementing the corresponding adapter.

## Define Scheduling Parameters in config.py

All interview timing rules are centralized in [`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py) (lines 9–16) within the `INTERVIEW_SCHEDULE_CONFIG` dictionary. This configuration drives the slot-selection algorithm:

```python
INTERVIEW_SCHEDULE_CONFIG = {
    "default_duration_minutes": 45,
    "buffer_minutes": 10,
    "working_hours": {
        "start": 9,
        "end": 17
    }
}

```

**Key parameters include:**
- **`default_duration_minutes`**: The standard length of interview slots (45 minutes).
- **`buffer_minutes`**: Minimum gap between consecutive interviews (10 minutes).
- **`working_hours`**: The time window (9 AM to 5 PM) during which interviews can be scheduled.

The scheduling engine imports this configuration at runtime to validate candidate availability against interviewer calendars, ensuring generated slots respect business hours and required buffers.

## Implement the Calendar Integration

While the repository defines the interface via [`providers.json`](https://github.com/interviewstreet/hiring-agent/blob/main/providers.json), you must implement the provider class that interacts with the Google Calendar API. The implementation should consume `INTERVIEW_SCHEDULE_CONFIG` to enforce scheduling constraints. Below is a complete reference implementation that connects the configuration to the Google Calendar API:

```python
import json
from pathlib import Path
from datetime import datetime, timedelta, time
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from config import INTERVIEW_SCHEDULE_CONFIG

# Load provider mapping

with open(Path(__file__).parent / "providers.json") as f:
    PROVIDERS = json.load(f)

class GoogleCalendarScheduler:
    SCOPES = ['https://www.googleapis.com/auth/calendar']
    
    def __init__(self):
        self.service = self._authenticate()
        self.config = INTERVIEW_SCHEDULE_CONFIG
        
    def _authenticate(self):
        """Initialize Google Calendar API service using OAuth2."""
        creds = None
        if Path('token.json').exists():
            creds = Credentials.from_authorized_user_file('token.json', self.SCOPES)
        if not creds or not creds.valid:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', self.SCOPES)
            creds = flow.run_local_server(port=0)
            Path('token.json').write_text(creds.to_json())
        return build('calendar', 'v3', credentials=creds)
    
    def find_available_slot(self, interviewer_busy, candidate_busy, days_ahead=5):
        """Find next available slot using config parameters."""
        duration = timedelta(minutes=self.config["default_duration_minutes"])
        buffer_time = timedelta(minutes=self.config["buffer_minutes"])
        work_start = time(self.config["working_hours"]["start"])
        work_end = time(self.config["working_hours"]["end"])
        
        now = datetime.utcnow()
        
        for day_offset in range(days_ahead):
            date = now.date() + timedelta(days=day_offset)
            start_dt = datetime.combine(date, work_start)
            end_dt = datetime.combine(date, work_end)
            
            current = start_dt
            while current + duration <= end_dt:
                slot_end = current + duration
                # Check against busy periods

                is_available = True
                for busy in interviewer_busy + candidate_busy:
                    if (current < busy['end'] and slot_end > busy['start']):
                        is_available = False
                        break
                
                if is_available:
                    return current, slot_end
                
                current += timedelta(minutes=30)  # 30-min increments

        
        raise ValueError("No available slots found within constraints")
    
    def create_interview_event(self, start_time, end_time, candidate_email, interviewer_id='primary'):
        """Create calendar event with conference data."""
        event = {
            'summary': 'Technical Interview - Hiring Agent',
            'description': 'Automated interview scheduled by hiring-agent',
            'start': {
                'dateTime': start_time.isoformat() + 'Z',
                'timeZone': 'UTC',
            },
            'end': {
                'dateTime': end_time.isoformat() + 'Z',
                'timeZone': 'UTC',
            },
            'attendees': [
                {'email': candidate_email},
            ],
            'conferenceData': {
                'createRequest': {
                    'requestId': f"interview-{start_time.timestamp()}",
                    'conferenceSolutionKey': {'type': 'hangoutsMeet'}
                }
            },
            'reminders': {
                'useDefault': False,
                'overrides': [
                    {'method': 'email', 'minutes': 24 * 60},
                    {'method': 'popup', 'minutes': 10},
                ],
            },
        }
        
        event = self.service.events().insert(
            calendarId=interviewer_id,
            body=event,
            conferenceDataVersion=1,
            sendUpdates='all'
        ).execute()
        
        return event.get('htmlLink')

# Usage example

if PROVIDERS.get("interview_scheduler") == "google_calendar":
    scheduler = GoogleCalendarScheduler()
    # Query free/busy for interviewer and candidate...

    # start, end = scheduler.find_available_slot(interviewer_busy, candidate_busy)

    # event_link = scheduler.create_interview_event(start, end, "candidate@example.com")

```

This implementation enforces the 45-minute duration and 10-minute buffer specified in [`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py), iterating only within the configured 9-to-5 working hours.

## Integrate with Resume Parsing

The scheduling workflow begins with candidate data extraction. The [`llm_utils.py`](https://github.com/interviewstreet/hiring-agent/blob/main/llm_utils.py) module provides the `get_completion()` function (lines 1–9) that queries OpenAI models to parse resumes and extract availability windows:

```python
import openai

def get_completion(prompt, model="gpt-3.5-turbo"):
    response = openai.ChatCompletion.create(
        model=model,
        messages=[{"role": "user", "content": prompt}],
        temperature=0.7,
    )
    return response.choices[0].message.content.strip()

```

**Typical scheduling workflow:**
1. Parse the candidate's resume using `get_completion()` to extract availability constraints and timezone.
2. Query the interviewer's Google Calendar for busy periods using the `GoogleCalendarScheduler` authentication flow.
3. Call `find_available_slot()` to identify the next valid window based on `INTERVIEW_SCHEDULE_CONFIG`.
4. Execute `create_interview_event()` to generate the calendar invite and video conference link.

## Generate Interview Communications

Use the Jinja2 template system defined in [`prompt.py`](https://github.com/interviewstreet/hiring-agent/blob/main/prompt.py) to generate consistent interview invitations. The `prompts/templates/` directory contains templates for system messages and evaluation criteria. Create a scheduling-specific template (e.g., `interview_invitation.jinja`) and load it via the `Environment` instance:

```python
from prompt import load_template

template = load_template('interview_invitation.jinja')
invitation_text = template.render(
    candidate_name="Jane Doe",
    interview_date="2024-01-15",
    interview_time="14:00 UTC",
    duration=INTERVIEW_SCHEDULE_CONFIG["default_duration_minutes"]
)

```

This ensures all automated communications reflect the correct duration and timing parameters defined in your centralized configuration.

## Summary

- **Provider configuration**: Map `interview_scheduler` to `google_calendar` in [`providers.json`](https://github.com/interviewstreet/hiring-agent/blob/main/providers.json) (lines 1–5) to activate automated scheduling.
- **Timing constraints**: Centralize interview duration, buffer time, and working hours in `INTERVIEW_SCHEDULE_CONFIG` within [`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py) (lines 9–16).
- **Calendar implementation**: Implement the provider class to consume these configurations when querying free/busy data and creating events via the Google Calendar API.
- **Pipeline integration**: Connect [`llm_utils.py`](https://github.com/interviewstreet/hiring-agent/blob/main/llm_utils.py) for resume parsing, use [`prompt.py`](https://github.com/interviewstreet/hiring-agent/blob/main/prompt.py) templates for communications, and validate all slots against the configured business rules before event creation.

## Frequently Asked Questions

### How do I change the default interview duration?

Modify the `default_duration_minutes` value in [`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py) (line 11). The scheduling algorithm automatically uses this value when calculating slot boundaries and buffer periods. If you set it to 60, the system will reserve 60-minute blocks plus the configured `buffer_minutes` between events.

### Can I use a different calendar provider instead of Google Calendar?

Yes. Update the `interview_scheduler` value in [`providers.json`](https://github.com/interviewstreet/hiring-agent/blob/main/providers.json) (line 3) to your preferred provider key (e.g., `"microsoft_graph"` or `"calendly"`). You must then implement a corresponding provider class that follows the same interface—accepting `INTERVIEW_SCHEDULE_CONFIG` parameters and exposing `find_available_slot()` and `create_interview_event()` methods.

### Where does the Hiring Agent extract candidate availability from?

The system uses the `get_completion()` function in [`llm_utils.py`](https://github.com/interviewstreet/hiring-agent/blob/main/llm_utils.py) (lines 3–9) to parse resume text via OpenAI's API. You should craft prompts that instruct the model to extract explicit availability windows (e.g., "Tuesday and Thursday afternoons") or timezone information, which the scheduler then uses to filter potential slots retrieved from the interviewer's calendar.

### What happens if no valid slots are found within the working hours?

The `find_available_slot()` implementation raises a `ValueError` when no availability exists within the `days_ahead` search window and configured `working_hours`. In production, you should wrap this call in error handling that notifies the recruiter to manually coordinate a time or expand the configured `working_hours` range in [`config.py`](https://github.com/interviewstreet/hiring-agent/blob/main/config.py).