Skip to content

Go URL to Markdown API

Convert any URL to clean, LLM-ready markdown with one HTTP request in Go — no headless browser, no readability pipeline, no servers to maintain.

Convert a URL to markdown in Go

No module and no browser — the Microlink REST API turns any URL into clean markdown with a single HTTP GET. Here it is with net/http from the Go standard library.
Step 01 · Convert any URL
A few lines with the standard library — no module to add. Point it at a page and read the markdown string from the JSON response.
convert.go
package main

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

func main() {
  params := url.Values{
    "url":                 {"https://example.com"},
    "data.markdown.attr":  {"markdown"},
    "meta":                {"false"}, // skip metadata for a faster response
  }

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

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

  fmt.Println(payload.Data.Markdown)
}
Step 02 · Scope the extraction
Pass a CSS selector to keep just the article body and drop headers, footers, and sidebars — fewer tokens, better embeddings.
scoped.go
package main

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

func main() {
  params := url.Values{
    "url":                    {"https://example.com/blog/post"},
    "data.markdown.attr":     {"markdown"},
    "data.markdown.selector": {"article"}, // keep just the article body
    "meta":                   {"false"},
  }

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

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

  fmt.Println(payload.Data.Markdown)
}
Step 03 · Render JavaScript pages
Client-side rendered content only exists after JavaScript runs — prerender with a real browser and wait for the content, 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/docs"},
    "data.markdown.attr":     {"markdown"},
    "data.markdown.selector": {"main"},
    "prerender":              {"true"},    // render JS in a real browser first
    "waitForSelector":        {"main h1"}, // wait until the content exists
    "meta":                   {"false"},
  }

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

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

  fmt.Println(payload.Data.Markdown)
}
Step 04 · Get markdown back directly
Skip the JSON envelope entirely: embed=markdown returns the page as text/markdown, ready to write into a file or a queue.
embed.go
package main

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

func main() {
  params := url.Values{
    "url":                {"https://example.com"},
    "data.markdown.attr": {"markdown"},
    "meta":               {"false"},
    "embed":              {"markdown"}, // respond with text/markdown
  }

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

  markdown, _ := io.ReadAll(res.Body)

  os.WriteFile("page.md", markdown, 0o644)
}

Drop it into your framework

A Gin handler, an Echo route, or a queue worker — the same request becomes your own URL-to-markdown primitive for agents and RAG pipelines.
  • Gin
  • Echo
  • Worker
  • Plain Go
package main

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

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

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

  // GET /markdown?url=https://example.com
  e.GET("/markdown", func(c echo.Context) error {
    params := url.Values{
      "url":                {c.QueryParam("url")},
      "data.markdown.attr": {"markdown"},
      "meta":               {"false"},
      "embed":              {"markdown"},
    }

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

    markdown, _ := io.ReadAll(res.Body)

    return c.Blob(http.StatusOK, "text/markdown; charset=utf-8", markdown)
  })

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

Skip the readability pipeline maintenance

Rolling your own means fetching HTML, running a readability extractor like go-readability, converting to markdown, and adding chromedp when a page needs JavaScript. The API gives you clean markdown from any page without any of the moving parts.

DIY extraction pipeline

  • Fetch HTML, then chain go-readability + an HTML-to-md converter yourself
  • Every site breaks your selectors in its own special way
  • JavaScript-rendered pages need chromedp — a 300 MB browser
  • Each browser eats hundreds of MB of RAM per worker
  • You build the queueing, retries, caching and autoscaling
  • Output quality drifts as sites change; you own the fixes

Microlink for Go

  • One HTTP request — net/http from the standard library, no module to add
  • Runs anywhere: a single static binary, serverless, containers, your laptop
  • Real browser rendering built in with prerender=true
  • CSS selector scoping keeps tokens focused on the content
  • 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 URL to Markdown guide to go deeper.

  • No Browser to Install

    No headless browser to install or keep patched. JavaScript rendering runs on Microlink’s side with prerender=true.
  • Standard Library Only

    net/http and encoding/json ship with Go — the examples compile with zero external modules.
  • LLM-Ready Output

    Clean markdown instead of HTML noise — around 80% fewer tokens on average, so agents spend context on meaning, not markup.
  • CSS Selector Scoping

    Extract the whole page or narrow to article, main, or any selector — precise content targeting for better embeddings.
  • JavaScript Rendering

    SPAs and client-rendered docs are rendered in a real browser first, with waitForSelector to catch late content.
  • Documents Too

    Point it at a PDF or an office file — docx, xlsx, pptx — and the content is converted to markdown the same way.
  • Framework Friendly

    Drop it into Gin, Echo, or a queue worker as a handler in a few lines.
  • text/markdown Responses

    embed=markdown returns the page as text/markdown — pipe it straight into a file, a queue, or a prompt.
  • Generous Free Tier

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

    No headless browser to install or keep patched. JavaScript rendering runs on Microlink’s side with prerender=true.
  • Standard Library Only

    net/http and encoding/json ship with Go — the examples compile with zero external modules.
  • LLM-Ready Output

    Clean markdown instead of HTML noise — around 80% fewer tokens on average, so agents spend context on meaning, not markup.
  • CSS Selector Scoping

    Extract the whole page or narrow to article, main, or any selector — precise content targeting for better embeddings.
  • JavaScript Rendering

    SPAs and client-rendered docs are rendered in a real browser first, with waitForSelector to catch late content.
  • Documents Too

    Point it at a PDF or an office file — docx, xlsx, pptx — and the content is converted to markdown the same way.
  • Framework Friendly

    Drop it into Gin, Echo, or a queue worker as a handler in a few lines.
  • text/markdown Responses

    embed=markdown returns the page as text/markdown — pipe it straight into a file, a queue, or a prompt.
  • 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 markdown output before you write a line of Go.

Go URL to Markdown FAQ

Everything Go developers ask before integrating the Microlink URL to Markdown API.

Do I need a headless browser?

No. JavaScript rendering runs on Microlink’s managed browser fleet — pass prerender=true and the page is rendered before conversion. Your Go process stays browser-free.

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.

How do I convert only the article body?

Pass a CSS selector with data.markdown.selector=article and the extraction is scoped to that element — headers, footers, and sidebars are dropped before conversion, which keeps token counts down.
See the URL to Markdown guide for scoping strategies.

Does it work in a single static binary?

Yes. Because there is no browser binary or CGO dependency to ship, your Go service stays a single static binary — the rendering fleet runs on Microlink’s side.

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 converting.
When you need more volume, pick a paid plan: same key, bigger quota. See pricing for the limits.

Can I get the response as markdown instead of JSON?

Yes. Add embed=markdown and the API responds with text/markdown directly — handy for piping into files, queues, or prompts without parsing an envelope.

Start converting 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 markdown in minutes.
Free API key
100 requests/month
No credit card