Embed
Microlink turns any URL into a rich preview, an interactive player, or a plain asset URL — pick how it gets rendered.
The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://www.youtube.com/watch?v=9P6rdqiybaw' URL:
CLI Microlink API example
microlink https://www.youtube.com/watch?v=9P6rdqiybawcURL Microlink API example
curl -G "https://api.microlink.io" \
-d "url=https://www.youtube.com/watch?v=9P6rdqiybaw"JavaScript Microlink API example
import mql from '@microlink/mql'
const { data } = await mql('https://www.youtube.com/watch?v=9P6rdqiybaw')Python Microlink API example
import requests
url = "https://api.microlink.io/"
querystring = {
"url": "https://www.youtube.com/watch?v=9P6rdqiybaw"
}
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://www.youtube.com/watch?v=9P6rdqiybaw"
}
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.bodyPHP Microlink API example
<?php
$baseUrl = "https://api.microlink.io/";
$params = [
"url" => "https://www.youtube.com/watch?v=9P6rdqiybaw"
];
$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://www.youtube.com/watch?v=9P6rdqiybaw")
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))
}import mql from '@microlink/mql'
const { data } = await mql('https://www.youtube.com/watch?v=9P6rdqiybaw')The default response already returns the normalized fields —
title, description, image, logo, publisher — needed to render any kind of preview.Shortcut: Drop in the SDK
If you just want a preview rendered on the page, skip everything below and use the SDK. One component, one prop, no API call to write:
import Microlink from '@microlink/react'
<Microlink url='https://stripe.com' />The SDK handles the API call, the iframe-vs-card decision, lazy-loading, and rendering. Available for React, Vue, and Vanilla JavaScript. See the SDK guide.
Granular control: Four steps
When you need the provider's native player, your own HTML, server-rendered output, or any custom delivery, walk through the workflow below. The SDK is a higher-level wrapper around these same four steps — calling them yourself unlocks the full surface.
- Call the API with a
url. Addiframe: true,palette: true, orscreenshot: truewhen you also want the provider's player, brand colors, or a fresh capture. - Read the response. Microlink returns normalized JSON with
data.title,data.image.url,data.logo.url, plus the optional fields you asked for. - Pick how to render it — the provider's native iframe, or your own HTML built from the JSON.
- Render it. Inject the iframe HTML, or paste the JSON into your template.
The rest of this page walks through each step and links out to the subguide that fits the path you pick.
"embed" means three things
The word collides. To keep this guide unambiguous:
| Where you see it | What it means |
|---|---|
| Embed in prose | The product workflow: rendering a URL as a preview |
embed in monospace | The API parameter that returns an asset (image, screenshot, logo, ...) as the response body |
| The SDK component | The <Microlink> React, Vue, or Vanilla component that wraps the four-step workflow |
Each section below states which one it means.
Step 1 — call the API
To run the JavaScript examples, install MQL:
npm install @microlink/mql --saveIt works in Node.js, edge runtimes, and the browser. See the MQL installation guide for environment-specific setup.
If you call the API directly with
fetch, curl, or any HTTP client, you do not need to install anything — every example also works as a plain HTTPS GET to https://api.microlink.io.Every example in this guide uses the same canonical shape:
import mql from '@microlink/mql'
const { data } = await mql('https://example.com', { /* options */ })The options object is equivalent to a query string:
mql(url, { iframe: true }) is the same call as ?url=…&iframe=true.Step 2 — read the response
The base response is the foundation for every embed:
{
"status": "success",
"data": {
"title": "Wormholes Explained – Breaking Spacetime",
"description": "Are wormholes real or are they just magic disguised as physics and maths?",
"publisher": "YouTube",
"author": "Kurzgesagt – In a Nutshell",
"url": "https://www.youtube.com/watch?v=9P6rdqiybaw",
"image": {
"url": "https://img.youtube.com/vi/9P6rdqiybaw/maxresdefault.jpg",
"width": 1280,
"height": 720
},
"logo": {
"url": "https://www.youtube.com/s/desktop/.../favicon_144x144.png"
}
}
}Three optional flags extend this response:
| Add | You get |
|---|---|
iframe: true | data.iframe.html + data.iframe.scripts — the provider's interactive embed (YouTube, Spotify, Twitter, ...) |
palette: true | Brand colors and contrast-checked color pairs on every image and logo |
screenshot: true | A fresh capture of the page under data.screenshot.url, useful when og:image is missing or bad |
Step 3 — pick how to render it
Two rendering approaches, same JSON underneath:
| When you need | Use | Result |
|---|---|---|
| The provider's native interactive player (YouTube, Spotify, X, Vimeo) | iframe parameter | Ready-to-inject html + scripts from oEmbed |
| Full control over markup and styling | Metadata API + custom HTML | Custom card built from data.title, data.image.url, data.logo.url… |
They are not mutually exclusive — a single page can use custom HTML for hero blocks and
iframe for media that needs the original player.If you want your AI coding assistant to write the custom HTML against your design system, see generate custom previews with AI — it's a flavor of the custom-HTML approach with ready-to-paste prompts.
Choosing between the two
- iframe parameter when the URL has a real player (YouTube, Spotify) and you want the provider's widget, not a card.
- Metadata API + custom HTML when previews must match your design system, you need server-rendered output, or you ship to environments without client JavaScript.
(Still want the wrapper component instead? Jump back to the SDK guide.)
Step 4 — render it
Each rendering approach has its own subguide with runnable examples — pick one and the rest of the guide is linear:
- iframe parameter — inject
iframe.htmland loadiframe.scripts. - Metadata API with custom HTML/CSS — render your own card from
data.*. - Generate custom previews with AI — prompt Cursor or Claude Code to write the markup.
Direct embed — skip the JSON
If you only need a single asset URL (an image, a screenshot, a logo) in static markup, the
embed parameter turns the API URL itself into that asset:<img
src="https://api.microlink.io?url=https://stripe.com&embed=image.url"
alt="Stripe"
/>It is the same pipeline as before —
embed just tells the API to return the field's content instead of wrapping it in JSON. Useful for <meta property="og:image">, READMEs, and CMS markdown. See the embed reference for the full field list.Free tier and API key
The Microlink API works without an API key. You get 50 free requests per day, enough to build and ship a real embed integration.
For production, a
PRO
plan unlocks features that matter for embeds specifically: configurable TTL, stale-while-revalidate caching, custom headers for private pages, and proxy for blocked or geofenced URLs.To authenticate, pass your API key as
x-api-key:The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://www.youtube.com/watch?v=9P6rdqiybaw' URL with 'apiKey' API parameter:
CLI Microlink API example
microlink https://www.youtube.com/watch?v=9P6rdqiybaw --api-key YOUR_API_TOKENcURL Microlink API example
curl -G "https://api.microlink.io" \
-H "x-api-key: YOUR_API_TOKEN" \
-d "url=https://www.youtube.com/watch?v=9P6rdqiybaw"JavaScript Microlink API example
import mql from '@microlink/mql'
const { data } = await mql('https://www.youtube.com/watch?v=9P6rdqiybaw', {
apiKey: "YOUR_API_TOKEN"
})Python Microlink API example
import requests
url = "https://api.microlink.io/"
querystring = {
"url": "https://www.youtube.com/watch?v=9P6rdqiybaw"
}
headers = {
"x-api-key": "YOUR_API_TOKEN"
}
response = requests.get(url, params=querystring, headers=headers)
print(response.json())Ruby Microlink API example
require 'uri'
require 'net/http'
base_url = "https://api.microlink.io/"
params = {
url: "https://www.youtube.com/watch?v=9P6rdqiybaw"
}
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)
request['x-api-key'] = "YOUR_API_TOKEN"
response = http.request(request)
puts response.bodyPHP Microlink API example
<?php
$baseUrl = "https://api.microlink.io/";
$params = [
"url" => "https://www.youtube.com/watch?v=9P6rdqiybaw"
];
$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",
CURLOPT_HTTPHEADER => [
"x-api-key: YOUR_API_TOKEN"
]
]);
$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://www.youtube.com/watch?v=9P6rdqiybaw")
u.RawQuery = q.Encode()
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
panic(err)
}
req.Header.Set("x-api-key", "YOUR_API_TOKEN")
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))
}import mql from '@microlink/mql'
const { data } = await mql('https://www.youtube.com/watch?v=9P6rdqiybaw', {
apiKey: "YOUR_API_TOKEN"
})You can enter your API key in any interactive example by clicking the key icon in the terminal toolbar.
See authentication and rate limit for the full details.
Cross-cutting concerns
These apply no matter which rendering approach you pick:
- Caching and performance — keep embeds fast at scale with TTL, stale-while-revalidate, and hot-cache patterns.
- Private pages and proxy — embed authenticated dashboards, geofenced content, and pages protected by antibot systems.
- Troubleshooting — debug missing iframes, broken images, hot-linking issues, and provider-specific quirks.
See also
- Metadata — when you only need the data (titles, descriptions, images) and have your own renderer.
- Screenshot — when the page has no usable
og:imageand you want a real capture as the preview. - SDK reference — the full SDK reference with every prop and integration.
- iframe parameter reference — the authoritative parameter docs and provider list.