Skip to content

JSON

JSON extraction is a specialized form of Microlink data extraction. You declare a data field with attr: 'json', and Microlink parses the response body as JSON instead of treating it as HTML.

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))
}
Run the request and inspect data.content. The parsed JSON object is returned as structured data, not a string.

MQL installation

To run the JavaScript examples with MQL, install @microlink/mql:
npm install @microlink/mql --save
It works in Node.js, Edge runtimes, and the browser. See the MQL installation guide for the environment-specific setup.
If you are using another language, you do not need to install MQL to follow this guide. You can use the terminal examples or call the API directly from any HTTP client.

The mental model

Unlike other attr values, json is whole-page only — it always operates on the entire response body. Do not combine it with selector or selectorAll.
  • The field name you declare becomes the response key.
  • attr: 'json' parses the body with JSON.parse and returns native structured data (objects, arrays, strings, numbers, booleans, or null).
  • The original shape is preserved exactly — no URL rewriting, no array compaction, no value normalization.
{
  url: 'https://jsonplaceholder.typicode.com/posts/1',
  data: {
    content: {
      attr: 'json'
    }
  },
  meta: false
}

The response

The parsed JSON appears under the field you declared:
{
  "status": "success",
  "data": {
    "content": {
      "userId": 1,
      "id": 1,
      "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
      "body": "quia et suscipit\nsuscipit recusandae..."
    }
  }
}
Arrays, nested objects, numbers, booleans, and null all survive the round trip unchanged.

When to use JSON extraction

NeedBest approach
Consume a REST API or JSON endpointattr: 'json' on the endpoint URL
Combine JSON data with HTML-extracted fieldsMix attr: 'json' (no selector) with other data rules that use selectors
Parse a page that returns application/jsonattr: 'json' handles it whether the body is raw or wrapped in <pre>
Extract structured data from an HTML pageUse selector + other attr values — json is not designed for HTML documents

How the parser works

Microlink tries two strategies depending on how the JSON arrives:
  1. <pre> tag present — when the response is prerendered or browser-rendered, JSON is often wrapped in a <pre> element. Microlink extracts the inner HTML, decodes HTML entities (&lt;<, &amp;&), and parses the result.
  2. Plain body text — when no <pre> exists, Microlink reads the raw body text directly and parses it.
This means attr: 'json' works regardless of whether you use prerender: true or prerender: false.

Combine JSON with other fields

You can declare JSON fields alongside HTML-extracted fields in the same request:
const mql = require('@microlink/mql')

const { data } = await mql('https://api.example.com/product/42', {
  data: {
    product: {
      attr: 'json'
    }
  },
  meta: false
})

console.log(data.product.name)
console.log(data.product.price)

Values that look like HTML are safe

If the JSON contains strings with angle brackets or HTML-like content, they are preserved as-is:
{
  "note": "<b>important</b>",
  "template": "<div class=\"card\">{{name}}</div>"
}
These strings pass through JSON.parse unchanged — they are not interpreted as DOM elements.

Free tier and advanced features

The examples here work on the free tier. Custom headers, proxy, and configurable cache remain
PRO
features, exactly as in the Data extraction guide.
See the authentication and rate limit docs for the plan details.

What's next

See also

  • Data extraction — the full MQL workflow for structured extraction.
  • Markdown — for converting pages to Markdown instead of parsing JSON.
  • attr reference — the MQL reference for all supported attr values.