Go HTML to PDF API guide

Use Go standard library HTTP clients to generate PDFs from services, CLIs, workers, or cron jobs.

EndpointPOST https://api.html2pdf.app/v1/generate
AuthenticationX-API-Key: <your-api-key>

Overview

Marshal a JSON payload, authenticate with X-API-Key, and copy the successful PDF response to a file.

The API accepts a JSON request body. Send either a public URL or inline HTML in the required html parameter. For normal synchronous conversions, the response body is the generated PDF and should be saved as binary data.

Requirements

  • Go 1.20 or newer
  • An html2pdf.app API key stored in the environment
  • A backend process or trusted command line task

Quick start

Replace <your-api-key> or the environment variable with your html2pdf.app API key, then run the example from a trusted backend environment.

This example converts a URL and streams the successful PDF response into document.pdf.

package main

import (
  "bytes"
  "encoding/json"
  "fmt"
  "io"
  "net/http"
  "os"
)

func main() {
  payload := map[string]interface{}{
    "html": "https://www.example.com",
  }

  body, err := json.Marshal(payload)
  if err != nil {
    panic(err)
  }

  req, err := http.NewRequest("POST", "https://api.html2pdf.app/v1/generate", bytes.NewReader(body))
  if err != nil {
    panic(err)
  }

  req.Header.Set("Content-Type", "application/json")
  req.Header.Set("X-API-Key", os.Getenv("HTML2PDF_API_KEY"))

  resp, err := http.DefaultClient.Do(req)
  if err != nil {
    panic(err)
  }
  defer resp.Body.Close()

  if resp.StatusCode < 200 || resp.StatusCode >= 300 {
    panic(fmt.Sprintf("PDF generation failed: %s", resp.Status))
  }

  file, err := os.Create("document.pdf")
  if err != nil {
    panic(err)
  }
  defer file.Close()

  if _, err := io.Copy(file, resp.Body); err != nil {
    panic(err)
  }
}

Go examples

These examples cover the next common production flows: generating from inline HTML with options and queuing a callback job.

1. Generate with PDF options

Add format, margin, media, and filename options to the JSON payload.

package main

import (
  "bytes"
  "encoding/json"
  "fmt"
  "io"
  "net/http"
  "os"
)

func main() {
  payload := map[string]interface{}{
    "html": "<h1>Invoice</h1><p>Total: $240.00</p>",
    "format": "A4",
    "media": "print",
    "marginTop": 40,
    "marginRight": 32,
    "marginBottom": 40,
    "marginLeft": 32,
    "filename": "invoice.pdf",
  }

  body, err := json.Marshal(payload)
  if err != nil {
    panic(err)
  }

  req, err := http.NewRequest("POST", "https://api.html2pdf.app/v1/generate", bytes.NewReader(body))
  if err != nil {
    panic(err)
  }

  req.Header.Set("Content-Type", "application/json")
  req.Header.Set("X-API-Key", os.Getenv("HTML2PDF_API_KEY"))

  resp, err := http.DefaultClient.Do(req)
  if err != nil {
    panic(err)
  }
  defer resp.Body.Close()

  if resp.StatusCode < 200 || resp.StatusCode >= 300 {
    panic(fmt.Sprintf("PDF generation failed: %s", resp.Status))
  }

  file, err := os.Create("invoice.pdf")
  if err != nil {
    panic(err)
  }
  defer file.Close()

  _, err = io.Copy(file, resp.Body)
  if err != nil {
    panic(err)
  }
}

2. Queue an asynchronous conversion

Send callback details when the generated PDF should be delivered to your webhook later.

package main

import (
  "bytes"
  "encoding/json"
  "fmt"
  "net/http"
  "os"
)

func main() {
  payload := map[string]interface{}{
    "html": "https://www.example.com/report",
    "callBackUrl": "https://your-app.com/webhooks/html2pdf",
    "state": "report-1042",
  }

  body, err := json.Marshal(payload)
  if err != nil {
    panic(err)
  }

  req, err := http.NewRequest("POST", "https://api.html2pdf.app/v1/generate", bytes.NewReader(body))
  if err != nil {
    panic(err)
  }

  req.Header.Set("Content-Type", "application/json")
  req.Header.Set("X-API-Key", os.Getenv("HTML2PDF_API_KEY"))

  resp, err := http.DefaultClient.Do(req)
  if err != nil {
    panic(err)
  }
  defer resp.Body.Close()

  if resp.StatusCode < 200 || resp.StatusCode >= 300 {
    panic(fmt.Sprintf("Unable to queue PDF job: %s", resp.Status))
  }
}

Request options

Most integrations start with html and then add options as the document design becomes more specific.

  • html is required and accepts a public URL or raw HTML.
  • format, landscape, width, and height control page size.
  • marginTop, marginRight, marginBottom, and marginLeft control whitespace around the rendered page.
  • media selects screen or print CSS rendering.
  • callBackUrl switches the request to asynchronous generation and sends the completed PDF to your webhook.

See the full API parameter reference for every supported field.

Troubleshooting

  • Use io.Copy to stream the response body directly into a PDF file.
  • Close response bodies to avoid leaking connections in workers.
  • Use structs in production if you want compile-time shape checks for payloads.

If the generated document is blank or missing styles, first confirm that the source URL is public and that required CSS, fonts, and images are reachable by the rendering service.