Job Application Forms in Laravel: Resumes, Cover Letters, and ATS-Friendly Exports | FilaForms                                 [ ![Filaforms Logo](https://filaforms.app/logo.svg)FilaForms

 ](https://filaforms.app)  [ Features ](https://filaforms.app#features) [ Pricing ](https://filaforms.app#pricing) [ Blog ](https://filaforms.app/blog) [ Documentation ](https://docs.filaforms.app)  [ Try Demo ](https://filaforms.app/login) [ Get Started ](https://filaforms.app#pricing)

 [ Features ](https://filaforms.app#features) [ Pricing ](https://filaforms.app#pricing) [ Blog ](https://filaforms.app/blog) [ Documentation ](https://docs.filaforms.app) [ Try Demo ](https://filaforms.app/login) [ Get Started ](https://filaforms.app#pricing)

   ![FilaForms](https://filaforms.app/logo.svg) FilaForms

 Use CasesJob Application Forms in Laravel: Resumes, Cover Letters, and ATS-Friendly Exports
==================================================================================

 filaforms.app/blog

  [    Back to blog ](https://filaforms.app/blog) [ Use Cases ](https://filaforms.app/blog/category/use-cases)

Job Application Forms in Laravel: Resumes, Cover Letters, and ATS-Friendly Exports
==================================================================================

 Manuk Minasyan ·  June 23, 2026  · 7 min read

 Greenhouse doesn't publish a public price list, but every third-party teardown I've read puts a small-company contract in the low five figures a year once seats and add-ons are stacked. Lever and Workable land in similar territory. For a 30-person company hiring four roles a year, that's thousands per hire for software the hiring manager opens twice a month and uses for one thing: reading the resumes a careers page collected.

I've watched this exact subscription get renewed three years in a row at a company that never used the interview-scheduling, never used the offer-letter workflow, never used the analytics dashboard. What they used was the inbox. A job application form in Laravel, a private S3 disk for the resumes, a CSV export the hiring manager could open in Numbers, and a signature field for the offer letter would have replaced 80% of it.

This post is that form. Seven fields, real validation on the resume upload, an honest read on the optional fields most ATS pages get wrong, and a CSV-first export with Airtable as the upgrade path when CSV stops being enough. Where self-hosting stops making sense is past 50 hires a year — at that volume you want a real ATS with interview scheduling, scorecards, and the integrations Greenhouse charges for. Below that, you're paying for capacity you don't use.

The smallest viable job application form
----------------------------------------

The smallest viable job application form has seven fields. Anything beyond this is a tax on the candidate before you've earned the right to ask. The point of the form is to get a qualified resume into your inbox; everything else — references, work samples, the deeper screen — happens after a human has decided this is a person worth talking to.

1. **Name.** First and last, one line. Don't split them into two fields; some candidates don't have a single first/last shape.
2. **Email.** The reply channel. One field, validated, required.
3. **Role.** A dropdown of the roles you're hiring for, pre-selected based on the page they came from.
4. **Resume upload.** PDF, capped at a sensible size. See the next section.
5. **Cover letter.** Optional, textarea. Most strong candidates skip it; most weak ones write three paragraphs. Useful signal either way.
6. **Work authorization.** "Are you legally authorized to work in \[country\]?" — yes/no. Required if you can't sponsor.
7. **Portfolio link.** Optional, URL field. Engineering, design, writing roles need this; ops and sales rarely do.

That's the floor. No phone number on the form. No demographic questions on the form. We'll get to both.

Resume uploads done right
-------------------------

A resume upload is the highest-risk field on the form, because a PDF from a stranger is an executable in a thin disguise. FilaForms ships a FileUpload field with mime-type validation, a size cap, and a required-flag — the four rules available are `FILE`, `MIMES`, `MAX`, and `REQUIRED`, verified in the field definition. The pattern I land on every time looks like this:

```
FileUpload::make('resume')
    ->label('Resume')
    ->required()
    ->rules(['mimes:pdf', 'max:5120']) // 5 MB cap
    ->disk('s3-private')
    ->visibility('private');

```

Three things make this safe enough to ship. First, the mime-type constraint catches the obvious "I renamed my exe to .pdf" attack — Laravel reads the file's actual mime type, not the extension. Second, a 5 MB cap is generous for a resume and tight enough to stop a candidate from uploading a video. Third, the private disk means the file isn't world-readable; it lives behind a signed temporary URL that the FileStorage helper generates for the hiring manager's table view in Filament.

FilaForms doesn't ship a built-in virus scanner on resume uploads. You get mime-type validation and a size cap, which catches most accidents. For a real scan, route the file through ClamAV or a hosted scanner before you let a hiring manager click it — a queued job on the `FormSubmitted` event is the place to put it.

The optional fields most ATS pages get wrong
--------------------------------------------

Three fields show up on most careers pages that shouldn't, or shouldn't in the way they do.

**Phone number.** Most hiring conversations start over email. The phone number you collect at application time gets used once — for the recruiter screen — and stored forever. Skip it on the form; ask for it when you schedule the call. Less data to lose, one fewer field on the way to submit.

**Demographic questions.** Race, gender, veteran status, disability status. These belong in a separate, voluntary, decoupled survey — not on the application form. Mixing them in signals the wrong thing to the candidate, and depending on where you hire, it creates legal exposure you don't want. The pattern that works: a post-submit redirect to a second form, opt-in, with a clear "this is not used in hiring decisions" notice.

**Salary expectations.** Salary history is illegal to ask for in California, New York, Colorado, and a growing list of others. Salary expectations sit in a grayer zone but read as bad faith — you're either ready to pay the market rate or you're not. Post the range on the job page, skip the field, and have the conversation in the screen.

Each of these is a small thing that signals a larger one. A short, honest form converts better than a long, defensive one.

ATS-friendly exports
--------------------

The hiring manager doesn't want to log into your admin panel. They want a spreadsheet, in a folder, on their laptop. FilaForms' built-in CSV export on the submissions table covers the first six months of hiring at most companies — filter by role, click export, drop the file in Slack. The hiring manager opens it in Numbers, scribbles on it, ships it back.

When CSV stops being enough — usually when more than one person is touching the pipeline, or when you want comments on each candidate — the next step up isn't Greenhouse. It's a shared base in Airtable. The pattern is to pipe every submission into a single base, one row per candidate, attachments on the row, status column you move as the candidate progresses. The forward link below walks through the two-way sync. For pipelines that need more than Airtable can carry — pushing to an existing HRIS, syncing back to Slack, fanning out to a recruiter's tool — [the webhooks delivery layer](/blog/webhooks-in-filaforms-send-submissions-anywhere) is where you wire that fan-out. If you'd rather keep candidates in Airtable as your single source of truth, [pipe submissions into Airtable as a lightweight pipeline](/blog/airtable-for-form-submissions-two-way-sync-laravel) covers the schema and the sync direction.

The line where self-hosting stops making sense is when you have a dedicated recruiter who lives in their tool all day. Below that, CSV and Airtable cover the work.

Offer letters and NDAs
----------------------

Once a candidate is in the late stage — verbal offer accepted, paperwork pending — you need a signature on something. The offer letter, the NDA, sometimes both. The default move is DocuSign, which is fine and which costs another subscription. The cheaper move, if you've already built the application form in FilaForms, is to use [FilaForms' signature field](/blog/signature-fields-in-laravel-forms) on a second form: paste the offer letter copy in, drop a signature field at the bottom, send the candidate the link.

The signature field captures a PNG of the candidate's drawn signature, stores it on the same private disk as the resume, and emits the same `FormSubmitted` event you can listen to for the "send the countersigned copy to HR" step. It's not a replacement for DocuSign at a regulated company — there's no full audit trail, no built-in tamper-evident PDF — but for an offer letter at a 30-person company, it's enough.

That's the careers form
-----------------------

Seven fields on the application, a private disk for the resume, a CSV export for the hiring manager, Airtable when you outgrow CSV, and a signature field for the offer letter. Nothing exotic. Most of it is wiring you already have.

If you haven't set up FilaForms yet, you can [grab FilaForms here](https://filaforms.app). For the lightweight pipeline upgrade, [pipe submissions into Airtable as a lightweight pipeline](/blog/airtable-for-form-submissions-two-way-sync-laravel) is the next read. For the offer-letter step, [FilaForms' signature field](/blog/signature-fields-in-laravel-forms) covers what's there and what isn't.

[Vendr's Greenhouse pricing teardown](https://www.vendr.com/marketplace/greenhouse) is the source for the cost framing at the top of this post.

 Related posts
-------------

 [  Use Cases   Jun 12, 2026

 Event Registration Forms in Laravel: From RSVP to Stripe Checkout
-------------------------------------------------------------------

Eventbrite takes $253 on a $20 workshop with 100 seats. Here's a Laravel registration form that handles RSVP, payment, capacity, and confirmations instead.

 ](https://filaforms.app/blog/event-registration-forms-in-laravel-rsvp-to-stripe) [  Use Cases   May 29, 2026

 Lead Generation Forms in Laravel: A Template That Actually Converts
---------------------------------------------------------------------

Most lead gen forms ask for too much, too soon. Here's a template — and the reasoning behind every field — that converts without scaring people off.

 ](https://filaforms.app/blog/lead-generation-forms-in-laravel-a-template-that-converts) [  Use Cases   Apr 23, 2026

 How to Build a Customer Feedback Survey in Laravel
----------------------------------------------------

Most customer feedback surveys are bad. They ask too many questions, they don't adapt, and they dump you on a generic thank-you page. Here's a 3-step NPS-style survey that actually works — built in FilaForms.

 ](https://filaforms.app/blog/how-to-build-a-customer-feedback-survey-in-laravel)

    ![FilaForms Logo](/logo.svg) FilaForms

 Laravel form infrastructure for Filament. Stop rebuilding forms on every project.

 ### Product

 [ Features ](https://filaforms.app#features) [ Documentation ](https://docs.filaforms.app) [ Blog ](https://filaforms.app/blog) [ Pricing ](https://filaforms.app#pricing) [ Contact ](mailto:hello@filaforms.app)

 ### Legal

 [ Terms of Service ](https://filaforms.app/terms-of-service) [ Privacy Policy ](https://filaforms.app/privacy-policy)

  © 2025-2026 FilaForms. All rights reserved.

 [    ](mailto:hello@filaforms.app) [    ](https://x.com/MinasyanManuk)
