PDF templates / Civic / Government

Council Meeting Minutes

Municipal council meeting minutes derived from published UK and US council minutes: masthead with meeting meta box, present/absent/staff attendance box, numbered minute items with motion and vote lines, and approval with clerk and mayor sign-off. Renders as a tagged PDF/A-2A + PDF/UA-1 document.

First page of the Council Meeting Minutes template, rendered with its sample data
council-minutes.pdfpage 1 of 2

DSL source

The whole template. Learn the language in the template DSL guide.

js
const template = doc(
  { size: "Letter", title: "{{jurisdiction}} {{councilBody}} {{meetingKind}} Minutes — {{date}}", padding: [36, 40, 36, 40],
    styles: {
      ".masthead":     { "font-family": "Inter", "font-size": 20, "font-weight": "bold", color: "#0b3d91", "margin": [0, 0, 2, 0] },
      ".meeting-kind": { "font-family": "Inter", "font-size": 13, "font-weight": "bold", color: "#1a1a1a", "margin": [0, 0, 2, 0] },
      ".meeting-line": { "font-family": "Inter", "font-size": 10, color: "#333", "line-height": 1.4 },
      ".meta-label":   { "font-family": "Inter", "font-size": 8, "font-weight": "bold", color: "#555" },
      ".meta-value":   { "font-family": "Inter", "font-size": 9.5, color: "#1a1a1a" },
      ".att-name":     { "font-family": "Inter", "font-size": 9, color: "#1a1a1a", "line-height": 1.4 },
      ".item-number":  { "font-family": "Inter", "font-size": 10, "font-weight": "bold", color: "#0b3d91" },
      ".item-title":   { "font-family": "Inter", "font-size": 10, "font-weight": "bold", color: "#1a1a1a", "line-height": 1.35 },
      ".item-body":    { "font-family": "Inter", "font-size": 9.5, color: "#1a1a1a", "line-height": 1.45, "margin": [1, 0, 0, 0] },
      ".item-meta":    { "font-family": "Inter", "font-size": 9, color: "#444", "line-height": 1.4, "margin": [1, 0, 0, 0] },
      ".cert":         { "font-family": "Inter", "font-size": 9, color: "#333", "line-height": 1.5 },
      ".sig-name":     { "font-family": "Inter", "font-size": 10, "font-weight": "bold", color: "#1a1a1a", "margin": [0, 0, 0, 0] },
      ".sig-title":    { "font-family": "Inter", "font-size": 9, color: "#444", "margin": [0, 0, 0, 0] },
    },
  },

  // Masthead
  s(".masthead", "{{jurisdiction}}"),
  s(".meeting-kind", "{{councilBody}} — {{meetingKind}} Minutes"),
  s(".meeting-line", "{{date}} at {{time}} — {{location}}"),
  gap(8),

  // Meeting meta box
  r({ "border": [1, 1, 1, 1], "border-color": "#0b3d91", padding: [8, 10, 8, 10] },
    col("50%",
      s(".meta-label", "MEETING DATE / TIME"),
      s(".meta-value", "{{date}} at {{time}}"),
      gap(4),
      s(".meta-label", "LOCATION"),
      s(".meta-value", "{{location}}"),
    ),
    col("50%",
      s(".meta-label", "MINUTES OF"),
      s(".meta-value", "{{meetingKind}} of {{date}}"),
      gap(4),
      s(".meta-label", "APPROVED"),
      s(".meta-value", "{{approvedAt}}"),
    ),
  ),
  gap(8),

  // Attendance box
  r({ "border": [1, 1, 1, 1], "border-color": "#0b3d91", padding: [8, 10, 8, 10] },
    col("50%",
      s(".meta-label", "PRESENT"),
      each("member in present",
        s(".att-name", "{{member}}"),
      ),
      gap(4),
      s(".meta-label", "ABSENT"),
      each("member in absent",
        s(".att-name", "{{member}}"),
      ),
    ),
    col("50%",
      s(".meta-label", "STAFF PRESENT"),
      each("member in staff",
        s(".att-name", "{{member}}"),
      ),
      gap(4),
      s(".meta-label", "QUORUM"),
      s(".meta-value", "{{quorum}}"),
    ),
  ),
  gap(10),

  // Numbered minute items
  each("item in items",
    r({ grid: ["34pt", "1fr"], "margin": [0, 0, 6, 0] },
      col(s(".item-number", "{{item.number}}")),
      col(
        s(".item-title", "{{item.title}}"),
        s(".item-body", "{{item.body}}"),
        when("item.motion",
          s(".item-meta", "Motion: {{item.motion}}"),
        ),
        when("item.vote",
          s(".item-meta", "Vote: {{item.vote}}"),
        ),
      ),
    ),
  ),

  gap(4),
  s(".cert", "{{approval}}"),
  s(".cert", "{{nextMeeting}}"),
  gap(8),
  r({ "margin": [0, 0, 0, 0] },
    col("50%",
      s(".sig-name", "{{clerkName}}"),
      s(".sig-title", "City Clerk"),
    ),
    col("50%",
      s(".sig-name", "{{mayorName}}"),
      s(".sig-title", "Mayor"),
    ),
  ),

  ftrPages("{{jurisdiction}} {{councilBody}} — Minutes {{date}}"),
);

const sampleData = {
  jurisdiction: "City of Riverton",
  councilBody: "City Council",
  meetingKind: "Regular Meeting",
  date: "12 November 2025",
  time: "6:30 PM",
  location: "Riverton City Hall, Council Chambers, 450 Civic Center Drive",
  approvedAt: "9 December 2025",
  present: [
    "Mayor A. Okafor",
    "Councillor J. Lind",
    "Councillor R. Patel",
    "Councillor S. Whitfield",
    "Councillor T. Brennan",
    "Councillor K. Adeyemi",
  ],
  absent: [
    "Councillor M. Duarte (excused)",
  ],
  staff: [
    "J. Ellis, City Manager",
    "D. Reyes, City Clerk",
    "P. Novak, City Attorney",
  ],
  quorum: "Quorum present — 6 of 7 members.",
  items: [
    {
      number: "1",
      title: "Call to Order, Pledge of Allegiance and Invocation",
      body: "Mayor Okafor called the meeting to order at 6:32 PM. Councillor Lind led the Pledge of Allegiance; Pastor R. Bell gave the invocation.",
      motion: "",
      vote: "",
    },
    {
      number: "2",
      title: "Roll Call and Determination of Quorum",
      body: "The City Clerk called the roll. Six of seven members were present; Councillor Duarte was excused. The Mayor declared a quorum present.",
      motion: "",
      vote: "",
    },
    {
      number: "3",
      title: "Approval of Minutes — Regular Meeting of 28 October 2025",
      body: "The draft minutes of 28 October 2025, circulated 30 October 2025, were presented for approval with no corrections offered.",
      motion: "Lind / Patel to approve as circulated.",
      vote: "Approved 6–0.",
    },
    {
      number: "4",
      title: "Claims Register for the Period Ending 7 November 2025",
      body: "The Finance Department presented disbursements totalling $1,284,309.55. No items were pulled for separate discussion.",
      motion: "Patel / Whitfield to approve the register.",
      vote: "Approved 6–0.",
    },
    {
      number: "5",
      title: "Resolution 2025-118 — Accepting the October 2025 Treasurer's Report",
      body: "The Treasurer's Report for October 2025 was received. Councillor Brennan asked about investment yields; staff undertook to circulate a note.",
      motion: "Whitfield / Adeyemi to adopt Resolution 2025-118.",
      vote: "Adopted 6–0.",
    },
    {
      number: "6",
      title: "Reappointment of L. Marsh to the Planning Commission (Term to 2029)",
      body: "The Mayor's reappointment of L. Marsh was put to the Council for confirmation. Marsh has served since 2021 with full attendance.",
      motion: "Okafor / Lind to confirm the reappointment.",
      vote: "Confirmed 5–1 (Brennan dissenting).",
    },
    {
      number: "7",
      title: "Public Hearing — Rezoning of 1200 Mill Road from R-2 to MU-N (Case Z-25-09)",
      body: "The hearing opened at 7:41 PM. Planning staff summarised the 6–1 Commission recommendation; three residents spoke in favour and one against. The hearing closed at 8:05 PM and first reading was set for 9 December 2025.",
      motion: "Patel / Brennan to close the hearing and set first reading.",
      vote: "Approved 6–0.",
    },
    {
      number: "8",
      title: "Ordinance 2025-44 — FY 2025-26 Mid-Year Budget Amendment (First Reading)",
      body: "First reading of the mid-year amendment appropriating a net $412,000 from General Fund balance. Councillor Brennan opposed the recreation-programme line.",
      motion: "Lind / Adeyemi to approve first reading.",
      vote: "Approved 5–1 (Brennan dissenting).",
    },
    {
      number: "9",
      title: "Change Order No. 3 — Elm Street Resurfacing (CIP Project ST-24-04)",
      body: "Public Works reported storm-drain repairs discovered during milling, adding $86,400 to the contract. The revised completion date is 19 December 2025.",
      motion: "Whitfield / Patel to approve Change Order No. 3.",
      vote: "Approved 6–0.",
    },
    {
      number: "10",
      title: "City Manager's Report and Adjournment",
      body: "The City Manager reported winter shelter operations at 94% occupancy and a pending $210,000 state grant decision in January. There being no further business, the meeting adjourned at 9:12 PM.",
      motion: "Brennan / Whitfield to adjourn.",
      vote: "Approved 6–0.",
    },
  ],
  approval: "These minutes were approved as a correct record by the Riverton City Council on 9 December 2025.",
  nextMeeting: "Next regular meeting: 9 December 2025 at 6:30 PM.",
  clerkName: "D. Reyes",
  mayorName: "A. Okafor",
};

Sample data

json
{
  "jurisdiction": "City of Riverton",
  "councilBody": "City Council",
  "meetingKind": "Regular Meeting",
  "date": "12 November 2025",
  "time": "6:30 PM",
  "location": "Riverton City Hall, Council Chambers, 450 Civic Center Drive",
  "approvedAt": "9 December 2025",
  "present": [
    "Mayor A. Okafor",
    "Councillor J. Lind",
    "Councillor R. Patel",
    "Councillor S. Whitfield",
    "Councillor T. Brennan",
    "Councillor K. Adeyemi"
  ],
  "absent": [
    "Councillor M. Duarte (excused)"
  ],
  "staff": [
    "J. Ellis, City Manager",
    "D. Reyes, City Clerk",
    "P. Novak, City Attorney"
  ],
  "quorum": "Quorum present — 6 of 7 members.",
  "items": [
    {
      "number": "1",
      "title": "Call to Order, Pledge of Allegiance and Invocation",
      "body": "Mayor Okafor called the meeting to order at 6:32 PM. Councillor Lind led the Pledge of Allegiance; Pastor R. Bell gave the invocation.",
      "motion": "",
      "vote": ""
    },
    {
      "number": "2",
      "title": "Roll Call and Determination of Quorum",
      "body": "The City Clerk called the roll. Six of seven members were present; Councillor Duarte was excused. The Mayor declared a quorum present.",
      "motion": "",
      "vote": ""
    },
    {
      "number": "3",
      "title": "Approval of Minutes — Regular Meeting of 28 October 2025",
      "body": "The draft minutes of 28 October 2025, circulated 30 October 2025, were presented for approval with no corrections offered.",
      "motion": "Lind / Patel to approve as circulated.",
      "vote": "Approved 6–0."
    },
    {
      "number": "4",
      "title": "Claims Register for the Period Ending 7 November 2025",
      "body": "The Finance Department presented disbursements totalling $1,284,309.55. No items were pulled for separate discussion.",
      "motion": "Patel / Whitfield to approve the register.",
      "vote": "Approved 6–0."
    },
    {
      "number": "5",
      "title": "Resolution 2025-118 — Accepting the October 2025 Treasurer's Report",
      "body": "The Treasurer's Report for October 2025 was received. Councillor Brennan asked about investment yields; staff undertook to circulate a note.",
      "motion": "Whitfield / Adeyemi to adopt Resolution 2025-118.",
      "vote": "Adopted 6–0."
    },
    {
      "number": "6",
      "title": "Reappointment of L. Marsh to the Planning Commission (Term to 2029)",
      "body": "The Mayor's reappointment of L. Marsh was put to the Council for confirmation. Marsh has served since 2021 with full attendance.",
      "motion": "Okafor / Lind to confirm the reappointment.",
      "vote": "Confirmed 5–1 (Brennan dissenting)."
    },
    {
      "number": "7",
      "title": "Public Hearing — Rezoning of 1200 Mill Road from R-2 to MU-N (Case Z-25-09)",
      "body": "The hearing opened at 7:41 PM. Planning staff summarised the 6–1 Commission recommendation; three residents spoke in favour and one against. The hearing closed at 8:05 PM and first reading was set for 9 December 2025.",
      "motion": "Patel / Brennan to close the hearing and set first reading.",
      "vote": "Approved 6–0."
    },
    {
      "number": "8",
      "title": "Ordinance 2025-44 — FY 2025-26 Mid-Year Budget Amendment (First Reading)",
      "body": "First reading of the mid-year amendment appropriating a net $412,000 from General Fund balance. Councillor Brennan opposed the recreation-programme line.",
      "motion": "Lind / Adeyemi to approve first reading.",
      "vote": "Approved 5–1 (Brennan dissenting)."
    },
    {
      "number": "9",
      "title": "Change Order No. 3 — Elm Street Resurfacing (CIP Project ST-24-04)",
      "body": "Public Works reported storm-drain repairs discovered during milling, adding $86,400 to the contract. The revised completion date is 19 December 2025.",
      "motion": "Whitfield / Patel to approve Change Order No. 3.",
      "vote": "Approved 6–0."
    },
    {
      "number": "10",
      "title": "City Manager's Report and Adjournment",
      "body": "The City Manager reported winter shelter operations at 94% occupancy and a pending $210,000 state grant decision in January. There being no further business, the meeting adjourned at 9:12 PM.",
      "motion": "Brennan / Whitfield to adjourn.",
      "vote": "Approved 6–0."
    }
  ],
  "approval": "These minutes were approved as a correct record by the Riverton City Council on 9 December 2025.",
  "nextMeeting": "Next regular meeting: 9 December 2025 at 6:30 PM.",
  "clerkName": "D. Reyes",
  "mayorName": "A. Okafor"
}

Render it with your data

Any API key can render this template by its ID. This call uses the sample data; add a data object to use your own. See the API reference.

bash
curl -X POST https://makespdf.com/api/v1/render \
  -H "Authorization: Bearer $MAKESPDF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"templateId": "council-minutes"}' \
  -o output.pdf