How to Capture an Instagram Embed as an Image
Render an Instagram post embed as a PNG. Useful for archiving posts, embedding in editorial content or printing.
Want it faster? Use the Instagram Square Post template and skip the embed widget. Send caption text, image and brand color as JSON.
HTML and CSS
<blockquote class="instagram-media"
data-instgrm-captioned
data-instgrm-permalink="https://www.instagram.com/p/POST_ID/"
data-instgrm-version="14">
</blockquote>
<script async src="//www.instagram.com/embed.js"></script>
body { margin: 0; padding: 16px; background: white; }
.instagram-media {
margin: 0 auto !important;
min-width: 326px !important;
max-width: 550px !important;
width: calc(100% - 2px) !important;
}
ms_delay
Instagram’s embed.js loads asynchronously. Use ms_delay of 1500ms minimum so the post and image render before capture.
Code examples
cURL
curl -X POST https://app.html2img.com/api/html \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<blockquote class=\"instagram-media\" data-instgrm-captioned data-instgrm-permalink=\"https://www.instagram.com/p/POST_ID/\" data-instgrm-version=\"14\"></blockquote><script async src=\"//www.instagram.com/embed.js\"></script>",
"css": "body { margin: 0; padding: 16px; background: white; } .instagram-media { margin: 0 auto !important; min-width: 326px !important; max-width: 550px !important; }",
"width": 600,
"height": 800,
"ms_delay": 1500
}'
PHP
$ch = curl_init('https://app.html2img.com/api/html');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['X-API-Key: ' . getenv('HTML2IMG_API_KEY'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'html' => '<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-permalink="https://www.instagram.com/p/POST_ID/" data-instgrm-version="14"></blockquote><script async src="//www.instagram.com/embed.js"></script>',
'css' => 'body { margin: 0; padding: 16px; background: white; } .instagram-media { margin: 0 auto !important; min-width: 326px !important; max-width: 550px !important; }',
'width' => 600, 'height' => 800, 'ms_delay' => 1500,
]),
]);
$url = json_decode(curl_exec($ch), true)['url'];
Node.js
const response = await fetch('https://app.html2img.com/api/html', {
method: 'POST',
headers: { 'X-API-Key': process.env.HTML2IMG_API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
html: '<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-permalink="https://www.instagram.com/p/POST_ID/" data-instgrm-version="14"></blockquote><script async src="//www.instagram.com/embed.js"></script>',
css: 'body { margin: 0; padding: 16px; background: white; } .instagram-media { margin: 0 auto !important; min-width: 326px !important; max-width: 550px !important; }',
width: 600, height: 800, ms_delay: 1500,
}),
});
const { url } = await response.json();
Python
import os, requests
response = requests.post(
'https://app.html2img.com/api/html',
headers={'X-API-Key': os.environ['HTML2IMG_API_KEY']},
json={
'html': '<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-permalink="https://www.instagram.com/p/POST_ID/" data-instgrm-version="14"></blockquote><script async src="//www.instagram.com/embed.js"></script>',
'css': 'body { margin: 0; padding: 16px; background: white; } .instagram-media { margin: 0 auto !important; min-width: 326px !important; max-width: 550px !important; }',
'width': 600, 'height': 800, 'ms_delay': 1500,
},
)
url = response.json()['url']
Common pitfalls
- Embed widget never renders. Instagram throttles automated traffic. The widget can fail entirely on a busy day. Prefer the Instagram Square Post template for reliability.
- Post is from a private account. The embed shows a placeholder. Confirm the account is public.
- Image lazy-loads after capture. Increase
ms_delayto 3000ms if the image is missing from the output.