Job application form template that screens as it collects

Build & score

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

{
  "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 and general quizzes 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 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 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.

$ curl quizgen.dev/blog/job-application-form-template.md

This guide as raw markdown — no HTML for your agent to parse.

View .md

Keep reading