Skip to content

Part 1 of 7 · Offer letter generator series ~6 min read

An offer letter generator on AWS for a few dollars a month

The gap between agreeing an offer and sending the letter is where small businesses lose candidates. Not because the letter is hard, but because it needs somebody with the template, the right numbers and half an hour, and those three things rarely coincide on the day the conversation happened. Four days later the candidate has had another offer in writing. This post walks through a small system that closes that gap to about ten minutes without letting anything improvise a contract.

a man in a green coverall climbing a yellow ladder
Photo by Marianna Krzakiewicz on Unsplash

Key takeaways

  • The wording is always your approved template. Nothing generates contractual language.
  • The terms come from a short form, or from a note that a model turns into form fields.
  • A term with no matching template clause stops the draft and asks for one.
  • The output is a draft plus a diff against the standard template, so review is quick.
  • Designed on AWS for about $2 a month.

The whole system on one page

Before any code, here is the shape of what we are designing.

System: agreed terms in, an approved-template draft outThree boxes across the top sit outside the AWS account. On the left, Agreed terms: arriving as a short form or as a free-text note. In the middle, Your templates: the approved clauses your business uses. On the right, Hiring manager: the person who reads the draft and sends it. Each connects by an arrow to the AWS account container below. What was agreed flows down into the account. The templates feed in the wording. A draft to review goes back out. Inside the AWS account are three components in a row. On the left, the Terms reader, which turns a note into fields or takes them straight from a form. In the middle, the Clause matcher, which maps every term to an approved clause. On the right, the Drafter, which produces the letter plus a diff against the standard template. A note at the bottom says no clause is ever written by the system, and unmatched terms stop the draft.AWS ACCOUNTAgreed termsa form, or a noteYour templatesapproved clausesHiring managerreads, then sendsTerms readera note into fields,or straight from a formClause matcherevery term to anapproved clauseDrafterthe letter, plus a diffagainst standardwhat was agreedthe wordinga draft to reviewNo clause is ever written by the system. Unmatched terms stop the draft.
Fig 1. Three things outside the account, three pieces inside it. The clause matcher is the safety mechanism: every term in the letter has to map to wording somebody approved.
  • Machine learning
  • Analytics
  • Front-end & mobile
  • People

What you set up once (the outside)

  • Your templates. The offer letter you already use, broken into clauses, with the variable bits marked. Most businesses have two or three variants — salaried, hourly, fixed term — and doing this once is a morning’s work with whoever approved the original wording.
  • A clause library. The optional bits: probation lengths, notice periods, car allowances, bonus structures, relocation. Each one is approved wording with variables. The library is what determines which offers the system can produce without stopping.
  • A terms form. Eight or nine fields: name, role, start date, salary or rate, hours, probation, notice, and anything else. Covered in Part 2, along with the note lane for people who would rather forward the email where it was agreed.

What runs on every offer (the inside)

  • The terms reader. If a form was filled in, this does nothing. If somebody forwarded “agreed with Kwame: 38k, starts 28th, 3 month probation, standard notice”, the reader turns that into fields and shows them for confirmation. It is the only place a model appears, and its output is checked by a person before anything is drafted.
  • The clause matcher. Takes each term and finds the approved clause that expresses it. A three-month probation matches the probation clause with a variable filled. A four-day week matches the part-time hours clause. A term with no match does not get improvised wording — it stops the draft and says which term needs a clause.
  • The drafter. Assembles the letter and produces two things: the document, and a diff against the standard template showing exactly which clauses differ and how. The diff is what makes review take two minutes rather than fifteen, because the reviewer reads the differences rather than the whole letter.

One offer, end to end

One offer from agreement to sent letter, in five stagesA horizontal row of five boxes joined by arrows. Agreed: in a conversation. Captured: by form or note. Matched: every term to an approved clause. Drafted: the letter plus a diff. Sent: by a person. A note says about ten minutes, of which nine are somebody reading the diff.ONE OFFER, END TO ENDAgreedin a conversationCapturedform or noteMatchedevery term to a clauseDraftedletter plus diffSentby a personAbout ten minutes, of which nine are somebody reading the diff.
Fig 2. The same system as one line. The time saved is not in the drafting; it is in never having to find the template, the last similar letter, or the right numbers.
  • Analytics
  • Front-end & mobile
  • People

In plain words

A hiring manager finishes a call at 11:40 having agreed an offer. They open the form on their phone: name, role, £38,000, starts the 28th, three-month probation, one-month notice, standard everything else. The clause matcher finds an approved clause for every one of those. The drafter assembles the letter from the salaried template and produces a diff showing two differences from standard: the probation is three months rather than six, and the start date is inside the usual notice window.

At 11:52 whoever approves offers gets a message with the draft and those two lines. They read two differences rather than a four-page letter, agree with both, and send it. The candidate has a written offer before lunch on the day they agreed it, which is the single most effective thing a small business can do to stop losing people to larger employers with faster HR functions.

Design rules that shaped every decision

  • The system never writes contractual wording. Every sentence in the letter came from a template somebody approved.
  • An unmatched term stops the draft. Improvising a clause is the one failure that could cost real money.
  • Show a diff, not a document. Reviewing two differences is quick; reviewing four pages is not, and the second one does not actually happen.
  • The model reads, it does not write. Its only job is turning a note into fields somebody then confirms.
  • Nothing is sent by the system. A draft is ready; a person sends it.
  • Every sent offer keeps the exact document and the clause versions it used, because contract wording changes and letters get read back years later.

Why this shape

The temptation with document generation and a capable model is to let it write the letter. It would do a plausible job, and plausible is exactly the wrong standard for a document that forms part of an employment contract. A clause that reads well and differs subtly from the one your solicitor approved is a liability that will not be noticed until it matters.

So the design confines generation entirely to assembly, and puts the model somewhere genuinely useful and completely safe: reading a hurried note into structured fields that a human confirms before anything is produced. The letter itself is your wording, every time, with variables filled in.

The next four posts walk through each piece: how the terms get captured, how clauses get matched, what happens to an unusual term, and what a sent offer leaves behind. One diagram per post, a cost breakdown, and an engineering reference at the end.

All posts