Skip to content

What is Microlink

Microlink is an API that turns any URL into structured data, screenshots, PDFs, and more. You send a URL, Microlink opens it in a headless browser, and returns exactly what you asked for — metadata, images, documents, or custom-extracted fields — through a single HTTP GET request.

The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://github.com/microlinkhq' URL:

CLI Microlink API example

microlink https://github.com/microlinkhq

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://github.com/microlinkhq"

JavaScript Microlink API example

import mql from '@microlink/mql'

const { data } = await mql('https://github.com/microlinkhq')

Python Microlink API example

import requests

url = "https://api.microlink.io/"

querystring = {
    "url": "https://github.com/microlinkhq"
}

response = requests.get(url, params=querystring)

print(response.json())

Ruby Microlink API example

require 'uri'
require 'net/http'

base_url = "https://api.microlink.io/"

params = {
  url: "https://github.com/microlinkhq"
}

uri = URI(base_url)
uri.query = URI.encode_www_form(params)

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Get.new(uri)
response = http.request(request)

puts response.body

PHP Microlink API example

<?php

$baseUrl = "https://api.microlink.io/";

$params = [
    "url" => "https://github.com/microlinkhq"
];

$query = http_build_query($params);
$url = $baseUrl . '?' . $query;

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET"
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
    echo "cURL Error #: " . $err;
} else {
    echo $response;
}

Golang Microlink API example

package main

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

func main() {
    baseURL := "https://api.microlink.io"

    u, err := url.Parse(baseURL)
    if err != nil {
        panic(err)
    }
    q := u.Query()
    q.Set("url", "https://github.com/microlinkhq")
    u.RawQuery = q.Encode()

    req, err := http.NewRequest("GET", u.String(), nil)
    if err != nil {
        panic(err)
    }

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }

    fmt.Println(string(body))
}
Every request starts with a URL. By default, Microlink returns normalized metadata for the page.
No infrastructure to manage. No browser to install. No Puppeteer cluster to scale. You get a production-ready API that handles rendering, caching, and asset delivery out of the box.
Plus automatic proxy resolution on any
PRO
plan to bypass IP blocking, CAPTCHAs, cookie banners, and other scraping shields, so you can reliably reach sites that actively resist automation.

The core idea

Most web automation tasks — taking screenshots, extracting data, generating PDFs, detecting technologies — require the same underlying work: open a browser, load a page, wait for it to render, then do something with the result.
Microlink abstracts that entire pipeline into query parameters. Instead of writing and maintaining browser automation code, you describe what you want and the API handles how to get it.
https://api.microlink.io?url=https://example.com&screenshot=true&pdf=true
That single URL opens a headless browser, renders the page, captures a screenshot, stores it on a CDN, and returns the asset metadata as JSON — all in one request.

What you can do

Microlink is not a single-purpose tool. It is a general-purpose browser automation API with several built-in workflows:
WorkflowWhat it doesKey parameter
MetadataExtract normalized title, description, image, author, date, logo from any URLDefault behavior
ScreenshotCapture a full-page or element-level image of any websitescreenshot
PDFGenerate a printable document from any pagepdf
Data extractionScrape specific fields using CSS selectors and extraction rulesdata
MarkdownConvert page content to clean Markdowndata + attr: 'markdown'
FunctionRun arbitrary JavaScript with full Puppeteer accessfunction
InsightsDetect technologies behind a site or run Lighthouse auditsinsights
Every workflow shares the same endpoint, the same caching layer, the same authentication model, and the same response format. Learn one, and the rest follow the same pattern.

See it in action

The default response gives you everything needed for a link preview — title, description, image, logo, author, date, language, and publisher:

The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://vercel.com' URL:

CLI Microlink API example

microlink https://vercel.com

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://vercel.com"

JavaScript Microlink API example

import mql from '@microlink/mql'

const { data } = await mql('https://vercel.com')

Python Microlink API example

import requests

url = "https://api.microlink.io/"

querystring = {
    "url": "https://vercel.com"
}

response = requests.get(url, params=querystring)

print(response.json())

Ruby Microlink API example

require 'uri'
require 'net/http'

base_url = "https://api.microlink.io/"

params = {
  url: "https://vercel.com"
}

uri = URI(base_url)
uri.query = URI.encode_www_form(params)

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Get.new(uri)
response = http.request(request)

puts response.body

PHP Microlink API example

<?php

$baseUrl = "https://api.microlink.io/";

$params = [
    "url" => "https://vercel.com"
];

$query = http_build_query($params);
$url = $baseUrl . '?' . $query;

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET"
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
    echo "cURL Error #: " . $err;
} else {
    echo $response;
}

Golang Microlink API example

package main

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

func main() {
    baseURL := "https://api.microlink.io"

    u, err := url.Parse(baseURL)
    if err != nil {
        panic(err)
    }
    q := u.Query()
    q.Set("url", "https://vercel.com")
    u.RawQuery = q.Encode()

    req, err := http.NewRequest("GET", u.String(), nil)
    if err != nil {
        panic(err)
    }

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }

    fmt.Println(string(body))
}
Normalized metadata works across millions of sites without any configuration. Useful for link previews, content aggregators, and SEO tools.

Take a screenshot

Add screenshot: true to capture a visual snapshot of the page:

The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://github.com/microlinkhq' URL with 'screenshot' & 'meta' API parameters:

CLI Microlink API example

microlink https://github.com/microlinkhq&screenshot

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://github.com/microlinkhq" \
  -d "screenshot=true" \
  -d "meta=false"

JavaScript Microlink API example

import mql from '@microlink/mql'

const { data } = await mql('https://github.com/microlinkhq', {
  screenshot: true,
  meta: false
})

Python Microlink API example

import requests

url = "https://api.microlink.io/"

querystring = {
    "url": "https://github.com/microlinkhq",
    "screenshot": "true",
    "meta": "false"
}

response = requests.get(url, params=querystring)

print(response.json())

Ruby Microlink API example

require 'uri'
require 'net/http'

base_url = "https://api.microlink.io/"

params = {
  url: "https://github.com/microlinkhq",
  screenshot: "true",
  meta: "false"
}

uri = URI(base_url)
uri.query = URI.encode_www_form(params)

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Get.new(uri)
response = http.request(request)

puts response.body

PHP Microlink API example

<?php

$baseUrl = "https://api.microlink.io/";

$params = [
    "url" => "https://github.com/microlinkhq",
    "screenshot" => "true",
    "meta" => "false"
];

$query = http_build_query($params);
$url = $baseUrl . '?' . $query;

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET"
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
    echo "cURL Error #: " . $err;
} else {
    echo $response;
}

Golang Microlink API example

package main

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

func main() {
    baseURL := "https://api.microlink.io"

    u, err := url.Parse(baseURL)
    if err != nil {
        panic(err)
    }
    q := u.Query()
    q.Set("url", "https://github.com/microlinkhq")
    q.Set("screenshot", "true")
    q.Set("meta", "false")
    u.RawQuery = q.Encode()

    req, err := http.NewRequest("GET", u.String(), nil)
    if err != nil {
        panic(err)
    }

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }

    fmt.Println(string(body))
}
The generated image is returned under data.screenshot.url, hosted on a CDN and ready to use.

Extract specific data

Use data rules to pull exactly the fields you need from any page:

The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://news.ycombinator.com' URL with 'data' API parameter:

CLI Microlink API example

microlink https://news.ycombinator.com&data.stories.selectorAll=.athing&data.stories.attr.title.selector='.titleline > a'&data.stories.attr.title.attr=text&data.stories.attr.href.selector='.titleline > a'&data.stories.attr.href.attr=href

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://news.ycombinator.com" \
  -d "data.stories.selectorAll=.athing" \
  -d "data.stories.attr.title.selector=.titleline%20%3E%20a" \
  -d "data.stories.attr.title.attr=text" \
  -d "data.stories.attr.href.selector=.titleline%20%3E%20a" \
  -d "data.stories.attr.href.attr=href"

JavaScript Microlink API example

import mql from '@microlink/mql'

const { data } = await mql('https://news.ycombinator.com', {
  data: {
    stories: {
      selectorAll: ".athing",
      attr: {
        title: {
          selector: ".titleline > a",
          attr: "text"
        },
        href: {
          selector: ".titleline > a",
          attr: "href"
        }
      }
    }
  }
})

Python Microlink API example

import requests

url = "https://api.microlink.io/"

querystring = {
    "url": "https://news.ycombinator.com",
    "data.stories.selectorAll": ".athing",
    "data.stories.attr.title.selector": ".titleline > a",
    "data.stories.attr.title.attr": "text",
    "data.stories.attr.href.selector": ".titleline > a",
    "data.stories.attr.href.attr": "href"
}

response = requests.get(url, params=querystring)

print(response.json())

Ruby Microlink API example

require 'uri'
require 'net/http'

base_url = "https://api.microlink.io/"

params = {
  url: "https://news.ycombinator.com",
  data.stories.selectorAll: ".athing",
  data.stories.attr.title.selector: ".titleline > a",
  data.stories.attr.title.attr: "text",
  data.stories.attr.href.selector: ".titleline > a",
  data.stories.attr.href.attr: "href"
}

uri = URI(base_url)
uri.query = URI.encode_www_form(params)

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Get.new(uri)
response = http.request(request)

puts response.body

PHP Microlink API example

<?php

$baseUrl = "https://api.microlink.io/";

$params = [
    "url" => "https://news.ycombinator.com",
    "data.stories.selectorAll" => ".athing",
    "data.stories.attr.title.selector" => ".titleline > a",
    "data.stories.attr.title.attr" => "text",
    "data.stories.attr.href.selector" => ".titleline > a",
    "data.stories.attr.href.attr" => "href"
];

$query = http_build_query($params);
$url = $baseUrl . '?' . $query;

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET"
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
    echo "cURL Error #: " . $err;
} else {
    echo $response;
}

Golang Microlink API example

package main

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

func main() {
    baseURL := "https://api.microlink.io"

    u, err := url.Parse(baseURL)
    if err != nil {
        panic(err)
    }
    q := u.Query()
    q.Set("url", "https://news.ycombinator.com")
    q.Set("data.stories.selectorAll", ".athing")
    q.Set("data.stories.attr.title.selector", ".titleline > a")
    q.Set("data.stories.attr.title.attr", "text")
    q.Set("data.stories.attr.href.selector", ".titleline > a")
    q.Set("data.stories.attr.href.attr", "href")
    u.RawQuery = q.Encode()

    req, err := http.NewRequest("GET", u.String(), nil)
    if err != nil {
        panic(err)
    }

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }

    fmt.Println(string(body))
}
Define what you want with CSS selectors. Microlink renders the page in a real browser first, so JavaScript-heavy sites work too.

Generate a PDF

Turn any page into a printable document:

The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://example.com' URL with 'pdf' & 'meta' API parameters:

CLI Microlink API example

microlink https://example.com&pdf

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://example.com" \
  -d "pdf=true" \
  -d "meta=false"

JavaScript Microlink API example

import mql from '@microlink/mql'

const { data } = await mql('https://example.com', {
  pdf: true,
  meta: false
})

Python Microlink API example

import requests

url = "https://api.microlink.io/"

querystring = {
    "url": "https://example.com",
    "pdf": "true",
    "meta": "false"
}

response = requests.get(url, params=querystring)

print(response.json())

Ruby Microlink API example

require 'uri'
require 'net/http'

base_url = "https://api.microlink.io/"

params = {
  url: "https://example.com",
  pdf: "true",
  meta: "false"
}

uri = URI(base_url)
uri.query = URI.encode_www_form(params)

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Get.new(uri)
response = http.request(request)

puts response.body

PHP Microlink API example

<?php

$baseUrl = "https://api.microlink.io/";

$params = [
    "url" => "https://example.com",
    "pdf" => "true",
    "meta" => "false"
];

$query = http_build_query($params);
$url = $baseUrl . '?' . $query;

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET"
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
    echo "cURL Error #: " . $err;
} else {
    echo $response;
}

Golang Microlink API example

package main

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

func main() {
    baseURL := "https://api.microlink.io"

    u, err := url.Parse(baseURL)
    if err != nil {
        panic(err)
    }
    q := u.Query()
    q.Set("url", "https://example.com")
    q.Set("pdf", "true")
    q.Set("meta", "false")
    u.RawQuery = q.Encode()

    req, err := http.NewRequest("GET", u.String(), nil)
    if err != nil {
        panic(err)
    }

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }

    fmt.Println(string(body))
}
The PDF is generated from a real browser render, so the output matches what you see in the browser print dialog.

Run custom code

When built-in parameters are not enough, run your own JavaScript inside the headless browser:

The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://news.ycombinator.com' URL with 'function' & 'meta' API parameters:

CLI Microlink API example

microlink https://news.ycombinator.com&function='({ page }) => page.evaluate(() => `There are ${document.querySelectorAll("a[href]").length} links`)'

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://news.ycombinator.com" \
  -d "function=(%7B%20page%20%7D)%20%3D%3E%20page.evaluate(()%20%3D%3E%20%60There%20are%20%24%7Bdocument.querySelectorAll(%22a%5Bhref%5D%22).length%7D%20links%60)" \
  -d "meta=false"

JavaScript Microlink API example

import mql from '@microlink/mql'

const { data } = await mql('https://news.ycombinator.com', {
  function: '({ page }) => page.evaluate(() => `There are ${document.querySelectorAll("a[href]").length} links`)',
  meta: false
})

Python Microlink API example

import requests

url = "https://api.microlink.io/"

querystring = {
    "url": "https://news.ycombinator.com",
    "function": '''({ page }) => page.evaluate(() => `There are ${document.querySelectorAll("a[href]").length} links`)''',
    "meta": "false"
}

response = requests.get(url, params=querystring)

print(response.json())

Ruby Microlink API example

require 'uri'
require 'net/http'

base_url = "https://api.microlink.io/"

params = {
  url: "https://news.ycombinator.com",
  function: '({ page }) => page.evaluate(() => `There are ${document.querySelectorAll("a[href]").length} links`)',
  meta: "false"
}

uri = URI(base_url)
uri.query = URI.encode_www_form(params)

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Get.new(uri)
response = http.request(request)

puts response.body

PHP Microlink API example

<?php

$baseUrl = "https://api.microlink.io/";

$params = [
    "url" => "https://news.ycombinator.com",
    "function" => '({ page }) => page.evaluate(() => `There are ${document.querySelectorAll("a[href]").length} links`)',
    "meta" => "false"
];

$query = http_build_query($params);
$url = $baseUrl . '?' . $query;

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET"
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
    echo "cURL Error #: " . $err;
} else {
    echo $response;
}

Golang Microlink API example

package main

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

func main() {
    baseURL := "https://api.microlink.io"

    u, err := url.Parse(baseURL)
    if err != nil {
        panic(err)
    }
    fn := `({ page }) => page.evaluate(() => `There are ${document.querySelectorAll("a[href]").length} links`)`

    q := u.Query()
    q.Set("url", "https://news.ycombinator.com")
    q.Set("function", fn)
    q.Set("meta", "false")
    u.RawQuery = q.Encode()

    req, err := http.NewRequest("GET", u.String(), nil)
    if err != nil {
        panic(err)
    }

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }

    fmt.Println(string(body))
}
Full Puppeteer access through a single API call. No infrastructure to manage.
Microlink is the right tool when you need browser rendering without owning browser infrastructure:
  • Link previews — show a rich card (title, image, description) for any URL your users share.
  • Social cards and OG images — generate dynamic og:image screenshots for blog posts, profiles, or dashboards.
  • Web scraping — extract structured data from pages that require JavaScript rendering.
  • PDF generation — convert invoices, reports, or articles into downloadable documents.
  • Content pipelines — convert web pages to Markdown for CMS imports or LLM training data.
  • Competitive intelligence — detect the tech stack behind any website.
  • Performance monitoring — run Lighthouse audits programmatically without a local Chrome installation.
  • Automated testing — capture visual snapshots for regression testing across devices and viewports.
  • Hard-to-reach sites — scrape or screenshot pages protected by CAPTCHAs, IP blocking, cookie banners, or bot detection.
  • AI agents and LLMs — give your agent eyes and hands on the web: browse behind proxy shields, convert pages to Markdown to save tokens, and take screenshots so the model can see what's on screen.

Automatic proxy resolution
PRO

Many websites actively block automated requests through IP rate limiting, CAPTCHAs, anti-bot shields, or geo-restrictions. With a
PRO
plan, Microlink includes automatic proxy resolution — the API routes requests through rotating, high-quality proxies so you don't have to deal with blocking yourself.
This means you can reliably extract data, take screenshots, or generate PDFs from sites that resist scraping, without configuring or paying for a separate proxy service. The proxy infrastructure is .
You can also bring your own proxy if you need a specific geographic location or a provider you already pay for. See the proxy reference for details.

When something else is better

Microlink is not the best fit for every scenario:
ScenarioBetter alternative
You need to crawl thousands of pages following linksA dedicated crawler (Scrapy, Crawlee)
You need real-time, bidirectional browser interaction (debugging, live preview)A local Puppeteer or Playwright instance
You only need static HTML — no JavaScript rendering requiredA simple HTTP client (fetch, curl)
You need to store large volumes of scraped dataA scraping platform with built-in storage

How requests work

Every Microlink request follows the same lifecycle:
  1. You send a URL plus optional parameters via HTTP GET.
  2. Microlink opens the page in a headless browser (Chromium), handling JavaScript, redirects, and rendering.
  3. The API executes your request — metadata extraction, screenshot capture, data rules, functions, or any combination.
  4. Assets are stored on a CDN and cached according to the TTL you configure.
  5. You get a JSON response with the results, or a direct asset response if you use embed.
The response always includes a status field (success or fail) and a data object with the requested fields:
{
  "status": "success",
  "data": {
    "title": "microlink.io",
    "description": "Turn websites into data.",
    "image": {
      "url": "https://avatars0.githubusercontent.com/u/29799436?s=280&v=4",
      "type": "png",
      "size": 4118,
      "width": 280,
      "height": 280,
      "size_pretty": "4.12 kB"
    }
  }
}

Combine workflows in one call

A single request can produce multiple outputs. For example, extract metadata and take a screenshot at the same time:

The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://github.com/microlinkhq' URL with 'screenshot' API parameter:

CLI Microlink API example

microlink https://github.com/microlinkhq&screenshot

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://github.com/microlinkhq" \
  -d "screenshot=true"

JavaScript Microlink API example

import mql from '@microlink/mql'

const { data } = await mql('https://github.com/microlinkhq', {
  screenshot: true
})

Python Microlink API example

import requests

url = "https://api.microlink.io/"

querystring = {
    "url": "https://github.com/microlinkhq",
    "screenshot": "true"
}

response = requests.get(url, params=querystring)

print(response.json())

Ruby Microlink API example

require 'uri'
require 'net/http'

base_url = "https://api.microlink.io/"

params = {
  url: "https://github.com/microlinkhq",
  screenshot: "true"
}

uri = URI(base_url)
uri.query = URI.encode_www_form(params)

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Get.new(uri)
response = http.request(request)

puts response.body

PHP Microlink API example

<?php

$baseUrl = "https://api.microlink.io/";

$params = [
    "url" => "https://github.com/microlinkhq",
    "screenshot" => "true"
];

$query = http_build_query($params);
$url = $baseUrl . '?' . $query;

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET"
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
    echo "cURL Error #: " . $err;
} else {
    echo $response;
}

Golang Microlink API example

package main

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

func main() {
    baseURL := "https://api.microlink.io"

    u, err := url.Parse(baseURL)
    if err != nil {
        panic(err)
    }
    q := u.Query()
    q.Set("url", "https://github.com/microlinkhq")
    q.Set("screenshot", "true")
    u.RawQuery = q.Encode()

    req, err := http.NewRequest("GET", u.String(), nil)
    if err != nil {
        panic(err)
    }

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }

    fmt.Println(string(body))
}
The response includes both data.screenshot and the normalized metadata fields. Disable metadata with meta: false when you only need the screenshot.

Embed assets directly

Instead of parsing JSON, you can make the API URL behave like a direct image, PDF, or any other asset. Use embed to reference the field you want:
<img src="https://api.microlink.io/?url=https://github.com/microlinkhq&screenshot&meta=false&embed=screenshot.url" />
This turns the API URL into a live screenshot you can use in <img> tags, CSS background-image, Markdown, or Open Graph meta tags — no JavaScript required.
LLMs and autonomous agents need to interact with the web, but they face two problems: most websites block bot traffic, and raw HTML wastes context window tokens. Microlink solves both.

Browse behind anti-bot shields

Agents that call URLs directly get blocked by CAPTCHAs, IP rate limits, and bot-detection scripts. Because Microlink renders pages through a real browser with automatic proxy resolution on
PRO
plans, the agent can reach virtually any site without managing proxies or solving challenges itself.

Save tokens with markdown

Feeding raw HTML to an LLM is expensive and noisy — a typical page is 80%+ markup, scripts, and styling that carries no useful information. Convert the page to clean Markdown instead and send only the content the model needs:

The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://example.com' URL with 'data' & 'meta' API parameters:

CLI Microlink API example

microlink https://example.com&data.content.selector=body&data.content.attr=markdown

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://example.com" \
  -d "data.content.selector=body" \
  -d "data.content.attr=markdown" \
  -d "meta=false"

JavaScript Microlink API example

import mql from '@microlink/mql'

const { data } = await mql('https://example.com', {
  data: {
    content: {
      selector: "body",
      attr: "markdown"
    }
  },
  meta: false
})

Python Microlink API example

import requests

url = "https://api.microlink.io/"

querystring = {
    "url": "https://example.com",
    "data.content.selector": "body",
    "data.content.attr": "markdown",
    "meta": "false"
}

response = requests.get(url, params=querystring)

print(response.json())

Ruby Microlink API example

require 'uri'
require 'net/http'

base_url = "https://api.microlink.io/"

params = {
  url: "https://example.com",
  data.content.selector: "body",
  data.content.attr: "markdown",
  meta: "false"
}

uri = URI(base_url)
uri.query = URI.encode_www_form(params)

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Get.new(uri)
response = http.request(request)

puts response.body

PHP Microlink API example

<?php

$baseUrl = "https://api.microlink.io/";

$params = [
    "url" => "https://example.com",
    "data.content.selector" => "body",
    "data.content.attr" => "markdown",
    "meta" => "false"
];

$query = http_build_query($params);
$url = $baseUrl . '?' . $query;

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET"
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
    echo "cURL Error #: " . $err;
} else {
    echo $response;
}

Golang Microlink API example

package main

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

func main() {
    baseURL := "https://api.microlink.io"

    u, err := url.Parse(baseURL)
    if err != nil {
        panic(err)
    }
    q := u.Query()
    q.Set("url", "https://example.com")
    q.Set("data.content.selector", "body")
    q.Set("data.content.attr", "markdown")
    q.Set("meta", "false")
    u.RawQuery = q.Encode()

    req, err := http.NewRequest("GET", u.String(), nil)
    if err != nil {
        panic(err)
    }

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }

    fmt.Println(string(body))
}
The Markdown output strips navigation, ads, and boilerplate. A page that would cost thousands of tokens as HTML fits in a fraction of that as Markdown.

Give the model eyes

Some tasks require the agent to see a page — verifying a layout, reading a chart, or understanding a visual element that isn't represented in the DOM. A screenshot gives the model a visual snapshot it can reason about:

The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://github.com/microlinkhq' URL with 'screenshot' & 'meta' API parameters:

CLI Microlink API example

microlink https://github.com/microlinkhq&screenshot

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://github.com/microlinkhq" \
  -d "screenshot=true" \
  -d "meta=false"

JavaScript Microlink API example

import mql from '@microlink/mql'

const { data } = await mql('https://github.com/microlinkhq', {
  screenshot: true,
  meta: false
})

Python Microlink API example

import requests

url = "https://api.microlink.io/"

querystring = {
    "url": "https://github.com/microlinkhq",
    "screenshot": "true",
    "meta": "false"
}

response = requests.get(url, params=querystring)

print(response.json())

Ruby Microlink API example

require 'uri'
require 'net/http'

base_url = "https://api.microlink.io/"

params = {
  url: "https://github.com/microlinkhq",
  screenshot: "true",
  meta: "false"
}

uri = URI(base_url)
uri.query = URI.encode_www_form(params)

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Get.new(uri)
response = http.request(request)

puts response.body

PHP Microlink API example

<?php

$baseUrl = "https://api.microlink.io/";

$params = [
    "url" => "https://github.com/microlinkhq",
    "screenshot" => "true",
    "meta" => "false"
];

$query = http_build_query($params);
$url = $baseUrl . '?' . $query;

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET"
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
    echo "cURL Error #: " . $err;
} else {
    echo $response;
}

Golang Microlink API example

package main

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

func main() {
    baseURL := "https://api.microlink.io"

    u, err := url.Parse(baseURL)
    if err != nil {
        panic(err)
    }
    q := u.Query()
    q.Set("url", "https://github.com/microlinkhq")
    q.Set("screenshot", "true")
    q.Set("meta", "false")
    u.RawQuery = q.Encode()

    req, err := http.NewRequest("GET", u.String(), nil)
    if err != nil {
        panic(err)
    }

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }

    fmt.Println(string(body))
}
Feed the screenshot URL to a vision-capable model. The agent can describe, compare, or act on what it sees.

Extract structured data for tool use

Instead of asking the LLM to parse HTML, extract exactly the fields the agent needs as structured JSON — ready for tool calls, database writes, or downstream logic:

The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://news.ycombinator.com' URL with 'data' & 'meta' API parameters:

CLI Microlink API example

microlink https://news.ycombinator.com&data.stories.selectorAll=.athing&data.stories.attr.title.selector='.titleline > a'&data.stories.attr.title.attr=text&data.stories.attr.href.selector='.titleline > a'&data.stories.attr.href.attr=href

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://news.ycombinator.com" \
  -d "data.stories.selectorAll=.athing" \
  -d "data.stories.attr.title.selector=.titleline%20%3E%20a" \
  -d "data.stories.attr.title.attr=text" \
  -d "data.stories.attr.href.selector=.titleline%20%3E%20a" \
  -d "data.stories.attr.href.attr=href" \
  -d "meta=false"

JavaScript Microlink API example

import mql from '@microlink/mql'

const { data } = await mql('https://news.ycombinator.com', {
  data: {
    stories: {
      selectorAll: ".athing",
      attr: {
        title: {
          selector: ".titleline > a",
          attr: "text"
        },
        href: {
          selector: ".titleline > a",
          attr: "href"
        }
      }
    }
  },
  meta: false
})

Python Microlink API example

import requests

url = "https://api.microlink.io/"

querystring = {
    "url": "https://news.ycombinator.com",
    "data.stories.selectorAll": ".athing",
    "data.stories.attr.title.selector": ".titleline > a",
    "data.stories.attr.title.attr": "text",
    "data.stories.attr.href.selector": ".titleline > a",
    "data.stories.attr.href.attr": "href",
    "meta": "false"
}

response = requests.get(url, params=querystring)

print(response.json())

Ruby Microlink API example

require 'uri'
require 'net/http'

base_url = "https://api.microlink.io/"

params = {
  url: "https://news.ycombinator.com",
  data.stories.selectorAll: ".athing",
  data.stories.attr.title.selector: ".titleline > a",
  data.stories.attr.title.attr: "text",
  data.stories.attr.href.selector: ".titleline > a",
  data.stories.attr.href.attr: "href",
  meta: "false"
}

uri = URI(base_url)
uri.query = URI.encode_www_form(params)

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Get.new(uri)
response = http.request(request)

puts response.body

PHP Microlink API example

<?php

$baseUrl = "https://api.microlink.io/";

$params = [
    "url" => "https://news.ycombinator.com",
    "data.stories.selectorAll" => ".athing",
    "data.stories.attr.title.selector" => ".titleline > a",
    "data.stories.attr.title.attr" => "text",
    "data.stories.attr.href.selector" => ".titleline > a",
    "data.stories.attr.href.attr" => "href",
    "meta" => "false"
];

$query = http_build_query($params);
$url = $baseUrl . '?' . $query;

$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET"
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
    echo "cURL Error #: " . $err;
} else {
    echo $response;
}

Golang Microlink API example

package main

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

func main() {
    baseURL := "https://api.microlink.io"

    u, err := url.Parse(baseURL)
    if err != nil {
        panic(err)
    }
    q := u.Query()
    q.Set("url", "https://news.ycombinator.com")
    q.Set("data.stories.selectorAll", ".athing")
    q.Set("data.stories.attr.title.selector", ".titleline > a")
    q.Set("data.stories.attr.title.attr", "text")
    q.Set("data.stories.attr.href.selector", ".titleline > a")
    q.Set("data.stories.attr.href.attr", "href")
    q.Set("meta", "false")
    u.RawQuery = q.Encode()

    req, err := http.NewRequest("GET", u.String(), nil)
    if err != nil {
        panic(err)
    }

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }

    fmt.Println(string(body))
}
The agent gets clean JSON it can use directly — no parsing, no hallucinated selectors, no wasted tokens.

Why this matters

Without MicrolinkWith Microlink
Agent fetches HTML, gets blocked by CAPTCHAAutomatic proxy resolution bypasses anti-bot shields
Raw HTML eats 10,000+ tokens per pageMarkdown conversion cuts token usage by 80%+
Agent cannot see visual contentScreenshot gives the model a visual snapshot
LLM parses messy HTML, hallucinates structureStructured JSON extraction returns exact fields
You manage headless browsers, proxies, and retriesOne HTTP GET call, zero infrastructure

Built-in caching

Every response is cached on a global CDN. You control freshness with two parameters:
ParameterWhat it doesDefault
ttl
PRO
How long the cached response is considered fresh24 hours
staleTtl
PRO
How long a stale response can be served while Microlink refreshes it in the background0
force
PRO
Bypass the cache entirely and generate a fresh responsefalse
For most production use cases, the best setup is ttl: '1d' with staleTtl: 0 — the user always gets an instant response, and Microlink refreshes the cache in the background.
See caching patterns for the full strategy.

Free to start, scales with you

The API works without an API key. You get 50 free requests per day, which is enough to build and test your integration. No signup, no credit card.
When you are ready for production, a
PRO
plan unlocks higher quotas, configurable cache TTL, custom headers, proxy support, and priority rendering. See rate limit and authentication for details.

Client libraries

You can call the API from any language that supports HTTP GET, but Microlink provides official libraries for a smoother developer experience:
LibraryUse case
MQLJavaScript/TypeScript client for Node.js, Edge runtimes, and the browser
SDKDrop-in React, Vue, and vanilla JS components for rendering link previews
CLIExplore the API from your terminal during local development

What's next

Now that you understand what Microlink does, pick the workflow that matches your goal:
  • Screenshot — capture high-quality images of any website.
  • Data extraction — scrape structured data with CSS selectors.
  • Metadata — get normalized link preview data.
  • PDF — generate printable documents from any page.
  • Markdown — convert pages to clean Markdown.
  • Function — run JavaScript with full Puppeteer access.
  • Insights — detect technologies or run Lighthouse audits.
Or jump to production patterns if you are ready to integrate.