Generate a PDF in Go

The simplest way to generate a PDF in Go is to call the Docweave API: POST your HTML to /api/v1/pdf with the standard net/http client and write the response to disk with os.WriteFile — no headless browser to run yourself.

Generate a PDF from Go with net/http

Build the request body, POST it with an Authorization: Bearer header, and write the returned PDF bytes to a file:

package main

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

type pdfSource struct {
	Type string `json:"type"`
	HTML string `json:"html"`
}

type pdfRequest struct {
	Source pdfSource `json:"source"`
	IdempotencyKey string `json:"idempotencyKey"`
}

func main() {
	reqBody := pdfRequest{
		Source: pdfSource{
			Type: "html",
			HTML: "<h1>Hello from Go</h1><p>Generated with Docweave.</p>",
		},
		IdempotencyKey: "go-example-001",
	}

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

	req, err := http.NewRequest(
		http.MethodPost,
		"https://docweave.dev/api/v1/pdf",
		bytes.NewReader(payload),
	)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("DOCWEAVE_API_KEY"))
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Accept", "application/pdf")

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

	if resp.StatusCode != http.StatusOK {
		body, _ := io.ReadAll(resp.Body)
		fmt.Printf("render failed: %d %s\n", resp.StatusCode, string(body))
		os.Exit(1)
	}

	pdfBytes, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}

	if err := os.WriteFile("output.pdf", pdfBytes, 0644); err != nil {
		panic(err)
	}

	fmt.Println("wrote output.pdf")
}

The source can also be { "type": "url", "url": "..." } to render a live page, or { "type": "template" } plus a data object to bind JSON into a stored HTML template. Docweave renders every source with Chromium and returns a ready PDF.

…or call it from an AI agent

The same rendering path is exposed as an open-source MCP server (npx @docweave/mcp), so an AI agent — including one your Go service shells out to or orchestrates — gets a generate_pdf tool with no HTTP boilerplate:

// From an AI agent (e.g. a Go-based agent or one your Go service
// shells out to) — no HTTP plumbing, via the MCP generate_pdf tool:
generate_pdf({
  source: {
    type: "html",
    html: "<h1>Hello from Go</h1><p>Generated with Docweave.</p>"
  },
  outputPath: "/tmp/output.pdf"
})

FAQ

What is the simplest way to generate a PDF in Go?

Call the Docweave API: POST your HTML (or a URL, or a template + JSON) to /api/v1/pdf with net/http and write the response body to disk with os.WriteFile. There's no headless browser to install, manage, or run yourself.

Do I need to run a headless Chrome/Chromium binary in my Go service?

No. Docweave renders with Chromium on its own infrastructure and streams back the finished PDF bytes. Your Go code only needs a standard net/http.Client — no chromedp, no wkhtmltopdf binary, no browser process to manage in production.

How do I convert Go HTML templates (html/template) to PDF?

Render your html/template.Template to a bytes.Buffer as you normally would, then send that string as the source.html field in the request body instead of writing it to an http.ResponseWriter. The rest of the request is identical to the example above.

How is PDF generation billed, and how do I avoid duplicate PDFs on retry?

Docweave bills per document, not per page, so a long report costs the same as a short one. Pass an idempotencyKey (for example a request or job ID) — a retried request with the same key returns the original result instead of rendering and billing again.

Ready to generate PDFs from your Go service?

Get an API key