revoked_key
revoked_key means the API key in the request was valid once, but someone on your account revoked it. A revoked key stops working at once and cannot be restored. Replace it with an active key; retries with the old key fail forever.
| Field | Value |
|---|---|
| HTTP status | 401 Unauthorized |
error.type |
authentication_error |
error.code |
revoked_key |
retryable |
false |
| Credit used | No |
The error code reference lists all authentication codes.
Example response
{ "error": { "type": "authentication_error", "code": "revoked_key", "message": "API key has been revoked", "retryable": false, "docs": "https://docs.renderscreenshot.com/errors/revoked_key" }, "request_id": "req_4fa9e0c3b7d21e86" }
A revoked key can also be reported as missing_credentials. Both mean "this key does not work", so handle them with one rule: stop, and fix the configuration.
Find which key was revoked
Open API Keys in the dashboard. For each key, the list shows:
- the prefix and the last four characters, for example
rs_live_********************a1B9; - Last Used, the time of the last accepted request;
- a Revoked badge with the time of revocation, for example "Revoked 2 hours ago".
Compare the last four characters with the key your app uses. To print them without exposing the key, run node -e "console.log(process.env.RS_API_KEY.slice(-4))" in the failing environment. If the revocation time matches the moment your errors started, you have found the cause. If nobody on the team revoked it on purpose, treat it as a possible leak, and check where the key was stored.
Replace a key without downtime
Revocation is immediate, so put the new key in place first and revoke the old one last:
- Create a new
rs_live_key in the dashboard. Copy it at once; it is shown only one time. - Store it in your secret manager or environment, next to the old key.
- Deploy, and confirm that the new key works (see the script below).
- Wait until Last Used of the old key stops changing. Then every process uses the new key.
- Revoke the old key.
If the old key is already revoked, steps 4 and 5 do not apply: deploy the new key as fast as you can. The security guide describes a regular rotation schedule.
This check confirms a key is accepted. It calls GET /v1/presets, which needs a valid key but does not render anything, so it uses no credit:
// verify-key.mjs (Node 22): confirm a key is accepted before you revoke the old one. // GET /v1/presets needs a valid key but renders nothing, so the check uses no credit. const API = process.env.RS_BASE_URL ?? 'https://api.renderscreenshot.com'; const name = process.argv[2] ?? 'RS_API_KEY'; const key = (process.env[name] ?? '').trim(); const res = await fetch(`${API}/v1/presets`, { headers: { Authorization: `Bearer ${key}` } }); if (res.ok) { console.log(`${name} (${key.slice(0, 8)}...${key.slice(-4)}) is accepted`); } else { const body = await res.json().catch(() => null); console.error(`${name} rejected: HTTP ${res.status} ${body?.error?.code ?? ''} ${body?.request_id ?? ''}`); process.exitCode = 1; }
Signed URLs and revoked keys
Signed URLs use a key pair: the rs_pub_ key in the URL and the rs_secret_ key that creates the signature. If you revoke the public key, every URL that carries it stops working, including URLs already published in og:image tags and emails. If the account has no active secret key, signed URLs stop working too. Before you revoke either half, create a new pair, sign new URLs with it, and give pages and caches time to pick them up. The publishable keys guide explains the pair.
Handle it in code
A background job must not retry an authentication error. With the Ruby SDK, stop the job and log the request ID:
require 'renderscreenshot' AUTH_CODES = %w[missing_credentials invalid_api_key revoked_key].freeze class ScreenshotJob def self.client @client ||= RenderScreenshot.client(ENV.fetch('RS_API_KEY')) end def perform(url) self.class.client.take(RenderScreenshot::TakeOptions.url(url).preset('og_card')) rescue RenderScreenshot::AuthenticationError => e raise unless AUTH_CODES.include?(e.code) # Same key, same answer on every retry: stop and tell a person. warn "[screenshots] API key rejected (#{e.code}, request #{e.request_id}). Pausing the queue." raise end end
In Sidekiq or Active Job, re-raise into a queue with no automatic retries, or pause the queue, so that thousands of jobs do not fail one by one.
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 for an active key and a revoked key.
Related
- API keys: key types, creation and revocation.
- invalidapikey: the key was never valid, for example a typo.