missing_required
missing_required means the request has no content to render. Every screenshot request needs exactly one input: url, html or markdown. The API found none of them, or found only empty values. Add the input and send the request again.
| Field | Value |
|---|---|
| HTTP status | 400 Bad Request |
error.type |
validation_error |
error.code |
missing_required |
error.param |
url |
retryable |
false |
| Credit used | No |
Find the other validation codes in the error code reference.
Example response
{ "error": { "type": "validation_error", "code": "missing_required", "message": "One of url, html, or markdown is required", "param": "url", "retryable": false, "docs": "https://docs.renderscreenshot.com/errors/missing_required" }, "request_id": "req_e81b4c09d2a37f56" }
param is url even when you meant to send html or markdown. It names the most common input, not the one you used.
The three inputs
| Input | Use it for | Details |
|---|---|---|
url |
A live web page | Must be an absolute http or https URL, else invalid_url |
html |
Markup you build, such as social cards or invoices | Add html_base_url if the markup uses relative links |
markdown |
Markdown text rendered with a theme | Optional markdown_theme |
The content input reference covers each one. An empty string or a value with only spaces counts as missing.
Common causes
The body is not read as JSON. This is the most common cause. curl -d sends application/x-www-form-urlencoded by default. The API then reads the whole JSON text as one strange form field name, and finds no url:
# Wrong: no Content-Type, so the JSON body is not parsed curl -X POST https://api.renderscreenshot.com/v1/screenshot \ -H "Authorization: Bearer $RS_API_KEY" \ -d '{"url":"https://example.com"}' # Right curl -X POST https://api.renderscreenshot.com/v1/screenshot \ -H "Authorization: Bearer $RS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"url":"https://example.com"}' \ -o screenshot.png
The same problem happens with requests.post(url, data=json.dumps(body)) without a header, and with fetch when you forget Content-Type. In Python, json=body sets the header for you.
A variable is undefined. JSON.stringify({ url: undefined }) produces {}. The key disappears, so the API sees no input at all. In Python, None becomes null, with the same result.
The input has another name. URL, target, page_url and website are not parameters. The name must be lowercase url.
The input is nested in the wrong place. url belongs at the top level of the JSON body, not inside options, viewport or capture. In a GET request, it is the query parameter url.
The preset was wrong too. The API checks the preset before the input. If you just fixed an invalid_preset error, missing_required can be the next problem in the same request.
Handle it in code
Check the input before the request leaves your code. Then a missing value fails with a message that names your variable, not with an HTTP 400 from the API:
// required-input.mjs (Node 22, no dependencies) const API = process.env.RS_BASE_URL ?? 'https://api.renderscreenshot.com'; export async function render(input, options = {}) { // Exactly one source: url, html or markdown. JSON.stringify drops undefined values, // so a missing variable becomes a missing key, and the API answers missing_required. const sources = ['url', 'html', 'markdown'].filter((k) => typeof input[k] === 'string' && input[k].trim()); if (sources.length !== 1) { throw new Error(`Pass exactly one of url, html or markdown (got: ${sources.join(', ') || 'none'})`); } const res = await fetch(`${API}/v1/screenshot`, { method: 'POST', headers: { Authorization: `Bearer ${process.env.RS_API_KEY}`, 'Content-Type': 'application/json', // without it, the JSON body is not read as parameters }, body: JSON.stringify({ ...options, [sources[0]]: input[sources[0]] }), }); if (!res.ok) { const { error } = await res.json(); throw new Error(`${res.status} ${error.code}: ${error.message}`); } return Buffer.from(await res.arrayBuffer()); } // render({ url: 'https://example.com' }, { preset: 'og_card' }) // render({ html: '<h1>Hello</h1>' }) // render({ url: process.env.PAGE_URL }) -> throws before the request if PAGE_URL is unset
Tested on 2026-10-15 with Node 22.18 against a local mock that returns the API's error envelope. The url and html calls returned images. The unset variable failed in the client with got: none. The curl request without Content-Type reproduced missing_required.
Related
- POST /v1/screenshot: the full request body.
- invalid_parameter: an input is present, but another value is out of range.