Questions API
Overview
This section provides API specification for the optional Questions to be attached to an existing job listing, sometimes known as screening or pre-screening questions — a short series of questions presented to your applicants during the application process.
Authentication
This API uses Basic authentication. Include your API key in the Authorization header of every request.
The Question Model
Questions are expressed as an array of objects, each object representing a question,
encoded as json in the request or response body.
This is the same question model described by the
Screener Questions Specification. The one difference
is that this API identifies each question with a question_id field, whereas the
XML feed format uses id.
Submitting questions through the API vs. XML. You can attach questions to a
job either through this API (using the operations below) or by including them in
your XML Job Feed. Both paths support
the same question types and features. When using this API, each question is keyed
by question_id.
Common Fields
The following fields are available on all question types unless noted otherwise.
Common fields reference
| Field | Required | Type | Description |
|---|---|---|---|
question_id | Yes | string | A unique identifier for this question. Returned alongside candidate answers so your ATS can match answers back to their questions. This can just be the ordinal number of the question (i.e. 1, 2, 3...) if you don't already have an identifier. |
type | Yes | string | The question type, which determines the appearance of the question and what other fields are required/allowed. One of: text, textarea, integer, decimal, date, select, radio, multiselect, checkbox, upload, information, pagebreak, question_group. Each type may have further required and allowed fields; see below. |
question | Conditional | string | The question text shown to applicants. Simple HTML formatting, like paragraphs and emphasis, is permitted. Required for every type except information (which uses text) and pagebreak (which takes no answer). |
required | No | boolean | If present and true, this question cannot be skipped by applicants, and is required in order for the application to be considered complete and delivered to you. |
repeatable | No | boolean | If present and true, the question (or question_group) can have multiple answer blocks. |
Supported Question Types
text — free-form text entry
text
A free-form single-line text entry.
| Field | Required | Description |
|---|---|---|
format | No | One of integer or decimal to restrict input to a number. |
min | No | Minimum character count (or minimum value when format is set). |
max | No | Maximum character count (or maximum value when format is set). |
limit | No | Character limit for the answer (alias for max). |
condition | No | Makes the question conditional on a previous answer. |
textarea — multi-line text entry
textarea
A free-form multi-line text entry.
| Field | Required | Description |
|---|---|---|
min | No | Minimum character count. |
max | No | Maximum character count. |
limit | No | Character limit for the answer (alias for max). |
condition | No | Makes the question conditional on a previous answer. |
integer / decimal — numeric entry
integer and decimal
An entry restricted to numeric input. integer accepts whole numbers; decimal accepts fractional values. (Equivalently, you may use the text type with a format of integer or decimal.)
| Field | Required | Description |
|---|---|---|
min | No | The minimum value required to accept an answer. |
max | No | The maximum value required to accept an answer. |
condition | No | Makes the question conditional on a previous answer. |
date — date entry with range
date
A date entry with optional earliest and latest date requirements.
| Field | Required | Description |
|---|---|---|
format | No | The expected date format string. |
min | No | The earliest date accepted. Applicants will be shown a datepicker restricted to this range. |
max | No | The latest date accepted. Applicants will be shown a datepicker restricted to this range. |
condition | No | Makes the question conditional on a previous answer. |
select / radio — single-choice option lists
select and radio
A list of options where only one may be selected. select renders as a dropdown; radio renders as radio buttons.
| Field | Required | Description |
|---|---|---|
options | Yes | A non-empty array of option objects (see below). |
dealbreaker | No | If true, this is a dealbreaker question. |
condition | No | Makes the question conditional on a previous answer. |
multiselect / checkbox — multiple-choice option lists
multiselect and checkbox
A list of options where any number may be selected. multiselect renders as a multi-select dropdown; checkbox renders as checkboxes.
| Field | Required | Description |
|---|---|---|
options | Yes | A non-empty array of option objects (see below). |
dealbreaker | No | If true, this is a dealbreaker question. |
condition | No | Makes the question conditional on a previous answer. |
Option objects (select / radio / multiselect / checkbox)
Each entry in options is an object:
| Field | Required | Description |
|---|---|---|
label | Yes | The option text shown to applicants. |
value | Yes | The corresponding value, or option identifier that is returned to your ATS in answers. |
is_correct | No | Used with dealbreaker questions; options with "is_correct": false disqualify the applicant. |
upload — file upload
upload
A file upload entry. Files from applicants for upload questions are limited to PDF and well-known image and text document formats, and may be no larger than 10MB. No additional fields are required.
information — display-only text
information
Text displayed to the applicant that does not require an answer. Uses the text field instead of question.
| Field | Required | Description |
|---|---|---|
text | Yes | The informational text to display. |
pagebreak — page separator
pagebreak
Indicates where a page of questions starts and ends; no answer is expected. All questions between pagebreak entries are displayed on the same page. Do not mix pagebreak with question_group. Because a pagebreak starts a new group, never place one between a conditional question and the parent question it references.
question_group — grouped, optionally repeatable questions
question_group
A set of questions presented together on a single page. When repeatable is true, applicants can provide multiple answer blocks.
| Field | Required | Description |
|---|---|---|
questions | Yes | An array of sub-questions to display within the group. May contain any question type except pagebreak and a nested question_group. |
Do not mix question_group with pagebreak.
Conditional Questions
A question can be shown conditionally based on the answer to a previous question by adding a condition object. The parent question must appear before the conditional question and in the same group — with no pagebreak or question_group boundary separating the two.
condition reference
| Field | Required | Description |
|---|---|---|
question_id | Yes | The question_id of the parent question. |
value | Yes | The parent answer value that makes this question appear. |
A pagebreak starts a new group, so a pagebreak between a conditional question and the parent it references places them in different groups — an invalid arrangement (as does putting the conditional question before its parent).
If you submit questions in this state, the entire set of questions for the job is rejected — not just the offending question. None of the questions are saved. The job itself stays published, but with no screening questions attached, so applicants are never asked them and no answers are collected or delivered to your ATS. This applies whether the affected question is required or not.
Keep the parent question and every question that references it in the same group — between the same pair of pagebreak entries (or inside the same question_group) — with the parent listed first.
Dealbreaker Questions
A dealbreaker question marks the application as disqualified when the provided answer does not qualify. Supported for the select, radio, multiselect, and checkbox types. A dealbreaker question must be "required": true; options with "is_correct": false disqualify the applicant (all other options are treated as correct).
For the multiple-choice types (multiselect / checkbox), selecting any option marked "is_correct": false disqualifies the applicant, regardless of which other options are also selected.
Dealbreaker question example
{
"question_id": "age",
"type": "select",
"question": "Are you at least 18 years old?",
"dealbreaker": true,
"required": true,
"options": [
{ "value": "0", "label": "Yes", "is_correct": true },
{ "value": "1", "label": "No", "is_correct": false },
{ "value": "2", "label": "Prefer not to answer" }
]
}
An applicant who answers "No" is disqualified. Answering "Yes" or "Prefer not to answer" qualifies, because any option without "is_correct": false is treated as correct.
Example
Comprehensive example with all question types
[
{
"question_id": "pet_name",
"type" : "text",
"question" : "What is your pet's name?",
"required" : true
},
{
"question_id": "pet_age",
"type" : "text",
"format" : "integer",
"question" : "How old is your pet, in months?",
"min" : 1,
"max" : 250
},
{
"question_id": "pet_weight",
"type" : "text",
"format" : "decimal",
"question" : "What is your pet's weight, in kg?",
"min" : 0.01,
"max" : 250
},
{
"question_id": "pet_adopt_date",
"type" : "date",
"question" : "When was your pet adopted, or born into your care?",
"min" : "1970-10-20",
"format" : "YYYY-MM-DD"
},
{
"question_id": "pet_sleep_pref",
"type" : "select",
"question" : "Where does your pet like to sleep?",
"options" : [
{"value": "bed", "label": "My Bed"},
{"value": "floor", "label": "The Floor"},
{"value": "alone", "label": "Its Bed"},
{"value": "na", "label": "None of the Above"}
]
},
{
"question_id": "pet_nose_color",
"type" : "multiselect",
"question" : "What colors are present on your pet's nose?",
"options" : [
{"value": "0", "label": "Pink"},
{"value": "1", "label": "Brown"},
{"value": "2", "label": "Liver"},
{"value": "3", "label": "Yellow"},
{"value": "4", "label": "Green"},
{"value": "5", "label": "None of the Above"}
]
},
{
"question_id": "pet_photo",
"type" : "upload",
"question" : "Please submit your cutest photo of your pet.",
"required" : true
}
]
Operations
The endpoint https://api.ziprecruiter.com/partner/v0/job/<JOB_ID>/questions supports basic CRUD operations.
| Parameter | Description |
|---|---|
JOB_ID | The ID of the job to which the Questions are attached. |
Create Questions
Creates questions for a job. The questions for the job (identified by JOB_ID) cannot already exist.
The body must contain a JSON array of questions matching the question model.
POST https://api.ziprecruiter.com/partner/v0/job/<JOB_ID>/questions
Example request
curl https://api.ziprecruiter.com/partner/v0/job/emlwcmVjcnVpdGVy-3215/questions \
-H "Authorization: Basic YOUR_API_KEY" \
-X POST \
-H "Content-Type: application/json" \
-d @questions.json
Example response
{
"success" : true,
"job_id" : "emlwcmVjcnVpdGVy-3215",
"questions": [
{
"question_id": "pet_name",
"type" : "text",
"question" : "What is your pet's name?",
"required" : true
}
]
}
Update Questions
Replaces all questions for a job. The questions for the job (identified by JOB_ID) may already exist, and will be overwritten.
The body must contain a JSON array of questions matching the question model.
PUT https://api.ziprecruiter.com/partner/v0/job/<JOB_ID>/questions
Example request
curl https://api.ziprecruiter.com/partner/v0/job/emlwcmVjcnVpdGVy-3215/questions \
-H "Authorization: Basic YOUR_API_KEY" \
-X PUT \
-H "Content-Type: application/json" \
-d @questions.json
Example response
{
"success" : true,
"job_id" : "emlwcmVjcnVpdGVy-3215",
"questions": [
{
"question_id": "pet_name",
"type" : "text",
"question" : "What is your pet's name?",
"required" : true
}
]
}
Get Questions
Retrieves the questions attached to a job.
GET https://api.ziprecruiter.com/partner/v0/job/<JOB_ID>/questions
Example request
curl "https://api.ziprecruiter.com/partner/v0/job/emlwcmVjcnVpdGVy-3215/questions" \
-H "Authorization: Basic YOUR_API_KEY"
Example response
{
"success" : true,
"job_id" : "emlwcmVjcnVpdGVy-3215",
"questions": [
{
"question_id": "pet_name",
"type" : "text",
"question" : "What is your pet's name?",
"required" : true
},
{
"question_id": "pet_age",
"type" : "text",
"format" : "integer",
"question" : "How old is your pet, in months?",
"min" : 1,
"max" : 250,
"required" : false
}
]
}
Delete Questions
Deletes all questions attached to a job.
DELETE https://api.ziprecruiter.com/partner/v0/job/<JOB_ID>/questions
Example request
curl "https://api.ziprecruiter.com/partner/v0/job/emlwcmVjcnVpdGVy-3215/questions" \
-H "Authorization: Basic YOUR_API_KEY" \
-X DELETE
Example response
{
"success": true,
"job_id" : "emlwcmVjcnVpdGVy-3215"
}
Error Responses
Errors from the Questions API return HTTP status 400 with a JSON body describing the problem:
Example error response
{
"error": "Invalid Payload: Property is required: /question_id.",
"success": false
}
Error scenarios
| Status | Scenario |
|---|---|
| 400 | Missing required field (e.g., question_id, type, question). |
| 400 | Invalid question type or format. |
| 400 | Questions already exist for the job (POST). |
| 401 | Invalid or missing API key. |
| 404 | Job not found. |
| 500 | Internal Server Error — try again later. |