Skip to content

Go HTML API

Get the fully rendered HTML of any URL with one HTTP request in Go — real Chromium under the hood, none to maintain.

Get HTML in Go

No module and no browser — the Microlink REST API renders any URL and returns the HTML with a single HTTP GET. Here it is with net/http and encoding/json from the Go standard library.
Step 01 · Extract any URL
A few lines with the standard library — no module to add, no Chromium download. Point it at a page and read the rendered HTML from the JSON response.
main.go
package main

import (
  "encoding/json"
  "fmt"
  "net/http"
  "net/url"
)

func main() {
  params := url.Values{
    "url":            {"https://microlink.io"},
    "data.html.attr": {"html"},
  }

  res, err := http.Get("https://api.microlink.io?" + params.Encode())
  if err != nil {
    panic(err)
  }
  defer res.Body.Close()

  var payload struct {
    Data struct {
      HTML string `json:"html"`
    } `json:"data"`
  }
  json.NewDecoder(res.Body).Decode(&payload)

  fmt.Println(len(payload.Data.HTML)) // full rendered document
}
Step 02 · Scope to a selector
Return the whole document or only the subtree you need — smaller responses, less parsing and lower token cost downstream.
selector.go
package main

import (
  "encoding/json"
  "fmt"
  "net/http"
  "net/url"
)

func main() {
  params := url.Values{
    "url":               {"https://microlink.io/blog"},
    "data.html.attr":    {"html"},
    "data.html.selector": {"main"}, // only the <main> subtree
  }

  res, err := http.Get("https://api.microlink.io?" + params.Encode())
  if err != nil {
    panic(err)
  }
  defer res.Body.Close()

  var payload struct {
    Data struct {
      HTML string `json:"html"`
    } `json:"data"`
  }
  json.NewDecoder(res.Body).Decode(&payload)

  // No nav, no footer — just the content you asked for
  fmt.Println(payload.Data.HTML)
}
Step 03 · Render JavaScript pages
Client-rendered apps only produce their markup after JavaScript runs — prerender in a real browser and wait for it, still one request.
spa.go
package main

import (
  "encoding/json"
  "fmt"
  "net/http"
  "net/url"
)

func main() {
  params := url.Values{
    "url":             {"https://app.example.com"},
    "data.html.attr":  {"html"},
    "prerender":       {"true"}, // render JS in a real browser first
    "waitForSelector": {"h1"},   // capture only when the content exists
  }

  res, err := http.Get("https://api.microlink.io?" + params.Encode())
  if err != nil {
    panic(err)
  }
  defer res.Body.Close()

  var payload struct {
    Data struct {
      HTML string `json:"html"`
    } `json:"data"`
  }
  json.NewDecoder(res.Body).Decode(&payload)

  fmt.Println(payload.Data.HTML)
}
Step 04 · Serve the raw HTML
Ask for embed=html and the API answers with text/html directly — proxy it straight to a browser or write it to a file.
raw.go
package main

import (
  "fmt"
  "io"
  "net/http"
  "net/url"
)

func main() {
  params := url.Values{
    "url":            {"https://microlink.io"},
    "data.html.attr": {"html"},
    "embed":          {"html"}, // respond with text/html, no JSON
  }

  res, err := http.Get("https://api.microlink.io?" + params.Encode())
  if err != nil {
    panic(err)
  }
  defer res.Body.Close()

  html, _ := io.ReadAll(res.Body) // ready to serve or store
  fmt.Println(string(html))
}

Drop it into your framework

A Gin handler, an Echo endpoint, or an archive worker — the same request becomes your own rendering endpoint.
  • Gin
  • Echo
  • Archiver
  • Plain Go
package main

import (
  "encoding/json"
  "net/http"
  "net/url"

  "github.com/labstack/echo/v4"
)

func main() {
  e := echo.New()

  // GET /render?url=https://microlink.io
  e.GET("/render", func(c echo.Context) error {
    params := url.Values{
      "url":            {c.QueryParam("url")},
      "data.html.attr": {"html"},
    }

    res, err := http.Get("https://api.microlink.io?" + params.Encode())
    if err != nil {
      return echo.ErrBadGateway
    }
    defer res.Body.Close()

    var payload struct {
      Data struct {
        HTML string `json:"html"`
      } `json:"data"`
    }
    json.NewDecoder(res.Body).Decode(&payload)

    return c.HTML(http.StatusOK, payload.Data.HTML)
  })

  e.Logger.Fatal(e.Start(":1323"))
}

Skip the browser-farm ops

Rolling your own means driving chromedp against your own Chromium fleet, writing per-site wait logic, and fighting antibot walls. The API returns the rendered HTML of any page without any of the moving parts.

DIY rendering stack

  • Run and patch your own headless Chromium fleet
  • Write per-site wait logic for JavaScript-rendered pages
  • Fight antibot walls and CAPTCHAs with your own proxy pool
  • Each browser eats hundreds of MB of RAM per worker
  • You build the caching, retries and autoscaling
  • Every Chromium upgrade breaks a selector somewhere

Microlink for Go

  • One HTTP request — no rendering infrastructure to run
  • Fully rendered HTML from managed Chromium, JS included
  • Selector scoping to return only the subtree you need
  • Antibot and CAPTCHA resolution handled for you
  • Cached responses from a global edge network
  • Autoscaled fleet with a 99.9% uptime SLA

Built for the way you write Go.

A REST API that feels native in Go — one call, JSON back, and at home in anything from a CLI to a render proxy. Read the API overview to go deeper.

  • Real Browser Rendering

    Every request runs in managed Chromium, so client-rendered apps return complete markup instead of an empty shell.
  • Standard Library Only

    net/http and encoding/json ship with Go — the examples compile with zero external dependencies and no browser to manage.
  • Selector Scoping

    Return the full document or a single subtree with a selector — smaller payloads and less parsing downstream.
  • JSON or Raw HTML

    Read data.html from the JSON response, or ask for embed=html and get the document back as text/html — no JSON involved.
  • Readiness You Control

    waitUntil and waitForSelector let you block on network idle or on a specific element before the HTML is captured.
  • One Call, Many Formats

    Request HTML together with markdown, text, metadata, screenshots or PDFs and pay for a single render instead of several.
  • Framework Friendly

    Drop it into Gin, Echo, or an archive worker as a handler in a few lines.
  • Zero Infrastructure

    Managed Headless Chrome, autoscaled and load-balanced. No browser pool, no servers, no patching to maintain.
  • Generous Free Tier

    Sign up for a free API key: 100 requests per month with every Pro feature, no credit card.
  • Real Browser Rendering

    Every request runs in managed Chromium, so client-rendered apps return complete markup instead of an empty shell.
  • Standard Library Only

    net/http and encoding/json ship with Go — the examples compile with zero external dependencies and no browser to manage.
  • Selector Scoping

    Return the full document or a single subtree with a selector — smaller payloads and less parsing downstream.
  • JSON or Raw HTML

    Read data.html from the JSON response, or ask for embed=html and get the document back as text/html — no JSON involved.
  • Readiness You Control

    waitUntil and waitForSelector let you block on network idle or on a specific element before the HTML is captured.
  • One Call, Many Formats

    Request HTML together with markdown, text, metadata, screenshots or PDFs and pay for a single render instead of several.
  • Framework Friendly

    Drop it into Gin, Echo, or an archive worker as a handler in a few lines.
  • Zero Infrastructure

    Managed Headless Chrome, autoscaled and load-balanced. No browser pool, no servers, no patching to maintain.
  • Generous Free Tier

    Sign up for a free API key: 100 requests per month with every Pro feature, no credit card.

Try it live in the playground

Paste a URL and see the rendered output before you write a line of Go.

Go HTML API FAQ

Everything Go developers ask before integrating the Microlink HTML API.

Do I get the source HTML or the rendered DOM?

Every request runs in a real Chromium instance, so data.html is the fully rendered DOM — JavaScript executed, lazy content loaded. Control the capture point with waitUntil and waitForSelector.

Do I need to install a module or a browser?

No. The examples use net/http and encoding/json from the Go standard library, and rendering runs on Microlink — no chromedp, no Chromium binary in your image.

How do I control when the HTML is captured?

Use waitUntil to block on network idle or a fixed delay, and waitForSelector to hold the capture until a specific element exists — the HTML comes back exactly when your page is ready, still in one request.

Can I get only part of the page?

Yes. Add a selector to the extraction rule and only that subtree comes back — ideal for articles, product cards or pricing tables, with smaller payloads and less parsing downstream.

Is there a free tier or do I need an API key?

Yes, and it is free: sign up for an API key and you get 100 requests per month with every Pro feature, no credit card. Add it as x-api-key and start extracting.
When you need more volume, pick a paid plan: same key, bigger quota. See pricing for the limits.

How fresh is the HTML?

Responses are cached at the edge with a sane default TTL, and you control freshness per request — see the API overview for cache parameters.

Start extracting in Go

Sign up for a free API key: 100 requests per month with every Pro feature, no credit card. Send your first request and get HTML back in minutes.
Free API key
100 requests/month
No credit card