Skip to Content
SDK ReferenceInterviews

Interviews

The client.interviews namespace provides methods for creating, managing, and retrieving interview data.

interviews.create(data)

Create an AI interview, human interview, or team meeting.

Parameters

ParameterTypeRequiredDescription
type'ai' | 'human' | 'team'YesInterview type
jobRolestringYes (ai/human)Job role or title
titlestringNoCustom title override
categorystringNoSCREENING | TECHNICAL | BEHAVIORAL | ASSIGNMENT | CULTURAL | CASE_STUDY | PANEL | FINAL
stagestringNoFree-form stage label (e.g., “Round 1”, “Final Interview”)
companyNamestringNoCompany name (defaults to your organization name)
candidate{ name, email }Yes (ai)Candidate info
participantsArray<{ name, email, role }>Yes (human/team)Participant list
candidateCVstringNoCV/resume text for better AI questions
skillsstring[]NoSkills to evaluate
senioritystringNoJUNIOR | MID | SENIOR | LEAD | PRINCIPAL
departmentstringNoDepartment name
jobDescriptionstringNoFull job description
workSetupstringNoREMOTE | ONSITE | HYBRID
employmentTypestringNoFULL_TIME | PART_TIME | CONTRACT
durationMinutesnumberNoDuration (default: 30, min: 5)
scheduledAtstringNoISO 8601 datetime
schedulingModestringNoIMMEDIATE | FIXED | CANDIDATE_PICKS
questionsstring[]NoCustom interview questions
aiGeneratebooleanNoAuto-generate questions with AI
evaluationFocusstringNoknowledge | balanced | communication | problem_solving | culture
sendCandidateFeedbackbooleanNoSend AI-generated feedback email to candidate after evaluation
externalJobIdstringNoExternal job/position ID from your ATS

Examples

// AI Interview — full options const interview = await client.interviews.create({ type: 'ai', jobRole: 'Senior Frontend Engineer', companyName: 'Acme Corp', candidate: { name: 'Jane Doe', email: 'jane@example.com' }, candidateCV: 'Full resume text here...', skills: ['React', 'TypeScript', 'GraphQL'], seniority: 'SENIOR', department: 'Engineering', jobDescription: 'We are looking for a senior frontend engineer...', workSetup: 'REMOTE', employmentType: 'FULL_TIME', durationMinutes: 25, evaluationFocus: 'knowledge', sendCandidateFeedback: true, aiGenerate: true, externalJobId: 'job_abc123', });
// Human Interview const interview = await client.interviews.create({ type: 'human', jobRole: 'Backend Engineer', scheduledAt: '2026-04-01T14:00:00Z', participants: [ { name: 'Jane Doe', email: 'jane@example.com', role: 'CANDIDATE' }, { name: 'Bob Smith', email: 'bob@company.com', role: 'INTERVIEWER' }, ], skills: ['Node.js', 'PostgreSQL'], });
// Team Meeting (with recording & transcription) const meeting = await client.interviews.create({ type: 'team', scheduledAt: '2026-04-01T10:00:00Z', durationMinutes: 60, participants: [ { name: 'Alice', email: 'alice@company.com', role: 'HOST' }, { name: 'Bob', email: 'bob@company.com', role: 'PARTICIPANT' }, { name: 'Carol', email: 'carol@company.com', role: 'PARTICIPANT' }, ], agenda: ['Q1 review', 'Roadmap planning'], transcriptionEnabled: true, // video recording + post-meeting transcript & AI recap });

Response

{ "meeting": { "meetingCode": "Boooply-AI-1234567890", "url": "https://meetings.boooply.com/join/Boooply-AI-1234567890", "meetingType": "AI_ONLY", "sessionStatus": "SCHEDULED", "participants": [ { "name": "Jane Doe", "email": "jane@example.com", "role": "CANDIDATE", "joinToken": "abc123..." } ] } }

interviews.getAvailability(params)

Fetch available time slots from a team member’s Google Calendar connected in Boooply. Use this instead of building your own calendar integration.

const { calendarConnected, slots } = await client.interviews.getAvailability({ email: 'bob@company.com', durationMinutes: 45, days: 7, }); if (calendarConnected && slots.length > 0) { // Use Boooply's calendar data to create an interview await client.interviews.create({ type: 'human', jobRole: 'Designer', durationMinutes: 45, schedulingMode: 'CANDIDATE_PICKS', availableSlots: slots, participants: [ { name: 'Jane', email: 'jane@example.com', role: 'CANDIDATE' }, { name: 'Bob', email: 'bob@company.com', role: 'INTERVIEWER' }, ], }); } else { // Calendar not connected — provide your own slots or use FIXED mode }
ParameterTypeRequiredDescription
emailstringYesTeam member’s email
durationMinutesnumberNoSlot duration in minutes (default: 30)
daysnumberNoDays ahead to look (default: 14, max: 30)

If calendarConnected is false, the user hasn’t connected Google Calendar in Boooply. You can either ask them to connect it, or provide availableSlots from your own calendar integration.


interviews.getBusyBlocks(params)

Fetch raw busy time blocks from a team member’s Google Calendar. Use this when you want to compute availability with your own logic.

const { calendarConnected, busyBlocks, timezone } = await client.interviews.getBusyBlocks({ email: 'bob@company.com', days: 7, }); if (calendarConnected) { // Apply your own rules to compute available slots const slots = myScheduler.findOpenSlots(busyBlocks, { timezone }); }
ParameterTypeRequiredDescription
emailstringYesTeam member’s email
daysnumberNoDays ahead to look (default: 14, max: 30)

Use getAvailability() for ready-to-use slots. Use getBusyBlocks() when you need raw data for custom availability logic.


interviews.list(params?)

List interviews with optional filters.

const { interviews, pagination } = await client.interviews.list({ status: 'COMPLETED', // SCHEDULED | ACTIVE | COMPLETED | CANCELLED type: 'AI_ONLY', // AI_ONLY | HUMAN search: 'frontend', // Search by role, candidate, email page: 1, limit: 20, });

interviews.get(meetingCode)

Get full interview details.

const interview = await client.interviews.get('Boooply-AI-1234567890');

interviews.getTranscript(meetingCode)

Get the full conversation transcript.

const { transcript } = await client.interviews.getTranscript('Boooply-AI-1234567890'); // transcript = [{ speaker, role, content, timestamp }, ...]

interviews.getEvaluation(meetingCode)

Get AI-generated evaluation and scores.

const evaluation = await client.interviews.getEvaluation('Boooply-AI-1234567890'); // { recommendation: 'PASS', overallScore: 82, communication: 85, technical: 78, cultureFit: 90 }

interviews.triggerAnalysis(meetingCode)

Re-trigger AI analysis on a completed interview.

await client.interviews.triggerAnalysis('Boooply-AI-1234567890');

interviews.reschedule(meetingCode, data)

Reschedule an interview.

await client.interviews.reschedule('Boooply-AI-1234567890', { scheduledAt: '2026-04-05T14:00:00Z', durationMinutes: 30, reason: 'Candidate requested new time', });

interviews.cancel(meetingCode, reason?)

Cancel an interview.

await client.interviews.cancel('Boooply-AI-1234567890', 'Position filled');

interviews.delete(meetingCode)

Permanently delete an interview and all associated data.

await client.interviews.delete('Boooply-AI-1234567890');

Warning: This action is irreversible.


interviews.addParticipant(meetingCode, data)

Add participants to an existing interview.

await client.interviews.addParticipant('Boooply-AI-1234567890', { participants: [ { name: 'New Person', email: 'new@company.com', role: 'INTERVIEWER' } ], });

interviews.getParticipants(meetingCode)

Get all participants for an interview.

const { participants } = await client.interviews.getParticipants('Boooply-AI-1234567890'); // [{ id, name, email, role, joinToken, joinedAt, leftAt, isActive }]

interviews.removeParticipant(meetingCode, participantId)

Remove a participant from an interview.

await client.interviews.removeParticipant('Boooply-AI-1234567890', 'participant-uuid');

interviews.getRecording(meetingCode)

Get the video recording for a completed interview.

const { recording } = await client.interviews.getRecording('Boooply-AI-1234567890'); if (recording) { console.log(recording.videoUrl); // pre-signed S3 URL (7 days) console.log(recording.videoApiUrl); // stable URL (always works) console.log(recording.duration); // seconds console.log(recording.format); // 'mp4' }
Last updated on