On this page

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

GoalAPI operation
Find a postingGET /api/v1/roles
Find its live interview roundGET /api/v1/postings/{id}/pipeline
Find times and eligible interviewersGET /api/v1/postings/{id}/slots?round_id={round_id}
Book a timePOST /api/v1/interviews
Read or list bookingsGET /api/v1/interviews/{id} or GET /api/v1/interviews
Change the interviewerPATCH /api/v1/interviews/{id}
ReschedulePOST /api/v1/interviews with replace_existing: true
CancelDELETE /api/v1/interviews/{id}
Detect stored changesGET /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 goalAPI callCandidate experience
Send a take-home assessmentPOST /invites targeting an async assessmentReceives an assessment invitation and completes the exercise under its configured deadline and access rules.
Let the candidate choose a live interview timePOST /invites targeting a sync assessmentReceives a scheduling email and chooses from available times in Litmus. The invite itself does not book a time.
Have your automation book a live interviewPOST /interviews with a start timeReceives a booking confirmation for the time your integration selected.
Schedule on your own calendar and provide access to LitmusPOST /interviews with externally_scheduled: trueReceives 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, and interviews:write.
  • Set LITMUS_API_KEY in 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

bash
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

bash
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:

json
{
  "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

bash
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:

json
{
  "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

bash
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.

Creating an interview has external side effects

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:

json
{
  "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

bash
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.

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.

bash
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:

json
{
  "interview": {
    "id": "sess_abc123",
    "status": "pending",
    "scheduled_start_at": null,
    "externally_scheduled": true
  },
  "candidate_link": "https://litmushiring.com/sign-in?gx=example_token"
}
External scheduling creates an on-demand session link

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.

    Schedule a live interview · Litmus docs