Skip to content

Delivery and response shaping

Once the Markdown output looks correct, the next questions are operational: how should you serve it, how small can the payload be, how aggressively should it cache, and can that URL be public?

Choose a response model

When you needUseWhy
Markdown plus surrounding structureDefault JSON responseBest fit for apps, queues, and ingestion pipelines
Smaller JSON with only one or two fieldsfilterKeeps JSON, trims the payload
The Markdown body itselfembedTurns the request into a direct Markdown response

Keep JSON when structure still matters

The default response keeps your Markdown field inside the normal payload:

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

CLI Microlink API example

microlink https://example.com&data.content.attr=markdown

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://example.com" \
  -d "data.content.attr=markdown" \
  -d "meta=false"

JavaScript Microlink API example

import mql from '@microlink/mql'

const { data } = await mql('https://example.com', {
  data: {
    content: {
      attr: "markdown"
    }
  },
  meta: false
})

Python Microlink API example

import requests

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

querystring = {
    "url": "https://example.com",
    "data.content.attr": "markdown",
    "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://example.com",
  data.content.attr: "markdown",
  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://example.com",
    "data.content.attr" => "markdown",
    "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://example.com")
    q.Set("data.content.attr", "markdown")
    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 normal JSON when your consumer still wants a predictable envelope around the Markdown field.
For Markdown-only workflows, meta: false is usually the right default. If you still need a few normalized fields, leave meta enabled or pass a selective object. See the meta reference.

Return the markdown body directly

Set embed to the extracted field name when the field already is the final output you want to serve:

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

CLI Microlink API example

microlink https://example.com&data.content.attr=markdown&embed=content

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://example.com" \
  -d "data.content.attr=markdown" \
  -d "meta=false" \
  -d "embed=content"

JavaScript Microlink API example

import mql from '@microlink/mql'

const { data } = await mql('https://example.com', {
  data: {
    content: {
      attr: "markdown"
    }
  },
  meta: false,
  embed: "content"
})

Python Microlink API example

import requests

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

querystring = {
    "url": "https://example.com",
    "data.content.attr": "markdown",
    "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://example.com",
  data.content.attr: "markdown",
  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://example.com",
    "data.content.attr" => "markdown",
    "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://example.com")
    q.Set("data.content.attr", "markdown")
    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 request behaves like the extracted Markdown itself instead of the full JSON envelope.
If your rule is named article, use embed: 'article'. embed always points to the response field name, not the selector.

Use a fast default for production

For most production Markdown 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://example.com' URL with 'data', 'meta', 'prerender', 'ttl' & 'staleTtl' API parameters:

CLI Microlink API example

microlink https://example.com&data.content.selector=main&data.content.attr=markdown&ttl=1d&staleTtl=0

cURL Microlink API example

curl -G "https://api.microlink.io" \
  -d "url=https://example.com" \
  -d "data.content.selector=main" \
  -d "data.content.attr=markdown" \
  -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://example.com', {
  data: {
    content: {
      selector: "main",
      attr: "markdown"
    }
  },
  meta: false,
  prerender: false,
  ttl: "1d",
  staleTtl: 0
})

Python Microlink API example

import requests

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

querystring = {
    "url": "https://example.com",
    "data.content.selector": "main",
    "data.content.attr": "markdown",
    "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://example.com",
  data.content.selector: "main",
  data.content.attr: "markdown",
  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://example.com",
    "data.content.selector" => "main",
    "data.content.attr" => "markdown",
    "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://example.com")
    q.Set("data.content.selector", "main")
    q.Set("data.content.attr", "markdown")
    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))
}
Scope the content, skip metadata, avoid browser work when possible, and let cache absorb repeated requests.
The usual levers are:
  • meta: false when you only need the Markdown field
  • filter when you still want JSON but only need one or two fields
  • ttl cache TTL for freshness control
  • staleTtl stale-while-revalidate when latency matters
  • force for the occasional fresh uncached run

Keep private markdown URLs off the public internet

The biggest Markdown-specific delivery risk is embed=content: it is convenient, but it also makes the final URL very shareable.
If the request needs cookies, authorization, or forwarded headers:
  • 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://example.com/private \
  -d data.content.attr=markdown \
  -d meta=false \
  -H 'x-api-key: YOUR_API_TOKEN' \
  -H 'x-api-header-cookie: session=abc123'

Use data extraction for the deeper dives

Markdown 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 around the Markdown field, continue with Data extraction. Otherwise, see the guides overview for the rest of the Microlink guide set.