Errors — Shotvik API error responses
Error format
Section titled “Error format”Errors return a non-2xx status, Content-Type: application/json, Cache-Control: no-store and this body:
{ "error": { "code": "url_blocked", "message": "this URL cannot be rendered", "request_id": "req_3f9c2a71b0d4e8a6", "reason": "private_ip" }}| Field | Always present | Description |
|---|---|---|
code |
yes | Machine-readable error code (table below). Use this in your code, not message. |
message |
yes | Human-readable explanation. The wording may change. |
request_id |
yes | Same as the X-Request-Id header. Include it when you contact support@shotvik.com. |
reason |
no | A fixed reason: the block reason on url_blocked (see below), key_suspended on key_suspended, and account_frozen on account_frozen. |
retry_after |
no | Seconds to wait before retrying. Also sent as the Retry-After header on 429 and 503. |
Error codes
Section titled “Error codes”| Status | Code | Meaning | What to do |
|---|---|---|---|
| 400 | invalid_request |
A parameter is missing, has the wrong type or range, or is unknown (e.g. jpeg_quality without format: "jpeg", or both/neither of template and html). |
Fix the request; message names the field. |
| 400 | api_key_in_url |
An API key was sent in the query string (api_key, key, apikey, access_key or token). |
Use the Authorization header, or a signed URL for public links. |
| 401 | unauthorized |
No API key was sent. | Send Authorization: Bearer <key> or X-API-Key. |
| 401 | invalid_api_key |
The key isn’t valid. | Check the key. |
| 401 | api_key_revoked |
The key has been revoked. | Create a new key. |
| 401 | invalid_signature |
The signed URL’s signature is missing or wrong, or a parameter appears twice. | Re-sign the URL; see Signed URLs. |
| 403 | signature_expired |
The signed URL’s exp has passed. |
Sign a new URL. |
| 403 | url_blocked |
The page URL (or a redirect of it) was refused. reason says why. Refused sub-resources (images, fonts, scripts) don’t cause this error; they’re dropped and the render continues. |
See block reasons below. Contact support if you think it’s wrong. |
| 403 | key_suspended |
The key is temporarily blocked (abuse protection). | Contact support@shotvik.com. |
| 403 | account_frozen |
The account is temporarily blocked. | Contact support@shotvik.com. |
| 403 | free_tier_paused |
The free plan is temporarily paused. | Try again later. |
| 404 | not_found |
Unknown path. | Check the endpoint. |
| 404 | template_not_found |
The OG template ID doesn’t exist in your account. | Check GET /v1/templates. |
| 413 | payload_too_large |
The request body or HTML is too large (html and css together max 1,048,576 bytes). |
Make the input smaller. |
| 429 | rate_limited |
Your per-minute rate limit was exceeded. | Wait Retry-After seconds. |
| 429 | too_many_concurrent_requests |
Too many of your requests are running at once. | Retry after Retry-After; lower your parallelism. |
| 429 | target_rate_limited |
Too many renders of this target domain right now, across all customers (30 per minute). | Retry after Retry-After. |
| 429 | monthly_quota_exceeded |
Your monthly quota is used up (hard limit). | Wait for the next period. Retry-After gives the seconds until the reset. |
| 429 | queue_full |
The render queue is full. | Retry after Retry-After. |
| 500 | render_failed |
The render failed on our side. | Retry with backoff. |
| 500 | internal_error |
Unexpected error on our side. | Retry with backoff; contact support with the request_id if it persists. |
| 502 | target_unreachable |
The target page couldn’t be loaded (e.g. connection failed). No image is returned. | Check that the site is up and publicly reachable. |
| 503 | queue_timeout |
No render slot became free in time. | Retry after Retry-After. |
| 503 | service_paused |
Rendering is temporarily paused. | Retry after Retry-After. |
| 503 | url_rendering_disabled |
URL rendering is temporarily disabled; HTML and OG rendering still work. | Retry after Retry-After. |
| 504 | render_timeout |
The render didn’t finish within 30 s (including delay_ms). |
Lower delay_ms, use a faster wait_until, or avoid full-page captures of very long pages. |
A target site’s own 4xx/5xx is not an error. You get the rendered page with 200, the target’s status in X-Target-Status, and it counts. None of the errors above count toward your quota, because no image or PDF is returned. See How usage is counted.
Block reasons (reason on url_blocked)
Section titled “Block reasons (reason on url_blocked)”| Reason | Meaning |
|---|---|
private_ip, loopback, link_local, metadata_ip, own_infra |
The URL or a redirect resolves to a private, loopback, link-local, cloud-metadata or Shotvik-internal address. |
redirect_to_private |
A redirect points to such an address. |
dns_rebinding, ip_encoding_trick |
The hostname resolved differently between checks, or the address is written in an unusual encoding. |
bad_scheme, bad_port, bad_hostname, invalid_url, credentials_in_url |
Not http/https; a port other than 80 or 443 (also after a redirect); a local or single-label hostname; an invalid URL; or a username/password in the URL. |
dns_failure |
The hostname couldn’t be resolved. |
too_many_redirects |
More than 5 redirects. |
size_limit, request_limit |
The page exceeded the per-render budget of 25 MiB downloaded or 400 requests. |
phishing_database |
The URL, its domain or its IP address is on the Phishing.Database list. |
own_blocklist |
The URL is on Shotvik’s own blocklist. |
reputation_unavailable |
Shotvik’s copy of Phishing.Database is more than 48 hours old, so URL renders are refused to be safe. Retry later. |
key_suspended errors carry reason: "key_suspended", and account_frozen errors carry reason: "account_frozen".
Fonts and images that are refused or over budget don’t cause an error. They’re skipped, and the response lists them in the X-Shotvik-Warnings header (see Skipped fonts and images).
Retrying
Section titled “Retrying”- Respect
Retry-Afteron 429 and 503. - Use exponential backoff for 500 and 503.
- Don’t retry 400, 401, 403 or 413 unchanged.
Shotvik is in private beta. Request access: support@shotvik.com · Privacy