Template gallery / sign-in-sheet

Sign-in sheet template

Ruled sign-in sheet for a clipboard: columns you define, rows numbered straight through a pre-filled roster and then a run of blank lines, a row deep enough for a biro, ruled boxes for the count and the quorum, and a certification block for whoever closes the sheet. The column header repeats on every page and a running foot carries the meeting and the sheet number.

chromium default PDF 15 top-level fields Billed per page

Rendered preview of the sign-in-sheet template
Rendered by Galley from the example payload below, at 816px wide , scale 2.

Fields

The full JSON Schema is below. Required fields are marked; anything missing comes back as a 422 naming the path, the expected type and a value that would be accepted.

Field Type Required Description
accent string optional The one spot colour: the PLEASE SIGN IN and CERTIFICATION labels. Rules and column heads are black. A hex colour or a CSS colour keyword. It is interpolated into the stylesheet, so nothing else is accepted.
title string optional
event object { name, organisation, date, time, … } required
sheet_of string optional Printed in a ruled box at the top right, and again in the running foot, when you are running several sheets at once.
row_numbers boolean optional Print the numbered column at the left. Turn it off when the sheet is a roster people tick rather than a run of lines people claim, and the columns you defined take the whole width.
purpose object { heading, text } optional The instruction under the header, set as a labelled hanging paragraph rather than a tinted panel.
columns array of object { label, align, key, width } required The ruled columns, left to right, after the row number. A column with a `key` is filled in from `prefilled`; one without is always blank for a pen.
prefilled array of object optional Rows printed with data already in them, before the blank ones. Useful for a roster you tick off.
blank_rows integer required How many empty ruled rows to print after the prefilled ones. Numbering runs straight through.
row_height string optional Height of a ruled row. 0.42in is the height a biro needs on a clipboard; drop it to 0.32in only when you would rather have the rows than the legibility.
stripe string optional Background of every second row. It is off by default and should usually stay off — the sheet has real vertical rules, and zebra banding on top of them is what makes a form look like a screenshot of a spreadsheet.
totals object { quorum_required, eligible } optional The four ruled boxes under the table: two to write in on the night, two printed from what you already know. Present the object and they print; leave it out and they do not.
certification object { text, left, right } optional Who is certifying that this sheet is what happened. The block is `break-inside: avoid`, so it never arrives on a page of its own.
footer string optional
privacy string optional A second footer line for whatever your notice has to say about the data collected.

Default render options

Applied unless you override them. Options are part of the cache key.

page_size "Letter"
margin "0.5in"
print_background true

Example payload

This exact object renders the preview above. It is also what the API echoes back in a validation error, so an agent can repair a payload without a round trip to the docs.

example.jsonjson
{
  "title": "Attendance and quorum sheet",
  "event": {
    "name": "Annual Meeting of the Members",
    "organisation": "Heron Bay Homeowners Association, Inc.",
    "date": "2026-12-01",
    "time": "Sign-in 6:30 p.m. · Order 7:00 p.m.",
    "location": "Heron Bay Clubhouse, 1400 Marsh Wren Drive"
  },
  "sheet_of": "1 of 3 — A to G",
  "purpose": {
    "heading": "Please sign in",
    "text": "One line per voting unit. Print your name, then sign on the same line. If you are carrying a proxy for another unit, write that unit in the last column and hand the proxy to the desk before you sit down."
  },
  "columns": [
    {
      "label": "Unit / lot",
      "key": "unit",
      "width": "0.85in",
      "align": "center"
    },
    {
      "label": "Owner of record",
      "key": "name",
      "width": "1.95in"
    },
    {
      "label": "Name of person signing (please print)"
    },
    {
      "label": "Signature",
      "width": "1.75in"
    },
    {
      "label": "Proxy held for",
      "width": "0.95in",
      "align": "center"
    }
  ],
  "prefilled": [
    {
      "unit": "101",
      "name": "Abadi, Nasrin"
    },
    {
      "unit": "104",
      "name": "Alvarez, Ana"
    },
    {
      "unit": "107",
      "name": "Bergeron, Thomas and Claire"
    },
    {
      "unit": "112",
      "name": "Castellanos, Ruben"
    },
    {
      "unit": "114",
      "name": "Nakamura, Curtis and Joan"
    },
    {
      "unit": "118",
      "name": "Delacroix-Hunt, Marguerite"
    },
    {
      "unit": "121",
      "name": "Demir, Yusuf"
    },
    {
      "unit": "126",
      "name": "Eberhardt, Simone"
    },
    {
      "unit": "129",
      "name": "Oyelaran, Priyanka and Sam"
    },
    {
      "unit": "133",
      "name": "Fitzgerald, Brendan"
    },
    {
      "unit": "136",
      "name": "Gallagher, Mary Beth"
    },
    {
      "unit": "140",
      "name": "Grunewald, Anke"
    }
  ],
  "blank_rows": 18,
  "row_height": "0.42in",
  "stripe": "transparent",
  "row_numbers": true,
  "totals": {
    "quorum_required": "56",
    "eligible": "186"
  },
  "certification": {
    "text": "I certify that the persons named above signed in at the meeting named at the top of this sheet, that each is an owner of record or the authorised representative of one, and that the count recorded on this sheet is accurate.",
    "left": "Inspector of elections · Signature",
    "right": "Date and time sign-in closed"
  },
  "footer": "Keep this sheet with the minutes of the meeting. Proxies collected at the desk are stapled to sheet 3.",
  "privacy": "Names and unit numbers collected here are used only to record attendance and to certify the quorum, and are retained with the minutes."
}

Render it

With an API keyshell
curl -sS https://api.galleyrender.com/v1/render \
  -H "Authorization: Bearer $GALLEY_API_KEY" \
  -H 'content-type: application/json' \
  -d '{
  "template": "sign-in-sheet@1",
  "format": "pdf",
  "data": "… the example payload above …"
}'
With no API key, over MCPshell
# No API key. The first call mints a trial of 10 PDF pages or 10 images.
curl -sS https://mcp.galleyrender.com/mcp \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "render",
      "arguments": {
        "template": "sign-in-sheet",
        "format": "pdf",
        "data": { … see the example payload above … }
      }
    }
  }'

Pin the version — sign-in-sheet@1 — in anything you ship. Publishing a new version never changes an old one. Render endpoint reference →

Try a free tool

Renders the example payload on the production service. No account, no key.

JSON Schema

schema.json (15 top-level properties)
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Sign-in sheet",
  "type": "object",
  "required": [
    "event",
    "columns",
    "blank_rows"
  ],
  "additionalProperties": true,
  "properties": {
    "accent": {
      "type": "string",
      "description": "The one spot colour: the PLEASE SIGN IN and CERTIFICATION labels. Rules and column heads are black. A hex colour or a CSS colour keyword. It is interpolated into the stylesheet, so nothing else is accepted.",
      "examples": [
        "#a4133c"
      ],
      "pattern": "^(#[0-9a-fA-F]{3,8}|[a-zA-Z]{3,20})$"
    },
    "title": {
      "type": "string",
      "default": "Sign-in sheet",
      "examples": [
        "Attendance and quorum sheet"
      ]
    },
    "event": {
      "type": "object",
      "required": [
        "name"
      ],
      "properties": {
        "name": {
          "type": "string",
          "examples": [
            "Annual Meeting of the Members"
          ]
        },
        "organisation": {
          "type": "string",
          "examples": [
            "Heron Bay Homeowners Association, Inc."
          ]
        },
        "date": {
          "type": "string",
          "format": "date",
          "examples": [
            "2026-12-01"
          ]
        },
        "time": {
          "type": "string",
          "examples": [
            "Sign-in from 6:30 p.m., meeting at 7:00 p.m."
          ]
        },
        "location": {
          "type": "string",
          "examples": [
            "Heron Bay Clubhouse"
          ]
        },
        "logo_url": {
          "type": "string",
          "format": "uri",
          "examples": [
            "https://example.com/heron-bay.png"
          ]
        }
      }
    },
    "sheet_of": {
      "type": "string",
      "description": "Printed in a ruled box at the top right, and again in the running foot, when you are running several sheets at once.",
      "examples": [
        "1 of 3 — A to G"
      ]
    },
    "row_numbers": {
      "type": "boolean",
      "default": true,
      "description": "Print the numbered column at the left. Turn it off when the sheet is a roster people tick rather than a run of lines people claim, and the columns you defined take the whole width.",
      "examples": [
        true
      ]
    },
    "purpose": {
      "type": "object",
      "description": "The instruction under the header, set as a labelled hanging paragraph rather than a tinted panel.",
      "properties": {
        "heading": {
          "type": "string",
          "default": "Please sign in",
          "examples": [
            "Please sign in"
          ]
        },
        "text": {
          "type": "string",
          "examples": [
            "One line per voting unit. Print your name, then sign. If you are holding a proxy, write the unit you hold it for in the last column and hand the proxy to the desk."
          ]
        }
      }
    },
    "columns": {
      "type": "array",
      "minItems": 1,
      "description": "The ruled columns, left to right, after the row number. A column with a `key` is filled in from `prefilled`; one without is always blank for a pen.",
      "items": {
        "type": "object",
        "required": [
          "label"
        ],
        "properties": {
          "label": {
            "type": "string",
            "examples": [
              "Name (please print)"
            ]
          },
          "align": {
            "type": "string",
            "enum": [
              "left",
              "center"
            ],
            "default": "left",
            "description": "Centre the narrow columns — a unit number or a tick box reads better on the middle of the rule than jammed against its left end.",
            "examples": [
              "center"
            ]
          },
          "key": {
            "type": "string",
            "description": "Property on each `prefilled` entry to print in this column.",
            "examples": [
              "name"
            ]
          },
          "width": {
            "type": "string",
            "description": "CSS width, e.g. `1.4in` or `22%`. Leave it off to share the remaining space.",
            "examples": [
              "1.6in"
            ]
          }
        }
      }
    },
    "prefilled": {
      "type": "array",
      "description": "Rows printed with data already in them, before the blank ones. Useful for a roster you tick off.",
      "items": {
        "type": "object",
        "additionalProperties": true,
        "examples": [
          {
            "unit": "Lot 101",
            "name": "Alvarez, Ana"
          }
        ]
      }
    },
    "blank_rows": {
      "type": "integer",
      "minimum": 0,
      "maximum": 200,
      "description": "How many empty ruled rows to print after the prefilled ones. Numbering runs straight through.",
      "examples": [
        26
      ]
    },
    "row_height": {
      "type": "string",
      "default": "0.42in",
      "description": "Height of a ruled row. 0.42in is the height a biro needs on a clipboard; drop it to 0.32in only when you would rather have the rows than the legibility.",
      "examples": [
        "0.42in"
      ]
    },
    "stripe": {
      "type": "string",
      "default": "transparent",
      "description": "Background of every second row. It is off by default and should usually stay off — the sheet has real vertical rules, and zebra banding on top of them is what makes a form look like a screenshot of a spreadsheet.",
      "examples": [
        "transparent"
      ]
    },
    "totals": {
      "type": "object",
      "description": "The four ruled boxes under the table: two to write in on the night, two printed from what you already know. Present the object and they print; leave it out and they do not.",
      "properties": {
        "quorum_required": {
          "type": "string",
          "description": "Set large in monospace in its own ruled box. A bare figure reads best; the unit belongs in the column head.",
          "examples": [
            "56"
          ]
        },
        "eligible": {
          "type": "string",
          "description": "Set large in monospace in its own ruled box.",
          "examples": [
            "186"
          ]
        }
      }
    },
    "certification": {
      "type": "object",
      "description": "Who is certifying that this sheet is what happened. The block is `break-inside: avoid`, so it never arrives on a page of its own.",
      "properties": {
        "text": {
          "type": "string",
          "examples": [
            "I certify that the persons named above signed in at the meeting named at the top of this sheet, and that the count recorded is accurate."
          ]
        },
        "left": {
          "type": "string",
          "default": "Signature",
          "examples": [
            "Secretary · Signature"
          ]
        },
        "right": {
          "type": "string",
          "default": "Date",
          "examples": [
            "Date and time closed"
          ]
        }
      }
    },
    "footer": {
      "type": "string",
      "default": "Keep this sheet with the records of the meeting.",
      "examples": [
        "Keep this sheet with the minutes."
      ]
    },
    "privacy": {
      "type": "string",
      "description": "A second footer line for whatever your notice has to say about the data collected.",
      "examples": [
        "Names and units collected here are used only to record attendance and are retained with the minutes."
      ]
    }
  }
}