Your resume is data pretending to be a document. A name, a job title, a list of jobs with dates, a list of skills. PDF locks that data inside a layout meant for a printer. JSON sets it free as fields a machine can read on the first try. Publishing your resume as JSON means putting that structured file at a web address you control, so one link does double duty: humans see a clean page, machines get clean data.

The format we'll use is cv.json, the open CV standard from FreeCV. It's MIT-licensed, the spec lives at github.com/freecvorg/cv-json, and the current version is 1.2. One file. One stable URL. No login wall between a recruiter's tooling and your actual career history.

A cv.json is a single open JSON file at a permanent URL that serves your career data to people, applicant tracking systems, and AI recruiters from the same address.

What "publishing as JSON" actually gives you

Think about what a recruiter's stack does with a PDF. It runs the file through a parser, guesses where your job titles end and your dates begin, and rebuilds a structured record from pixels and text runs. That guess-and-rebuild step is exactly where things break. Tables, text boxes, multi-column layouts, and graphics raise the risk of misread or lost structure during parsing. Publishing as JSON skips the guessing entirely. The structure is already there.

One address, two audiences

A published cv.json lives at something like livelink.cv/ashley/cv.json. Open it in a browser and you get raw JSON. Point a tool at it and you get the same fields, parsed in milliseconds, no OCR, no layout heuristics. The human-readable portfolio page and the machine-readable file share one canonical link. You hand out a single URL and stop maintaining four versions of the same career.

Built for where hiring is going

By 2025 and 2026, AI in recruiting stopped being experimental. A 2026 Lever article frames AI and automation as table stakes in modern ATS evaluation: candidate matching, ranking, interview summarization, predictive analytics. Bullhorn, citing the 2026 GRID Industry Trends Report, reports that 78% of staffing firms growing revenue by more than 25% have AI tools embedded in their ATS. That's a fast-growing-staffing-firm figure, not an everyone figure, but the direction is clear. These systems all want structured input. A JSON file is structured input by definition.

cv.json is designed for AI recruiters and ATS to read. To be precise about it: no major ATS vendor has announced native cv.json ingestion, so this is about where hiring is heading, not a box that's already checked. The bet is that machine-readable beats machine-guessable, and the trend line on AI screening backs that bet.

The fast path: build and host with FreeCV

If you want a published JSON resume in the next ten minutes, don't write the file by hand. Use the builder. It handles the schema, the hosting, the discovery tags, and the contact-privacy defaults so you don't have to think about any of them.

Step by step

  1. Go to https://freecv.org/builder and start a CV. Free, no payment, and you don't need an account to begin editing.
  2. Fill in the basics: name, job title, location, a short summary. Add your work history, education, skills, and anything else that fits.
  3. Pick a portfolio template and publish. You'll get a public page at a slug you choose, for example livelink.cv/ashley.
  4. Add /cv.json to that slug. Your machine-readable file is live at livelink.cv/ashley/cv.json. That's the link you give to tools and agents.
  5. Share the page link with people, share the same root with machines. The discovery tags (covered below) get wired up for you automatically.

That last point matters more than it sounds. The hard parts of publishing JSON correctly are the parts you can't see: the link rel="alternate" tag in the page head, the /.well-known/cv.json manifest, the X-CV-Version header, and open CORS so a browser-based tool can actually fetch your file. FreeCV sets all of those. Skip the next section unless you genuinely want to run your own server.

If you just want a live JSON resume, build it at freecv.org/builder and you're done in minutes. The DIY path below is for people who want to host the file themselves.

The DIY path: self-host your own cv.json

Maybe you already have a personal site. Maybe you want the file on your own domain for reasons of pride or control. Both are fine. The cv.json spec is open, MIT-licensed, and deliberately simple to serve. Here's what a minimal valid file looks like.

{
  "meta": {
    "version": "1.2",
    "canonical": "https://ashley.dev/cv.json"
  },
  "basics": {
    "name": "Ashley Carter",
    "label": "Senior Backend Engineer",
    "location": { "city": "Berlin", "countryCode": "DE" },
    "summary": "Backend engineer focused on payments infrastructure."
  }
}

That's it. Only basics and meta are required. Everything else is optional and additive. You can publish that two-block file today and fill in the rest over time.

The fuller shape

A real cv.json grows the obvious sections: work, education, skills, projects, languages, certificates. It also carries two things a PDF never could. An availability block tells systems whether you're open to work, which roles, what work type, and your visa situation. And the meta block stamps a version and a canonical URL so tools know which file is the real one. Here's a more complete worked example.

{
  "meta": {
    "version": "1.2",
    "canonical": "https://ashley.dev/cv.json"
  },
  "basics": {
    "name": "Ashley Carter",
    "label": "Senior Backend Engineer",
    "location": { "city": "Berlin", "countryCode": "DE" },
    "summary": "Payments infrastructure, 8 years, mostly Go and Postgres."
  },
  "work": [
    {
      "name": "Stripe-like Co",
      "position": "Senior Backend Engineer",
      "startDate": "2021-03",
      "endDate": "",
      "highlights": [
        "Cut settlement latency from 9s to under 600ms",
        "Owned the idempotency layer across 40 services"
      ]
    }
  ],
  "skills": [
    { "name": "Go", "level": "Expert" },
    { "name": "PostgreSQL", "level": "Advanced" }
  ],
  "availability": {
    "openToWork": true,
    "roles": ["Backend Engineer", "Staff Engineer"],
    "workType": ["remote", "hybrid"],
    "visa": "EU work authorization"
  }
}

Date and field conventions that keep parsers happy

Two small habits save you grief later. First, write dates as ISO 8601 strings: 2021-03 for a month, 2021-03-15 for a day, a full 2021 if that's all you know. Consistent date formatting is the single thing parsers stumble over most in free-text resumes, and JSON lets you sidestep the ambiguity entirely. Second, mark a current role with an empty endDate rather than the word "Present" buried in a string. An empty string is unambiguous to a machine. The word "Present" is a parsing guess waiting to go wrong.

Keep highlights as separate array items, one achievement per line, instead of cramming three accomplishments into a single sentence. A ranking model that scores bullet relevance treats each array element as its own unit. Three short, specific highlights read better to both a recruiter and a model than one run-on paragraph. And put numbers where you have them. "Cut settlement latency from 9s to under 600ms" is a fact. "Improved performance significantly" is filler that no parser can score.

Serving it correctly

Hosting the file is the easy half. Serving it so machines can find and trust it is the half people skip. Four things to get right:

  • Content type. Serve the file with Content-Type: application/json. A file served as text/html confuses parsers that check headers before reading bodies.
  • Open CORS. Add Access-Control-Allow-Origin: * so a browser-based tool on another domain can fetch your file. Without it, client-side fetches fail silently and the recruiter's widget shows nothing.
  • Version header. Send X-CV-Version: 1.2 so a consumer can check the spec version without parsing the body first.
  • A stable path. Keep the file at a URL you won't change. The whole value of publishing is the permanence of the address. A link that 404s in six months is worse than no link.

And don't host it behind Cloudflare's bot-fight mode or a login. The point of a public cv.json is that a recruiter's agent can fetch it without solving a CAPTCHA. If your file needs a human to click through, it isn't published, it's just stored.

Validate before you ship

JSON is unforgiving about syntax. A trailing comma after the last array item, a missing closing brace, a smart quote that snuck in from a word processor: any of these makes the whole file unparseable, and a strict consumer will reject the lot rather than read around the error. Run your file through a JSON validator before you publish, and if you want stronger guarantees, check it against the cv.json schema published in the spec repo. The FreeCV builder validates on every save, which is one more reason the fast path exists. Self-hosting, a thirty-second paste into any JSON linter catches the trailing-comma class of mistakes that would otherwise silently break every machine that fetches your file.

Make your JSON discoverable

A file at a URL nobody knows about is a tree falling in an empty forest. Discovery is how a tool that lands on your homepage figures out that a structured resume exists. cv.json defines three discovery mechanisms, and you want all three.

The link tag

Put this in the <head> of your HTML portfolio or homepage:

<link rel="alternate"
      type="application/json"
      href="https://ashley.dev/cv.json"
      title="cv.json">

This is the same pattern RSS feeds used for years. A crawler reading your page sees the alternate representation and knows where the structured version lives. It's the lowest-effort, highest-compatibility discovery signal you can add, and it's one line.

The well-known manifest

The /.well-known/ convention is an IETF standard path that lots of protocols use, from SSL certificate validation to security.txt. cv.json borrows it. Host a small manifest at https://ashley.dev/.well-known/cv.json pointing at your canonical file:

{
  "version": "1.2",
  "cv": "https://ashley.dev/cv.json"
}

Now an agent that knows the convention can find your resume from your bare domain alone. It doesn't need to scrape a page. It checks a predictable path. That predictability is the whole point of well-known URIs.

The version header

Discovery isn't only about location, it's about knowing what you found before you commit to parsing it. The X-CV-Version response header lets a consumer do a cheap HEAD request, read the version, and decide whether it speaks that dialect. Combined with the meta.version field inside the file, you get version clarity from both the envelope and the contents.

Help search engines too

The three cv.json signals target tools that already know to look for them. Search engines and general crawlers are a separate audience, and they reward a bit of extra plumbing. Add a schema.org Person or ProfilePage JSON-LD block to your portfolio page so Google can read your name, job title, and links as structured data. That's a different job from cv.json: schema.org is structured-data markup for discoverability and parsing assistance, not a canonical applicant-data format you'd hand a recruiter. The two complement each other. cv.json carries the full career record for tools that fetch it. The schema.org markup helps a search index understand the page wrapped around it. Listing your cv.json URL in your sitemap doesn't hurt either, since it gives crawlers an explicit path to the structured file.

Privacy: what gets published and what doesn't

The first worry everyone has is reasonable. If I put my resume at a public URL, is my phone number now crawlable by every scraper on earth? With cv.json, no. Contact details are hidden by default.

The default is private contact

By design, a published cv.json does not expose your raw email and phone to the open file. The structure, your work history, skills, and availability is public, because that's the part that helps you get found. The direct-contact channel is gated. A recruiter reaches you through the portfolio's contact flow rather than copying your number off a JSON blob. So the data that markets you is open, and the data that spammers want is not.

This is a deliberate split. A scraper harvesting email addresses gets nothing useful from your file. A legitimate recruiter who wants to talk uses the contact path on your page. You publish the resume, not your inbox.

You stay in control

Because it's your file at your URL, or your slug on FreeCV, you decide what's in it. Don't want your exact city? Use a region. Don't want a section? Leave it out, since only basics and meta are required. Publishing as JSON gives you more granular control over what's visible than a PDF ever did, because in a PDF everything on the page is exposed the moment you send it.

What to keep out of the file entirely

Privacy by default handles contact details, but the rest is your judgment. A few things have no business in a public career file regardless of format. Date of birth, marital status, a national ID or social security number, a photo if you're hiring into a region where photos invite bias: none of these help a machine rank you and all of them widen your exposure. The cv.json schema doesn't force any of them on you, so the safe default is to omit. If a specific employer or country genuinely requires a detail, add it to the PDF you submit to that one application rather than baking it into the file the whole internet can fetch. Public file gets the marketing data. Targeted submission gets the sensitive extras, and only when asked.

Keep it current and share one link

Here's the quiet superpower of a published JSON resume. You update the file, and every place that link lives is now current. No re-attaching a PDF to forty applications. No "v3-final-FINAL-2.pdf" in your downloads folder. One canonical source.

The update loop

  1. Edit the file. On FreeCV, you edit in the builder and republish. Self-hosting, you change the JSON and redeploy.
  2. Bump nothing else. The URL stays identical, so every link you've ever shared now resolves to the new content.
  3. The discovery tags still point where they pointed. No maintenance there.
  4. Recruiters and agents that re-fetch your file get the latest version automatically.

That's the difference between sending a copy and sharing a source. A PDF is a photograph of your career on the day you exported it. A cv.json is a live address that always shows the current state.

Use it as the spine, not the only artifact

You'll still need a PDF sometimes. Some application forms demand an upload, and a hiring manager often wants something to print or skim on a phone in a meeting. The smart pattern is to treat cv.json as the source of truth and generate the PDF from it when a form insists. FreeCV does exactly this: same data, one structured master, multiple outputs. You maintain the JSON, the document falls out of it.

Keep the JSON as your single source of truth. Generate a PDF from it when a form demands an upload, never the other way around.

A pre-publish checklist

Before you hand anyone the link, run down this list. It's the difference between a file that works for every consumer and one that quietly fails for half of them.

  • Valid JSON. No trailing commas, no smart quotes, no missing braces. Pass it through a linter.
  • Required blocks present. meta with a version, and basics with at least a name and label.
  • Canonical URL set. The meta.canonical field points at the exact public URL the file lives at, so consumers know which copy is authoritative.
  • ISO dates everywhere. YYYY-MM or YYYY-MM-DD, empty endDate for current roles.
  • Correct content type. The server returns application/json, not text/html.
  • CORS open. Access-Control-Allow-Origin: * so browser-based tools can fetch it.
  • Discovery wired. The link rel="alternate" tag, the /.well-known/cv.json manifest, and the X-CV-Version header all in place.
  • No login or bot wall. An anonymous fetch returns the file, not a CAPTCHA or a redirect.
  • No sensitive fields. No date of birth, no ID numbers, raw contact details gated by default.
  • Stable path. You're confident the URL won't move. If you ever migrate, set a redirect rather than letting the old link 404.

Common mistakes that break a published JSON resume

Most failures aren't dramatic. They're small, silent, and easy to avoid once you've seen them named.

Serving the wrong content type

A lot of static hosts serve unknown extensions as text/html by default. Your cv.json looks fine in a browser because the browser renders text either way, but a strict consumer that branches on the response header sees HTML and walks away. Check the actual Content-Type your host returns, don't assume.

Letting the URL drift

You move from a free subdomain to a custom domain, or you reorganize your site, and the old cv.json URL 404s. Every link you ever shared now points at nothing. Permanence is the entire value proposition. If you must move the file, leave a redirect at the old address so existing links keep resolving, and update the meta.canonical field to the new home.

Treating the PDF as the master

The tempting shortcut is to keep editing your old PDF and export a JSON copy now and then. That inverts the right relationship. The PDF is a snapshot rendered for a printer, and rebuilding clean structure from it is the exact problem JSON was meant to retire. Edit the JSON, generate the PDF from it. One direction only.

Burying achievements in prose

JSON gives you arrays for a reason. A wall of text in a single summary string with everything jammed together throws away the structure that makes the file worth publishing. Break work into entries, achievements into highlights, skills into named items with levels. The structure is the point.

Where this fits with other formats

cv.json didn't appear in a vacuum. There's prior art, and it's worth knowing where each piece sits, because the honest summary is that no single open resume-data standard is in broad ATS use today. The market is fragmented and system-specific. That's the gap cv.json is built for.

JSON Resume

JSON Resume, at jsonresume.org, is the community-driven open schema that proved the idea: a resume as a structured JSON object with basics, work, education, and friends. cv.json is field-compatible with JSON Resume, so if you already maintain one, migration is mostly a matter of adding the meta block and the cv.json-specific availability fields. Real-world employer adoption of JSON Resume is limited and not well measured, but as a foundation and a developer-friendly format, it earned its place. cv.json builds on it and adds the publishing layer: discovery, versioning, contact privacy, the open-to-work signals.

The institutional standards

Then there's the heavier machinery. Europass is the European Commission's supported CV and profile format, useful inside EU contexts but not a dominant global ATS interchange standard. HR-Open Standards LER-RS is best described as an emerging or specialized interoperability standard, aimed at learning-and-employment records rather than mass-market resumes. HR-XML mattered historically for HR system interoperability, but current public evidence doesn't support calling it a mainstream resume format today. And schema.org is genuinely useful, just for a narrower job: structured-data markup that helps discoverability and parsing, not a canonical applicant-data format you'd hand a recruiter.

JSON versus PDF, plainly

A PDF is for human eyes and printers. It carries layout, fonts, and exact positioning, and it loses structure the moment a machine tries to read it back into fields. JSON is the inverse: no layout, perfect structure, trivially machine-readable. Given that ATS usage is mainstream in enterprise hiring, with publicly cited industry summaries reporting that nearly 99% of Fortune 500 companies use ATS platforms, those figures being directional secondary-source estimates rather than audited census data, the safe move is to have both. The PDF for the human in the room. The JSON for everything automated that touches your application before a human ever does.

A note on what the screening software actually does

It helps to be precise about the failure you're avoiding. The popular line that "75% of resumes are rejected by ATS" isn't supported by solid evidence, and in one 2025 recruiter sample, 92% of ATS users said their system does not auto-reject based on resume content. What these systems mostly do is parse, then rank, sort, and filter, with employer-set knockout questions doing a lot of the early screening. So the real risk of a badly parsed resume isn't a hard rejection email. It's quieter: your skills land in the wrong field, your latest role reads as your oldest, your ranking score comes out lower than it should, and you never find out why. Publishing structured data removes that parse-then-guess step, which is where the silent damage happens. That's the honest case for JSON, no scare statistic required.

You don't have to choose a side in some format war. You just need a structured source the machines can read and a printable artifact the people can hold. Publishing as cv.json gives you the first and lets you generate the second. Build yours free at freecv.org/builder, claim a slug, and in a few minutes you'll have one link that serves your career to a recruiter, a parser, and an AI agent without breaking a sweat between them.