Create an interview
POST/v1/applications/:application_id/interviews
Schedules an interview on an application.
Two ways to schedule
Always required: organizer_id, application_id, start_time, timezone — even when scheduling from an interview plan, since the plan defines the interview's setup but not its time or organizer.
Everything else depends on whether you pass the optional stage_activity_id:
Plan-driven — pass stage_activity_id (an activity from the job's interview plan). The activity supplies the configuration: any field you omit is inherited; pass a field only to override it. Inherited fields:
kind,location,duration_minutes,interviewer_idsoffice_id,name,hackerrank_template_idai_note_taker_enabled,ai_scorecard_assist_enabledcandidate_template_id,interviewer_template_id, and the scorecard configuration
The interview is placed on the activity's stage (which may be any stage of the job). scorecard_template_id is ignored.
Ad-hoc — omit stage_activity_id and supply the configuration yourself:
- Required:
kind,location,duration_minutes,interviewer_ids,candidate_template_id,interviewer_template_id - Location-specific:
office_id(foronsite),host_id(forzoom),hackerrank_template_id(forhackerrank)
The interview uses the application's current stage.
Use Retrieve a job's interview plan to discover valid stage_activity_id values.
External events (calendar managed elsewhere)
When the calendar event is created and owned by an external system, send an external object with managed: true. Kula then only stores the interview record — it creates no calendar event, conference, calendar invites, RSVP tracking, notifications, or interview.event.created webhook.
Still send the core details (kind, duration_minutes, interviewer_ids) plus the always-required fields, so the record is complete. The external object carries:
managed—trueto mark the event as externally owned (create-only).video_conferencing_url— the meeting link participants use. The AI note-taker joins it only if it is a Zoom, Google Meet, or Microsoft Teams link (embed the passcode in the URL if the meeting requires one). Any other URL is stored but the note-taker cannot join it. Optional.source— free-text label of the originating system (e.g. the integration name). Optional.event_id— the external system's id for the event. Optional.
For external events: location and candidate_template_id / interviewer_template_id are not required (Kula sends no invites); the organizer needs no connected calendar; location: zoom does not require a Kula conference host. external.managed is set at creation only — on update you may still change external.video_conferencing_url, external.source, and external.event_id.
Finding interviewer availability
Before scheduling, use Compute interviewer availability to find free slots for the organizer and interviewers across a date range. It returns a poll_id; poll Retrieve an interviewer-availability result until the result is ready, then pass the chosen organizer_id, interviewer_ids, start_time, and duration_minutes into this call.
Asynchronous provisioning
For Kula-managed interviews, calendar invites and notification emails are dispatched asynchronously — the conference URL may be null in this 201 response and populated within a few seconds. Subscribe to the interview.event.created webhook to receive the fully-provisioned interview (with conference URL). This does not apply to external events (see above), which create no calendar event or webhook.
Request
Responses
- 201
- 404
- 422
Interview created
Application not found (err_application_not_found)
Validation error. Common error codes:
err_kind_required/err_location_required/err_duration_minutes_required/err_interviewer_ids_required/err_candidate_template_id_required/err_interviewer_template_id_required— required whenstage_activity_idis not seterr_start_time_not_aligned— start_time must be on a 15-min boundary, zero secondserr_start_time_in_past— start_time must be in the futureerr_end_time_before_start_time/err_duration_out_of_range— end_time must be after start_time and yield a 5–1440 minute durationerr_invalid_set_of_interviewers—kind: one_on_onerequires exactly one interviewererr_onsite_office_required— office_id required when location is onsiteerr_zoom_host_id_required— host_id required when location is zoomerr_zoom_host_id_not_in_interviewers— host_id must be in interviewer_idserr_zoom_host_invalid_user— host_id user does not have an active Zoom workspace seaterr_hackerrank_template_id_required— hackerrank_template_id required when location is hackerrankerr_candidate_template_not_found/err_interviewer_template_not_found— template_id is unknown in your accounterr_candidate_template_invalid_category— candidate_template_id must havechannel: calendar_inviteandcategory: interview_coordinationerr_interviewer_template_invalid_category— interviewer_template_id must havechannel: calendar_inviteandcategory: interviewer_coordinationerr_organizer_not_found/err_organizer_no_calendar/err_application_not_found/err_office_not_found/err_interviewers_not_found/err_scorecard_template_not_found— referenced resource missingerr_organizer_no_job_permission/err_organizer_no_application_permission— organizer cannot manage this job or applicationerr_stage_activity_not_found— stage_activity_id is not an activity on this joberr_stage_activity_not_interview— stage_activity_id is not an interview activityerr_invalid_iso_8601/err_invalid_timezone— bad time/zone format