How to Convert a Password-Protected Webpage to PDF with PDFShift
Convert a page protected by HTTP Basic Auth or an existing session cookie to PDF with PDFShift, using cURL, Python, or Node.js.
To convert a password-protected webpage with PDFShift, send a POST request to its PDF conversion endpoint with the page URL in source, the PDFShift API key in the X-API-Key header, and source-page credentials in the JSON body. Use the auth object for HTTP Basic Authentication. If the page relies on an existing logged-in session, send its valid session cookie in a cookies array instead.
The page password or session cookie grants access to the source webpage; the PDFShift API key authenticates your conversion request. They are separate credentials. The examples below use placeholders—replace them through a secure configuration mechanism with credentials you are authorized to use.
1. Identify how the page is protected
Before making the request, determine which access method the source page uses:
| What protects the page | PDFShift request field | What you need |
|---|---|---|
| HTTP Basic Authentication challenge | auth object |
Username and password accepted by the page server |
| An existing authenticated session | cookies array |
Current cookie name and value for an authorized session |
These documented methods do not establish that PDFShift automates ordinary interactive login forms. Do not assume that submitting a username and password will complete a form-based login, SSO, or an MFA challenge. If a site requires those steps, ask its administrator for an approved export or another supported access path.
2. Convert a page protected by HTTP Basic Auth
PDFShift documents sending the source URL and an auth object in the JSON request body to https://api.pdfshift.io/v3/convert/pdf. The API key goes in the X-API-Key header.
cURL
curl --fail-with-body --silent --show-error \
-X POST "https://api.pdfshift.io/v3/convert/pdf" \
-H "X-API-Key: YOUR_PDFSHIFT_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"source": "https://www.example.com/protected-page",
"auth": {
"username": "YOUR_PAGE_USERNAME",
"password": "YOUR_PAGE_PASSWORD"
}
}' \
--output protected-page.pdf
--fail-with-body makes cURL return a failure status for HTTP errors while preserving the response body for diagnosis. If your cURL version does not support that flag, remove it and inspect the HTTP status separately. The output file should be treated as a PDF only after the request succeeds.
Python
import requests
url = "https://api.pdfshift.io/v3/convert/pdf"
headers = {
"X-API-Key": "YOUR_PDFSHIFT_API_KEY",
"Content-Type": "application/json",
}
payload = {
"source": "https://www.example.com/protected-page",
"auth": {
"username": "YOUR_PAGE_USERNAME",
"password": "YOUR_PAGE_PASSWORD",
},
}
response = requests.post(url, headers=headers, json=payload, timeout=90)
response.raise_for_status()
with open("protected-page.pdf", "wb") as pdf_file:
pdf_file.write(response.content)
This follows PDFShift’s documented Python pattern: check for an HTTP error before writing the binary response to disk. Install the dependency if needed with python -m pip install requests.
Node.js
const response = await fetch("https://api.pdfshift.io/v3/convert/pdf", {
method: "POST",
headers: {
"X-API-Key": "YOUR_PDFSHIFT_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
source: "https://www.example.com/protected-page",
auth: {
username: "YOUR_PAGE_USERNAME",
password: "YOUR_PAGE_PASSWORD",
},
}),
});
if (!response.ok) {
const details = await response.text();
throw new Error(`PDFShift returned HTTP ${response.status}: ${details}`);
}
const pdf = Buffer.from(await response.arrayBuffer());
await import("node:fs/promises").then(({ writeFile }) =>
writeFile("protected-page.pdf", pdf)
);
Use a Node.js version with built-in fetch. The response body is binary data, so save an array buffer or buffer rather than trying to parse it as JSON.
3. Convert a page using an existing session cookie
If you already have a valid cookie for a session authorized to access the page, pass the cookie name and value in the cookies array. PDFShift’s cookie guide also documents optional secure and http_only Boolean fields.
cURL
curl --fail-with-body --silent --show-error \
-X POST "https://api.pdfshift.io/v3/convert/pdf" \
-H "X-API-Key: YOUR_PDFSHIFT_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"source": "https://www.example.com/protected-page",
"cookies": [
{
"name": "SESSION_COOKIE_NAME",
"value": "SESSION_COOKIE_VALUE",
"secure": true,
"http_only": true
}
]
}' \
--output protected-page.pdf
Include the flags only when they accurately describe the cookie. The cookie guide lists them as optional; the essential example fields are name and value.
Python
import requests
url = "https://api.pdfshift.io/v3/convert/pdf"
headers = {"X-API-Key": "YOUR_PDFSHIFT_API_KEY"}
payload = {
"source": "https://www.example.com/protected-page",
"cookies": [
{
"name": "SESSION_COOKIE_NAME",
"value": "SESSION_COOKIE_VALUE",
"secure": True,
"http_only": True,
}
],
}
response = requests.post(url, headers=headers, json=payload, timeout=90)
response.raise_for_status()
with open("protected-page.pdf", "wb") as pdf_file:
pdf_file.write(response.content)
Node.js
import { writeFile } from "node:fs/promises";
const response = await fetch("https://api.pdfshift.io/v3/convert/pdf", {
method: "POST",
headers: {
"X-API-Key": "YOUR_PDFSHIFT_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
source: "https://www.example.com/protected-page",
cookies: [
{
name: "SESSION_COOKIE_NAME",
value: "SESSION_COOKIE_VALUE",
secure: true,
http_only: true,
},
],
}),
});
if (!response.ok) {
throw new Error(`PDFShift returned HTTP ${response.status}: ${await response.text()}`);
}
await writeFile("protected-page.pdf", Buffer.from(await response.arrayBuffer()));
A session cookie is sensitive: anyone who can use it may be able to act as that session until it expires or is revoked. Pass it only for a page you are allowed to access, keep it out of source control and public logs, and follow your organization’s rules for sending credentials to a conversion service.
4. Keep the two authentication layers separate
| Credential | Where it goes | What it authorizes |
|---|---|---|
| PDFShift API key | X-API-Key HTTP header |
Your caller’s request to PDFShift |
| Basic Auth username and password | auth.username and auth.password in JSON |
PDFShift’s access to the protected source page |
| Session cookie | cookies array in JSON |
PDFShift’s access through an existing source-page session |
A valid page password cannot replace the PDFShift API key, and a valid API key cannot grant access to the protected page. PDFShift’s Help Center says requests missing the API key header may be treated as unauthenticated and watermarked. It recommends checking account usage at GET https://api.pdfshift.io/v3/credits/usage to confirm that the key is being accepted. Consult the [PDFShift Basic Auth guide](https://pdfshift.io/guides/python/requests/accessing-secured-pages/) and [PDFShift cookie guide](https://pdfshift.io/guides/node/unfetch/using-cookies/) for their documented request formats; see the [watermark and API key help article](https://help.pdfshift.io/en/article/why-is-the-watermark-present-when-sandbox-is-set-to-false-10llcn/) for key behavior.
5. Secure credentials and the resulting PDF
- Keep the PDFShift key, page password, and session cookie in environment variables or a secrets manager in production; do not commit them to a repository or embed them in public client-side code.
- Send only credentials for pages you are authorized to retrieve. Consider whether your organization permits forwarding those credentials and page contents to a third-party conversion service.
- Restrict access to the generated PDF as appropriate. The PDF may contain the same confidential data as the source page.
- Avoid logging full request bodies or cookie values when diagnosing a failed conversion. Log the HTTP status and a sanitized error instead.
- Use HTTPS for the source URL and API endpoint. Do not disable certificate checks to work around a connection problem.
6. Troubleshooting
| Symptom | Likely cause | What to check |
|---|---|---|
| PDFShift returns an authentication error | The X-API-Key header is absent, misspelled, or has an invalid key. |
Check the header name and key source. Confirm the key is accepted through the usage endpoint noted above. Do not confuse the PDFShift key with the page password. |
| The PDF shows a login page | The request used the wrong source-page authentication method, or the supplied credential is not valid for that URL. | For a Basic Auth challenge, use auth. For an already authenticated session, send the correct current cookie. Generic login-form automation is not established by the cited PDFShift documentation. |
| The output is watermarked | The request may have been treated as unauthenticated because the API key header was missing or not accepted. | Verify X-API-Key and consult PDFShift’s watermark help article. Page credentials and API authentication are separate. |
| The cookie request returns an unauthorized page | The cookie may be expired, copied incorrectly, or not valid for the requested page’s session. | Obtain a fresh cookie through an approved login process, confirm its name and value, and check that it belongs to the relevant site and session. Cookie behavior can vary by site. |
| The script saves an unreadable file | An HTTP error or text response was written as though it were a PDF. | Check the response status before writing bytes. Inspect the error response as text when the status is not successful; save the response body as binary only after success. |
| Request times out | The source page or conversion request did not finish within the client timeout. | Use a suitable client timeout, check that the source URL is reachable, and retry selectively for transient network failures. Avoid tight retry loops that repeatedly submit the same request. |
| Basic Auth works in a browser but not in conversion | The browser may have retained credentials or session state that the API request did not include. | Confirm the page truly uses HTTP Basic Auth and pass the matching credentials in the JSON auth object. If it is session-based, use the cookie method instead. |
7. Reliability, performance, and cost considerations
The documented workflow is one conversion request per PDF. The sources reviewed for this guide do not establish conversion speed, success-rate guarantees, retry semantics, or current plan limits, so do not build those assumptions into a cost or performance estimate. Check PDFShift’s current account details and documentation before production planning.
For reliable application behavior, apply a finite network timeout, check HTTP status before saving, keep an error path that does not mistake an error body for a PDF, and retry only failures you have determined are transient. A timeout does not by itself prove the source credentials were rejected. If an application may submit the same job repeatedly after an uncertain timeout, consider how it will prevent duplicate work.
Or skip the browser setup
If your goal is a clean screenshot or PDF and you do not need PDFShift’s protected-page workflow, ScreenshotNeo is a website screenshot API and MCP server for developers. Its API returns a screenshot or PDF from one GET request. 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
This call captures the supplied URL. ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents use screenshot tools. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Yearly billing gives two months free, and every feature is on every plan. For this password-protected-page task, use only the access methods supported by the target page and the selected service; the ScreenshotNeo facts here do not establish that it accepts Basic Auth credentials or session cookies.
Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.
FAQ
Can I put the webpage password in the PDFShift API key header?
No. The header identifies your PDFShift caller. Put Basic Auth credentials in the JSON auth object, or use the cookies array for an existing session.
Can PDFShift log in to any site if I provide a username and password?
The cited official material documents HTTP Basic Auth and existing cookies. It does not establish general support for interactive forms, SSO, MFA, CAPTCHA, or JavaScript-driven login.
Does the cookie guide explain how to obtain a session cookie?
It documents how to include cookies in the conversion request, not how to log in and obtain a cookie. Use a site-approved method and handle the resulting session credential as sensitive.
Should I use Basic Auth and cookies together?
Choose the method that matches how the source page is protected. The documented examples establish each method independently; they do not establish a need to combine them.


