# Job application form template that screens as it collects

Short answer: this is a complete QuizGen form definition for a job
application — name, contact, an uploaded resume, a portfolio link, a few
screening questions, and a scoring block that sorts applicants into "screen
now," "review," or "not a fit" as they submit. POST it as-is, or hand it to
an AI assistant to adapt for your role.

## Resume uploads need a paid plan

Candidates can attach a resume directly: the `file_upload` question type
takes PDFs and Word documents, and the file lands in your account rather
than in a share link that may or may not still work in three weeks.

The catch is plan gating. `file_upload` is **Pro or Business only** — on
the free plan or in the sandbox, creating a form that contains one returns
402 `plan_limit`. Limits differ by plan too: Pro allows 10 MB per file and
1 GB of storage in total, Business 25 MB per file and 10 GB.

If you're on the free plan, delete the `resume_file` question from the
template below and keep `portfolio_link` — a `url` question asking for a
Drive link, personal site, LinkedIn, or GitHub. That's a genuinely fine
substitute for engineering, design, and writing roles, where a live
portfolio often tells you more than a PDF. It's a worse substitute when you
need a formatted document to pass along to someone else.

The template below asks for both, which is usually the right call: the file
for your records, the link for the work itself.

One thing worth knowing if an assistant is building this for you: the answer
to a `file_upload` question is an array of file ids that the server issues
while the candidate uploads. You never write that value into a definition,
and there is no API for attaching a file on someone's behalf — uploads only
happen through the hosted form.

## The template

```json
{
  "schema_version": 1,
  "kind": "form",
  "title": "Apply: Product Designer",
  "description": "Takes about 5 minutes. We read every application.",
  "settings": {
    "collect_respondent": "email_required"
  },
  "sections": [
    {
      "key": "candidate",
      "title": "About you",
      "questions": [
        { "id": "full_name", "type": "short_text", "prompt": "Full name",
          "required": true, "placeholder": "Jordan Smith" },
        { "id": "email", "type": "email", "prompt": "Email address",
          "required": true, "placeholder": "you@example.com" },
        { "id": "phone", "type": "phone", "prompt": "Phone number",
          "required": true, "placeholder": "+1 555 555 5555" },
        { "id": "resume_file", "type": "file_upload", "prompt": "Upload your resume",
          "help": "PDF or Word document.",
          "required": true, "max_files": 1, "accept": ["pdf", "document"] },
        { "id": "portfolio_link", "type": "url", "prompt": "Link to a portfolio, LinkedIn, or GitHub",
          "help": "Optional, but it usually helps more than the resume does.",
          "placeholder": "https://" }
      ]
    },
    {
      "key": "role",
      "title": "The role",
      "questions": [
        { "id": "position", "type": "choice", "prompt": "Which role are you applying for?",
          "required": true,
          "options": [
            { "value": "product_designer", "label": "Product Designer" },
            { "value": "senior_product_designer", "label": "Senior Product Designer" },
            { "value": "design_intern", "label": "Design Intern" }
          ] },
        { "id": "years_experience", "type": "number",
          "prompt": "Years of relevant experience", "required": true,
          "min": 0, "unit": "years" },
        { "id": "authorization", "type": "choice",
          "prompt": "Work authorization and location", "required": true,
          "options": [
            { "value": "us_remote", "label": "Authorized to work in the US, remote" },
            { "value": "us_onsite", "label": "Authorized to work in the US, near our office" },
            { "value": "sponsorship_needed", "label": "Would need visa sponsorship" },
            { "value": "outside_us", "label": "Based outside the US" }
          ] },
        { "id": "key_skills", "type": "multi_choice",
          "prompt": "Which of these do you have hands-on experience with?",
          "min": 1,
          "options": [
            { "value": "figma", "label": "Figma" },
            { "value": "design_systems", "label": "Design systems" },
            { "value": "user_research", "label": "User research" },
            { "value": "html_css", "label": "HTML/CSS" },
            { "value": "prototyping", "label": "Prototyping (motion/interaction)" }
          ] },
        { "id": "why_role", "type": "long_text",
          "prompt": "Why this role, and why us?", "rows": 5, "required": true,
          "examples": [
            "I've used your product for two years and want to fix the onboarding flow I struggled with"
          ] }
      ]
    },
    {
      "key": "consent",
      "title": "Before you submit",
      "questions": [
        { "id": "data_consent", "type": "consent",
          "prompt": "I consent to this application, including my contact details and answers, being stored and reviewed by the hiring team for this role.",
          "required": true }
      ]
    }
  ],
  "outcomes": {
    "method": "points",
    "points": {
      "authorization": { "us_remote": 3, "us_onsite": 3, "sponsorship_needed": 1, "outside_us": 0 },
      "key_skills": { "figma": 1, "design_systems": 2, "user_research": 1, "html_css": 1, "prototyping": 1 }
    },
    "buckets": [
      { "key": "not_a_fit", "max": 2, "title": "Thanks for applying",
        "body": "We'll keep your application on file and reach out if a better-matched role opens up." },
      { "key": "review", "min": 3, "max": 5, "title": "Application received",
        "body": "Your application is in the queue for review — we'll follow up within two weeks either way." },
      { "key": "screen_now", "min": 6, "title": "Thanks — you're a strong match on paper",
        "body": "We'll reach out to schedule a first call within the next few days." }
    ]
  }
}
```

Note on `years_experience`: `outcomes.points` scores option values, which
only exist on choice-shaped questions — a plain `number` field can't be
scored directly. `years_experience` is collected here for display and
manual review, not scoring. If you want years of experience to feed the
score (e.g. 0–1 years = 0 points, 2–4 years = 2, 5+ years = 4), convert it
to a `choice` question with those bands as options and score each option in
`outcomes.points` the same way `authorization` is scored below.

## What each piece is doing

- `resume_file` is a `file_upload` limited to `["pdf", "document"]` with
  `max_files: 1` — resumes only, so you don't get a folder of screenshots.
  Requires Pro or Business; drop this question on the free plan.
- `portfolio_link` is a `url`, deliberately optional. Asking for both a
  file and a link costs the candidate nothing and covers both the "send this
  to the hiring manager" case and the "actually look at their work" case.
- `authorization` as a `choice` (not free text) means you can score it
  and filter responses by it later — much easier than parsing sentences.
- `key_skills` is `multi_choice` with `min: 1`; each selected skill adds
  its own points in `outcomes.points`, so someone who checks three
  relevant skills scores higher than someone who checks one.
- `data_consent` is a required `consent` question — a timestamped record
  that the candidate agreed to have their application stored and reviewed,
  which is worth having regardless of your local privacy-law requirements.
- `outcomes` with `points`/`buckets` is the differentiator here: instead
  of just collecting applications, QuizGen scores each one as it comes in
  and stores `score` and `outcome` on the response, so you can sort your
  dashboard by "screen_now" first instead of reading 200 applications in
  submission order.

## This is a triage aid, not a hiring decision

Say this plainly to whoever's using it: automated scoring should narrow the
queue, not make the call. A few rules worth following:

- Score only job-relevant criteria — years of experience, required
  authorization, named skills. Never score name, address, alma mater, or
  anything that correlates with a protected characteristic.
- Keep a human reviewing every bucket, including "not_a_fit" — automated
  screening is good at surfacing the strong matches faster, bad at being
  the final word on a candidate.
- Check your local rules. Some jurisdictions (New York City's Local Law 144
  is the well-known example) regulate automated employment decision tools
  specifically — know whether yours applies before you rely on scoring for
  more than internal triage.

The same `outcomes` mechanism — points per answer, buckets with a
title/body — is exactly what powers
[lead qualification forms](/blog/lead-qualification-form-that-scores-itself)
and general [quizzes with scoring](/blog/how-to-make-a-quiz-with-scoring); if
you haven't used `outcomes` before, either of those is a good second read.

## Route new applications into Slack or your ATS

Don't make anyone babysit a dashboard. Set a
[webhook](/blog/quiz-response-webhooks) on the quiz and every completed
application POSTs to your endpoint immediately, with the answers, `score`,
and `outcome` bucket included — pipe it into a Slack channel, or into
whatever ATS or spreadsheet already runs your hiring pipeline.

## Let an AI assistant fill it in

Connect [QuizGen's MCP server](/mcp)
and say something like:

> Read https://quizgen.dev/blog/job-application-form-template.md and build
> me an application form for a "Backend Engineer" role — require 3+ years
> of experience, score Python and Postgres skills highest, and require US
> work authorization to land in the screen_now bucket. Give me the link.

## FAQ

**Can candidates actually attach a PDF resume?** Yes, on Pro or Business —
that's the `file_upload` question. On the free plan or in the sandbox it
returns 402 `plan_limit`, so drop the question and rely on the link.

**How big a file can they send?** 10 MB per file on Pro, 25 MB on Business,
against 1 GB and 10 GB of account storage respectively. A resume will never
come close; a reel or a design portfolio might.

**Can I accept a cover letter too?** Raise `max_files` (up to 5) on the
same question, or add a second `file_upload` for cover letters
specifically. Keep `accept` narrow either way.

**Can I require the resume but not phone?** Yes — toggle `required`
per question independently; nothing forces you to require every field.

**Does the scoring reject anyone automatically?** No. `outcomes` only sets
a `score` and `outcome` bucket on the stored response and (optionally) a
different completion message — it never blocks submission or hides an
application from you.

**Can I add more screening questions later?** Yes — `PUT` a revised
definition; existing responses keep the `definition_version` they answered
under, so past applications aren't retroactively rescored.

**What if I don't want scoring at all?** Drop the `outcomes` block
entirely — the rest of the form works fine as a plain application collector.

---

Full schema, question types, and endpoints: [quizgen.dev/llms.txt](/llms.txt).
