ScreenshotNeo

BlogHow-to

How to Capture a Password-Protected Webpage with Cloudinary

Cloudinary can capture public webpages and fetch some Basic-authenticated media. For pages that require an interactive login, capture them in an authorized browser session first.

By the ScreenshotNeo team4 October 20268 min read

Short answer: Cloudinary’s URL2PNG add-on captures webpages documented as public websites. Its Fetch feature can retrieve some remote image and video files protected with HTTP Basic Authentication, but that does not mean it can sign in through a webpage’s login form or reuse an authenticated browser session. For an interactive login, sign in with an authorized browser workflow, save the screenshot, and upload that image to Cloudinary if you need Cloudinary storage or image transformations.

Cloudinary URL2PNG is intended for webpage screenshot creation; Cloudinary Fetch’s Basic Authentication support is for remote media retrieval. Those are different workflows. [Cloudinary Fetch documentation, Cloudinary URL2PNG documentation]

Choose the workflow that matches the protected target

What you need to capture Use Important limit
A public webpage Cloudinary URL2PNG Register the add-on. A delivery transformation must be signed or eagerly generated unless unsigned add-on transformations are allowed in Console settings.
An image or video file served directly with HTTP Basic Authentication Cloudinary Fetch, if enabled and allowed for the host This retrieves a media file; it does not render an HTML page or complete a form login.
A webpage behind a login form, application session, or browser cookie An authorized browser session, followed by an image upload to Cloudinary if needed The URL2PNG documentation reviewed does not establish interactive login or authenticated-session support.

Cloudinary describes URL2PNG as creating dynamic website screenshots and integrating them into its image management and transformation pipeline. Its documented capture options include viewport, user agent, and delay. The resulting screenshot is cached and delivered through Cloudinary’s CDN. [URL2PNG documentation]

Capture an interactive page with an authenticated browser

Use a browser automation workflow when the page requires you to enter credentials, complete a multi-step login, or establish an application session. The example below uses Playwright for Node.js. Install the package and a browser, set the page URL and credentials through environment variables, and run the script in a trusted server-side environment.

npm install playwright
npx playwright install chromium
PAGE_URL='https://example.com/account' LOGIN_URL='https://example.com/login' USERNAME='your-user' PASSWORD='your-password' node capture.mjs

Save this as capture.mjs. The example assumes the login page has fields named username and password, and that submitting the form completes login. Change the selectors and success condition to match the site you are authorized to access.

import { chromium } from 'playwright';

const pageUrl = process.env.PAGE_URL;
const loginUrl = process.env.LOGIN_URL;
const username = process.env.USERNAME;
const password = process.env.PASSWORD;

if (!pageUrl || !loginUrl || !username || !password) {
  throw new Error('Set PAGE_URL, LOGIN_URL, USERNAME, and PASSWORD.');
}

const browser = await chromium.launch({ headless: true });
try {
  const page = await browser.newPage({ viewport: { width: 1440, height: 1000 } });
  await page.goto(loginUrl, { waitUntil: 'domcontentloaded', timeout: 30000 });
  await page.locator('input[name="username"]').fill(username);
  await page.locator('input[name="password"]').fill(password);
  await page.locator('button[type="submit"]').click();

  // Replace this with a page-specific confirmation that login succeeded.
  await page.waitForURL(url => url.href !== loginUrl, { timeout: 30000 });
  await page.goto(pageUrl, { waitUntil: 'domcontentloaded', timeout: 30000 });
  await page.screenshot({ path: 'authenticated-page.png', fullPage: true });
} finally {
  await browser.close();
}

domcontentloaded waits for the document to be parsed, not for every image or application request to finish. If the page renders content later, wait for a page-specific selector that indicates the important content is ready, then capture. Avoid relying on an arbitrary long delay when a reliable selector is available.

  1. Confirm you are authorized to access and capture the page.
  2. Run the browser script on a trusted machine or server. Do not put the password in browser-delivered code, source control, or a public URL.
  3. Adapt the form selectors and login-success check. Sites may use single sign-on, multi-factor authentication, CAPTCHA, or JavaScript-driven controls that need a site-specific authorized workflow.
  4. Save the screenshot locally and inspect it for missing content, overlays, or sensitive information.
  5. Upload the image to Cloudinary server-side if you need Cloudinary storage, transformations, or delivery.

Upload the captured image to Cloudinary

Cloudinary’s Upload API accepts authenticated server-side uploads using API key and API secret credentials, or signature-based authentication. Keep the API secret on the server; never expose it in public client-side code. The following Python example uses Cloudinary’s Python SDK and expects the account credentials in environment variables.

pip install cloudinary
export CLOUDINARY_CLOUD_NAME='your-cloud-name'
export CLOUDINARY_API_KEY='your-api-key'
export CLOUDINARY_API_SECRET='your-api-secret'
python upload_capture.py
import os
import cloudinary
import cloudinary.uploader

cloudinary.config(
    cloud_name=os.environ['CLOUDINARY_CLOUD_NAME'],
    api_key=os.environ['CLOUDINARY_API_KEY'],
    api_secret=os.environ['CLOUDINARY_API_SECRET'],
    secure=True,
)

result = cloudinary.uploader.upload(
    'authenticated-page.png',
    resource_type='image',
)
print(result['secure_url'])

For request fields, authentication choices, and upload behavior, use Cloudinary’s Upload API reference. Uploading a screenshot is separate from capturing or logging into the webpage. [Cloudinary Upload API documentation]

Cloudinary options and security details

URL2PNG for public pages

  • Register URL2PNG as an add-on on the Cloudinary account.
  • Use the documented dynamic delivery URL with the url2png delivery type and the public website URL as the public ID.
  • Review the add-on’s viewport, user-agent, and delay options for the capture you need.
  • By default, sign the transformation or eagerly generate it. Console settings can allow unsigned add-on transformations.
  • A Cloudinary transformation signature protects the Cloudinary request. It is not a password or login credential for the target website.

See Cloudinary’s URL2PNG documentation for the current URL construction and parameters before implementing a delivery URL.

Fetch for Basic-authenticated media

Cloudinary documents Fetch for remote image or video URLs protected by HTTP Basic Authentication. Credentials embedded in a remote URL can leak through client-side code or the delivery URL. Keep this workflow server-side or use an auto-upload mapping to keep credentials out of delivery URLs. URL-encode special characters where needed. Check whether Fetch is enabled, whether the URL must be signed, and whether the host satisfies any allowed-fetch-domain restriction. Cloudinary also documents a limit of five redirects before Fetch returns a 404. [Fetch documentation]

Interactive page authentication

For a form-based login or application session, authenticate in the browser and capture after the page reaches the required state. Do not assume that adding credentials to a Cloudinary transformation URL will log in to the target. Do not send website passwords or Cloudinary API secrets to a public frontend.

Cost, performance, and reliability considerations

  • Cost: The available documentation establishes URL2PNG as a registered add-on, but this guide does not state a price. Check the current Cloudinary account and add-on terms before planning usage.
  • Capture latency: Browser startup, login redirects, application rendering, and full-page image loading all add time. Wait for the content you need instead of adding an unnecessarily large fixed delay.
  • Reliability: Login flows can change, expire, or require additional verification. Use a page-specific success condition and fail the job if it is not met, rather than saving a screenshot of the login screen as if it were authenticated content.
  • Image size: Full-page screenshots can be large. Choose a viewport and capture scope that fit the actual need, and check upload limits and downstream transformation requirements.
  • Credential handling: Restrict access to environment variables and stored screenshots. Authenticated captures may contain private account data.

Troubleshooting

Symptom Likely cause Fix
URL2PNG does not show the page behind a login The page requires interactive authentication or a browser session not established by the documented screenshot workflow. Sign in using an authorized browser automation flow, capture the rendered page, then upload the image if Cloudinary storage is needed.
Cloudinary rejects a URL2PNG delivery request The add-on may not be registered, or the transformation may need signing or eager generation. Check add-on registration and the account’s unsigned-transformation setting; sign or eagerly generate as required.
Fetch returns 404 for a protected media URL Fetch may be disabled, the host may be outside the allowed domain configuration, the request may need signing, or redirects may exceed the documented limit. Check Fetch settings, signing, domain restrictions, credentials, and the redirect chain.
The upload returns an authentication error Cloudinary credentials are absent, incorrect, or paired with the wrong cloud account. Check server environment variables and use the documented Upload API authentication method. Never move the API secret into client code.
The screenshot contains a login page or incomplete content Login did not complete, the success condition was too weak, or the app had not rendered the target content. Wait for a page-specific authenticated selector or URL, then wait for the content selector before capturing.
Playwright times out at login Selectors differ from the example, login includes extra steps, or the site requires an interactive verification step. Inspect the authorized login flow, update selectors and success checks, and handle additional steps according to the site’s permitted process.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. For pages its API can access, a single GET request returns an image or PDF. The API supports custom headers and cookies, but this example does not perform a form-based login; do not put passwords or session secrets in public code. See the ScreenshotNeo API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before the shot. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000.

Sign up for ScreenshotNeo free: 1,000 screenshots a month, no card.

FAQ

Can a Cloudinary transformation signature log in to a website?

No. The signature protects the Cloudinary transformation request; the reviewed URL2PNG documentation does not describe it as target-site authentication.

Can Cloudinary Fetch capture an HTML page protected by Basic Auth?

The documented Basic Authentication support applies to remote image or video assets. It does not establish webpage rendering after authentication.

Can I upload the screenshot after capturing it?

Yes. Cloudinary documents server-side Upload API requests for uploading an image file. Keep the API secret server-side.