Unified.to
All articles

How to Pull Screening Questions from an ATS and Embed Them in Your Product Using Unified's ATS API


February 25, 2026

Screening questions are often defined inside the ATS.

If you're building:

  • A custom apply flow
  • A sourcing portal
  • A talent CRM
  • A recruiting automation layer
  • A candidate engagement product

…you need to:

  1. Pull screening questions from the ATS
  2. Render them dynamically in your product
  3. Collect structured responses
  4. Push those responses back into the ATS
  5. Attach them to the correct application

This guide walks through that full read + structured write-back workflow using Unified's ATS API.

The Mental Model

The workflow looks like this:

  1. Retrieve the job from the ATS
  2. Extract job.questions[]
  3. Normalize question types
  4. Render a dynamic form in your UI
  5. Create (or retrieve) the candidate
  6. Create the application
  7. Attach answers[] to the application

The ATS remains the system of record.

Your product becomes a structured front-end for screening.

Step 1: Retrieve the Job Object

Screening questions live on the job object.

Endpoint

GET /ats/{connection_id}/job/{id}

Node SDK Example

const job = await sdk.ats.getAtsJob({
  connectionId,
  id: jobId,
  fields: '',
  raw: '',
});

Screening Question Structure

From the AtsJob model:

questions: [
  {
    id: string,
    question: string,
    required: boolean,
    description?: string,
    prompt?: string,
    type:
      'TEXT' |
      'NUMBER' |
      'DATE' |
      'BOOLEAN' |
      'MULTIPLE_CHOICE' |
      'FILE' |
      'TEXTAREA' |
      'MULTIPLE_SELECT' |
      'UNIVERSITY' |
      'YES_NO' |
      'CURRENCY' |
      'URL',
    options?: string[]
  }
]

Each question includes a unique id.

That id is what you will later use as question_id when writing answers back to the application.

Step 2: Normalize Question Types

Your frontend should normalize ATS question types into your own UI schema.

Example mapping:

ATS TypeUI Component
TEXTSingle-line input
TEXTAREAMulti-line input
NUMBERNumeric input
DATEDate picker
BOOLEANCheckbox
YES_NORadio buttons
MULTIPLE_CHOICESingle select dropdown
MULTIPLE_SELECTMulti-select control
FILEFile upload
URLURL input
CURRENCYCurrency field

Render dynamically based on:

  • type
  • required
  • options[] (when applicable)

Do not hardcode question definitions. Always trust the job object.

Step 3: Collect Candidate Responses

Your form should produce a structured payload like:

[
  {
    "question_id": "q_123",
    "answers": ["Yes"]
  },
  {
    "question_id": "q_456",
    "answers": ["5"]
  }
]

Important:

  • answers is always an array of strings
  • Even for single-value questions
  • Maintain order but rely on question_id for mapping

Step 4: Handle FILE-Type Questions

For FILE questions, responses must be represented as a string.

Unified's ATS Application model expects:

answers[].answers[]: string[]

For file-based questions, supply:

  • A publicly accessible file URL (recommended), or
  • A document ID if the downstream ATS requires pre-upload

Typical workflow:

  1. Upload the file via the Document endpoint
  2. Capture the returned document_url or id
  3. Use that value as the answer

Upload File

POST /ats/{connection_id}/document

Example:

const doc = await sdk.ats.createAtsDocument({
  connectionId,
  atsDocument: {
    filename: 'resume.pdf',
    type: 'RESUME',
    candidate_id: candidateId,
    document_data: base64EncodedFile,
  },
});

Then in your answers:

{
  "question_id": "file_q_001",
  "answers": ["https://your-storage.com/file.pdf"]
}

or:

{
  "question_id": "file_q_001",
  "answers": ["document_id_789"]
}

File handling requirements vary by integration. Always confirm provider expectations.

Step 5: Create the Candidate (If Needed)

Before attaching answers, ensure the candidate exists.

const candidate = await sdk.ats.createAtsCandidate({
  connectionId,
  atsCandidate: {
    first_name: 'Jane',
    last_name: 'Doe',
    emails: [{ email: 'jane@example.com', type: 'WORK' }]
  },
});

Or dedupe first using:

query: 'jane@example.com'

Step 6: Create the Application With Answers

You can attach screening responses during application creation.

Endpoint

POST /ats/{connection_id}/application

Example

const application = await sdk.ats.createAtsApplication({
  connectionId,
  atsApplication: {
    candidate_id: candidate.id,
    job_id: job.id,
    answers: [
      {
        question_id: "q_123",
        answers: ["Yes"]
      },
      {
        question_id: "q_456",
        answers: ["5"]
      }
    ],
    status: "NEW"
  },
});

Alternatively, you can update answers after application creation:

await sdk.ats.updateAtsApplication({
  connectionId,
  id: application.id,
  atsApplication: {
    answers: [
      {
        question_id: "q_123",
        answers: ["Yes"]
      }
    ]
  }
});

Mapping Questions to Answers

There is no explicit documentation stating that Unified automatically resolves mappings between job questions and application answers.

The intended implementation pattern is:

  • Retrieve job.questions[]
  • Use job.questions[].id
  • Submit that same ID as answers[].question_id

If provider-native IDs are needed, use the raw field to inspect vendor-specific structures.

Step 7: Handling Custom Fields

If your product captures additional metadata:

  • Use metadata[] on AtsApplication or AtsCandidate
  • Confirm writable support for your integration
  • Avoid assuming universal custom-field availability

Full Workflow Summary

  1. GET job
  2. Extract job.questions[]
  3. Render dynamic form
  4. Upload files if needed
  5. Create candidate (or dedupe)
  6. POST application with answers[]
  7. Optionally update stage

All structured responses remain inside the ATS.

What Unified Does Not Guarantee

Unified documentation does not explicitly guarantee:

  • That all ATS integrations expose questions[]
  • That all integrations support writing answers[]
  • That question ID formats are consistent across providers
  • That file-answer semantics are identical across providers

Always consult integration-specific field support before deploying.

Closing Thoughts

Pulling screening questions from the ATS and embedding them into your product allows you to:

  • Build fully custom apply experiences
  • Control candidate UX
  • Preserve structured screening logic
  • Keep the ATS as the source of truth

Unified's ATS API provides:

  • Normalized job question definitions
  • Structured answer submission
  • File upload support
  • Application-level write-back

The rest is orchestration: render dynamically, validate locally, and write back cleanly.

→ Start your 30-day free trial

→ Book a demo

All articles