Copycurl -X POST https://pdfgen.com/api/v1/generate \
-H "Authorization: Bearer pdfg_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"data": {
"name": "Olive & Thyme",
"tagline": "Mediterranean kitchen",
"address": "18 Rua das Flores, Lisbon",
"hours": "Tue–Sun, 12:00–22:30",
"currency": "EUR",
"locale": "en-IE",
"sections": [
{
"name": "Starters",
"items": [
{
"name": "Grilled halloumi",
"description": "Honey, thyme, toasted pistachio",
"tags": [
"V",
"GF"
],
"price": 9
},
{
"name": "Whipped feta & flatbread",
"description": "Roasted peppers, chilli oil, warm flatbread",
"tags": [
"V"
],
"price": 8.5
},
{
"name": "Garlic prawns",
"description": "Olive oil, parsley, lemon, sourdough",
"tags": [],
"price": 12
}
]
},
{
"name": "Mains",
"items": [
{
"name": "Lamb kofta",
"description": "Tahini yoghurt, herb salad, pickled onion",
"tags": [
"GF"
],
"price": 21
},
{
"name": "Whole sea bream",
"description": "Charred lemon, capers, crushed potatoes",
"tags": [
"GF"
],
"price": 24
},
{
"name": "Mushroom & farro risotto",
"description": "Wild mushrooms, parmesan, truffle oil",
"tags": [
"V"
],
"price": 18
},
{
"name": "Roasted cauliflower steak",
"description": "Romesco, almonds, pomegranate",
"tags": [
"VG",
"GF"
],
"price": 17
}
]
},
{
"name": "Desserts",
"items": [
{
"name": "Pastel de nata",
"description": "Warm custard tart, cinnamon",
"tags": [
"V"
],
"price": 4.5
},
{
"name": "Olive oil cake",
"description": "Orange, mascarpone, candied peel",
"tags": [
"V"
],
"price": 7
},
{
"name": "Dark chocolate mousse",
"description": "Sea salt, olive oil, hazelnut crumb",
"tags": [
"VG"
],
"price": 7.5
}
]
}
],
"legend": "V vegetarian · VG vegan · GF gluten free · Please tell us about any allergies"
},
"format": "A4",
"engine": "handlebars",
"html": "<link href=\"https://fonts.googleapis.com/css2?family=Playfair+Display:wght@500;700&display=swap\" rel=\"stylesheet\">\n<div style=\"max-width:700px;margin:0 auto;padding:52px 56px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;color:#111827;\">\n <div style=\"text-align:center;margin-bottom:30px;\">\n <p style=\"margin:0;font-size:11px;letter-spacing:4px;text-transform:uppercase;color:#a16207;\">{{tagline}}</p>\n <h1 style=\"margin:8px 0 0;font-family:' \ ' 'Playfair Display' \ ' ',Georgia,serif;font-size:42px;font-weight:700;color:#1c1917;\">{{name}}</h1>\n <div style=\"display:flex;align-items:center;justify-content:center;gap:10px;margin:14px 0;\">\n <span style=\"width:60px;height:1px;background:#d6c7b0;\"></span><span style=\"width:6px;height:6px;background:#a16207;transform:rotate(45deg);\"></span><span style=\"width:60px;height:1px;background:#d6c7b0;\"></span>\n </div>\n <p style=\"margin:0;font-size:12px;color:#78716c;\">{{address}} · {{hours}}</p>\n </div>\n {{#each sections}}\n <h2 style=\"margin:0 0 12px;font-family:' \ ' 'Playfair Display' \ ' ',Georgia,serif;font-size:22px;font-weight:500;text-align:center;color:#a16207;\">{{name}}</h2>\n <div style=\"margin-bottom:24px;\">\n {{#each items}}\n <div style=\"margin-bottom:11px;\">\n <div style=\"display:flex;align-items:baseline;gap:8px;\">\n <span style=\"font-weight:700;font-size:14px;color:#1c1917;\">{{name}}</span>\n {{#each tags}}<span style=\"font-size:9px;font-weight:700;color:#15803d;border:1px solid #bbf7d0;border-radius:3px;padding:0 4px;\">{{this}}</span>{{/each}}\n <span style=\"flex:1;border-bottom:1px dotted #d6c7b0;\"></span>\n <span style=\"font-weight:700;font-size:14px;color:#1c1917;\">{{formatCurrency price ../../currency ../../locale}}</span>\n </div>\n <p style=\"margin:2px 0 0;font-size:12px;color:#78716c;\">{{description}}</p>\n </div>\n {{/each}}\n </div>\n {{/each}}\n <p style=\"margin:8px 0 0;text-align:center;font-size:11px;color:#a8a29e;\">{{legend}}</p>\n</div>"
}' --output restaurant-menu.pdf
Copyimport fs from "node:fs" ;
const template = "<link href=\"https://fonts.googleapis.com/css2?family=Playfair+Display:wght@500;700&display=swap\" rel=\"stylesheet\">\n<div style=\"max-width:700px;margin:0 auto;padding:52px 56px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;color:#111827;\">\n <div style=\"text-align:center;margin-bottom:30px;\">\n <p style=\"margin:0;font-size:11px;letter-spacing:4px;text-transform:uppercase;color:#a16207;\">{{tagline}}</p>\n <h1 style=\"margin:8px 0 0;font-family:'Playfair Display',Georgia,serif;font-size:42px;font-weight:700;color:#1c1917;\">{{name}}</h1>\n <div style=\"display:flex;align-items:center;justify-content:center;gap:10px;margin:14px 0;\">\n <span style=\"width:60px;height:1px;background:#d6c7b0;\"></span><span style=\"width:6px;height:6px;background:#a16207;transform:rotate(45deg);\"></span><span style=\"width:60px;height:1px;background:#d6c7b0;\"></span>\n </div>\n <p style=\"margin:0;font-size:12px;color:#78716c;\">{{address}} · {{hours}}</p>\n </div>\n {{#each sections}}\n <h2 style=\"margin:0 0 12px;font-family:'Playfair Display',Georgia,serif;font-size:22px;font-weight:500;text-align:center;color:#a16207;\">{{name}}</h2>\n <div style=\"margin-bottom:24px;\">\n {{#each items}}\n <div style=\"margin-bottom:11px;\">\n <div style=\"display:flex;align-items:baseline;gap:8px;\">\n <span style=\"font-weight:700;font-size:14px;color:#1c1917;\">{{name}}</span>\n {{#each tags}}<span style=\"font-size:9px;font-weight:700;color:#15803d;border:1px solid #bbf7d0;border-radius:3px;padding:0 4px;\">{{this}}</span>{{/each}}\n <span style=\"flex:1;border-bottom:1px dotted #d6c7b0;\"></span>\n <span style=\"font-weight:700;font-size:14px;color:#1c1917;\">{{formatCurrency price ../../currency ../../locale}}</span>\n </div>\n <p style=\"margin:2px 0 0;font-size:12px;color:#78716c;\">{{description}}</p>\n </div>\n {{/each}}\n </div>\n {{/each}}\n <p style=\"margin:8px 0 0;text-align:center;font-size:11px;color:#a8a29e;\">{{legend}}</p>\n</div>" ;
const res = await fetch ( "https://pdfgen.com/api/v1/generate" , {
method : "POST" ,
headers : {
Authorization : "Bearer pdfg_live_xxx" ,
"Content-Type" : "application/json" ,
} ,
body : JSON . stringify ( {
html : template ,
engine : "handlebars" ,
format : "A4" ,
data : {
"name" : "Olive & Thyme" ,
"tagline" : "Mediterranean kitchen" ,
"address" : "18 Rua das Flores, Lisbon" ,
"hours" : "Tue–Sun, 12:00–22:30" ,
"currency" : "EUR" ,
"locale" : "en-IE" ,
"sections" : [
{
"name" : "Starters" ,
"items" : [
{
"name" : "Grilled halloumi" ,
"description" : "Honey, thyme, toasted pistachio" ,
"tags" : [
"V" ,
"GF"
] ,
"price" : 9
} ,
{
"name" : "Whipped feta & flatbread" ,
"description" : "Roasted peppers, chilli oil, warm flatbread" ,
"tags" : [
"V"
] ,
"price" : 8.5
} ,
{
"name" : "Garlic prawns" ,
"description" : "Olive oil, parsley, lemon, sourdough" ,
"tags" : [ ] ,
"price" : 12
}
]
} ,
{
"name" : "Mains" ,
"items" : [
{
"name" : "Lamb kofta" ,
"description" : "Tahini yoghurt, herb salad, pickled onion" ,
"tags" : [
"GF"
] ,
"price" : 21
} ,
{
"name" : "Whole sea bream" ,
"description" : "Charred lemon, capers, crushed potatoes" ,
"tags" : [
"GF"
] ,
"price" : 24
} ,
{
"name" : "Mushroom & farro risotto" ,
"description" : "Wild mushrooms, parmesan, truffle oil" ,
"tags" : [
"V"
] ,
"price" : 18
} ,
{
"name" : "Roasted cauliflower steak" ,
"description" : "Romesco, almonds, pomegranate" ,
"tags" : [
"VG" ,
"GF"
] ,
"price" : 17
}
]
} ,
{
"name" : "Desserts" ,
"items" : [
{
"name" : "Pastel de nata" ,
"description" : "Warm custard tart, cinnamon" ,
"tags" : [
"V"
] ,
"price" : 4.5
} ,
{
"name" : "Olive oil cake" ,
"description" : "Orange, mascarpone, candied peel" ,
"tags" : [
"V"
] ,
"price" : 7
} ,
{
"name" : "Dark chocolate mousse" ,
"description" : "Sea salt, olive oil, hazelnut crumb" ,
"tags" : [
"VG"
] ,
"price" : 7.5
}
]
}
] ,
"legend" : "V vegetarian · VG vegan · GF gluten free · Please tell us about any allergies"
} ,
} ) ,
} ) ;
fs . writeFileSync ( "restaurant-menu.pdf" , Buffer . from ( await res . arrayBuffer ( ) ) ) ;
Copyimport requests
template = "<link href=\"https://fonts.googleapis.com/css2?family=Playfair+Display:wght@500;700&display=swap\" rel=\"stylesheet\">\n<div style=\"max-width:700px;margin:0 auto;padding:52px 56px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;color:#111827;\">\n <div style=\"text-align:center;margin-bottom:30px;\">\n <p style=\"margin:0;font-size:11px;letter-spacing:4px;text-transform:uppercase;color:#a16207;\">{{tagline}}</p>\n <h1 style=\"margin:8px 0 0;font-family:'Playfair Display',Georgia,serif;font-size:42px;font-weight:700;color:#1c1917;\">{{name}}</h1>\n <div style=\"display:flex;align-items:center;justify-content:center;gap:10px;margin:14px 0;\">\n <span style=\"width:60px;height:1px;background:#d6c7b0;\"></span><span style=\"width:6px;height:6px;background:#a16207;transform:rotate(45deg);\"></span><span style=\"width:60px;height:1px;background:#d6c7b0;\"></span>\n </div>\n <p style=\"margin:0;font-size:12px;color:#78716c;\">{{address}} · {{hours}}</p>\n </div>\n {{#each sections}}\n <h2 style=\"margin:0 0 12px;font-family:'Playfair Display',Georgia,serif;font-size:22px;font-weight:500;text-align:center;color:#a16207;\">{{name}}</h2>\n <div style=\"margin-bottom:24px;\">\n {{#each items}}\n <div style=\"margin-bottom:11px;\">\n <div style=\"display:flex;align-items:baseline;gap:8px;\">\n <span style=\"font-weight:700;font-size:14px;color:#1c1917;\">{{name}}</span>\n {{#each tags}}<span style=\"font-size:9px;font-weight:700;color:#15803d;border:1px solid #bbf7d0;border-radius:3px;padding:0 4px;\">{{this}}</span>{{/each}}\n <span style=\"flex:1;border-bottom:1px dotted #d6c7b0;\"></span>\n <span style=\"font-weight:700;font-size:14px;color:#1c1917;\">{{formatCurrency price ../../currency ../../locale}}</span>\n </div>\n <p style=\"margin:2px 0 0;font-size:12px;color:#78716c;\">{{description}}</p>\n </div>\n {{/each}}\n </div>\n {{/each}}\n <p style=\"margin:8px 0 0;text-align:center;font-size:11px;color:#a8a29e;\">{{legend}}</p>\n</div>"
res = requests . post (
"https://pdfgen.com/api/v1/generate" ,
headers = { "Authorization" : "Bearer pdfg_live_xxx" } ,
json = {
"html" : template ,
"engine" : "handlebars" ,
"format" : "A4" ,
"data" : {
"name" : "Olive & Thyme" ,
"tagline" : "Mediterranean kitchen" ,
"address" : "18 Rua das Flores, Lisbon" ,
"hours" : "Tue–Sun, 12:00–22:30" ,
"currency" : "EUR" ,
"locale" : "en-IE" ,
"sections" : [
{
"name" : "Starters" ,
"items" : [
{
"name" : "Grilled halloumi" ,
"description" : "Honey, thyme, toasted pistachio" ,
"tags" : [
"V" ,
"GF"
] ,
"price" : 9
} ,
{
"name" : "Whipped feta & flatbread" ,
"description" : "Roasted peppers, chilli oil, warm flatbread" ,
"tags" : [
"V"
] ,
"price" : 8.5
} ,
{
"name" : "Garlic prawns" ,
"description" : "Olive oil, parsley, lemon, sourdough" ,
"tags" : [ ] ,
"price" : 12
}
]
} ,
{
"name" : "Mains" ,
"items" : [
{
"name" : "Lamb kofta" ,
"description" : "Tahini yoghurt, herb salad, pickled onion" ,
"tags" : [
"GF"
] ,
"price" : 21
} ,
{
"name" : "Whole sea bream" ,
"description" : "Charred lemon, capers, crushed potatoes" ,
"tags" : [
"GF"
] ,
"price" : 24
} ,
{
"name" : "Mushroom & farro risotto" ,
"description" : "Wild mushrooms, parmesan, truffle oil" ,
"tags" : [
"V"
] ,
"price" : 18
} ,
{
"name" : "Roasted cauliflower steak" ,
"description" : "Romesco, almonds, pomegranate" ,
"tags" : [
"VG" ,
"GF"
] ,
"price" : 17
}
]
} ,
{
"name" : "Desserts" ,
"items" : [
{
"name" : "Pastel de nata" ,
"description" : "Warm custard tart, cinnamon" ,
"tags" : [
"V"
] ,
"price" : 4.5
} ,
{
"name" : "Olive oil cake" ,
"description" : "Orange, mascarpone, candied peel" ,
"tags" : [
"V"
] ,
"price" : 7
} ,
{
"name" : "Dark chocolate mousse" ,
"description" : "Sea salt, olive oil, hazelnut crumb" ,
"tags" : [
"VG"
] ,
"price" : 7.5
}
]
}
] ,
"legend" : "V vegetarian · VG vegan · GF gluten free · Please tell us about any allergies"
} ,
} ,
)
with open ( "restaurant-menu.pdf" , "wb" ) as f :
f . write ( res . content )