Go Metadata API
Extract title, description, image and logo from any URL with one HTTP request in Go — no HTML parsing, no tag soup, no browser to maintain.
Extract metadata in Go
No module and no parser — the Microlink REST API turns any URL into normalized metadata with a single HTTP GET. Here it is with net/http from the Go standard library.
Step 01 · Extract any URL
A few lines with the standard library — no module to add. Point it at a page and read the metadata from the JSON response.
extract.go
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
type Metadata struct {
Title string `json:"title"`
Description string `json:"description"`
Image *Asset `json:"image"`
Logo *Asset `json:"logo"`
}
type Asset struct {
URL string `json:"url"`
}
func main() {
params := url.Values{"url": {"https://microlink.io"}}
res, _ := http.Get("https://api.microlink.io?" + params.Encode())
defer res.Body.Close()
var payload struct {
Data Metadata `json:"data"`
}
json.NewDecoder(res.Body).Decode(&payload)
fmt.Println(payload.Data.Title)
fmt.Println(payload.Data.Description)
}Step 02 · Pick the fields you need
Title, description, publisher, author, date, lang, image and logo all come back in one call — build exactly the object your product needs.
fields.go
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
type Metadata struct {
Title string `json:"title"`
Description string `json:"description"`
Publisher string `json:"publisher"`
Author *string `json:"author"`
Date *string `json:"date"`
Lang string `json:"lang"`
Image *Asset `json:"image"`
Logo *Asset `json:"logo"`
}
type Asset struct {
URL string `json:"url"`
}
func main() {
params := url.Values{"url": {"https://microlink.io"}}
res, _ := http.Get("https://api.microlink.io?" + params.Encode())
defer res.Body.Close()
var payload struct {
Data Metadata `json:"data"`
}
json.NewDecoder(res.Body).Decode(&payload)
fmt.Printf("%+v
", payload.Data)
}Step 03 · Render JavaScript pages
Tags injected by client-side JavaScript only exist after the page renders — prerender with a real browser and wait for them, 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"},
"prerender": {"true"}, // render JS in a real browser first
"waitForSelector": {"h1"}, // wait until the content exists
}
res, _ := http.Get("https://api.microlink.io?" + params.Encode())
defer res.Body.Close()
var payload struct {
Data struct {
Title string `json:"title"`
} `json:"data"`
}
json.NewDecoder(res.Body).Decode(&payload)
fmt.Println(payload.Data.Title)
}Step 04 · Build a link preview
Image and logo come back as absolute, CDN-hosted URLs — drop them straight into an img tag and you have a link preview.
link_preview.go
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
type Metadata struct {
URL string `json:"url"`
Title string `json:"title"`
Description string `json:"description"`
Image *Asset `json:"image"`
Logo *Asset `json:"logo"`
}
type Asset struct {
URL string `json:"url"`
}
func main() {
params := url.Values{"url": {"https://microlink.io"}}
res, _ := http.Get("https://api.microlink.io?" + params.Encode())
defer res.Body.Close()
var payload struct {
Data Metadata `json:"data"`
}
json.NewDecoder(res.Body).Decode(&payload)
data := payload.Data
image := ""
if data.Image != nil {
image = data.Image.URL
} else if data.Logo != nil {
image = data.Logo.URL
}
fmt.Printf(`<a href="%s" class="card">
<img src="%s" alt="" />
<strong>%s</strong>
<p>%s</p>
</a>`, data.URL, image, data.Title, data.Description)
}Drop it into your framework
A Gin handler, an Echo route, or an enrichment worker — the same request becomes your own metadata endpoint for link previews and data pipelines.
- Gin
- Echo
- Worker
- Plain Go
package main
import (
"encoding/json"
"net/http"
"net/url"
"github.com/labstack/echo/v4"
)
func main() {
e := echo.New()
// GET /preview?url=https://microlink.io
e.GET("/preview", func(c echo.Context) error {
params := url.Values{"url": {c.QueryParam("url")}}
res, err := http.Get("https://api.microlink.io?" + params.Encode())
if err != nil {
return echo.ErrBadGateway
}
defer res.Body.Close()
var payload struct {
Data map[string]any `json:"data"`
}
json.NewDecoder(res.Body).Decode(&payload)
return c.JSON(http.StatusOK, payload.Data)
})
e.Logger.Fatal(e.Start(":1323"))
}Skip the tag-parsing maintenance
Rolling your own means fetching HTML, parsing Open Graph and Twitter Cards with goquery, merging JSON-LD and oEmbed, and adding chromedp for JavaScript-injected tags. The API gives you normalized metadata from any page without any of the moving parts.
DIY tag parsing
- Fetch the HTML and parse og, twitter and meta tags yourself
- Merge JSON-LD, oEmbed and microdata by hand — every site differs
- Resolve relative image and logo URLs against redirects yourself
- JavaScript-injected tags need a headless browser — a 300 MB binary
- Each browser eats hundreds of MB of RAM per worker
- You build the caching, retries and autoscaling
Microlink for Go
- One HTTP request — net/http from the standard library, no module to add
- Open Graph, Twitter Cards, JSON-LD and oEmbed merged for you
- Image and logo as absolute, CDN-hosted URLs
- JavaScript-injected tags captured with prerender=true
- 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 tool to a worker fleet. Read the API overview to go deeper.
No HTML Parsing
No tag soup, no regex, no DOM library to install. One HTTP GET returns a normalized JSON object.
Standard Library Only
net/http and encoding/json ship with Go — the examples compile with zero external modules.
Every Source Merged
Open Graph, Twitter Cards, JSON-LD, oEmbed, microdata and plain HTML tags are merged into a single normalized response.
CDN-Hosted Assets
Image and logo come back as absolute URLs on a global CDN — hot-link them directly, no downloading or proxying.
JavaScript Rendering
Tags injected by client-side JavaScript are captured too, with prerender=true and waitForSelector.
Link Preview Ready
Title, description, image, logo and publisher are exactly the fields a link preview card needs — one call, one card.
Framework Friendly
Drop it into Gin, Echo, or an enrichment 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.
No HTML Parsing
No tag soup, no regex, no DOM library to install. One HTTP GET returns a normalized JSON object.Standard Library Only
net/http and encoding/json ship with Go — the examples compile with zero external modules.Every Source Merged
Open Graph, Twitter Cards, JSON-LD, oEmbed, microdata and plain HTML tags are merged into a single normalized response.
CDN-Hosted Assets
Image and logo come back as absolute URLs on a global CDN — hot-link them directly, no downloading or proxying.JavaScript Rendering
Tags injected by client-side JavaScript are captured too, with prerender=true and waitForSelector.Link Preview Ready
Title, description, image, logo and publisher are exactly the fields a link preview card needs — one call, one card.
Framework Friendly
Drop it into Gin, Echo, or an enrichment 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 exact metadata response before you write a line of Go.
Go Metadata API FAQ
Everything Go developers ask before integrating the Microlink metadata API.
Which metadata sources are covered?
Open Graph, Twitter Cards, JSON-LD, oEmbed, microdata, RDFa and plain HTML tags — all merged and normalized into a single JSON response, so you never parse tag soup yourself.
Do I need to install a module?
No. The examples use net/http and encoding/json from the Go standard library — they compile with zero external dependencies.
What about tags rendered by JavaScript?
Pass
prerender=true and the page is rendered in a real browser before extraction, so tags injected by React, Vue or any client-side framework are captured too. Combine it with waitForSelector to wait for specific content.Are image and logo URLs ready to use?
Yes. They come back as absolute URLs hosted on a global CDN — resolve-relative-URL bugs included — so you can hot-link them directly in an
img tag or store them as-is.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 metadata?
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 ship metadata in minutes.
Free API key
100 requests/month
No credit card