Template gallery / menu
menu
Restaurant menu on A4 or Letter: sections with dish, description, dietary marks and price, optional two-column layout, a wine-by-the-glass block, and a footnote line. Sections never split mid-heading.
chromium default PDF 15 top-level fields 1 unit per page
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 |
|---|---|---|---|
| title | string | optional | The menu's own name, under the restaurant name. |
| served | string | optional | |
| currency | string | optional | |
| columns | 1 | 2 | 3 | optional | Column count for the sections. |
| accent | string | optional | |
| paper | string | optional | Sheet background. |
| text_color | string | optional | |
| muted_color | string | optional | |
| rule_color | string | optional | |
| notes | string | optional | |
| pours_title | string | optional | |
| restaurant | object { name, address, phone, website, … } | required | |
| sections | array of object { name, blurb, items } | required | |
| pours | array of object { name, detail, glass_price, bottle_price } | optional | Wine or cocktail list in its own bordered block. |
| dietary_key | array of object { mark, meaning } | optional |
Default render options
Applied unless you override them. Options are part of the cache key.
| page_size | "Letter" |
| margin | "0.6in" |
| 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.
{
"title": "Dinner",
"served": "Served Tuesday through Sunday, 5pm to 10pm",
"currency": "USD",
"columns": 2,
"accent": "#7c2d12",
"restaurant": {
"name": "The Salt Line",
"address": "11 South Second St, Fernandina Beach, FL",
"phone": "(904) 555-0119",
"website": "saltline.test"
},
"sections": [
{
"name": "To start",
"blurb": "Meant for the middle of the table.",
"items": [
{
"name": "Mayport shrimp toast",
"description": "Cultured butter, preserved lemon, fennel fronds, grilled sourdough",
"price": 18,
"marks": [
"N"
]
},
{
"name": "Oysters on the half shell",
"description": "Amelia River, mignonette, horseradish — half dozen",
"price": 21,
"marks": [
"GF",
"R"
]
},
{
"name": "Chilled green tomato soup",
"description": "Buttermilk, dill oil, cucumber, toasted benne",
"price": 13,
"marks": [
"V",
"GF"
]
},
{
"name": "Smoked mullet dip",
"description": "House crackers, pickled okra, hot honey",
"price": 16
}
]
},
{
"name": "From the water",
"items": [
{
"name": "Whole roasted snapper",
"description": "Charred scallion, brown butter, lime, herb salad — for two",
"price_text": "MP",
"marks": [
"GF"
]
},
{
"name": "Seared cobia",
"description": "Field pea succotash, tomato broth, basil",
"price": 38
},
{
"name": "Shrimp and grits",
"description": "Anson Mills grits, tasso, sweet pepper gravy",
"price": 32
},
{
"name": "Fried flounder sandwich",
"description": "Tartar, shaved cabbage, sesame bun, salt vinegar chips",
"price": 24
}
]
},
{
"name": "From the land",
"items": [
{
"name": "Coal-roasted half chicken",
"description": "Sorghum glaze, collards, cornbread crumb",
"price": 34
},
{
"name": "Dry-aged strip",
"description": "Twelve ounces, bone marrow butter, watercress",
"price": 62,
"marks": [
"GF"
]
},
{
"name": "Charred cabbage steak",
"description": "Peanut romesco, crispy shallot, herbs",
"price": 26,
"marks": [
"V",
"N"
]
}
]
},
{
"name": "Sides",
"items": [
{
"name": "Skillet cornbread",
"description": "Whipped honey butter",
"price": 9,
"marks": [
"V"
]
},
{
"name": "Charred okra",
"description": "Lemon, chili, bonito",
"price": 11,
"marks": [
"GF"
]
},
{
"name": "Rice middlins",
"description": "Brown butter, thyme",
"price": 10,
"marks": [
"V",
"GF"
]
}
]
},
{
"name": "To finish",
"items": [
{
"name": "Buttermilk pie",
"description": "Blackberry, cane syrup, crème fraîche",
"price": 12,
"marks": [
"V"
]
},
{
"name": "Salted chocolate cremeux",
"description": "Olive oil, sea salt, sourdough crumb",
"price": 13,
"marks": [
"V"
]
},
{
"name": "Citrus granita",
"description": "Amelia satsuma, mint",
"price": 9,
"marks": [
"V",
"GF"
]
}
]
}
],
"pours": [
{
"name": "Muscadet, Domaine de la Pépière",
"detail": "Loire Valley, France — 2024",
"glass_price": 14,
"bottle_price": 52
},
{
"name": "Vermentino, Tenuta Argentiera",
"detail": "Tuscany, Italy — 2023",
"glass_price": 16,
"bottle_price": 60
},
{
"name": "Cinsault, Broc Cellars",
"detail": "Sonoma County, California — 2024",
"glass_price": 17,
"bottle_price": 64
},
{
"name": "Fino sherry, Bodegas Tradición",
"detail": "Jerez, Spain — NV",
"glass_price": 15
},
{
"name": "Amelia highball",
"detail": "Rye, satsuma cordial, soda",
"glass_price": 15
}
],
"dietary_key": [
{
"mark": "V",
"meaning": "vegetarian"
},
{
"mark": "GF",
"meaning": "gluten free"
},
{
"mark": "N",
"meaning": "contains nuts"
},
{
"mark": "R",
"meaning": "served raw"
}
],
"notes": "Consuming raw or undercooked seafood may increase your risk of foodborne illness. A 20% service charge is added to parties of six or more."
} Render it
curl -sS https://api.galleyrender.com/v1/render \
-H "Authorization: Bearer $GALLEY_API_KEY" \
-H 'content-type: application/json' \
-d '{
"template": "menu@1",
"format": "pdf",
"data": "… the example payload above …"
}' # No API key. The first call mints a 50-render trial.
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": "menu",
"format": "pdf",
"data": { … see the example payload above … }
}
}
}'
Pin the version — menu@1 — in anything you ship. Publishing a new
version never changes an old one. Render endpoint reference →
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": "Menu",
"type": "object",
"required": [
"restaurant",
"sections"
],
"additionalProperties": true,
"properties": {
"title": {
"type": "string",
"description": "The menu's own name, under the restaurant name.",
"examples": [
"Dinner"
]
},
"served": {
"type": "string",
"examples": [
"Served Tuesday through Sunday, 5pm to 10pm"
]
},
"currency": {
"type": "string",
"default": "USD",
"examples": [
"USD"
]
},
"columns": {
"type": "integer",
"enum": [
1,
2,
3
],
"default": 2,
"description": "Column count for the sections.",
"examples": [
2
]
},
"accent": {
"type": "string",
"examples": [
"#7c2d12"
]
},
"paper": {
"type": "string",
"description": "Sheet background.",
"examples": [
"#fdfbf7"
]
},
"text_color": {
"type": "string",
"examples": [
"#1c1a17"
]
},
"muted_color": {
"type": "string",
"examples": [
"#7a7268"
]
},
"rule_color": {
"type": "string",
"examples": [
"#ded7cc"
]
},
"notes": {
"type": "string",
"examples": [
"Consuming raw or undercooked seafood may increase your risk of foodborne illness. A 20% service charge is added to parties of six or more."
]
},
"pours_title": {
"type": "string",
"default": "By the glass",
"examples": [
"By the glass"
]
},
"restaurant": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"examples": [
"The Salt Line"
]
},
"address": {
"type": "string",
"examples": [
"11 South Second St, Fernandina Beach, FL"
]
},
"phone": {
"type": "string",
"examples": [
"(904) 555-0119"
]
},
"website": {
"type": "string",
"examples": [
"saltline.test"
]
},
"logo_url": {
"type": "string",
"format": "uri",
"examples": [
"https://example.com/logo.png"
]
}
}
},
"sections": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": [
"name",
"items"
],
"properties": {
"name": {
"type": "string",
"examples": [
"To start"
]
},
"blurb": {
"type": "string",
"examples": [
"Everything here is meant for the middle of the table."
]
},
"items": {
"type": "array",
"items": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"examples": [
"Mayport shrimp toast"
]
},
"description": {
"type": "string",
"examples": [
"Cultured butter, preserved lemon, fennel fronds, grilled sourdough"
]
},
"price": {
"type": "number",
"minimum": 0,
"examples": [
18
]
},
"price_text": {
"type": "string",
"description": "Use instead of price for things like \"MP\".",
"examples": [
"MP"
]
},
"marks": {
"type": "array",
"description": "Short dietary marks matched by dietary_key.",
"items": {
"type": "string",
"examples": [
"GF"
]
},
"examples": [
[
"GF",
"N"
]
]
}
}
}
}
}
}
},
"pours": {
"type": "array",
"description": "Wine or cocktail list in its own bordered block.",
"items": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"examples": [
"Muscadet, Domaine de la Pépière"
]
},
"detail": {
"type": "string",
"examples": [
"Loire Valley, France — 2024"
]
},
"glass_price": {
"type": "number",
"minimum": 0,
"examples": [
14
]
},
"bottle_price": {
"type": "number",
"minimum": 0,
"examples": [
52
]
}
}
}
},
"dietary_key": {
"type": "array",
"items": {
"type": "object",
"required": [
"mark",
"meaning"
],
"properties": {
"mark": {
"type": "string",
"examples": [
"GF"
]
},
"meaning": {
"type": "string",
"examples": [
"gluten free"
]
}
}
}
}
}
}