## Table of Contents

- [What the iframe field returns](#what-the-iframe-field-returns)
  - [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)
- [Inject the iframe HTML](#inject-the-iframe-html)
    - [Vanilla JavaScript](#vanilla-javascript)
    - [React](#react)
    - [Server-side rendering](#server-side-rendering)
- [When to use iframe vs SDK vs custom HTML](#when-to-use-iframe-vs-sdk-vs-custom-html)
- [Customize the iframe with oEmbed options](#customize-the-iframe-with-oembed-options)
  - [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)
- [When iframe discovery fails](#when-iframe-discovery-fails)
- [Pair iframe with metadata in one call](#pair-iframe-with-metadata-in-one-call)
  - [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)
- [Security and sandboxing](#security-and-sandboxing)
- [Next step](#next-step)

---

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

[GUIDES](https://microlink.io/docs/guides) [MQL](https://microlink.io/docs/mql/getting-started/overview) [SDK](https://microlink.io/docs/sdk/getting-started/overview) [CARDS](https://microlink.io/docs/cards/getting-started/overview)

API GUIDES MQL SDK CARDS

Getting Started

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

[What is Microlink](https://microlink.io/docs/guides/what-is-microlink)

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

[Customizing output](https://microlink.io/docs/guides/screenshot/customizing-output)

[Browser settings](https://microlink.io/docs/guides/screenshot/browser-settings)

[Page interaction](https://microlink.io/docs/guides/screenshot/page-interaction)

[Delivery and embedding](https://microlink.io/docs/guides/screenshot/embedding)

[Caching and performance](https://microlink.io/docs/guides/screenshot/caching-and-performance)

[Private pages](https://microlink.io/docs/guides/screenshot/private-pages)

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

[Data extraction](https://microlink.io/docs/guides/data-extraction)

[Defining rules](https://microlink.io/docs/guides/data-extraction/defining-rules)

[Page preparation](https://microlink.io/docs/guides/data-extraction/page-preparation)

[Delivery and response shaping](https://microlink.io/docs/guides/data-extraction/delivery-and-response)

[Caching and performance](https://microlink.io/docs/guides/data-extraction/caching-and-performance)

[Private pages](https://microlink.io/docs/guides/data-extraction/private-pages)

[Troubleshooting](https://microlink.io/docs/guides/data-extraction/troubleshooting)

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

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

[Iframe parameter](https://microlink.io/docs/guides/embed/iframe)

[Custom HTML/CSS](https://microlink.io/docs/guides/embed/metadata-api)

[Custom previews with AI](https://microlink.io/docs/guides/embed/custom-previews-with-ai)

[Caching and performance](https://microlink.io/docs/guides/embed/caching-and-performance)

[Private pages and proxy](https://microlink.io/docs/guides/embed/private-pages-and-proxy)

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

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

[Choosing scope](https://microlink.io/docs/guides/markdown/choosing-scope)

[Delivery and response shaping](https://microlink.io/docs/guides/markdown/delivery-and-response)

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

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

[Page size and layout](https://microlink.io/docs/guides/pdf/page-size-and-layout)

[Page preparation](https://microlink.io/docs/guides/pdf/page-preparation)

[Delivery and embedding](https://microlink.io/docs/guides/pdf/embedding)

[Caching and performance](https://microlink.io/docs/guides/pdf/caching-and-performance)

[Private pages](https://microlink.io/docs/guides/pdf/private-pages)

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

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

[Choosing fields](https://microlink.io/docs/guides/metadata/choosing-fields)

[Extending results](https://microlink.io/docs/guides/metadata/extending-results)

[Delivery and response shaping](https://microlink.io/docs/guides/metadata/delivery-and-response)

[Page preparation](https://microlink.io/docs/guides/metadata/page-preparation)

[Caching and performance](https://microlink.io/docs/guides/metadata/caching-and-performance)

[Private pages](https://microlink.io/docs/guides/metadata/private-pages)

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

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

[Technology detection](https://microlink.io/docs/guides/insights/technology-detection)

[Lighthouse reports](https://microlink.io/docs/guides/insights/lighthouse-reports)

[Caching and performance](https://microlink.io/docs/guides/insights/caching-and-performance)

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

[Common patterns](https://microlink.io/docs/guides/common/caching)

[Caching patterns](https://microlink.io/docs/guides/common/caching)

[Private pages](https://microlink.io/docs/guides/common/private-pages)

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

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

[Production patterns](https://microlink.io/docs/guides/common/production-patterns)

API GUIDES MQL SDK CARDS

Getting Started

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

[What is Microlink](https://microlink.io/docs/guides/what-is-microlink)

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

[Customizing output](https://microlink.io/docs/guides/screenshot/customizing-output)

[Browser settings](https://microlink.io/docs/guides/screenshot/browser-settings)

[Page interaction](https://microlink.io/docs/guides/screenshot/page-interaction)

[Delivery and embedding](https://microlink.io/docs/guides/screenshot/embedding)

[Caching and performance](https://microlink.io/docs/guides/screenshot/caching-and-performance)

[Private pages](https://microlink.io/docs/guides/screenshot/private-pages)

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

[Data extraction](https://microlink.io/docs/guides/data-extraction)

[Defining rules](https://microlink.io/docs/guides/data-extraction/defining-rules)

[Page preparation](https://microlink.io/docs/guides/data-extraction/page-preparation)

[Delivery and response shaping](https://microlink.io/docs/guides/data-extraction/delivery-and-response)

[Caching and performance](https://microlink.io/docs/guides/data-extraction/caching-and-performance)

[Private pages](https://microlink.io/docs/guides/data-extraction/private-pages)

[Troubleshooting](https://microlink.io/docs/guides/data-extraction/troubleshooting)

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

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

[Iframe parameter](https://microlink.io/docs/guides/embed/iframe)

[Custom HTML/CSS](https://microlink.io/docs/guides/embed/metadata-api)

[Custom previews with AI](https://microlink.io/docs/guides/embed/custom-previews-with-ai)

[Caching and performance](https://microlink.io/docs/guides/embed/caching-and-performance)

[Private pages and proxy](https://microlink.io/docs/guides/embed/private-pages-and-proxy)

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

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

[Choosing scope](https://microlink.io/docs/guides/markdown/choosing-scope)

[Delivery and response shaping](https://microlink.io/docs/guides/markdown/delivery-and-response)

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

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

[Page size and layout](https://microlink.io/docs/guides/pdf/page-size-and-layout)

[Page preparation](https://microlink.io/docs/guides/pdf/page-preparation)

[Delivery and embedding](https://microlink.io/docs/guides/pdf/embedding)

[Caching and performance](https://microlink.io/docs/guides/pdf/caching-and-performance)

[Private pages](https://microlink.io/docs/guides/pdf/private-pages)

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

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

[Choosing fields](https://microlink.io/docs/guides/metadata/choosing-fields)

[Extending results](https://microlink.io/docs/guides/metadata/extending-results)

[Delivery and response shaping](https://microlink.io/docs/guides/metadata/delivery-and-response)

[Page preparation](https://microlink.io/docs/guides/metadata/page-preparation)

[Caching and performance](https://microlink.io/docs/guides/metadata/caching-and-performance)

[Private pages](https://microlink.io/docs/guides/metadata/private-pages)

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

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

[Technology detection](https://microlink.io/docs/guides/insights/technology-detection)

[Lighthouse reports](https://microlink.io/docs/guides/insights/lighthouse-reports)

[Caching and performance](https://microlink.io/docs/guides/insights/caching-and-performance)

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

[Common patterns](https://microlink.io/docs/guides/common/caching)

[Caching patterns](https://microlink.io/docs/guides/common/caching)

[Private pages](https://microlink.io/docs/guides/common/private-pages)

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

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

[Production patterns](https://microlink.io/docs/guides/common/production-patterns)

[Copy for LLM](https://microlink.io/docs/guides/embed/iframe.md "Copy content for LLM")

\|

[View as Markdown](https://microlink.io/docs/guides/embed/iframe.md "View content as Markdown")

The `iframe` parameter asks Microlink to discover the provider's official interactive embed for the target URL — a real YouTube player, a Spotify track, a Tweet widget, a Vimeo video. When discovery succeeds, the response includes a new `iframe` field with HTML and any required scripts.

This is the right path when the goal is *the experience the source provides*: playable media, interactive widgets, or anything that is not just a thumbnail and title. If you want a wrapper component that handles the injection for you, see [SDK](https://microlink.io/docs/guides/embed/sdk) with `media='iframe'`. If you want a styled card built from JSON, see [metadata API + custom HTML](https://microlink.io/docs/guides/embed/metadata-api).

## What the iframe field returns

The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw' URL with 'iframe' API parameter:

### CLI Microlink API example

```bash
microlink https://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw&iframe
```

### cURL Microlink API example

```bash
curl -G "https://api.microlink.io" \
  -d "url=https://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw" \
  -d "iframe=true"
```

### JavaScript Microlink API example

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

const { data } = await mql('https://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw', {
  iframe: true
})
```

### Python Microlink API example

```python
import requests

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

querystring = {
    "url": "https://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw",
    "iframe": "true"
}

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://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw",
  iframe: "true"
}

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://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw",
    "iframe" => "true"
];

$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://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw")
    q.Set("iframe", "true")
    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://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw', {

  iframe: true

})
```

The discovered iframe is rendered above. The response payload contains the markup that produced it.

The `iframe` object has two subfields:

```json
{

  "iframe": {

    "html": "<iframe width=\"100%\" height=\"152\" src=\"https://open.spotify.com/embed/track/3BovdzfaX4jb5KFQwoPfAw?utm_source=oembed\" ...></iframe>",

    "scripts": []

  }

}
```

- `html` — the markup to inject into the page.
- `scripts` — an array of `{ src, async, charset }` entries that some providers need. Empty for most video and audio providers; populated for Twitter, Instagram, and other widget-based embeds.

## Inject the iframe HTML

The simplest pattern: fetch the data server-side, pass `iframe.html` to the client, and inject it.

#### Vanilla JavaScript

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

const { data } = await mql(url, { iframe: true })

if (data.iframe) {

  document.getElementById('embed').innerHTML = data.iframe.html

  data.iframe.scripts.forEach(({ src, async, charset }) => {

    if (document.querySelector(`script[src="${src}"]`)) return

    const script = document.createElement('script')

    script.src = src

    if (async) script.async = true

    if (charset) script.charset = charset

    document.head.appendChild(script)

  })

}
```

The script step is what makes Twitter, Instagram, and similar widgets actually render — without it you get unstyled blockquotes.

#### React

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

function ProviderEmbed({ url }) {

  const [iframe, setIframe] = useState(null)

  useEffect(() => {

    let cancelled = false

    mql(url, { iframe: true }).then(({ data }) => {

      if (cancelled) return

      setIframe(data.iframe)

      data.iframe?.scripts?.forEach(({ src, async, charset }) => {

        if (document.querySelector(`script[src="${src}"]`)) return

        const s = document.createElement('script')

        s.src = src

        if (async) s.async = true

        if (charset) s.charset = charset

        document.head.appendChild(s)

      })

    })

    return () => {

      cancelled = true

    }

  }, [url])

  if (!iframe) return null

  return

}
```

For React, the SDK already handles this — see [SDK](https://microlink.io/docs/guides/embed/sdk) and pass `media="iframe"`.

#### Server-side rendering

If you SSR the page, write the HTML and the script tags directly into the response — no client fetch needed:

```js
const { data } = await mql(url, { iframe: true })

res.send(`

  <article>

    <h1>${data.title}</h1>

    ${data.iframe.html}

    ${data.iframe.scripts

      .map(s => `<script async src="${s.src}"></script>`)

      .join('')}

  </article>

`)
```

## When to use iframe vs SDK vs custom HTML

| If you want                                                  | Use                                                                               |
| ------------------------------------------------------------ | --------------------------------------------------------------------------------- |
| The provider's *real* interactive player or widget           | iframe parameter (this page)                                                      |
| A drop-in component with fetching, lazy-loading, and theming | [SDK](https://microlink.io/docs/guides/embed/sdk) with `media="iframe"`           |
| A static rich card, fully styled by you                      | [metadata API + custom HTML](https://microlink.io/docs/guides/embed/metadata-api) |

The SDK and the iframe parameter are not alternatives — the SDK consumes the same `iframe` field internally when you set `media="iframe"`. Pick the SDK if you want the wrapping component to also handle the loading state, lazy-loading, and CSS theming. Pick the raw `iframe` parameter if you want the markup and nothing else.

## Customize the iframe with oEmbed options

The iframe parameter accepts an object that forwards consumer options to the oEmbed endpoint:

The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw' URL with 'iframe' API parameter:

### CLI Microlink API example

```bash
microlink https://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw&iframe.maxWidth=350
```

### cURL Microlink API example

```bash
curl -G "https://api.microlink.io" \
  -d "url=https://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw" \
  -d "iframe.maxWidth=350"
```

### JavaScript Microlink API example

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

const { data } = await mql('https://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw', {
  iframe: {
    maxWidth: 350
  }
})
```

### Python Microlink API example

```python
import requests

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

querystring = {
    "url": "https://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw",
    "iframe.maxWidth": "350"
}

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://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw",
  iframe.maxWidth: "350"
}

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://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw",
    "iframe.maxWidth" => "350"
];

$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://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw")
    q.Set("iframe.maxWidth", "350")
    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://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw', {

  iframe: {

    maxWidth: 350

  }

})
```

Each provider chooses which options it honors. `maxWidth` and `maxHeight` are the most widely supported.

See the

[oEmbed specification](https://oembed.com/)

for the full list of consumer parameters.

## When iframe discovery fails

Not every URL has an oEmbed endpoint. If discovery fails, the `iframe` field is absent from the response — the rest of the metadata is still returned.

Plan your code for both shapes:

```js
const { data } = await mql(url, { iframe: true })

if (data.iframe) {

  container.innerHTML = data.iframe.html

} else {

  // fall back to a custom card built from data.title / data.image / data.description

  container.innerHTML = renderCard(data)

}
```

The full provider list lives in the [iframe parameter reference](https://microlink.io/docs/api/parameters/iframe#providers-supported) — 280+ providers including YouTube, Spotify, Twitter/X, Vimeo, Instagram, TikTok, Figma, CodeSandbox, CodePen, Reddit, Pinterest, Behance, Dribbble, TED, SoundCloud, and Mixcloud.

## Pair iframe with metadata in one call

You usually want both — the iframe for playback, the metadata for the surrounding card frame:

The following examples show how to use the Microlink API with CLI, cURL, JavaScript, Python, Ruby, PHP & Golang, targeting 'https://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw' URL with 'iframe' & 'palette' API parameters:

### CLI Microlink API example

```bash
microlink https://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw&iframe&palette
```

### cURL Microlink API example

```bash
curl -G "https://api.microlink.io" \
  -d "url=https://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw" \
  -d "iframe=true" \
  -d "palette=true"
```

### JavaScript Microlink API example

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

const { data } = await mql('https://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw', {
  iframe: true,
  palette: true
})
```

### Python Microlink API example

```python
import requests

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

querystring = {
    "url": "https://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw",
    "iframe": "true",
    "palette": "true"
}

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://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw",
  iframe: "true",
  palette: "true"
}

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://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw",
    "iframe" => "true",
    "palette" => "true"
];

$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://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw")
    q.Set("iframe", "true")
    q.Set("palette", "true")
    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://open.spotify.com/track/3BovdzfaX4jb5KFQwoPfAw', {

  iframe: true,

  palette: true

})
```

One request returns the player, the title and description, the publisher logo, and brand colors — enough to render a full provider-styled card.

This is also why the SDK works the way it does: it requests `iframe`, `audio`, `video`, `image`, `logo` together and picks the best media available per URL.

## Security and sandboxing

Injecting third-party HTML and scripts is intentional here — that is how the player renders. To reduce blast radius:

- Apply a strict [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) that allowlists only the providers you embed.
- Add `sandbox` to the iframe element if you want to restrict navigation or popups.
- Strip query parameters that could leak referrer data when privacy matters (use the `nocookie` variants where the provider supports them, e.g. `youtube-nocookie.com`).

The HTML returned by Microlink mirrors what the provider hands out via oEmbed, so the security posture is the same as if you embedded the provider directly.

## Next step

For a wrapper component that handles the iframe injection plus loading/lazy/theming for you, see [SDK](https://microlink.io/docs/guides/embed/sdk).

Last updated on May 17, 2026

[Edit on GitHub](https://github.com/microlinkhq/www/blob/master/src/content/docs/guides/embed/iframe.md)