## Table of Contents

- [Proxy](#proxy)
- [When you need a proxy](#when-you-need-a-proxy)
- [Automatic proxy PRO](#automatic-proxy-pro)
- [Bring your own proxy PRO](#bring-your-own-proxy-pro)
  - [CLI Microlink API example](#cli-microlink-api-example)
  - [cURL Microlink API example](#curl-microlink-api-example)
  - [JavaScript Microlink API example](#javascript-microlink-api-example)
  - [Python Microlink API example](#python-microlink-api-example)
  - [Ruby Microlink API example](#ruby-microlink-api-example)
  - [PHP Microlink API example](#php-microlink-api-example)
  - [Golang Microlink API example](#golang-microlink-api-example)
- [Verify proxy is active](#verify-proxy-is-active)
- [Combine proxy with other parameters](#combine-proxy-with-other-parameters)
  - [Screenshot through a proxy](#screenshot-through-a-proxy)
  - [CLI Microlink API example](#cli-microlink-api-example-1)
  - [cURL Microlink API example](#curl-microlink-api-example-1)
  - [JavaScript Microlink API example](#javascript-microlink-api-example-1)
  - [Python Microlink API example](#python-microlink-api-example-1)
  - [Ruby Microlink API example](#ruby-microlink-api-example-1)
  - [PHP Microlink API example](#php-microlink-api-example-1)
  - [Golang Microlink API example](#golang-microlink-api-example-1)
  - [Data extraction through a proxy](#data-extraction-through-a-proxy)
  - [CLI Microlink API example](#cli-microlink-api-example-2)
  - [cURL Microlink API example](#curl-microlink-api-example-2)
  - [JavaScript Microlink API example](#javascript-microlink-api-example-2)
  - [Python Microlink API example](#python-microlink-api-example-2)
  - [Ruby Microlink API example](#ruby-microlink-api-example-2)
  - [PHP Microlink API example](#php-microlink-api-example-2)
  - [Golang Microlink API example](#golang-microlink-api-example-2)
  - [Proxy with retry for flaky targets](#proxy-with-retry-for-flaky-targets)
  - [CLI Microlink API example](#cli-microlink-api-example-3)
  - [cURL Microlink API example](#curl-microlink-api-example-3)
  - [JavaScript Microlink API example](#javascript-microlink-api-example-3)
  - [Python Microlink API example](#python-microlink-api-example-3)
  - [Ruby Microlink API example](#ruby-microlink-api-example-3)
  - [PHP Microlink API example](#php-microlink-api-example-3)
  - [Golang Microlink API example](#golang-microlink-api-example-3)
- [Geolocation: Target region-specific content](#geolocation-target-region-specific-content)
  - [CLI Microlink API example](#cli-microlink-api-example-4)
  - [cURL Microlink API example](#curl-microlink-api-example-4)
  - [JavaScript Microlink API example](#javascript-microlink-api-example-4)
  - [Python Microlink API example](#python-microlink-api-example-4)
  - [Ruby Microlink API example](#ruby-microlink-api-example-4)
  - [PHP Microlink API example](#php-microlink-api-example-4)
  - [Golang Microlink API example](#golang-microlink-api-example-4)
- [Keep proxy credentials secure](#keep-proxy-credentials-secure)
- [See also](#see-also)

---

[](https://microlink.io/docs/api/getting-started/overview)

[API](https://microlink.io/docs/api/getting-started/overview)

[](https://microlink.io/docs/guides)

GUIDES

[](https://microlink.io/docs/mql/getting-started/overview)

MQL

[](https://microlink.io/docs/sdk/getting-started/overview)

SDK

[](https://microlink.io/docs/cards/getting-started/overview)

CARDS

## Proxy

These proxy patterns apply to every Microlink workflow: screenshots, PDFs, data extraction, metadata, and insights. Use them whenever a target site blocks headless browsers, enforces rate limits on a specific IP, or geofences content by region.

## When you need a proxy

Not every site needs one. Use a proxy when you encounter:

| Signal                                       | What is happening                                                        |
| -------------------------------------------- | ------------------------------------------------------------------------ |
| `EPROXYNEEDED` error code                    | The API detected blocking and the request cannot succeed without a proxy |
| Empty or partial results on a known-good URL | The target is returning a CAPTCHA or an antibot challenge page           |
| Works locally but not via the API            | Your origin IP is blocked or throttled by the target                     |
| Content differs by region                    | The target serves different content based on geographic IP               |

## Automatic proxy PRO

Every

PRO

plan includes **automatic proxy resolution** — you do not need to supply a proxy URL. When Microlink detects that a site requires a proxy to fetch correctly, it routes the request through a rotating proxy pool automatically.

Microlink identifies the specific antibot provider blocking your request and [routes it through a dedicated resolution path](https://microlink.io/blog/antibot-detection-at-scale). For most sites, the Pro plan handles this automatically. We ensure performance across the [Top 500](https://microlink.io/blog/microlink-proxy-how-it-works) most popular websites worldwide.

You can confirm automatic proxy was used by checking the `x-fetch-mode` response header. Any value prefixed with `proxy-` means a proxy was active:

``` bash
x-fetch-mode: prerender-proxy
```

## Bring your own proxy PRO

If you have a dedicated proxy service — for example a residential proxy with a specific country IP — pass the proxy URL using the `proxy` parameter:

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

### CLI Microlink API example

``` bash
microlink https://geolocation.microlink.io&proxy=https://myproxy:603f60f5@superproxy.cool:8001
```

### cURL Microlink API example

``` bash
curl -G "https://api.microlink.io" \
  -d "url=https://geolocation.microlink.io" \
  -d "proxy=https://myproxy:603f60f5@superproxy.cool:8001"
```

### JavaScript Microlink API example

``` javascript
import mql from '@microlink/mql'

const { data } = await mql('https://geolocation.microlink.io', {
  proxy: "https://myproxy:603f60f5@superproxy.cool:8001"
})
```

### Python Microlink API example

``` python
import requests

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

querystring = {
    "url": "https://geolocation.microlink.io",
    "proxy": "https://myproxy:603f60f5@superproxy.cool:8001"
}

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

print(response.json())
```

### Ruby Microlink API example

``` ruby
require 'uri'
require 'net/http'

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

params = {
  url: "https://geolocation.microlink.io",
  proxy: "https://myproxy:603f60f5@superproxy.cool: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
<?php

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

$params = [
    "url" => "https://geolocation.microlink.io",
    "proxy" => "https://myproxy:603f60f5@superproxy.cool: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

``` bash
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://geolocation.microlink.io")
    q.Set("proxy", "https://myproxy:603f60f5@superproxy.cool: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))
}
```

``` javascript
import mql from '@microlink/mql'

const { data } = await mql('https://geolocation.microlink.io', {

  proxy: "https://myproxy:603f60f5@superproxy.cool:8001"

})
```

The `x-fetch-mode` response header will be prefixed with `proxy-*` when the request routes through your proxy.

The proxy URL must be a valid [](https://nodejs.org/api/url.html#url_the_whatwg_url_api)

[WHATWG URL](https://nodejs.org/api/url.html#url_the_whatwg_url_api)

. The supported format is:

`https://username:password@hostname:port `

All sub-requests made while resolving the target URL (redirects, assets, dynamic fetches) go through the same proxy server.

## Verify proxy is active

Check these response headers to confirm a proxy was used:

| Header           | Expected value                                                           |
| ---------------- | ------------------------------------------------------------------------ |
| `x-fetch-mode`   | Any value starting with `proxy-` (e.g. `prerender-proxy`, `fetch-proxy`) |
| `x-pricing-plan` | `pro` — proxy requires a paid plan                                       |
| `x-cache-status` | `BYPASS` on a fresh uncached request                                     |

A full response using a proxy looks like:

```
HTTP/2 200

content-type: application/json; charset=utf-8

x-response-time: 1.7s

x-pricing-plan: pro

x-fetch-mode: prerender-proxy

x-cache-ttl: 86400000

x-request-id: iad:2eb66538-0a16-4c56-b613-511d99507c9f

x-cache-status: BYPASS

cache-control: public, must-revalidate, max-age=0
```

## Combine proxy with other parameters

Proxy works with every workflow parameter. Some useful combinations:

### Screenshot through a proxy

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

### CLI Microlink API example

``` bash
microlink https://microlink.io&screenshot&proxy=https://myproxy:603f60f5@superproxy.cool:8001
```

### cURL Microlink API example

``` bash
curl -G "https://api.microlink.io" \
  -d "url=https://microlink.io" \
  -d "screenshot=true" \
  -d "meta=false" \
  -d "proxy=https://myproxy:603f60f5@superproxy.cool:8001"
```

### JavaScript Microlink API example

``` javascript
import mql from '@microlink/mql'

const { data } = await mql('https://microlink.io', {
  screenshot: true,
  meta: false,
  proxy: "https://myproxy:603f60f5@superproxy.cool:8001"
})
```

### Python Microlink API example

``` python
import requests

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

querystring = {
    "url": "https://microlink.io",
    "screenshot": "true",
    "meta": "false",
    "proxy": "https://myproxy:603f60f5@superproxy.cool:8001"
}

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

print(response.json())
```

### Ruby Microlink API example

``` ruby
require 'uri'
require 'net/http'

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

params = {
  url: "https://microlink.io",
  screenshot: "true",
  meta: "false",
  proxy: "https://myproxy:603f60f5@superproxy.cool: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
<?php

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

$params = [
    "url" => "https://microlink.io",
    "screenshot" => "true",
    "meta" => "false",
    "proxy" => "https://myproxy:603f60f5@superproxy.cool: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

``` bash
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://microlink.io")
    q.Set("screenshot", "true")
    q.Set("meta", "false")
    q.Set("proxy", "https://myproxy:603f60f5@superproxy.cool: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))
}
```

``` javascript
import mql from '@microlink/mql'

const { data } = await mql('https://microlink.io', {

  screenshot: true,

  meta: false,

  proxy: "https://myproxy:603f60f5@superproxy.cool:8001"

})
```

Adding `meta: false` skips metadata extraction and focuses the request on the screenshot alone.

### Data extraction through a proxy

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

### CLI Microlink API example

``` bash
microlink https://microlink.io&data.title.selector=h1&data.title.attr=text&proxy=https://myproxy:603f60f5@superproxy.cool:8001
```

### cURL Microlink API example

``` bash
curl -G "https://api.microlink.io" \
  -d "url=https://microlink.io" \
  -d "data.title.selector=h1" \
  -d "data.title.attr=text" \
  -d "proxy=https://myproxy:603f60f5@superproxy.cool:8001" \
  -d "meta=false"
```

### JavaScript Microlink API example

``` javascript
import mql from '@microlink/mql'

const { data } = await mql('https://microlink.io', {
  data: {
    title: {
      selector: "h1",
      attr: "text"
    }
  },
  proxy: "https://myproxy:603f60f5@superproxy.cool:8001",
  meta: false
})
```

### Python Microlink API example

``` python
import requests

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

querystring = {
    "url": "https://microlink.io",
    "data.title.selector": "h1",
    "data.title.attr": "text",
    "proxy": "https://myproxy:603f60f5@superproxy.cool:8001",
    "meta": "false"
}

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

print(response.json())
```

### Ruby Microlink API example

``` ruby
require 'uri'
require 'net/http'

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

params = {
  url: "https://microlink.io",
  data.title.selector: "h1",
  data.title.attr: "text",
  proxy: "https://myproxy:603f60f5@superproxy.cool:8001",
  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
<?php

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

$params = [
    "url" => "https://microlink.io",
    "data.title.selector" => "h1",
    "data.title.attr" => "text",
    "proxy" => "https://myproxy:603f60f5@superproxy.cool:8001",
    "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

``` bash
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://microlink.io")
    q.Set("data.title.selector", "h1")
    q.Set("data.title.attr", "text")
    q.Set("proxy", "https://myproxy:603f60f5@superproxy.cool:8001")
    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))
}
```

``` javascript
import mql from '@microlink/mql'

const { data } = await mql('https://microlink.io', {

  data: {

    title: {

      selector: "h1",

      attr: "text"

    }

  },

  proxy: "https://myproxy:603f60f5@superproxy.cool:8001",

  meta: false

})
```

Pass custom extraction rules alongside a proxy when the target requires one to deliver content.

### Proxy with retry for flaky targets

Some proxy endpoints are temporarily unreachable or the target site intermittently challenges requests. Combine `proxy` with `retry` to handle transient failures automatically:

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

### CLI Microlink API example

``` bash
microlink https://microlink.io&proxy=https://myproxy:603f60f5@superproxy.cool:8001&retry=3
```

### cURL Microlink API example

``` bash
curl -G "https://api.microlink.io" \
  -d "url=https://microlink.io" \
  -d "proxy=https://myproxy:603f60f5@superproxy.cool:8001" \
  -d "retry=3" \
  -d "meta=false"
```

### JavaScript Microlink API example

``` javascript
import mql from '@microlink/mql'

const { data } = await mql('https://microlink.io', {
  proxy: "https://myproxy:603f60f5@superproxy.cool:8001",
  retry: 3,
  meta: false
})
```

### Python Microlink API example

``` python
import requests

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

querystring = {
    "url": "https://microlink.io",
    "proxy": "https://myproxy:603f60f5@superproxy.cool:8001",
    "retry": "3",
    "meta": "false"
}

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

print(response.json())
```

### Ruby Microlink API example

``` ruby
require 'uri'
require 'net/http'

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

params = {
  url: "https://microlink.io",
  proxy: "https://myproxy:603f60f5@superproxy.cool:8001",
  retry: "3",
  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
<?php

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

$params = [
    "url" => "https://microlink.io",
    "proxy" => "https://myproxy:603f60f5@superproxy.cool:8001",
    "retry" => "3",
    "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

``` bash
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://microlink.io")
    q.Set("proxy", "https://myproxy:603f60f5@superproxy.cool:8001")
    q.Set("retry", "3")
    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))
}
```

``` javascript
import mql from '@microlink/mql'

const { data } = await mql('https://microlink.io', {

  proxy: "https://myproxy:603f60f5@superproxy.cool:8001",

  retry: 3,

  meta: false

})
```

Server-side retries with exponential backoff reduce failures from temporarily blocked or slow proxy connections.

## Geolocation: Target region-specific content

A common use case is scraping a site that serves different content depending on the visitor's country. Route through a country-specific proxy IP to get the version you need:

``` js
import mql from '@microlink/mql'

const { data } = await mql('https://example.com/pricing', {

  proxy: 'https://user:pass@fr-proxy.example.com:8080',

  meta: false

})
```

Pair this with a reliable geolocation test URL to verify the proxy is resolving from the expected country before sending production requests:

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

### CLI Microlink API example

``` bash
microlink https://geolocation.microlink.io&proxy=https://myproxy:603f60f5@superproxy.cool:8001
```

### cURL Microlink API example

``` bash
curl -G "https://api.microlink.io" \
  -d "url=https://geolocation.microlink.io" \
  -d "proxy=https://myproxy:603f60f5@superproxy.cool:8001" \
  -d "meta=false"
```

### JavaScript Microlink API example

``` javascript
import mql from '@microlink/mql'

const { data } = await mql('https://geolocation.microlink.io', {
  proxy: "https://myproxy:603f60f5@superproxy.cool:8001",
  meta: false
})
```

### Python Microlink API example

``` python
import requests

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

querystring = {
    "url": "https://geolocation.microlink.io",
    "proxy": "https://myproxy:603f60f5@superproxy.cool:8001",
    "meta": "false"
}

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

print(response.json())
```

### Ruby Microlink API example

``` ruby
require 'uri'
require 'net/http'

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

params = {
  url: "https://geolocation.microlink.io",
  proxy: "https://myproxy:603f60f5@superproxy.cool:8001",
  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
<?php

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

$params = [
    "url" => "https://geolocation.microlink.io",
    "proxy" => "https://myproxy:603f60f5@superproxy.cool:8001",
    "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

``` bash
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://geolocation.microlink.io")
    q.Set("proxy", "https://myproxy:603f60f5@superproxy.cool:8001")
    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))
}
```

``` javascript
import mql from '@microlink/mql'

const { data } = await mql('https://geolocation.microlink.io', {

  proxy: "https://myproxy:603f60f5@superproxy.cool:8001",

  meta: false

})
```

`geolocation.microlink.io` returns the origin IP and country seen by the server — useful to confirm a proxy is routing through the right region.

## Keep proxy credentials secure

Proxy URLs contain credentials. Treat them the same as API keys:

- **Never embed them in client-side code**, public HTML, or embed URLs.
- Pass them from environment variables in server-side code:

``` js
import mql from '@microlink/mql'

const { data } = await mql('https://example.com', {

  proxy: process.env.PROXY_URL,

  meta: false

})
```

- Use [](https://github.com/microlinkhq/proxy)

  @microlink/proxy

  or [](https://github.com/microlinkhq/edge-proxy)

  @microlink/edge-proxy

  to keep your API key and proxy URL server-side when calling Microlink from a frontend.

<table>
<colgroup>
<col style="width: 33%" />
<col style="width: 33%" />
<col style="width: 33%" />
</colgroup>
<thead>
<tr>
<th>Error</th>
<th>Cause</th>
<th>Fix</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>EPROXYNEEDED</code></td>
<td>The target requires a proxy but none was supplied</td>
<td>Add <code>proxy</code> to the request or upgrade to a
<p>PRO</p>
plan for automatic proxy</td>
</tr>
<tr>
<td><code>EPROXY</code></td>
<td><code>proxy</code> parameter used without a
<p>PRO</p>
plan</td>
<td>Upgrade to a paid plan</td>
</tr>
<tr>
<td><code>EAUTH</code></td>
<td>API key missing or invalid</td>
<td>Check your <code>x-api-key</code> header</td>
</tr>
<tr>
<td><code>EPRO</code></td>
<td>Sent <code>x-api-key</code> to <code>api.microlink.io</code></td>
<td>Use <code>pro.microlink.io</code> instead</td>
</tr>
</tbody>
</table>

See the full [error codes reference](https://microlink.io/docs/api/basics/error-codes) and the [proxy parameter reference](https://microlink.io/docs/api/parameters/proxy) for all supported values.

## See also

- [Private pages](https://microlink.io/docs/guides/common/private-pages) — forward cookies, authorization headers, and other credentials to target pages.
- [Troubleshooting](https://microlink.io/docs/guides/common/troubleshooting) — fix timeouts, blocked sites, and auth errors across all workflows.
- [Production patterns](https://microlink.io/docs/guides/common/production-patterns) — endpoint selection, retries, rate limits, and credential safety.