Skip to content

Delivery and response shaping

Once your JSON extraction returns the right data, the next questions are operational: how should you serve it, how aggressively should it cache, and how do you keep private endpoints secure?

Choose a response model

When you needUseWhy
Parsed JSON inside the Microlink envelopeDefault JSON responseBest fit for apps that already expect the { status, data } wrapper
A trimmed envelope with specific fieldsfilterKeeps JSON, reduces payload size
The raw parsed JSON directlyembedTurns the request into a passthrough for the upstream JSON

Keep JSON in the envelope

The default response wraps your parsed JSON inside the standard Microlink payload:

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

CLI Microlink API example

microlink https://jsonplaceholder.typicode.com/posts/1&data.content.attr=json

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://jsonplaceholder.typicode.com/posts/1" \
  -d "data.content.attr=json" \
  -d "meta=false"

JavaScript Microlink API example

import mql from '@microlink/mql'

const { data } = await mql('https://jsonplaceholder.typicode.com/posts/1', {
  data: {
    content: {
      attr: "json"
    }
  },
  meta: false
})

Python Microlink API example

import requests

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

querystring = {
    "url": "https://jsonplaceholder.typicode.com/posts/1",
    "data.content.attr": "json",
    "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://jsonplaceholder.typicode.com/posts/1",
  data.content.attr: "json",
  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://jsonplaceholder.typicode.com/posts/1",
    "data.content.attr" => "json",
    "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://jsonplaceholder.typicode.com/posts/1")
    q.Set("data.content.attr", "json")
    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))
}
Use the envelope when your consumer expects the standard status and data structure.
This is the safest default. Your application gets a predictable shape regardless of what the upstream API returns.

Return parsed JSON directly

Set embed to the field name when the parsed JSON is the only output you need:

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

CLI Microlink API example

microlink https://jsonplaceholder.typicode.com/posts/1&data.content.attr=json&embed=content

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://jsonplaceholder.typicode.com/posts/1" \
  -d "data.content.attr=json" \
  -d "meta=false" \
  -d "embed=content"

JavaScript Microlink API example

import mql from '@microlink/mql'

const { data } = await mql('https://jsonplaceholder.typicode.com/posts/1', {
  data: {
    content: {
      attr: "json"
    }
  },
  meta: false,
  embed: "content"
})

Python Microlink API example

import requests

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

querystring = {
    "url": "https://jsonplaceholder.typicode.com/posts/1",
    "data.content.attr": "json",
    "meta": "false",
    "embed": "content"
}

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://jsonplaceholder.typicode.com/posts/1",
  data.content.attr: "json",
  meta: "false",
  embed: "content"
}

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://jsonplaceholder.typicode.com/posts/1",
    "data.content.attr" => "json",
    "meta" => "false",
    "embed" => "content"
];

$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://jsonplaceholder.typicode.com/posts/1")
    q.Set("data.content.attr", "json")
    q.Set("meta", "false")
    q.Set("embed", "content")
    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))
}
With embed, the response is the parsed JSON itself — no Microlink envelope.
This turns the Microlink URL into a cached, normalized proxy for the upstream JSON endpoint. Useful for frontend apps that want to consume the API response directly.

Use a fast default for production

For most production JSON proxy endpoints, a good default is:

The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://jsonplaceholder.typicode.com/posts/1' URL with 'data', 'meta', 'prerender', 'ttl' & 'staleTtl' API parameters:

CLI Microlink API example

microlink https://jsonplaceholder.typicode.com/posts/1&data.content.attr=json&ttl=1d&staleTtl=0

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://jsonplaceholder.typicode.com/posts/1" \
  -d "data.content.attr=json" \
  -d "meta=false" \
  -d "prerender=false" \
  -d "ttl=1d" \
  -d "staleTtl=0"

JavaScript Microlink API example

import mql from '@microlink/mql'

const { data } = await mql('https://jsonplaceholder.typicode.com/posts/1', {
  data: {
    content: {
      attr: "json"
    }
  },
  meta: false,
  prerender: false,
  ttl: "1d",
  staleTtl: 0
})

Python Microlink API example

import requests

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

querystring = {
    "url": "https://jsonplaceholder.typicode.com/posts/1",
    "data.content.attr": "json",
    "meta": "false",
    "prerender": "false",
    "ttl": "1d",
    "staleTtl": "0"
}

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://jsonplaceholder.typicode.com/posts/1",
  data.content.attr: "json",
  meta: "false",
  prerender: "false",
  ttl: "1d",
  staleTtl: "0"
}

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://jsonplaceholder.typicode.com/posts/1",
    "data.content.attr" => "json",
    "meta" => "false",
    "prerender" => "false",
    "ttl" => "1d",
    "staleTtl" => "0"
];

$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://jsonplaceholder.typicode.com/posts/1")
    q.Set("data.content.attr", "json")
    q.Set("meta", "false")
    q.Set("prerender", "false")
    q.Set("ttl", "1d")
    q.Set("staleTtl", "0")
    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))
}
Skip metadata, avoid browser work, and let cache absorb repeated requests.
The usual levers are:
  • meta: false when you only need the parsed JSON
  • prerender: false since JSON endpoints rarely need a browser
  • filter when you still want the envelope but only need specific keys
  • ttl cache TTL for freshness control
  • staleTtl stale-while-revalidate when latency matters
  • force for the occasional fresh uncached run

Keep private endpoints off the public internet

If the upstream JSON endpoint requires authentication:
  • do not expose it as a public embed URL
  • keep it on your backend whenever possible
  • forward secrets with x-api-header-*, not query parameters
curl -G https://pro.microlink.io \
  -d url=https://api.example.com/internal/data \
  -d data.content.attr=json \
  -d meta=false \
  -H 'x-api-key: YOUR_API_TOKEN' \
  -H 'x-api-header-authorization: Bearer SECRET'

JSON fields skip URL resolution

When Microlink processes extracted data, it normally resolves relative URLs and validates link-like fields. Fields declared with attr: 'json' are excluded from this step entirely.
This means:
  • Arrays are not compacted (falsy values like null, 0, false, "" are preserved).
  • Strings that look like URLs are not rewritten or pinged.
  • The full structure from JSON.parse arrives unchanged.
This is by design — JSON payloads represent structured data, not HTML metadata, so URL normalization would corrupt the values.

Use data extraction for the deeper dives

JSON extraction follows the same shared response model as any other extracted field. Continue with Data extraction when you need:
  • deeper filter coverage, including dot notation
  • a fuller cache strategy with ttl, staleTtl, and force
  • private-page setup, endpoint choice, and proxy-backed requests
  • timeout and response-header debugging
The most relevant deeper pages are:

Next step

If you need richer structured extraction alongside the JSON field, continue with Data extraction. Otherwise, see the guides overview for the rest of the Microlink guide set.