Generate an employment offer letter with Claude
Set up your HR offer-letter template, lock down required fields, and have Claude draft offers from candidate notes — same brand, same boilerplate, every time.
Start from your existing offer-letter template
Open the Word offer letter your HR team uses today — letterhead, salutation, role description, salary, benefits paragraph, signature block. You'll keep all the legal boilerplate and formatting; only the parts that change per candidate become tokens.
- Replace the candidate's name with
{{candidateName}}and the address block with{{candidateAddress}}. - Tokenize the role details:
{{jobTitle}},{{department}},{{startDate | dd MMMM yyyy}},{{workLocation}}. - Tokenize the compensation block:
{{annualSalary}},{{currency}},{{bonusTarget}},{{equityGrant}}. - Leave any optional clauses (signing bonus, relocation package) as inline tokens like
{{signingBonusClause}}— you'll mark them as not-required in step 2 so Claude can omit them when they don't apply. - Save as
employment-offer.docx.
Upload, annotate, and lock down required fields
Sign in at app.docexport.ai, click New template, and upload employment-offer.docx. The placeholder list appears with every token DocExport extracted.
- Mark every legally-material field as Required:
candidateName,jobTitle,startDate,annualSalary,currency,workLocation. If any of these are missing in the JSON,generate_documentwill refuse to render — exactly what you want for an HR document. - For optional clauses (
signingBonusClause,relocationClause), leave Required off and write a description explaining when to include them. Example: "Signing bonus paragraph. Include only when offering a signing bonus; pass empty string otherwise." - Write tight descriptions on every field. For
annualSalary: "Gross annual base salary as a number, no currency symbol or thousands separator. Example: 95000." Forcurrency: "ISO 4217 code. EUR, USD, GBP, CHF." - Set the template description: "Standard full-time employment offer letter. Use for FTE hires only — not for contractors, interns, or internal transfers."
Connect Claude Desktop and limit who can use the key
Open API keys and create a key dedicated to HR use — name it hr-offer-letters so it's easy to revoke later. Copy the plaintext key once.
- Paste the snippet into Claude Desktop's
claude_desktop_config.jsonand restart. - For HR data, prefer running this on a single, controlled laptop rather than sharing the key across the team. If multiple people need it, mint one key per person — that way you can revoke individually if someone leaves.
{
"mcpServers": {
"docexport": {
"command": "npx",
"args": [
"mcp-remote",
"https://app.docexport.ai/mcp",
"--header",
"Authorization: Bearer dxp_<prefix>_<secret>"
]
}
}
} generate_document call writes an audit log entry tied to the API key that made the call. Per-person keys make the audit trail meaningful. Decide where Claude gets the candidate and offer details from
Same principle as the sales walkthrough: DocExport renders, Claude assembles. For HR, the data usually lives in one of three places:
- Your ATS (Greenhouse, Lever, Ashby) — if there's an MCP server for it, connect that alongside DocExport. Claude pulls the candidate record, the role, and the agreed comp; DocExport renders.
- A hiring-manager email or Slack thread — paste the thread into Claude. "Here's what we agreed with Sasha. Draft the offer." Claude extracts the structured fields itself.
- Just type it in the prompt — for the first run while you're testing the template, this is the fastest path.
Preview, review, then generate
Start with a preview so you can see Claude's interpretation before anything is rendered:
- Claude calls
list_templates, picks the offer template, callsget_template_schema, builds the JSON, and callspreview_generate. - Read the preview output carefully. Look at
missingFields,unresolvedFields, andnormalizedPreviewText— does the salary number look right? Did the optional signing-bonus clause get correctly omitted? - If anything's off, correct Claude in the chat — "the bonus target should be percentage of base, not a flat number" — and ask for another preview. Iterate until it's clean.
- Then: "Generate the final PDF and the .docx so I can route it through DocuSign." Claude calls
generate_documenttwice (once per format). Each call returns a 15-minute signed download URL.
Draft an offer letter for Sasha Müller using our standard FTE template.
Role: Senior Software Engineer, Engineering team, starting 1 June 2026.
Comp: €95,000 base, 10% bonus target, 1,500 RSUs vesting 4 years.
Working location: Berlin office, hybrid. No signing bonus.
Use today's date as the offer date. Run a preview first. Operationalize it
Once one offer works end-to-end, lock the workflow in so other people can use it consistently.
- Save a Claude Project (or a custom prompt template) with a system prompt like: "You generate employment offers for <Company>. Always preview first, always confirm comp numbers with me before generating, always output both PDF and DOCX."
- Document the data sources you settled on (ATS MCP? Slack paste?) in your team's HR runbook so the next person doesn't reinvent it.
- Watch the Documents page for a few weeks. If you see Claude consistently struggling with a particular field, that's a signal to improve its placeholder description, not to add a workaround.
Troubleshooting
currency placeholder description probably says "EUR or USD" — too vague. Tighten it to: "ISO 4217 currency code, three letters, uppercase. Pick from EUR, USD, GBP, CHF based on the candidate's working country: Germany/EU → EUR, US → USD, UK → GBP, Switzerland → CHF." Re-run the preview.Still stuck?
Email [email protected] with your template and the prompt you're trying to run — we usually reply same day.