invalid_preset

The API returns invalid_preset when the preset value in your request is not the ID of a built-in preset. Nothing is rendered. Correct the name and send the request again; a retry with the same name fails the same way.

Field Value
HTTP status 400 Bad Request
error.type validation_error
error.code invalid_preset
error.param preset (batch: options.preset or requests[N].preset)
retryable false
Credit used No

This page is part of the error code reference.

Example response

{
  "error": {
    "type": "validation_error",
    "code": "invalid_preset",
    "message": "Unknown preset 'og-card'. Use GET /v1/presets to see available presets.",
    "param": "preset",
    "retryable": false,
    "docs": "https://docs.renderscreenshot.com/errors/invalid_preset"
  },
  "request_id": "req_7f3c2a9e1b4d6f80"
}

The message repeats the name the API received, quotes included. Check it for stray spaces or an unexpected value from a template.

The valid preset IDs

The API accepts exactly these ten IDs. Each one is lowercase with underscores:

og_card, twitter_card, twitter_card_large, link_preview, full_page, mobile, mobile_landscape, desktop_hd, desktop_4k, pdf_document

The presets reference shows the viewport, format and cache TTL of each one. To get the list from the API itself, call GET /v1/presets. That endpoint needs a valid key but does not render a page, so it does not use a credit.

Common causes

What you sent Why it fails Send instead
og-card, OG_CARD The match is exact and case-sensitive og_card
twitter, twitter_large Not a preset ID twitter_card, twitter_card_large
og_image, opengraph Name from another screenshot service og_card
pdf, a4 A format or paper size, not a preset pdf_document, or set output.format and pdf.paper
"og_card " Trailing space from a config file or form Trim the value
retina, 1920x1080 Settings, not presets viewport.scale, viewport.width and viewport.height

An empty preset value is not an error: the API ignores it and uses the default settings.

Checking order

The API checks a request in a fixed order: credentials, then remaining credits, then the preset, then the url, html or markdown input. So a request with a wrong preset and a missing URL reports invalid_preset first. After you correct the preset, you can see missing_required on the next attempt. This is the same request, not a new problem.

Handle it in code

Presets rarely change, so check the name once against GET /v1/presets and fail before you send the screenshot request. This Node version also accepts friendly spellings such as OG-Card:

// preset-guard.mjs  (Node 22, no dependencies)
const API = process.env.RS_BASE_URL ?? 'https://api.renderscreenshot.com';
const headers = { Authorization: `Bearer ${process.env.RS_API_KEY}` };

let presetIds; // loaded once per process
async function knownPresets() {
  if (!presetIds) {
    const res = await fetch(`${API}/v1/presets`, { headers });
    if (!res.ok) throw new Error(`GET /v1/presets failed with HTTP ${res.status}`);
    presetIds = new Set((await res.json()).presets.map((p) => p.id));
  }
  return presetIds;
}

export async function screenshot(url, preset) {
  const id = String(preset).trim().toLowerCase().replaceAll('-', '_');
  const presets = await knownPresets();
  if (!presets.has(id)) {
    throw new Error(`Unknown preset "${preset}". Valid: ${[...presets].join(', ')}`);
  }

  const res = await fetch(`${API}/v1/screenshot`, {
    method: 'POST',
    headers: { ...headers, 'Content-Type': 'application/json' },
    body: JSON.stringify({ url, preset: id }),
  });
  if (!res.ok) {
    const { error, request_id } = await res.json();
    throw new Error(`${error.code} on ${error.param ?? '-'}: ${error.message} (${request_id})`);
  }
  return Buffer.from(await res.arrayBuffer());
}

With the Ruby SDK, catch the error and print the valid names, so the person who set the wrong value can correct it:

require 'renderscreenshot'

client = RenderScreenshot.client(ENV.fetch('RS_API_KEY'))
preset = ENV.fetch('SCREENSHOT_PRESET', 'og-card') # a typo that reaches the API

begin
  image = client.take(RenderScreenshot::TakeOptions.url('https://example.com').preset(preset))
  File.binwrite('card.png', image)
rescue RenderScreenshot::Error => e
  raise unless e.code == 'invalid_preset'

  valid = client.presets.map { |p| p['id'] }
  abort "Preset #{preset.inspect} does not exist (request #{e.request_id}). Valid presets: #{valid.join(', ')}"
end

Tested on 2026-10-15 with Node 22.18 and with Ruby 4.0.7 plus the renderscreenshot gem 1.0.0, against a local mock that returns the API's error envelope. og-card produced the error and the list of valid names. og_card saved the image.

Related in this topic

Was this page helpful?