Skip to content

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.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 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

    Start with 25 requests per day — no account, no credit card. Add an API key when you are ready to scale.
  • 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

    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 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?

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 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

Get 25 requests/day with zero commitment — no account and no credit card. Send your first request and ship metadata in minutes.
No login needed
25 reqs/day free
No credit card