Skip to content

210 × 297 mm

Letters

Employment offer letter

An A4 offer letter on company letterhead with a role details table covering start date, salary, hours and location, body sections written in Markdown, a numbered list of conditions and a detachable acceptance slip. The wording is sample text only, not legal advice.

A4 portraitLocale en-GBHTML + JinjaHeader & footer

Opens Dynamic Document API with this template preloaded in a free workspace.

Template language features

  • Loops
  • Conditionals
  • Macros
  • Filters
  • Currency formatting
  • Date formatting
  • Markdown
  • Header & footer
  • Page numbers

Filters such as format_currency and qrcode are described in the template language reference.

Variables

Derived from the sample data: 7 top-level fields, 40 paths in total. Send the same shape as data.

PathTypeExample
companyobject
company.namestring"Lanternfish Software Ltd"
company.trading_namestring"Lanternfish"
company.addressstring"3rd Floor, Brightwater House ⏎ 27 Leman Street…"
company.phonestring"+44 20 7946 0742"
company.emailstring"people@lanternfish.example.com"
company.websitestring"lanternfish.example.com"
company.company_numberstring"12345678"
company.registered_officestring"3rd Floor, Brightwater House, 27 Leman Street,…"
candidateobject
candidate.titlestring"Ms"
candidate.first_namestring"Imogen"
candidate.last_namestring"Adeyemi"
candidate.addressstring"Flat 3, 27 Wren Terrace ⏎ London ⏎ SE15 4XY"
offerobject
offer.referencestring"OFR-2026-118"
offer.datedate"2026-09-17"
offer.respond_within_daysnumber8
offer.currencystring"GBP"
offer.localestring"en-GB"
roleobject
role.titlestring"Senior Product Designer"
role.departmentstring"Product and Design"
role.reports_tostring"Rafael Oduya, Head of Design"
role.start_datedate"2026-10-19"
role.contractstring"Permanent, full-time"
role.salarynumber62500
role.salary_periodstring"per year"
role.hoursstring"37.5 hours a week, Monday to Friday"
role.locationstring"Hybrid: London studio two days a week, remote …"
role.holidaystring"27 days a year plus public holidays"
role.probation_monthsnumber6
role.noticestring"One month during probation, three months after…"
sectionsarray<object> · 4
sections[].headingstring"Your role"
sections[].bodystring"You will lead design for our scheduling produc…"
conditionsarray<string> · 4"Two satisfactory references, one of them from …"
signatoryobject
signatory.namestring"Hannah Okonjo-Reid"
signatory.titlestring"People Partner"

Sample data

Fictional records used for previews. Replace them with your own data when you call the API.

data.json
{
  "company": {
    "name": "Lanternfish Software Ltd",
    "trading_name": "Lanternfish",
    "address": "3rd Floor, Brightwater House\n27 Leman Street\nLondon E1 8XY",
    "phone": "+44 20 7946 0742",
    "email": "people@lanternfish.example.com",
    "website": "lanternfish.example.com",
    "company_number": "12345678",
    "registered_office": "3rd Floor, Brightwater House, 27 Leman Street, London E1 8XY"
  },
  "candidate": {
    "title": "Ms",
    "first_name": "Imogen",
    "last_name": "Adeyemi",
    "address": "Flat 3, 27 Wren Terrace\nLondon\nSE15 4XY"
  },
  "offer": {
    "reference": "OFR-2026-118",
    "date": "2026-09-17",
    "respond_within_days": 8,
    "currency": "GBP",
    "locale": "en-GB"
  },
  "role": {
    "title": "Senior Product Designer",
    "department": "Product and Design",
    "reports_to": "Rafael Oduya, Head of Design",
    "start_date": "2026-10-19",
    "contract": "Permanent, full-time",
    "salary": 62500,
    "salary_period": "per year",
    "hours": "37.5 hours a week, Monday to Friday",
    "location": "Hybrid: London studio two days a week, remote on other days",
    "holiday": "27 days a year plus public holidays",
    "probation_months": 6,
    "notice": "One month during probation, three months afterwards"
  },
  "sections": [
    {
      "heading": "Your role",
      "body": "You will lead design for our scheduling products, working with product managers and engineers from early research through to release. Your main responsibilities are described in the enclosed role profile, which we will review with you as the team grows."
    },
    {
      "heading": "Pay and benefits",
      "body": "- Your salary is paid monthly by bank transfer on the last working day of the month.\n- You can join the workplace pension scheme. We contribute **6%** of your salary when you contribute at least 4%.\n- Private medical cover starts after your first full month.\n- You have a learning budget of **£1,000 a year** for courses, books and conferences."
    },
    {
      "heading": "Probation",
      "body": "The first six months of your employment are a probationary period. You and your manager will meet monthly to review how things are going, and we will confirm the end of your probation in writing."
    },
    {
      "heading": "Next steps",
      "body": "Please sign and return the acceptance slip at the end of this letter. When we receive it, we will send your contract of employment, details of your first day and a short form for the checks listed below."
    }
  ],
  "conditions": [
    "Two satisfactory references, one of them from your most recent employer",
    "Proof of your right to work in the United Kingdom",
    "Confirmation of the qualifications listed in your application",
    "Your signature on our standard terms and conditions of employment"
  ],
  "signatory": {
    "name": "Hannah Okonjo-Reid",
    "title": "People Partner"
  }
}

Source

The body markup with Jinja, the stylesheet placed in <head> and the header and footer settings.

{#- Offer of employment on letterhead. The role details table, the response deadline and the
    acceptance slip all read from the same data, and the body sections are Markdown so each company
    can supply its own wording. Sample wording only; it is not legal advice. -#}
{%- set locale = offer.locale | default("en-GB") -%}
{%- set respond_by = offer.date | date_add(days=offer.respond_within_days) -%}
{%- set full_name = candidate.first_name ~ " " ~ candidate.last_name -%}

{%- macro detail(label, value) -%}
<tr><th scope="row">{{ label }}</th><td>{{ value }}</td></tr>
{%- endmacro -%}

<header class="letterhead">
  <div class="brand">
    <svg class="logo" viewBox="0 0 48 32" aria-hidden="true">
      <path d="M4 16c6-9 17-12 27-8l9-6v28l-9-6C21 28 10 25 4 16z" fill="#4b2a5e"/>
      <circle cx="15" cy="14.5" r="2.2" fill="#ffffff"/>
      <path d="M15 3.5c4 1.5 6 4.5 5.5 7.5" fill="none" stroke="#c9a7df" stroke-width="1.6" stroke-linecap="round"/>
      <circle cx="21" cy="11.5" r="1.8" fill="#f2c14e"/>
    </svg>
    <span class="brand-name">{{ company.trading_name }}</span>
  </div>
  <div class="company-contact">
    {{ company.address | nl2br }}<br>
    {{ company.phone }} · {{ company.email }}
  </div>
</header>

<section class="addressing">
  <div class="recipient">
    <p class="confidential">Private and confidential</p>
    <p>{{ candidate.title }} {{ full_name }}</p>
    <p>{{ candidate.address | nl2br }}</p>
  </div>
  <dl class="letter-meta">
    <dt>Date</dt><dd>{{ offer.date | format_date("long", locale) }}</dd>
    <dt>Our reference</dt><dd>{{ offer.reference }}</dd>
  </dl>
</section>

<p class="salutation">Dear {{ candidate.first_name }},</p>
<h1 class="subject">Offer of employment: {{ role.title }}</h1>

<p class="intro">
  Thank you for the time you spent with us during the interview process. I am delighted to offer you the role of
  <strong>{{ role.title }}</strong> in our {{ role.department }} team at {{ company.name }}, starting on
  {{ role.start_date | format_date("full", locale) }}. The main terms of the offer are set out below.
</p>

<table class="details">
  <tbody>
    {{ detail("Job title", role.title) }}
    {{ detail("Department", role.department) }}
    {{ detail("Reporting to", role.reports_to) }}
    {{ detail("Start date", role.start_date | format_date("long", locale)) }}
    {{ detail("Contract", role.contract) }}
    {{ detail("Salary", (role.salary | format_currency(offer.currency, locale, 0)) ~ " " ~ role.salary_period ~ ", before tax") }}
    {{ detail("Working hours", role.hours) }}
    {{ detail("Location", role.location) }}
    {{ detail("Holiday", role.holiday) }}
    {{ detail("Probation", role.probation_months ~ " months") }}
    {{ detail("Notice period", role.notice) }}
  </tbody>
</table>

{% for section in sections %}
<section class="body-section">
  <h2>{{ section.heading }}</h2>
  {{ section.body | markdown }}
</section>
{% endfor %}

{% if conditions %}
<section class="body-section conditions">
  <h2>Conditions of this offer</h2>
  <p>This offer is conditional on the following:</p>
  <ol>
    {% for condition in conditions %}
    <li><span class="cond-no">{{ loop.index }}</span>{{ condition }}</li>
    {% endfor %}
  </ol>
</section>
{% endif %}

<p class="respond">
  Please let us know your decision by <strong>{{ respond_by | format_date("long", locale) }}</strong>. If you have any
  questions in the meantime, contact me at {{ company.email }}. We are looking forward to working with you.
</p>

<section class="closing">
  <p>Yours sincerely,</p>
  <div class="signature-space"></div>
  <p class="signatory-name">{{ signatory.name }}</p>
  <p class="signatory-title">{{ signatory.title }}, {{ company.name }}</p>
</section>

<section class="tear-off">
  <div class="cut-line">
    <svg class="scissors" viewBox="0 0 24 24" aria-hidden="true">
      <circle cx="6" cy="6" r="3" fill="none" stroke="#6b5a78" stroke-width="1.6"/>
      <circle cx="6" cy="18" r="3" fill="none" stroke="#6b5a78" stroke-width="1.6"/>
      <path d="M8.5 7.5L21 17M8.5 16.5L21 7" stroke="#6b5a78" stroke-width="1.6" stroke-linecap="round"/>
    </svg>
    <span>Detach and return</span>
  </div>
  <div class="slip">
    <div class="slip-head">
      <h2>Acceptance of offer</h2>
      <span class="slip-ref">Ref. {{ offer.reference }}</span>
    </div>
    <p>
      I, {{ full_name }}, accept the offer of employment as {{ role.title }} with {{ company.name }} on the terms set
      out in the letter dated {{ offer.date | format_date("long", locale) }}, with a start date of
      {{ role.start_date | format_date("long", locale) }}.
    </p>
    <div class="slip-fields">
      <div class="field wide"><span>Signature</span></div>
      <div class="field"><span>Date</span></div>
    </div>
    <p class="slip-note">Please return by {{ respond_by | format_date("long", locale) }} to {{ company.email }} or to the address at the top of this letter.</p>
  </div>
</section>

Render it with the API

After adding the template to your workspace, render it by ID and pass your data. Arrays are shortened here.

curl -X POST https://api-eu.dynamicdocumentapi.com/v1/renders \
  -H "Authorization: Bearer $DYNAMIC_DOCUMENT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "input": {
    "type": "template",
    "template_id": "tpl_01J9ZK3M7Q8V5W2X4Y6Z8A0B1C"
  },
  "data": {
    "company": {
      "name": "Lanternfish Software Ltd",
      "trading_name": "Lanternfish",
      "address": "3rd Floor, Brightwater House\n27 Leman Street\nLondon E1 8XY",
      "phone": "+44 20 7946 0742",
      "email": "people@lanternfish.example.com",
      "website": "lanternfish.example.com",
      "company_number": "12345678",
      "registered_office": "3rd Floor, Brightwater House, 27 Leman Street, London E1 8XY"
    },
    "candidate": {
      "title": "Ms",
      "first_name": "Imogen",
      "last_name": "Adeyemi",
      "address": "Flat 3, 27 Wren Terrace\nLondon\nSE15 4XY"
    },
    "offer": {
      "reference": "OFR-2026-118",
      "date": "2026-09-17",
      "respond_within_days": 8,
      "currency": "GBP",
      "locale": "en-GB"
    },
    "role": {
      "title": "Senior Product Designer",
      "department": "Product and Design",
      "reports_to": "Rafael Oduya, Head of Design",
      "start_date": "2026-10-19",
      "contract": "Permanent, full-time",
      "salary": 62500,
      "salary_period": "per year",
      "hours": "37.5 hours a week, Monday to Friday",
      "location": "Hybrid: London studio two days a week, remote on other days",
      "holiday": "27 days a year plus public holidays",
      "probation_months": 6,
      "notice": "One month during probation, three months afterwards"
    },
    "sections": [
      {
        "heading": "Your role",
        "body": "You will lead design for our scheduling products, working with product managers and engineers from early research through to release. Your main responsibilities are described in the enclosed role profile, which we will review with you as the team grows."
      },
      {
        "heading": "Pay and benefits",
        "body": "- Your salary is paid monthly by bank transfer on the last working day of the month.\n- You can join the workplace pension scheme. We contribute **6%** of your salary when you contribute at least 4%.\n- Private medical cover starts after your first full month.\n- You have a learning budget of **£1,000 a year** for courses, books and conferences."
      }
    ],
    "conditions": [
      "Two satisfactory references, one of them from your most recent employer",
      "Proof of your right to work in the United Kingdom"
    ],
    "signatory": {
      "name": "Hannah Okonjo-Reid",
      "title": "People Partner"
    }
  },
  "output": {
    "format": "pdf",
    "filename": "letter-offer-employment.pdf"
  }
}'