HTML to PDF in Ruby
The classic Rails answer — wicked_pdf — depends on
wkhtmltopdf, which was archived in 2023 and renders CSS like it's 2012. Prawn means
hand-positioning every element. Or: one Net::HTTP call,
zero gems, real Chromium rendering.
1. Convert HTML to PDF
require 'net/http'
require 'json'
uri = URI('https://inkpdf.dev/v1/pdf')
req = Net::HTTP::Post.new(uri)
req['Authorization'] = "Bearer #{ENV.fetch('INKPDF_KEY')}"
req['Content-Type'] = 'application/json'
req.body = {
html: '<h1>Hello from Ruby</h1><p>Modern CSS included.</p>',
options: { format: 'A4' }
}.to_json
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true, read_timeout: 60) do |http|
http.request(req)
end
raise JSON.parse(res.body)['message'] unless res.is_a?(Net::HTTPSuccess)
File.binwrite('hello.pdf', res.body)2. Invoice from a hash (no HTML)
req.body = {
template: 'invoice',
data: {
brand: { name: 'Acme Studio', color: '#0f766e' },
invoiceNumber: 'INV-2043',
issueDate: '2026-07-01',
dueDate: '2026-07-31',
currency: 'USD',
to: { name: 'Northwind Traders', address: '1 Market St, SF' },
items: [
{ description: 'Design work', quantity: 10, unitPrice: 95 }
],
taxRate: 8.5
}
}.to_jsonTotals and tax are computed server-side — see the template gallery for receipt, quote, report, and certificate layouts too.
3. Rails controller: send the PDF
class InvoicesController < ApplicationController
def show
invoice = Invoice.find(params[:id])
pdf = InkpdfClient.render(template: 'invoice', data: invoice.to_template_data)
send_data pdf,
filename: "#{invoice.number}.pdf",
type: 'application/pdf',
disposition: 'attachment'
end
endWrap the Net::HTTP call from step 1 in a small
InkpdfClient class (or use Faraday/HTTParty if they're
already in your Gemfile — it's one POST either way).
Markdown mode for reports
req.body = { markdown: report_markdown, theme: 'serif' }.to_jsonErrors and quotas
Non-200 responses are JSON: {"error": "quota_exceeded",
"message": "…"}. Only successful renders count against your monthly quota, and
every PDF response carries x-inkpdf-used /
x-inkpdf-quota headers so you always know where you stand.
Try it without writing code
The playground renders live against the real pipeline — 20 free renders a day, no signup.