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 api.microlink.io?url=microlink.io → data
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Microlink | The web, transformed</title>
<meta name="description" content="A single API for turning any URL into data." />
<meta property="og:image" content="https://microlink.io/images/og/home.png" />
</head>
<body>
<header class="hero">…</header>
<main>…</main>
</body>
</html>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.95% 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
Start with 25 requests per day — no account, no credit card. Add an API key when you are ready to scale.
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
Start with 25 requests per day — no account, no credit card. Add an API key when you are ready to scale.
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?
The free tier gives you 25 requests per day with no account, no credit card, and no API key. Just call the endpoint and start extracting.
When you need more throughput or caching control, add an
apiKey header and requests route to the Pro tier. 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
Get 25 requests/day with zero commitment — no account and no credit card. Send your first request and get HTML back in minutes.
No login needed
25 reqs/day free
No credit card