Skip to content
Screenshot API · Use case

Screenshot pages behind a login without scripting the sign-in

To screenshot pages behind a login, the browser has to carry a session, and that session has to stay out of any URL. Dashboards for client reports, invoices for billing emails, admin panels for audits and staging sites behind basic auth all live behind authentication. The Screenshot API forwards headers on the request itself, so the page loads as your logged-in user.

The problem

A screenshot of an authenticated page shows the login form

A fresh headless browser has no cookies, so an authenticated URL redirects to the login page and the capture shows a sign-in form. The request succeeds, the image is delivered, and the report you emailed contains a password field instead of a chart.

Automating the login flow is the obvious fix and the worst one. Filling the form on every capture is slow, breaks whenever the markup changes, and is exactly what multi-factor authentication and bot protection are designed to stop. It also means storing a real password next to your screenshot job.

Microlink lets you forward any header to the target: send it as an x-api-header-* HTTP header on your request and it reaches the page as the original header. A session cookie or an authorization token is enough for the browser to load the page as that user, and the headers reference explains why secrets belong there and not in the query string.

How it works

How to screenshot a page behind a login

Two paths exist: the headers query parameter for public values such as a language, and x-api-header-* request headers for cookies and tokens. Use the second for anything secret. The private pages guide covers both.

1 · Forward a session cookie with the SDK
import createClient from 'microlink.io'

const microlink = createClient({
  apiKey: process.env.MICROLINK_API_KEY
})

const { url } = await microlink.screenshot('https://app.example.com/dashboard', {
  headers: {
    'x-api-header-cookie': `session=${process.env.SESSION_COOKIE}`
  }
})

The SDK sends headers as real HTTP request headers. Microlink strips the x-api-header- prefix and forwards cookie to the target, so the dashboard renders as the session owner and you get back the hosted image URL.

2 · Or a bearer token
import createClient from 'microlink.io'

const microlink = createClient({
  apiKey: process.env.MICROLINK_API_KEY
})

const { url } = await microlink.screenshot('https://app.example.com/reports/42', {
  headers: {
    'x-api-header-authorization': `Bearer ${process.env.APP_TOKEN}`
  },
  waitForSelector: '#report'
})

Any header works the same way, Basic and Bearer authorization included. waitForSelector holds the capture until the authenticated content exists, which also proves the session was accepted.

3 · The same request with curl
curl -G https://pro.microlink.io \
  -d url=https://app.example.com/dashboard \
  -d screenshot=true \
  -d meta=false \
  -H 'x-api-key: $MICROLINK_API_KEY' \
  -H 'x-api-header-cookie: session=abc123'

Credentials travel as HTTP headers on the Microlink request, never in the query string. x-api-key authenticates you against pro.microlink.io, and the x-api-header-cookie value is what the target receives.

Parameters used
  • headers Non-sensitive headers as a public query parameter; secrets go in x-api-header-* request headers. Pro plans.
  • waitForSelector Waits for an element that only exists once the user is authenticated.
  • screenshot.element Crops the capture to the widget or table you need from the dashboard.
  • styles Injects CSS to hide navigation, avatars or other app chrome before the capture.
  • cacheKey Appends a custom identifier, such as a user id, to the cache key. Pro plans.
  • proxy Add it when the authenticated site also sits behind antibot protection. Pro plans.

Forwarding headers requires a Pro plan. Sending x-api-key to the free endpoint fails with EPRO, so point authenticated requests at pro.microlink.io, as the authentication docs describe.

Why it works

Why forwarding headers beats scripting the login for screenshots

A session is the smallest thing that makes a page render for a user, and forwarding it keeps the sensitive part off the wire you do not control.

01 · No login automation
Skip the form, the redirect and the second factor.
Your application already holds a valid session or token. Forward it and the browser lands on the authenticated page directly, without replaying a login flow that changes and that MFA is designed to stop.

The cache key is derived from the URL and the query parameters. When several users capture the same URL, add a cacheKey per user so their captures live in separate cache entries.

02 · Secrets stay in headers
x-api-header-* never touches the query string.
Query parameters end up in logs, browser history and shared links. HTTP headers on the Microlink request do not, which is why cookies and tokens go there and only harmless values go in the headers parameter.

Keep these requests on your backend. The custom headers feature shows how the values ride the HTTP layer, and every capture runs in its own isolated browser that is destroyed afterwards, so a forwarded session is never shared between requests.

03 · Composable
Everything else still applies to the authenticated page.
Wait for the report to render, capture a single element, emulate a phone or hide the navigation with styles. The session is one more request option, not a different product.

When not to: if the page renders user data you are not authorized to store, or the session belongs to a third party, do not forward it. For documents rather than images, the same header pattern drives PDF invoices from authenticated pages.

FAQ

Send it as the x-api-header-cookie header on your request to pro.microlink.io. Microlink strips the x-api-header- prefix and forwards it to the target as a regular cookie header, so the page loads with that session.
You can, but query parameters are public and end up in logs and history. Use the headers parameter for values such as Accept-Language, and x-api-header-* request headers for anything sensitive.

Can I screenshot a page behind a login on the free plan?

No. Forwarding headers, whether through the headers parameter or x-api-header-* request headers, requires a Pro plan and the pro.microlink.io endpoint. Using the headers parameter without one returns the EHEADERS error.

Why does my screenshot still show the login form?

Check that the cookie name and domain match what the application sets, that the session has not expired, and that you are sending the request to pro.microlink.io with a valid x-api-key.
If the site also uses antibot protection, add proxy: true; an EPROXYNEEDED error confirms it is needed. The built-in proxy recipe covers that case.

Can I screenshot a page protected by HTTP basic auth?

Yes. Send the credentials as an x-api-header-authorization header with the value Basic followed by the base64-encoded user and password. Microlink forwards it as a regular Authorization header, so the browser gets past the basic auth prompt and captures the page.
Related use cases

Solve the next problem with the same API

Screenshot a single element

Crop the capture to one CSS selector, such as a chart or a pricing table, with a transparent background if you need it.

Screenshots of JavaScript-rendered pages

Wait for a selector, a lifecycle event or a delay so single-page apps and lazy sections finish rendering before capture.

Screenshot blocked websites

When a site blocks headless browsers, one option routes the capture through a managed, rotating proxy pool.

Screenshots without cookie banners or ads

Ads, trackers and consent popups are blocked before the page renders, and one option dismisses first-party banners.

Screenshots under traffic spikes

Absorb bursts of screenshot traffic without a browser pool: no throttling, parallel requests and a cache whose hits are free.

PDF invoices from authenticated pages

Print the invoice page your app already renders: forward the session, hide the chrome, name the file.

Ready to capture private pages?

Forward the session, keep the secret off the URL. Get a Pro key and screenshot the dashboards only your users can see.