Indeed Interview API guide
Schedule, manage, and get information about virtual interviews with job candidates.
Note:
By using this API and its documentation and building an integration, you agree to the Additional API Terms and Guidelines.
Before you start
Note:
Before you can develop against this API, you must contact [email protected] to request access.
To understand Indeed’s requirements to use the Interview API, read the Additional API Terms and Guidelines.
Guidelines
As a consumer of the Interview API, you agree to:
-
Place a button in your user interface that enables your clients, the employers, to create an interview with Indeed Platform.
The button must meet the specifications that Indeed provides.
-
Describe to a job seeker which data you collect from and about them, and how you share that data with Indeed when they are scheduled for an interview.
-
Honor any request from a job seeker for their data in connection with any API.
-
Provide applicant tracking system (ATS) name and interviewee email address through this API.
-
Provide the employer name when that data is available to you.
Authentication
Use the authorization code flow (3-legged OAuth) to get a client ID and secret, an authorization code, and an access token.
You exchange the client ID for an authorization code with the interviews.schedule
, employer_access
, and offline_access
scopes. To enable the user to select an Indeed employer that is associated with their Indeed account, specify the prompt=select_employer
parameter in the authorization code request.
After you get an authorization code, exchange it and the client ID and secret for an access token, which lasts one hour, a refresh token that lasts 60 days, and an ID token that contains user information. The employer is returned as an advertiser ID in the ID token.
Use the access token for authentication when you call the Interview API.
To call the API, POST
the request to the following endpoint:
POST https://apis.indeed.com/graphql
Note:
Use the
POST
method for all queries and mutations. The API does not support theGET
method.
In the POST
request body, include the query, an optional operation name, and variable inputs:
{
"query": "...",
"operationName": "...",
"variables": {
"myVariable": "someValue",
...
}
}
Interview API overview
Note:
For information about how to authenticate and call the API, see Before you start.
Use the Interview API to schedule, update, get information about, or cancel a virtual event.
An event can include one, or no, interviewee, and from 1 to 49 interviewers. You can add an interviewee and interviewers to the event after you schedule it.
If the request succeeds, the API confirms that the event was scheduled and returns information about the event, including the unique interview ID. The API automatically adds you as an interviewer to the event, notifies each interviewer that they have been added to the event, adds calendar items to each interviewer's calendar, and sends the interviewer link to the interviewers. The applicant tracking system (ATS) handles communications with the interviewee.
A few minutes before the event begins, Indeed emails the interviewee to remind them of the event with a link to the event. When the event begins, each interviewer must log in with their Indeed account. Any interviewer without an account must create one. Interviewees do not need to create accounts.
An interviewer for an event can use the unique interview ID for an event to get details about, update, or cancel the event. You can make only one type of update at a time in an update request for an event. You can reschedule it, add interviewers to it, add an interviewee to it, change its title, or change its associated time zone. You can only add an interviewee to an event that does not already have an interviewee.
You can also:
- List virtual interview events, by IDs
- List events within a data range and optionally sorted by start or end time, status, and media type
Schedule and manage events
Use the Interview API to schedule, update, or cancel a virtual event.
Schedule an event
createVirtualInterviewEvent(
input: CreateVirtualInterviewEventInput!
): CreateVirtualInterviewEventPayload
To schedule a virtual event, call the createVirtualInterviewEvent
mutation with the CreateVirtualInterviewEventInput
input object. All fields are required except interviewee
, languageCode
, and countryCode
.
An event can include 1, or no, interviewee, and from 1 to 49 interviewers.
mutation CreateEvent {
createVirtualInterviewEvent(input: {
startTime: "2022-08-18T22:30:00+00:00"
endTime: "2022-08-18T23:30:00+00:00"
title: "Interview with Candidate"
timezone: "America/Los_Angeles"
interviewers: [{
email: "[email protected]"
}, {
email: "[email protected]"
}]
interviewee: {
name: "Candidate",
email: "[email protected]"
}
requestMetadata: {
atsName: "ExampleATS",
employerName: "Test Company"
}
languageCode: "fr"
countryCode: "CA"
}) {
event {
id
countryCode
languageCode
interviewerLobbyUrl
intervieweesConnection {
interviewees {
intervieweeLobbyUrl
name
email
}
}
interviewersConnection {
pageInfo {
endCursor
}
interviewers {
email
}
}
}
}
}
The mutation returns the CreateVirtualInterviewEventPayload
return type.
If the request succeeds, the API confirms that the event was scheduled and returns information about the event, including the unique interview ID. The API automatically adds you as an interviewer to the event, notifies each interviewer that they have been added to the event, adds calendar items to each interviewer's calendar, and sends the interviewer link to the interviewers. The applicant tracking system (ATS) handles communications with the interviewee.
A few minutes before the event begins, Indeed emails the interviewee to remind them of the event with a link to the event. When the event begins, each interviewer must log in with their Indeed account. Any interviewer without an account must create one. Interviewees do not need to create accounts.
If a validation error occurs, the request fails.
Validation error:
A validation error occurs when:
- The total number of interviewers exceeds 49.
- The interview duration is greater than 24 hours.
Reschedule an event
updateVirtualInterviewEvent(
input: UpdateVirtualInterviewEventInput!
): UpdateVirtualInterviewEventPayload
To update the start date and time and end date and time for the event, call the updateVirtualInterviewEvent
mutation with the UpdateVirtualInterviewEventInput
input object. In that input object, specify the reschedule
field with the RescheduleVirtualInterviewEventInput
input object.
mutation RescheduleEvent {
updateVirtualInterviewEvent(input: {
reschedule: {
id: "aXJpOi8vYXBpcy5pbmRlZWQuY29tL1ZpcnR1YWxJbnRlcnZpZXdFdmVudC8zZjM3MmEzNy05NTI5LTQ0NmItYmQ5OC01ZGJjOGMwNTdjODQ="
startTime: "2022-08-19T22:30:00+00:00"
endTime: "2022-08-19T23:30:00+00:00"
}
}) {
event {
id
status
title
startTime
endTime
timezone
languageCode
countryCode
interviewerLobbyUrl
interviewersConnection {
interviewers {
name
email
}
}
intervieweesConnection {
interviewees {
intervieweeLobbyUrl
name
email
}
}
}
}
}
The mutation returns the UpdateVirtualInterviewEventPayload
return type, which includes the updated VirtualInterviewEvent
return type.
-
If the request succeeds, the API confirms that the event was rescheduled successfully and returns information about the event, including the unique interview ID.
-
If a validation error occurs, the request fails.
Validation error:
A validation error occurs when the event duration is greater than 24 hours.
Add interviewers to an event
updateVirtualInterviewEvent(
input: UpdateVirtualInterviewEventInput!
): UpdateVirtualInterviewEventPayload
To add interviewers to an event, call the updateVirtualInterviewEvent
mutation with the UpdateVirtualInterviewEventInput
input object. In that input object, specify the addInterviewers
field with the UpdateVirtualInterviewEventInterviewersInput
input object.
mutation AddInterviewersToEvent {
updateVirtualInterviewEvent(input: {
addInterviewers: {
id: "c0cbfcf3-961a-4b6f-a199-e4043f4016cf"
interviewers: [{
email: "[email protected]"
},
{
email: "[email protected]"
},
{
email: "[email protected]"
}
]
}
}) {
event {
id
status
title
startTime
endTime
timezone
languageCode
countryCode
interviewerLobbyUrl
interviewersConnection {
interviewers {
name
email
}
}
intervieweesConnection {
interviewees {
intervieweeLobbyUrl
name
email
}
}
}
}
}
The mutation returns the UpdateVirtualInterviewEventPayload
return type, which includes the updated VirtualInterviewEvent
return type.
-
If the request succeeds, the API confirms that the interviewers for the event were added successfully and returns information about the event, including the unique interview ID.
-
If a validation error occurs, the request fails.
Validation error:
A validation error occurs when the total number of interviewers exceeds 49.
Add an interviewee to an event
updateVirtualInterviewEvent(
input: UpdateVirtualInterviewEventInput!
): UpdateVirtualInterviewEventPayload
To add an interviewee to an event, call the updateVirtualInterviewEvent
mutation with the UpdateVirtualInterviewEventInput
input object. In that input object, specify the addInterviewee
field with the AddVirtualInterviewEventIntervieweeInput
input object.
Notes:
- You can add only one interviewee to an event, and you cannot change the interviewee for an event.
- If you need to change the interviewee for an event, cancel the event and schedule one with the correct interviewee.
mutation AddIntervieweeToEvent {
updateVirtualInterviewEvent(input: {
addInterviewee: {
id: "c0cbfcf3-961a-4b6f-a199-e4043f4016cf"
interviewee: {
name: "intervieweeName"
email: "[email protected]"
}
}
}) {
event {
id
status
title
startTime
endTime
timezone
languageCode
countryCode
interviewerLobbyUrl
interviewersConnection {
interviewers {
name
email
}
}
intervieweesConnection {
interviewees {
intervieweeLobbyUrl
name
email
}
}
}
}
}
The mutation returns the UpdateVirtualInterviewEventPayload
return type, which includes the updated VirtualInterviewEvent
return type.
- If the request succeeds, the API confirms that the interviewee for the event was added successfully and returns information about the event, including the unique interview ID.
- If a validation error occurs, the request fails.
Change the title for an event
updateVirtualInterviewEvent(
input: UpdateVirtualInterviewEventInput!
): UpdateVirtualInterviewEventPayload
To change the title for an event, call the updateVirtualInterviewEvent
mutation with the UpdateVirtualInterviewEventInput
input object. In that input object, specify the setTitle
field with the UpdateVirtualInterviewEventTitleInput
input object.
mutation SetTitleOfEvent {
updateVirtualInterviewEvent(input: {
setTitle: {
id: "c0cbfcf3-961a-4b6f-a199-e4043f4016cf"
title: "Interview with Candidate"
}
}) {
event {
id
status
title
startTime
endTime
timezone
languageCode
countryCode
interviewerLobbyUrl
interviewersConnection {
interviewers {
name
email
}
}
intervieweesConnection {
interviewees {
intervieweeLobbyUrl
name
email
}
}
}
}
}
The mutation returns the UpdateVirtualInterviewEventPayload
return type, which includes the updated VirtualInterviewEvent
return type.
- If the request succeeds, the API confirms that the title for the event was changed successfully and returns information about the event, including the unique interview ID.
- If a validation error occurs, the request fails.
Change the time zone for an event
updateVirtualInterviewEvent(
input: UpdateVirtualInterviewEventInput!
): UpdateVirtualInterviewEventPayload
To change the time zone for an event, call the updateVirtualInterviewEvent
mutation with the UpdateVirtualInterviewEventInput
input object. In that input object, specify the setTimezone
field with the UpdateVirtualInterviewEventTimezoneInput
input object.
mutation SetTimezoneOfEvent {
updateVirtualInterviewEvent(input: {
setTimezone: {
id: "c0cbfcf3-961a-4b6f-a199-e4043f4016cf"
timezone: "America/Los_Angeles"
}
}) {
event {
id
status
title
startTime
endTime
timezone
languageCode
countryCode
interviewerLobbyUrl
interviewersConnection {
interviewers {
name
email
}
}
intervieweesConnection {
interviewees {
intervieweeLobbyUrl
name
email
}
}
}
}
}
The mutation returns the UpdateVirtualInterviewEventPayload
return type, which includes the updated VirtualInterviewEvent
return type.
- If the request succeeds, the API confirms that the time zone for the event was changed successfully and returns information about the event, including the unique interview ID.
- If a validation error occurs, the request fails.
Cancel an event
cancelVirtualInterviewEvent(
input: CancelVirtualInterviewEventInput!
): CancelVirtualInterviewEventPayload
To cancel an event, call the cancelVirtualInterviewEvent
mutation with the CancelVirtualInterviewEventInput
input object:
mutation CancelEvent {
cancelVirtualInterviewEvent(input: {
id: "c0cbfcf3-961a-4b6f-a199-e4043f4016cf"
}) {
event {
id
status
title
startTime
endTime
timezone
languageCode
countryCode
interviewerLobbyUrl
interviewersConnection {
interviewers {
name
email
}
}
intervieweesConnection {
interviewees {
intervieweeLobbyUrl
name
email
}
}
}
}
}
The mutation returns the CancelVirtualInterviewEventPayload
return type, which includes the updated VirtualInterviewEvent
return type.
- If the request succeeds, the API confirms that the event was canceled successfully and returns information about the event.
- If a validation error occurs, the request fails.
Get information about events
You can show details for one or more events, by ID, or list events within a date range.
List virtual interview events, by IDs
virtualInterviewEvents(
input: VirtualInterviewEventsInput!
): VirtualInterviewEventsPayload
To list virtual interview events, by IDs, call the virtualInterviewEvents
query with the VirtualInterviewEventsInput
input object:
query GetEvent {
virtualInterviewEvents(input: {
ids: [
"aXJpOi8vYXBpcy5pbmRlZWQuY29tL1ZpcnR1YWxJbnRlcnZpZXdFdmVudC9jMGNiZmNmMy05NjFhLTRiNmYtYTE5OS1lNDA0M2Y0MDE2Y2Y=",
"aXJpOi8vYXBpcy5pbmRlZWQuY29tL1ZpcnR1YWxJbnRlcnZpZXdFdmVudC8zZjM3MmEzNy05NTI5LTQ0NmItYmQ5OC01ZGJjOGMwNTdjODQ="
]
}) {
events {
id
interviewerLobbyUrl
intervieweesConnection {
interviewees {
intervieweeLobbyUrl
name
email
interviewRecordsConnection {
records {
id
recordingUrl
interviewOutcomesConnection {
outcomes {
interviewer {
id
email
name
}
decision {
value
noteText
}
}
}
}
}
}
}
interviewersConnection {
pageInfo {
endCursor
}
interviewers {
email
}
}
}
}
}
The query returns the VirtualInterviewEventsPayload
return type, which includes the updated VirtualInterviewEvent
return type, which lists events.
List events within a date range
findVirtualInterviewEvents(
first: Int = 10,
after: String,
input: FindVirtualInterviewEventsInput!
): VirtualInterviewEventsConnection
To list events within a date range, call the findVirtualInterviewEvents
query with the FindVirtualInterviewEventsInput
input object.
You can use the first
and after
fields to specify:
first
. The number of events to list.after
. The date and time after which to list events.
In the FindVirtualInterviewEventsInput
input object, you can specify these optional filters:
- Start time of the time range of the event.
- End time of the time range of the event.
- Sort options.
query FindEvents {
findVirtualInterviewEvents(
first: 50,
after: "ZmIyNDUxZjAtYjBjMy00NTljLTk4MGItNTVlMThhNWNlOWU0fDQ"
input: {
startTime: {
after: "2022-06-29T22:00:00+00:00"
}
}
) {
events {
id
title
startTime
endTime
interviewersConnection {
interviewers {
email
}
}
}
pageInfo {
startCursor
endCursor
hasNextPage
hasPreviousPage
}
totalCount
}
}
The query returns the VirtualInterviewEventsConnection
return type with a paginated list of events that are scheduled after a specified date.
- If the request succeeds, the API returns pagination information for the events within the date range.
- If a validation error occurs, the request fails.
Notes on accessing event recordings
When you conduct an interview on Indeed's platform, you can record it. When an interview concludes, Indeed sends an email to the interviewers with a link to the recording. You can also access this link through the API, in the recordingUrl
field in the VirtualInterviewRecord
return type.
Each VirtualInterviewRecord
return type corresponds to an individual interview. If an interviewee participates in multiple interviews in separate sessions in a single event, a recording exists for each interview.
If there are multiple videos from a single interview, that is, recordings are repeatedly enabled and disabled, those videos are concatenated.
The recording appears in the UI on our website. Only interviewers who participated in the interview can view the recording even if the link is shared. Recordings expire after 90 days, after which the link shows an error page.
Sometimes a delay occurs between the end of an interview and when the recording becomes available to view. If a recording is not available after 24 hours, contact Indeed to investigate the issue.
The recordingUrl
field value is null if no recording is available for an interview record, either because it wasn't recorded or because it hasn't finished processing. It is also null if an error occurs in processing the video. If a recording is available, the field contains the URL for the webpage where it can be viewed.
Troubleshoot errors
Troubleshoot common errors
When a request fails, the data
field is null, and the errors
field contains information about what went wrong.
The following table describes the common error types:
Error | Description and common causes |
---|---|
BAD_USER_INPUT
|
The value of an input parameter is not valid or the server cannot process your request based on the provided input. See consult the error message for details. |
INTERNAL_SERVER_ERROR
|
The server encountered an unexpected failure, error, or exception and did not provide a response. This can happen for various reasons and is closely monitored by Indeed. Try your request again. |
UNAUTHENTICATED
|
The request did not include sufficient authentication credentials. For details on how to provide authentication credentials, see Authorization. |
FORBIDDEN
|
Valid authentication credentials are present but insufficient to perform the associated query or mutation. For details, see the error message.
|
Example – Invalid request
In this request, the after
pagination cursor incorrectly contains special characters.
query {
findVirtualInterviewEvents(
input: {
startTime: {
after: "2022-07-19T23:21:27+00:00"
before: "2022-07-19T23:21:30+00:00"
}
endTime: {
after: "2022-07-19T23:21:27+00:00"
before: "2022-07-19T23:21:30+00:00"
}
}, after: "1˙∆") {
events {
id
}
}
}
Example – Error response
In an error response, data
is null. Information about what went wrong appears in the errors
section, with details in message
.
{
"errors": [{
"message": "Encountered issue parsing cursor '1˙∆'.",
"locations": [{
"line": 3,
"column": 3
}],
"path": [
"findVirtualInterviewEvents"
],
"extensions": {
"code": "BAD_USER_INPUT",
"logLevel": "INFO"
}
}],
"data": {
"findVirtualInterviewEvents": null
}
}
Note:
When using the
Get
query type and some IDs encounter errors, they appear as null in"data"
along with any successes.
Troubleshoot authorization errors
Authorization endpoints, such as https://apis.indeed.com/oauth/v2/tokens
, return errors in the format that the OAuth 2.0 authorization framework requires. See RFC6749.
For example:
{
"error_description": "Invalid grant",
"error": "invalid_grant"
}
Error | Description |
---|---|
|
Your client ID, client secret, authorization code, or refresh token is incorrect. The |
invalid_request
|
A request parameter has an issue. The |
unsupported_grant_type
|
The requested grant type is not supported. The requested
|
invalid_request errors – Causes and resolutions
To resolve an invalid_request
error, review the following causes and resolutions:
Cause | Resolution |
---|---|
Incorrect or missing parameter | |
A required parameter is missing or has an invalid value. |
Include or correct the parameter. |
Misplaced query string parameters | |
The |
Include query string parameters in the HTTP request body, by using the |
Incorrect employer parameter value | |
The issue can occur for one of these reasons:
|
To list valid
Then, update the value of the |
invalid_grant errors – Causes and resolutions
To resolve an invalid_grant
error, review the following causes and resolutions:
Cause | Resolution |
---|---|
Incorrect client ID or secret | |
You copy a credential incorrectly from Manage app credentials. |
Verify your client ID and secret. |
Incorrect client secret | |
You add a secret and delete the original secret for your client ID but do not update all your credential stores. |
Verify that your credential stores contain the latest client secret. |
Disabled client credentials grant type | |
You use the client credentials flow (2-legged OAuth) and the client credentials grant type is not enabled. |
On Manage app credentials, select Client credentials in Allowed grant types. |
Disabled authorization code grant type | |
You use the authorization code flow (3-legged OAuth) and the authorization code grant type is not enabled. |
On Manage app credentials, select Authorization code in Allowed grant types. |
Mismatched redirect_uri parameter values | |
You use the authorization code flow (3-legged OAuth) and these values do not match:
|
Ensure that the two |
Expired or already-used authorization code | |
You use the authorization code flow (3-legged OAuth) and you used an expired or already-used authorization code. You can use an authorization code only one time. |
To renew access tokens without reauthorization, request the |
Refresh token is not valid | |
You use the authorization code flow (3-legged OAuth) and the refresh token is not valid. Refresh tokens expire 60 days after last usage or after issue if never used. This issue can occur for one of these reasons:
|
Ask the user to request another refresh token through the authorization code flow (3-legged OAuth). |
The authorization code or refresh token is not valid for your app | |
You use the authorization code flow (3-legged OAuth) and the authorization code or refresh token is valid but it was issued to a different app. |
Use the same client ID and secret through all stages of the authorization process. |
See also
Updated 3 days ago