Skip to content

Troubleshooting

These troubleshooting patterns apply to every Microlink workflow. Each guide's own troubleshooting page covers workflow-specific issues (wrong screenshots, bad PDF layout, empty extraction fields, etc.); this page covers the problems that appear across all workflows.

The request times out

If you hit ETIMEOUT or EBRWSRTIMEOUT, reduce the amount of work before raising timeout:
  1. Replace waitForTimeout with waitForSelector — selector-based waits finish as soon as content appears.
  2. Set meta: false when you do not need normalized metadata.
  3. Use prerender: false when the page already ships the content in HTML.
  4. Disable javascript when the page does not need client-side execution.
  5. Remove unnecessary scripts, modules, or function work.
  6. Only then raise timeout and increase retry:

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

CLI Microlink API example

microlink https://example.com&retry=3&timeout=20s

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://example.com" \
  -d "meta=false" \
  -d "retry=3" \
  -d "timeout=20s"

JavaScript Microlink API example

import mql from '@microlink/mql'

const { data } = await mql('https://example.com', {
  meta: false,
  retry: 3,
  timeout: "20s"
})

Python Microlink API example

import requests

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

querystring = {
    "url": "https://example.com",
    "meta": "false",
    "retry": "3",
    "timeout": "20s"
}

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",
  meta: "false",
  retry: "3",
  timeout: "20s"
}

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",
    "meta" => "false",
    "retry" => "3",
    "timeout" => "20s"
];

$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("meta", "false")
    q.Set("retry", "3")
    q.Set("timeout", "20s")
    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))
}
Increase timeout only after removing unnecessary work. The maximum allowed timeout is 28 seconds.

The site blocks the browser
PRO

Some sites block headless browsers, require a region-specific IP, or trigger antibot protection. In those cases, 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 'meta' & 'proxy' API parameters:

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 "meta=false" \
  -d "proxy=https://myproxy:[email protected]:8001"

JavaScript Microlink API example

import mql from '@microlink/mql'

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

Python Microlink API example

import requests

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

querystring = {
    "url": "https://example.com",
    "meta": "false",
    "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",
  meta: "false",
  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",
    "meta" => "false",
    "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("meta", "false")
    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 headless traffic, geofences content, or rate-limits your origin.
If the API returns EPROXYNEEDED, that is the clearest signal that the target needs a proxy-backed request.

Auth and plan errors

These errors point directly to setup issues and apply to all workflows:
Error codeCauseFix
EAUTHAPI key missing or invalidCheck your x-api-key header
EPROSent x-api-key to api.microlink.ioUse pro.microlink.io instead
EHEADERSheaders used without Pro planUpgrade to a
PRO
plan
EPROXYproxy used without Pro planUpgrade to a
PRO
plan
EFILENAMEfilename used without Pro planUpgrade to a
PRO
plan
ETTLttl used without Pro planUpgrade to a
PRO
plan
ESTTLstaleTtl used without Pro planUpgrade to a
PRO
plan
ERATERate limit reachedWait for reset or upgrade
EINVALURLURL format is invalidCheck protocol and hostname
EFORBIDDENURLURL resolves to a forbidden IPUse a public URL
EMAXREDIRECTSMore than 10 redirectsProvide the final destination URL
See the full error codes reference for every error.

Useful headers while debugging

Open the response headers view in the interactive editor and look for:
HeaderWhat it tells you
x-cache-statusMISS (fresh), HIT (cached), or BYPASS (forced)
x-cache-ttlEffective cache lifetime in milliseconds
x-fetch-modefetch, prerender, proxy-*, or skipped
x-fetch-timeTime spent fetching and rendering
x-pricing-planWhether the request ran on free or pro
x-response-timeTotal request duration
These headers usually tell you whether the problem is timing, auth, caching, or target-site protection.