Resumes
Classic resume PDF API
A LaTeX resume API template for polished, ATS-friendly one-page resumes generated from JSON. Best for job boards, career tools, and profile export features. Send this LaTeX template and JSON data to Texify in one /render request.
JSON to resume PDF, without browser print bugs.
Use this template when your product stores structured profile data and needs a polished resume export. JSON data plus this LaTeX template becomes a deterministic PDF through /render, with real text, readable spacing, and predictable page breaks.
It is built for developer platforms, portfolio builders, job marketplaces, and AI agents that assemble candidate data into a finished resume PDF.
JSON schema
Fields this template expects.
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Candidate full name. |
| headline | string | Yes | Short professional summary. |
| contact | object | Yes | Email, phone, location, website, and profiles. |
| experience | array | Yes | Roles with company, dates, bullets, and impact metrics. |
| skills | array | Yes | Grouped technical or professional skills. |
API examples
POST LaTeX and JSON. Receive PDF bytes.
cat > resume-classic-payload.json <<'JSON'
{
"entrypoint": "main.tex",
"resources": {
"main.tex": "\\documentclass[10pt]{article}\n\\usepackage[margin=0.65in]{geometry}\n\\usepackage{array}\n\\pagestyle{empty}\n\\begin{document}\n\\begin{center}\n{\\LARGE\\bfseries [[ .name ]]}\\\\\n[[ .headline ]]\\\\[3pt]\n[[ .contact.email ]] \\quad [[ with .contact.phone ]][[ . ]] \\quad[[ end ]] [[ with .contact.location ]][[ . ]] \\quad[[ end ]] [[ with .contact.website ]][[ . ]][[ end ]]\n[[ with .contact.github ]]\\\\[[ . ]][[ end ]][[ with .contact.linkedin ]] \\quad [[ . ]][[ end ]]\n\\end{center}\n\\section*{Experience}\n[[ range .experience ]]\\noindent\\textbf{[[ .role ]]} --- [[ .company ]]\\hfill [[ .dates ]]\\\\\n\\begin{itemize}\n[[ range .bullets ]]\\item [[ . ]]\n[[ end ]]\\end{itemize}\n[[ end ]]\n[[ with .projects ]]\\section*{Projects}\n[[ range . ]]\\noindent\\textbf{[[ .name ]]} --- [[ .description ]]\\\\\n\\textit{[[ range .stack ]][[ . ]] [[ end ]]}\\\\[4pt]\n[[ end ]][[ end ]]\n\\section*{Skills}\n[[ range .skills ]]\\noindent\\textbf{[[ .group ]]}: [[ range .items ]][[ . ]] [[ end ]]\\\\\n[[ end ]]\\end{document}"
},
"data": {
"name": "Taylor Brooks",
"headline": "Product-minded backend engineer",
"contact": {
"email": "taylor@example.com",
"phone": "",
"location": "Toronto",
"website": "taylor.dev",
"github": "",
"linkedin": ""
},
"experience": [
{
"company": "LedgerOps",
"role": "Senior Software Engineer",
"dates": "2023-2026",
"bullets": [
"Cut invoice rendering latency by 48%",
"Led migration to typed document templates"
]
}
],
"projects": null,
"skills": [
{
"group": "Backend",
"items": [
"TypeScript",
"Postgres",
"Queues"
]
}
]
}
}
JSON
curl -sS -X POST https://api.texify.dev/render \
-H "Content-Type: application/json" \
--data @resume-classic-payload.json \
--output resume-classic.pdfimport json
import requests
payload = json.loads(r'''{
"entrypoint": "main.tex",
"resources": {
"main.tex": "\\documentclass[10pt]{article}\n\\usepackage[margin=0.65in]{geometry}\n\\usepackage{array}\n\\pagestyle{empty}\n\\begin{document}\n\\begin{center}\n{\\LARGE\\bfseries [[ .name ]]}\\\\\n[[ .headline ]]\\\\[3pt]\n[[ .contact.email ]] \\quad [[ with .contact.phone ]][[ . ]] \\quad[[ end ]] [[ with .contact.location ]][[ . ]] \\quad[[ end ]] [[ with .contact.website ]][[ . ]][[ end ]]\n[[ with .contact.github ]]\\\\[[ . ]][[ end ]][[ with .contact.linkedin ]] \\quad [[ . ]][[ end ]]\n\\end{center}\n\\section*{Experience}\n[[ range .experience ]]\\noindent\\textbf{[[ .role ]]} --- [[ .company ]]\\hfill [[ .dates ]]\\\\\n\\begin{itemize}\n[[ range .bullets ]]\\item [[ . ]]\n[[ end ]]\\end{itemize}\n[[ end ]]\n[[ with .projects ]]\\section*{Projects}\n[[ range . ]]\\noindent\\textbf{[[ .name ]]} --- [[ .description ]]\\\\\n\\textit{[[ range .stack ]][[ . ]] [[ end ]]}\\\\[4pt]\n[[ end ]][[ end ]]\n\\section*{Skills}\n[[ range .skills ]]\\noindent\\textbf{[[ .group ]]}: [[ range .items ]][[ . ]] [[ end ]]\\\\\n[[ end ]]\\end{document}"
},
"data": {
"name": "Taylor Brooks",
"headline": "Product-minded backend engineer",
"contact": {
"email": "taylor@example.com",
"phone": "",
"location": "Toronto",
"website": "taylor.dev",
"github": "",
"linkedin": ""
},
"experience": [
{
"company": "LedgerOps",
"role": "Senior Software Engineer",
"dates": "2023-2026",
"bullets": [
"Cut invoice rendering latency by 48%",
"Led migration to typed document templates"
]
}
],
"projects": null,
"skills": [
{
"group": "Backend",
"items": [
"TypeScript",
"Postgres",
"Queues"
]
}
]
}
}''')
response = requests.post(
"https://api.texify.dev/render",
json=payload,
timeout=90,
)
response.raise_for_status()
with open("resume-classic.pdf", "wb") as pdf:
pdf.write(response.content)import { writeFile } from "node:fs/promises";
const payload = {
"entrypoint": "main.tex",
"resources": {
"main.tex": "\\documentclass[10pt]{article}\n\\usepackage[margin=0.65in]{geometry}\n\\usepackage{array}\n\\pagestyle{empty}\n\\begin{document}\n\\begin{center}\n{\\LARGE\\bfseries [[ .name ]]}\\\\\n[[ .headline ]]\\\\[3pt]\n[[ .contact.email ]] \\quad [[ with .contact.phone ]][[ . ]] \\quad[[ end ]] [[ with .contact.location ]][[ . ]] \\quad[[ end ]] [[ with .contact.website ]][[ . ]][[ end ]]\n[[ with .contact.github ]]\\\\[[ . ]][[ end ]][[ with .contact.linkedin ]] \\quad [[ . ]][[ end ]]\n\\end{center}\n\\section*{Experience}\n[[ range .experience ]]\\noindent\\textbf{[[ .role ]]} --- [[ .company ]]\\hfill [[ .dates ]]\\\\\n\\begin{itemize}\n[[ range .bullets ]]\\item [[ . ]]\n[[ end ]]\\end{itemize}\n[[ end ]]\n[[ with .projects ]]\\section*{Projects}\n[[ range . ]]\\noindent\\textbf{[[ .name ]]} --- [[ .description ]]\\\\\n\\textit{[[ range .stack ]][[ . ]] [[ end ]]}\\\\[4pt]\n[[ end ]][[ end ]]\n\\section*{Skills}\n[[ range .skills ]]\\noindent\\textbf{[[ .group ]]}: [[ range .items ]][[ . ]] [[ end ]]\\\\\n[[ end ]]\\end{document}"
},
"data": {
"name": "Taylor Brooks",
"headline": "Product-minded backend engineer",
"contact": {
"email": "taylor@example.com",
"phone": "",
"location": "Toronto",
"website": "taylor.dev",
"github": "",
"linkedin": ""
},
"experience": [
{
"company": "LedgerOps",
"role": "Senior Software Engineer",
"dates": "2023-2026",
"bullets": [
"Cut invoice rendering latency by 48%",
"Led migration to typed document templates"
]
}
],
"projects": null,
"skills": [
{
"group": "Backend",
"items": [
"TypeScript",
"Postgres",
"Queues"
]
}
]
}
};
const response = await fetch("https://api.texify.dev/render", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
signal: AbortSignal.timeout(90_000),
});
if (!response.ok) throw new Error(await response.text());
const pdf = Buffer.from(await response.arrayBuffer());
await writeFile("resume-classic.pdf", pdf);The template
LaTeX source sent as resources["main.tex"].
\documentclass[10pt]{article}
\usepackage[margin=0.65in]{geometry}
\usepackage{array}
\pagestyle{empty}
\begin{document}
\begin{center}
{\LARGE\bfseries [[ .name ]]}\\
[[ .headline ]]\\[3pt]
[[ .contact.email ]] \quad [[ with .contact.phone ]][[ . ]] \quad[[ end ]] [[ with .contact.location ]][[ . ]] \quad[[ end ]] [[ with .contact.website ]][[ . ]][[ end ]]
[[ with .contact.github ]]\\[[ . ]][[ end ]][[ with .contact.linkedin ]] \quad [[ . ]][[ end ]]
\end{center}
\section*{Experience}
[[ range .experience ]]\noindent\textbf{[[ .role ]]} --- [[ .company ]]\hfill [[ .dates ]]\\
\begin{itemize}
[[ range .bullets ]]\item [[ . ]]
[[ end ]]\end{itemize}
[[ end ]]
[[ with .projects ]]\section*{Projects}
[[ range . ]]\noindent\textbf{[[ .name ]]} --- [[ .description ]]\\
\textit{[[ range .stack ]][[ . ]] [[ end ]]}\\[4pt]
[[ end ]][[ end ]]
\section*{Skills}
[[ range .skills ]]\noindent\textbf{[[ .group ]]}: [[ range .items ]][[ . ]] [[ end ]]\\
[[ end ]]\end{document}Live render
Try sample data now.
Posts this LaTeX template and sample JSON to /render, then opens the returned PDF bytes.
{
"name": "Taylor Brooks",
"headline": "Product-minded backend engineer",
"contact": {
"email": "taylor@example.com",
"phone": "",
"location": "Toronto",
"website": "taylor.dev",
"github": "",
"linkedin": ""
},
"experience": [
{
"company": "LedgerOps",
"role": "Senior Software Engineer",
"dates": "2023-2026",
"bullets": [
"Cut invoice rendering latency by 48%",
"Led migration to typed document templates"
]
}
],
"projects": null,
"skills": [
{
"group": "Backend",
"items": [
"TypeScript",
"Postgres",
"Queues"
]
}
]
}FAQ
FAQ
Can I use Classic resume as a LaTeX resume API?
Yes. Copy the LaTeX template, send it in resources with your data to /render, and Texify returns PDF bytes.
Can I change colors, copy, or field names?
Yes. Edit the LaTeX source and JSON placeholders to match your data model and brand before posting to /render.
Does this render real PDF text?
Yes. Texify compiles LaTeX to PDF, so text remains selectable, searchable, and stable across environments.
Related templates
More LaTeX PDF templates.
Resumes
Developer resume
Dedicated JSON to resume PDF template for software engineers, with projects, skills, links, and measurable impact bullets. Designed for LaTeX resume API searches and developer tooling workflows.
Letters
Formal letter
Business letter template with sender block, recipient block, subject, body paragraphs, and signature. Good for notices, approvals, and generated correspondence.
Certificates
Course certificate
Elegant completion certificate for online courses, LMS products, and developer education platforms. Designed to print well while keeping verification ids visible.