Quick start
This page takes you from no account to a saved screenshot in about a minute. You create a key, send one request, and check the response headers. It is the first step in the RenderScreenshot documentation.
Step by step: Take your first screenshot walks through this task with screenshots of every step.
1. Get an API key
Create a free account and verify your email address. A new account gets 10 trial credits, so you can make your first screenshot at once. The full free allowance unlocks after verification. The free plan renews its credits every month and needs no credit card. The current allowance for each plan is on the pricing page. One successful screenshot uses one credit. Failed requests use none.
Open API Keys in the dashboard and create a key. It is shown once, so copy it now. A live key is rs_live_ followed by 32 letters and digits. Keep it in an environment variable, not in your code:
export RS_API_KEY=rs_live_your_key_here
API keys explains the other key types, rotation and storage.
2. Take your first screenshot
The request below renders https://example.com at the og_card preset (1200×630 PNG) and saves it. To send it from a GUI instead, import the Postman collection. -D - prints the response headers, which step 3 explains.
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", "preset": "og_card"}' \ -D - --output screenshot.png
Or use an official SDK. Each tab starts with its install command.
Node.js
// npm install renderscreenshot import { Client, TakeOptions } from 'renderscreenshot'; import { writeFile } from 'node:fs/promises'; const client = new Client(process.env.RS_API_KEY); const image = await client.take( TakeOptions.url('https://example.com').preset('og_card') ); await writeFile('screenshot.png', image);
Python
# pip install renderscreenshot import os from renderscreenshot import Client, TakeOptions client = Client(os.environ['RS_API_KEY']) image = client.take(TakeOptions.url('https://example.com').preset('og_card')) with open('screenshot.png', 'wb') as f: f.write(image)
Ruby
# gem install renderscreenshot require 'renderscreenshot' client = RenderScreenshot.client(ENV.fetch('RS_API_KEY')) image = client.take( RenderScreenshot::TakeOptions.url('https://example.com').preset('og_card') ) File.binwrite('screenshot.png', image)
PHP
<?php // composer require renderscreenshot/renderscreenshot require 'vendor/autoload.php'; use RenderScreenshot\Client; use RenderScreenshot\TakeOptions; $client = new Client(getenv('RS_API_KEY')); $image = $client->take( TakeOptions::url('https://example.com')->preset('og_card') ); file_put_contents('screenshot.png', $image);
Go
// go get github.com/Render-Screenshot/rs-go package main import ( "context" "log" "os" rs "github.com/Render-Screenshot/rs-go" ) func main() { client, err := rs.New(os.Getenv("RS_API_KEY")) if err != nil { log.Fatal(err) } image, err := client.Take(context.Background(), rs.URL("https://example.com").Preset("og_card"), ) if err != nil { log.Fatal(err) } if err := os.WriteFile("screenshot.png", image, 0o644); err != nil { log.Fatal(err) } }
Java
// Add com.github.Render-Screenshot:rs-java from JitPack (see the Java SDK page) import com.renderscreenshot.sdk.Client; import com.renderscreenshot.sdk.TakeOptions; import java.nio.file.Files; import java.nio.file.Path; public class QuickStart { public static void main(String[] args) throws Exception { Client client = new Client(System.getenv("RS_API_KEY")); byte[] image = client.take( TakeOptions.url("https://example.com").preset("og_card") ); Files.write(Path.of("screenshot.png"), image); } }
CLI
# brew install render-screenshot/tap/rs (reads RS_API_KEY) rs take https://example.com --preset og_card -o screenshot.png
Tested on 2026-10-15: the curl, Node, Python, Ruby, PHP and Go listings ran against a local stub of the API and each sent the same {"url", "preset"} request. The Java listing follows the Java SDK reference and was not run.
3. Read the response
A success is HTTP 200 with the image as the body. The headers tell you what happened:
| Header | What it tells you |
|---|---|
X-Credits-Used |
1 for a fresh render, 0 for a cached result |
X-Credits-Remaining |
Your balance after this request |
X-Cache-URL |
A public CDN link to this image. It needs no key. |
X-Cache-Expires |
Until when that CDN link is kept |
X-Request-Id |
The ID to quote to support |
X-RateLimit-Remaining |
Requests left in the current minute |
To get JSON with the CDN URL instead of the image bytes, send Accept: application/json. See response formats.
If the first request fails
curl still writes the body to screenshot.png, so a failed request leaves a small JSON file there. A missing or mistyped key gives HTTP 401:
{ "error": { "type": "authentication_error", "code": "missing_credentials", "message": "No valid API key or signature provided", "retryable": false, "docs": "https://renderscreenshot.com/docs/errors/missing-credentials" }, "request_id": "b1c2d3e4-0000-4000-8000-000000000001" }
| Status and code | Usual cause on a first request | Fix |
|---|---|---|
401 missing_credentials |
RS_API_KEY is empty in this shell, or the key was revoked |
Run echo $RS_API_KEY and export the key again |
400 invalid_url |
The URL has no scheme, for example example.com |
Send https://example.com |
400 invalid_preset |
A typo in the preset name | Use a name from the table below |
403 email_not_verified |
You used the 10 trial credits, and the free credits are still locked | Use the link in the verification email, or resend it from the dashboard |
403 insufficient_credits |
The monthly credits are used up | Wait for the next period or upgrade the plan |
429 too_many_requests |
A loop sent requests faster than your plan allows | Wait Retry-After seconds. See rate limits. |
In an SDK, catch the error class and log the status, code and request ID. The Ruby version, tested against the same stub:
require 'renderscreenshot' client = RenderScreenshot.client(ENV.fetch('RS_API_KEY')) begin image = client.take(RenderScreenshot::TakeOptions.url('https://example.com').preset('og_card')) File.binwrite('screenshot.png', image) rescue RenderScreenshot::Error => e warn "HTTP #{e.http_status} #{e.code}: #{e.message} (request #{e.request_id})" exit 1 end
The error codes page has retry code for Node, Python and Ruby.
4. Pick a preset
A preset sets the viewport and format in one parameter. Any parameter you send yourself overrides the preset value.
| Preset | Size | Use it for |
|---|---|---|
og_card |
1200×630 PNG | Open Graph images for Facebook, LinkedIn, Slack |
twitter_card |
1200×600 PNG | X summary cards |
twitter_card_large |
1200×628 PNG | X large image cards |
link_preview |
800×600 PNG | Chat and link previews |
full_page |
1280 wide, whole page | Long pages, captured top to bottom |
mobile |
390×844 | Phone layouts |
desktop_hd |
1920×1080 | Full HD desktop |
The presets reference lists all of them, including pdf_document, mobile_landscape and desktop_4k.
5. Show the image on a web page
Do not put an rs_live_ key in HTML. Anyone who views the source can copy it and spend your credits. Use one of these instead:
- Render once, link the CDN copy. Take the screenshot on your server and use the
X-Cache-URLfrom the response. See caching. - Sign the URL. Build a signed URL on your server. It can go straight into an
og:imagetag and stops working after its expiry.
Next steps
- POST /v1/screenshot: every option in one request body
- GET /v1/screenshot: the same capture as a URL
- All parameters: viewport, wait, blocking, PDF and more
- SDKs and the CLI