How to add custom CSS to a Urlbox screenshot
Inject CSS into a Urlbox screenshot with the `css` render option. See GET and POST examples, capture-scope choices, troubleshooting, and a ScreenshotNeo alternative.
To add custom CSS to a Urlbox screenshot, pass your stylesheet in the css render option alongside the page url (or an HTML input). Urlbox injects that CSS into the rendered page before capture. Use full_page or selector separately to choose what part of the styled page to capture. The examples below use Urlbox’s documented POST API and its HTTP Basic authentication method; see the POST API documentation and render options.
1. Add CSS with a Urlbox POST request
POST accepts JSON or form data, and the render options are the same as the GET render options. The example sends JSON. Replace the placeholder credentials and URL, and use CSS text as the value of css.
curl -X POST "https://api.urlbox.io/v1/render" \
-u "YOUR_URLBOX_SECRET_KEY:" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"css": "body { background: #f4f6f8 !important; } h1 { color: #173b63 !important; }"
}' \
--output screenshot.png
Use the endpoint and credential format configured for your Urlbox account. Urlbox documentation describes HTTP Basic authentication with the secret key as the username for its POST API; its API reference describes bearer authentication for its synchronous endpoint. Follow the authentication instructions for the exact endpoint you call rather than mixing the two schemes.
Python
import requests
urlbox_endpoint = "https://api.urlbox.io/v1/render"
secret_key = "YOUR_URLBOX_SECRET_KEY"
payload = {
"url": "https://example.com",
"css": "body { background: #f4f6f8 !important; } h1 { color: #173b63 !important; }",
}
response = requests.post(
urlbox_endpoint,
auth=(secret_key, ""),
json=payload,
timeout=90,
)
response.raise_for_status()
with open("screenshot.png", "wb") as screenshot:
screenshot.write(response.content)
Node.js
const endpoint = 'https://api.urlbox.io/v1/render';
const secretKey = 'YOUR_URLBOX_SECRET_KEY';
const payload = {
url: 'https://example.com',
css: 'body { background: #f4f6f8 !important; } h1 { color: #173b63 !important; }',
};
const auth = Buffer.from(`${secretKey}:`).toString('base64');
const response = await fetch(endpoint, {
method: 'POST',
headers: {
Authorization: `Basic ${auth}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(`Urlbox returned ${response.status}: ${await response.text()}`);
}
const image = Buffer.from(await response.arrayBuffer());
await import('node:fs/promises').then(({ writeFile }) => writeFile('screenshot.png', image));
For a render link or GET request, include css with the other render options. URL-encode the CSS when assembling a URL by hand; using a URL builder or a POST body avoids many encoding mistakes. The documentation describes render links and POST requests, but the retrieved reference does not specify a CSS-specific size limit.
2. Make the CSS affect the intended content
Write CSS selectors for the target page’s actual DOM. For a small visual override, a rule such as body { font-family: Arial, sans-serif !important; } may be enough. Use !important only when the site’s own stylesheet has stronger rules or loads later; first try a more specific selector.
Injected stylesheets cannot guarantee identical results on every site. The page may use changing markup, inline styles, dynamically loaded content, or shadow DOM. The Urlbox reference establishes that css injects CSS; it does not promise site-by-site behavior, so inspect the returned capture when the target page is important.
Capture the whole page or one element
| Goal | Option | What it controls |
|---|---|---|
| Capture the full page | full_page |
Capture scope; independent of styling. |
| Capture one component | selector |
Target element for capture; independent of styling. |
| Change page appearance | css |
Styles injected into the rendered page. |
For example, combine your css with selector if you want to restyle the page and return just a chart or card. Use full_page when the screenshot should include the entire page. These options solve different problems; CSS does not itself select the capture area.
When JavaScript is needed
Use CSS for visual changes. Urlbox documents a separate js option for custom JavaScript that runs after the page DOM loads and before the screenshot. Its documentation says await may be used in that code and that js requires the Ultra plan or above. The options reference does not state an equivalent plan restriction for css. Prefer CSS when it can express the change; use JavaScript only when the page needs a DOM change or an interaction that styling cannot perform.
3. Choose a request and full-page mode
A render link is useful when you want a URL that directly returns a render. POST is useful when you want to send JSON or form data, handle a larger options payload, or use a synchronous or asynchronous workflow. Urlbox’s POST page says it accepts the same render options as GET. Use the workflow and authentication documented for the endpoint you choose.
For full-page screenshots, Urlbox documents stitch as the default mode, optimized for accuracy, and native as faster but less reliable on some sites. Choose based on the page and the result you need: favor the documented accuracy-oriented default where complete capture matters, and consider native when speed matters and the page renders correctly with it.
4. Troubleshoot CSS screenshots
| Symptom | Likely cause | Fix |
|---|---|---|
| The screenshot looks unchanged | The selector does not match the page, or the site’s rule overrides yours. | Inspect the selector against the target DOM, try a more specific selector, then use !important if needed. |
| Only part of the page appears | The capture scope is limited, or a selected element is smaller than expected. | Check whether selector is set; use full_page for a full-page capture. |
| The API rejects the request | Authentication format, endpoint, or request encoding does not match the selected API method. | Follow the endpoint’s own authentication instructions. For POST, send valid JSON with Content-Type: application/json, or use the documented form-data option. |
| CSS breaks the request URL | Characters such as spaces, quotes, braces, ampersands, or hashes were not URL-encoded. | Use a URL-encoding library for GET/render links, or send CSS in a JSON POST body. |
| The override works on one page but not another | Sites differ in markup, style priority, dynamic rendering, and component boundaries. | Tailor selectors to each page. If styling cannot make the required change, consider the separate js option and its plan requirement. |
| A full-page capture is incomplete or unreliable | The chosen full-page mode may behave differently on that page. | Urlbox describes stitch as accuracy-optimized and native as faster but less reliable on some sites; compare the modes for the target page. |
5. Performance, reliability, and cost considerations
- Keep CSS focused. A few targeted overrides are easier to reason about than broad page-wide changes. The cited Urlbox documentation does not publish a CSS-specific size limit or CSS performance benchmark.
- Make captures reproducible. Keep the URL, CSS text, capture scope, and full-page mode consistent when comparing renders. Page markup and content can change independently of your stylesheet.
- Use the right capture mode. For full-page output, the documented stitch/native tradeoff is accuracy versus speed; test on the actual page when reliability matters.
- Check plan-specific options. The source documents a plan requirement for custom JavaScript (Ultra or above), but does not state that CSS has the same restriction. Confirm current account and endpoint requirements in Urlbox’s official docs.
- Budget based on your account terms. The reviewed sources do not provide pricing or per-render cost details, so no price or cost estimate is asserted here.
6. Or skip the browser setup
If the goal is a styled or clean screenshot through a single API call, ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. It supports custom CSS and JavaScript among its capture options, along with full-page and selector capture. See the ScreenshotNeo API documentation for request options.
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}`);
- Cookie banners are accepted and more than 60 known consent platforms, newsletter popups, and chat widgets are removed before the shot; each step can be turned off.
- Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing. Response headers report the page verdict and whether the shot was billed.
- An MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs.
- 1,000 screenshots a month are free with no card. Paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo and get 1,000 screenshots a month free, with no card.
7. FAQ
Does the CSS option replace the target URL?
No. A render still needs a publicly accessible URL or HTML input; CSS is an additional render option.
Can I use CSS and select an element in the same request?
Yes. CSS controls styling while selector controls capture scope, so they can be used together.
Does custom CSS require Urlbox Ultra?
The retrieved options reference says custom JavaScript requires Ultra or above. It does not state that CSS has that requirement.
Can I use this to change page content?
CSS changes presentation. For DOM changes or interactions, Urlbox documents the separate JavaScript option, subject to its stated plan requirement.
Sources
- Urlbox render options — CSS, JavaScript, and capture options.
- Urlbox screenshots guide — capture scope and full-page options.
- Urlbox POST API — POST payloads and authentication.
- Urlbox API reference — endpoint request details and authentication.


