Skip to content

Private pages

These authentication patterns apply to every Microlink workflow: screenshots, PDFs, data extraction, metadata, and insights. Each guide's own private pages section covers workflow-specific examples; this page covers the shared patterns.

Choose the right header path
PRO

SituationUseWhy
Language, user-agent, or other non-sensitive valuesheaders parameterFine when the value is safe to expose in the URL
Cookies, bearer tokens, or secretsx-api-header-* request headersKeeps credentials out of the public query string
Both approaches require a
PRO
plan.

Non-sensitive headers
PRO

Use headers when the value is safe to appear in the URL:

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

CLI Microlink API example

microlink https://example.com&headers.Accept-Language=es-ES

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://example.com" \
  -d "headers.Accept-Language=es-ES"

JavaScript Microlink API example

import mql from '@microlink/mql'

const { data } = await mql('https://example.com', {
  headers: {
    "Accept-Language": "es-ES"
  }
})

Python Microlink API example

import requests

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

querystring = {
    "url": "https://example.com",
    "headers.Accept-Language": "es-ES"
}

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",
  headers.Accept-Language: "es-ES"
}

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",
    "headers.Accept-Language" => "es-ES"
];

$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("headers.Accept-Language", "es-ES")
    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))
}
Good for locale and request shaping. Avoid putting cookies or authorization tokens here because query parameters are public.

Sensitive headers and cookies
PRO

For cookies, authorization tokens, or any other secret, pass the value as an HTTP header on the Microlink request itself using the x-api-header-* prefix:
curl -G https://pro.microlink.io \
  -d url=https://example.com/dashboard \
  -H 'x-api-key: YOUR_API_TOKEN' \
  -H 'x-api-header-cookie: session=abc123' \
  -H 'x-api-header-authorization: Bearer YOUR_BEARER_TOKEN'
Microlink strips the x-api-header- prefix and forwards the original header to the target page. Any header can be forwarded this way:
  • x-api-header-cookie
  • x-api-header-authorization
  • x-api-header-x-my-custom-header

Use MQL from the server

Keep credentials in the request headers passed via httpOptions, not in public client-side code:
import mql from '@microlink/mql'

const { data } = await mql(
  'https://example.com/dashboard',
  {
    headers: {
      'accept-language': 'es-ES'
    }
  },
  {
    headers: {
      'x-api-key': process.env.MICROLINK_API_KEY,
      'x-api-header-cookie': `session=${process.env.SESSION_COOKIE}`
    }
  }
)
See the MQL API reference for more on httpOptions.

Use the correct endpoint

  • https://api.microlink.io — unauthenticated, free-tier requests.
  • https://pro.microlink.io — authenticated requests with x-api-key.
If you send x-api-key to the free endpoint, the request fails with EPRO. See the endpoint docs and authentication docs.

Keep credentials out of the browser

Do not expose API keys, cookies, or authorization headers in client-side code or public embed URLs.
This is especially important when you use embed in public markup, because the full URL can end up in HTML source, logs, or browser devtools.

Proxy for blocked or geofenced sites
PRO

When the target site blocks headless browsers, geofences content, or triggers antibot protection, use proxy:

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

CLI Microlink API example

microlink https://example.com&proxy=https://myproxy:[email protected]:8001

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://example.com" \
  -d "proxy=https://myproxy:[email protected]:8001"

JavaScript Microlink API example

import mql from '@microlink/mql'

const { data } = await mql('https://example.com', {
  proxy: "https://myproxy:[email protected]:8001"
})

Python Microlink API example

import requests

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

querystring = {
    "url": "https://example.com",
    "proxy": "https://myproxy:[email protected]:8001"
}

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",
  proxy: "https://myproxy:[email protected]:8001"
}

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",
    "proxy" => "https://myproxy:[email protected]:8001"
];

$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("proxy", "https://myproxy:[email protected]:8001")
    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))
}
Use a proxy URL when the target site blocks automation, needs a specific region, or rate-limits your origin.
If the API returns EPROXYNEEDED, that is the clearest signal that the target needs a proxy-backed request. See the proxy reference.