Find a live round, choose an available time, and book an interview through the API.
Schedule a live interview
Use the REST API to find available interview times, select an interviewer, create a booking, and manage the interview afterward.
posting_id + round_id → available start_at + interviewer_email → interview
| Goal | API operation |
|---|---|
| Find a posting | GET /api/v1/roles |
| Find its live interview round | GET /api/v1/postings/{id}/pipeline |
| Find times and eligible interviewers | GET /api/v1/postings/{id}/slots?round_id={round_id} |
| Book a time | POST /api/v1/interviews |
| Read or list bookings | GET /api/v1/interviews/{id} or GET /api/v1/interviews |
| Change the interviewer | PATCH /api/v1/interviews/{id} |
| Reschedule | POST /api/v1/interviews with replace_existing: true |
| Cancel | DELETE /api/v1/interviews/{id} |
| Detect stored changes | GET /api/v1/interviews?updated_since={timestamp} |
The interview reference has request fields and responses. The steps below show one complete booking.
Choose the scheduling workflow
In Litmus, an assessment is the exercise a candidate completes. Its
delivery_mode determines whether it is a take-home (async), a live
interview (sync), or a work trial (trial). An assessment invitation and an
interview booking are separate actions.
| Your goal | API call | Candidate experience |
|---|---|---|
| Send a take-home assessment | POST /invites targeting an async assessment | Receives an assessment invitation and completes the exercise under its configured deadline and access rules. |
| Let the candidate choose a live interview time | POST /invites targeting a sync assessment | Receives a scheduling email and chooses from available times in Litmus. The invite itself does not book a time. |
| Have your automation book a live interview | POST /interviews with a start time | Receives a booking confirmation for the time your integration selected. |
| Schedule on your own calendar and provide access to Litmus | POST /interviews with externally_scheduled: true | Receives the candidate link from your integration. You manage the calendar invitation and booking communications. |
Paths in this table are relative to https://litmushiring.com/api/v1.
For self-scheduling and API-controlled booking, Litmus manages booking emails
and calendar invitations. For external scheduling, your application chooses
the time, creates the calendar event, supplies the meeting link, and sends the
candidate the returned access link. Litmus tracks the interview session and
assessment.
The steps below cover booking through Litmus. For candidate self-scheduling,
see Send assessment invites. For your own calendar,
see External scheduling.
Before you begin
- Create a role with a live interview assessment in its pipeline in the Litmus dashboard.
- Set up interviewer availability: have interviewers connect Google Calendar and set working hours in Litmus, or add their available start times through
POST /api/v1/postings/{id}/slots. In step 3, your automation reads the resulting bookable times. - Create an API key with
roles:read,interviews:read, andinterviews:write. - Set
LITMUS_API_KEYin the environment where you run these examples.
Replace the example IDs and candidate details with your own. Read Testing scheduling integrations before sending a write request.
1. Find the posting
curl --fail-with-body https://litmushiring.com/api/v1/roles \
-H "Authorization: Bearer $LITMUS_API_KEY"Choose the relevant entry in roles and use its id as posting_id.
You can also find this ID in the dashboard URL: /company/posting/{posting_id}.
2. Select a live round
curl --fail-with-body \
https://litmushiring.com/api/v1/postings/posting_abc123/pipeline \
-H "Authorization: Bearer $LITMUS_API_KEY"Find a step in the candidate's track with type: "assessment",
delivery_mode: "sync", and bookable: true. For example:
{
"round_id": "step_abc123",
"type": "assessment",
"title": "System design",
"assessment_id": "asmt_ghi789",
"delivery_mode": "sync",
"duration_minutes": 60,
"bookable": true
}Use round_id for booking. Use assessment_id when sending an assessment
invite. These IDs are not interchangeable. The same assessment can appear in
multiple tracks with a different round_id in each.
If bookable is false, or the assessment appears only in
unstaged_assessments, configure and save its round in the dashboard pipeline
before booking through the API.
3. Choose an available time and interviewer
curl --fail-with-body --get \
https://litmushiring.com/api/v1/postings/posting_abc123/slots \
-H "Authorization: Bearer $LITMUS_API_KEY" \
--data-urlencode "round_id=step_abc123"Example response:
{
"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
}
]
}Choose a future start_at and one of its interviewer_emails. If no slots are
returned, add availability or ask the
interviewer to update their schedule. Read slots again after a booking conflict;
availability can change between reading and booking.
Slot reads do not reserve time. start_at is returned in UTC; send that
instant back with its Z suffix or another explicit offset. The response's
duration_minutes is the calendar block for this round. A slot can come from
posting-level times or an interviewer's personal schedule or connected calendar;
read the interviewer roster
before writing availability.
4. Book the interview
curl --fail-with-body -X POST https://litmushiring.com/api/v1/interviews \
-H "Authorization: Bearer $LITMUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"posting_id": "posting_abc123",
"round_id": "step_abc123",
"candidate_email": "candidate@example.com",
"candidate_name": "Sample Candidate",
"scheduled_start_at": "2026-10-20T17:00:00Z",
"interviewer_email": "interviewer@example.com",
"time_zone": "America/Los_Angeles"
}'Use a future time from your slots response. Timestamps use ISO 8601 with an
explicit UTC offset; Z means UTC. time_zone controls how the time is
displayed in booking emails, not how scheduled_start_at is interpreted.
A successful request returns 201 with an interview object. Save
interview.id in your system.
The booking can create a candidate record for this assessment. Litmus creates
session access, creates or updates a calendar event when its calendar
integration is configured, emails the candidate a booking confirmation and
the selected interviewer a briefing, and attaches calendar invitations. It may
create a meeting link if none was provided. These emails are sent after the
booking is written. There is no dry-run mode. A separate POST /invites call
is unnecessary and would send an extra invitation.
201 confirms the booking, not delivery of the emails sent afterward. If
calendar integration is not configured, the booking emails still include
calendar invitations. Check meeting_link in the response; it can be empty
when no meeting link was supplied or created.
Example response excerpt:
{
"interview": {
"id": "sess_abc123",
"status": "scheduled",
"scheduled_start_at": "2026-10-20T17:00:00.000Z",
"interviewer_email": "interviewer@example.com",
"meeting_link": "https://video.example.com/room/abc",
"duration_minutes": 60,
"time_zone": "America/Los_Angeles"
}
}See the interview reference for the complete response fields.
Booking by email creates a candidate for this round's assessment when needed, or reuses the existing candidate. A separate self-scheduling invite is not needed when your application already chose the time.
Inspect interview.meeting_link and any top-level warnings before treating
the interview as ready. A 201 with warnings means the interview was created;
resolve the warning without repeating the booking.
Handle a booking conflict
Availability can change after you read it. A full time, an already booked
interviewer, or an existing interview for the candidate returns 409. Treat
that request as unsuccessful: inspect error, read the candidate's current
interview if necessary, refresh GET /postings/{id}/slots, and deliberately
choose a currently available time and interviewer. Do not blindly retry the
same write. See Errors and retries.
5. Read and manage the booking
curl --fail-with-body \
https://litmushiring.com/api/v1/interviews/sess_abc123 \
-H "Authorization: Bearer $LITMUS_API_KEY"Replace sess_abc123 with the saved interview.id. The read endpoint returns
the interview object directly, without an interview wrapper.
- Reassign the interviewer with
PATCH /interviews/{id}. - Reschedule with
POST /interviewsandreplace_existing: true. - Cancel with
DELETE /interviews/{id}. - Synchronize changes with
GET /interviewsandupdated_since.
Synchronize interview changes
Litmus does not expose scheduling webhooks. Poll GET /interviews with
updated_since, follow every next_cursor, and store interviews by their
id, including cancellations. The synchronization guide
covers checkpoints and statuses that change as time passes without a database
write.
Testing scheduling integrations
The REST API has no dry-run parameter or documented public sandbox credentials. Use an isolated test organization or environment supplied by Litmus, with a test posting, a bookable live round, and candidate and interviewer addresses you control. Confirm the target host and organization before writing. A normal booking sends real email and calendar invitations and can create a real meeting link; an external booking creates a real access link. Cancel test bookings and remove test calendar events you own when finished. A read-only walk through roles, pipeline, and slots is a safe first test.
External scheduling
Use this mode when your integration owns the calendar event, meeting link, and communications. It creates access to a live assessment in Litmus.
curl --fail-with-body -X POST https://litmushiring.com/api/v1/interviews \
-H "Authorization: Bearer $LITMUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"posting_id": "posting_abc123",
"round_id": "step_abc123",
"candidate_email": "candidate@example.com",
"candidate_name": "Sample Candidate",
"interviewer_email": "interviewer@example.com",
"meeting_link": "https://video.example.com/room/abc",
"externally_scheduled": true
}'Both interviewer_email and meeting_link are required. The 201 response
includes interview and a top-level candidate_link. Save the interview ID
and share that link with the candidate through your own workflow. The
interviewer runs the session from the Litmus dashboard.
Example response excerpt:
{
"interview": {
"id": "sess_abc123",
"status": "pending",
"scheduled_start_at": null,
"externally_scheduled": true
},
"candidate_link": "https://litmushiring.com/sign-in?gx=example_token"
}This endpoint does not import a scheduled calendar appointment. A newly
created external link has status: "pending" and scheduled_start_at: null.
A supplied scheduled_start_at does not set the appointment time in this mode.
Keep the appointment time in your scheduling system. Litmus creates no calendar
event and sends no booking confirmation; your integration is responsible for
both.
The returned candidate_link is single-use and expires after 24 hours.
Create it within 24 hours of the interview; an interviewer can issue a fresh
link from the console if needed. Separately, an unstarted external session
expires after seven days. A pending interview status does not guarantee that
the original candidate link is still valid.
Store candidate_link securely when it is returned: the interview read
endpoints do not include it. Manage changes to your external calendar in your
own system; Litmus cancellation does not update an event your integration created.
Next, synchronize interview changes and review booking error recovery.
