Manage interviewers and find available times for live interviews.
Interviewers and availability
Each role has a list of interviewers shared across its live interview rounds.
Use the role’s posting_id in the endpoints below.
Availability is assigned to individual interviewers; available capacity depends
on how many interviewers can take a call at a given start time.
Set up interviewer availability
Choose how each interviewer's availability is managed. Both options let your
automation find available interview times
with GET /api/v1/postings/{id}/slots?round_id={round_id} before booking.
Use Google Calendar and working hours
Have each interviewer open Interviewing Availability in the Litmus dashboard:
- Under Connect, select Google Calendar, authorize access, and select the calendars Litmus should check.
- Under Set availability, select From calendar and set their working days and hours.
- Under Interviewing, select the role they will interview for.
Litmus calculates available times from those working hours and calendar busy events, accounting for the round's duration. Interviewers can also mark availability by hand and explicitly override a calendar conflict in the dashboard. If this is already configured for the role, your automation can read available times immediately; it does not need to copy calendar events into the API.
Connecting Google Calendar and changing personal working hours require the dashboard. These setup actions are not exposed through the public REST API.
Set available start times through the API
If your integration manages an interviewer's availability, use
POST /api/v1/postings/{id}/slots with their email
and available start times. This also adds the interviewer to the role if needed.
Use DELETE /api/v1/postings/{id}/slots to remove times.
Both operations require interviews:write.
Before writing times for an existing interviewer, read their availability source.
When availability_source is personal, their dashboard schedule takes
precedence over times added through the API. Read the resulting bookable times
or ask the interviewer to update their schedule in Litmus.
Read all interviewers
GET /api/v1/postings/{id}/interviewers · Required scope: interviews:read.
Returns all interviewers assigned to the role, with their meeting links and availability settings.
curl --fail-with-body https://litmushiring.com/api/v1/postings/posting_abc123/interviewers \
-H "Authorization: Bearer $LITMUS_API_KEY"{
"posting_id": "posting_abc123",
"interviewers": [
{
"email": "interviewer@example.com",
"meeting_link": null,
"slots": ["2026-10-20T17:00:00.000Z", "2026-10-20T17:30:00.000Z"],
"availability_source": "painted"
}
]
}Check availability_source before updating slots:
| Value | Availability used for scheduling |
|---|---|
painted | Slots configured on this posting. The slot write endpoints update these times. |
personal | The interviewer's personal Litmus schedule or connected calendar. Posting-level slot writes do not override it. |
Add interviewer availability
POST /api/v1/postings/{id}/slots · Required scope: interviews:write.
Add start times when an interviewer is available to conduct live interviews for this role. These times can be used for candidate self-scheduling or API bookings. This operation does not send invitations or book interviews.
Each entry requires interviewer_email and start_at. The slots array must
contain at least one entry. This operation adds times without replacing other
interviewers or their availability.
curl --fail-with-body -X POST https://litmushiring.com/api/v1/postings/posting_abc123/slots \
-H "Authorization: Bearer $LITMUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"slots": [
{ "interviewer_email": "interviewer@example.com", "start_at": "2026-10-20T17:00:00Z" },
{ "interviewer_email": "interviewer@example.com", "start_at": "2026-10-20T17:30:00Z" }
]
}'{
"posting_id": "posting_abc123",
"interviewers": [
{
"email": "interviewer@example.com",
"slots": ["2026-10-20T17:00:00.000Z", "2026-10-20T17:30:00.000Z"],
"applied": true
}
]
}Returns 200 with each affected interviewer's resulting slots. An interviewer
not already assigned to the role is added automatically.
Each slot is an allowed start time, independent of round duration. For a 45-minute round, adding 17:00 and 17:30 permits overlapping starts. Space starts at least one round duration apart to avoid overlap for the same person. Slot capacity does not guarantee that differently timed interviews cannot overlap.
Times must fall on the hour or half hour, with zero seconds and milliseconds.
An invalid time rejects the entire request with 400; it is not rounded.
Returned times are normalized to UTC.
For interviewers using a personal schedule, available starts are calculated
from free blocks and the round's duration instead. A write returns
applied: false and reason: "personal_schedule_wins" when personal availability
takes precedence. The stored posting slots will not affect the displayed schedule.
Remove interviewer availability
DELETE /api/v1/postings/{id}/slots · Required scope: interviews:write.
Send the same body shape as the add operation. Returns 200 with the affected
interviewers' resulting slots. This removes the specified start times from an
interviewer’s availability for the role. The interviewer remains assigned to
the role, and their meeting link is preserved. Existing interviews are not canceled.
Replace all interviewers for a role
PUT /api/v1/postings/{id}/interviewers · Required scope: interviews:write.
Set the complete list of interviewers for the role. Include every interviewer you want to keep. For example, sending a list with only one interviewer removes any other interviewers previously assigned to the role.
{
"interviewers": [
{
"email": "interviewer@example.com",
"meeting_link": "https://video.example.com/room/abc",
"slots": ["2026-10-20T17:00:00Z"]
}
]
}email is required for each entry; meeting_link and slots are optional.
Returns 200 with posting_id and the resulting interviewers array.
Interviewers omitted from the request are removed. Omitting an included
interviewer's slots clears their posting-level availability. Use POST /slots
when you only need to add availability. An empty interviewers array removes
all interviewers from the role.
Find available interview times
GET /api/v1/postings/{id}/slots · Required scope: interviews:read.
Read the available start times and interviewers for a live round. Use the results to choose a start time and interviewer before booking an interview.
round_id is required. Optional from and to parameters are inclusive ISO
8601 bounds on slot start times.
curl --fail-with-body "https://litmushiring.com/api/v1/postings/posting_abc123/slots?round_id=step_abc123" \
-H "Authorization: Bearer $LITMUS_API_KEY"{
"posting_id": "posting_abc123",
"round_id": "step_abc123",
"duration_minutes": 60,
"slots": [
{
"start_at": "2026-10-20T17:00:00.000Z",
"interviewer_emails": ["interviewer@example.com"],
"capacity": 1
}
]
}Each entry identifies a start time, the available interviewers, and remaining
capacity. Select a future start_at and one of its interviewer_emails when
booking an interview.
Capacity is shared across the posting's live rounds. Bookings at the same start time reduce capacity even when they belong to a different round. A booking without a named interviewer consumes one place without removing a specific email from the list, so capacity can be lower than the number of emails.
A fully booked start time is omitted from available slots. Attempting to
book it returns 409. Slot reads do not reserve capacity; handle conflicts by
refreshing availability and choosing another time or interviewer.
