Bubble Screenshot API: API Connector Setup

Add website screenshots to a Bubble.io app with the API Connector: exact call settings, binding the result to an image field, private keys and error handling.

By Simon Chiu · Updated

Bubble has no screenshot element, but its API Connector plugin can call the RenderScreenshot API and store the returned image in a field like any upload. This page gives you the exact call settings, shows how to bind the result to an image field, and covers the two mistakes that cost credits in Bubble: initializing too often, and running the call on page load. It is part of our integrations hub.

Status: written 2026-10-15 from the API's documented request and response shapes. The settings below have not been run in a live Bubble app yet, so there are no Bubble UI screenshots on this page. The API side (the GET URL, headers and responses) matches the GET endpoint reference.

What you can build

  • A link directory with thumbnails. When a user submits a website, a workflow captures it and saves the image on the new Listing.
  • Client approval boards. An agency app captures each staging page on request, so a client can compare versions side by side.
  • Social cards for user pages. Each public profile gets a 1200x630 card in the og_card preset, saved on the profile and used in the page's SEO settings.

Prerequisites

  • A Bubble app with the API Connector plugin installed (by Bubble).
  • A RenderScreenshot API key (rs_live_...). Create a free account; no credit card is needed.
  • A data type with an image field, for example Listing with screenshot (image).

Step 1: add the API

In Plugins → API Connector, click Add another API:

Setting Value
API Name RenderScreenshot
Authentication None or self-handled
Shared header Authorization = Bearer rs_live_..., with Private ticked

Private keeps the key on Bubble's server. Never put the key in a URL parameter in Bubble: client-side calls and logs can show URLs.

Step 2: add the call

Click Add another call and use these settings.

Setting Value
Name Capture page
Use as Action
Data type Image
Method GET
URL https://api.renderscreenshot.com/v1/screenshot

Then add the parameters. Untick Private on the ones that a workflow must set, so they appear as inputs on the action:

Key Value for initialization Private Notes
url https://example.com No The page to capture. Map it from the workflow.
preset desktop_hd No og_card for social cards, mobile for phone layout. See presets.
format jpeg Yes Smaller files in Bubble storage. Use png for text-heavy pages.
block_cookies true Yes Removes cookie banners before capture.
block_ads true Yes Removes ads.
cache_available true Yes Returns an identical earlier render for 0 credits.

Click Initialize call. Bubble sends one real request, so initialization uses one credit. Initialize once; you do not need to initialize again when you change a parameter's value, only when you change the call's shape.

Why the data type is Image

With Data type: Image, Bubble treats the response body as a file and keeps a copy in your app's file storage. The result of the action is a normal Bubble image that you can save to a field. The alternative is a JSON response with a CDN link (send the header Accept: application/json). That link needs no key, but it expires when the cache entry expires: after 24 hours by default and after 30 days at most. A field that holds the CDN link breaks after that. The caching docs explain the TTL.

Step 3: bind the image in a workflow

  1. Create a workflow, for example When Button Capture is clicked.
  2. Add the action Plugins → RenderScreenshot – Capture page. Set url to Input URL's value.
  3. Add Data → Make changes to a thing. Choose the Listing, and set screenshot = Result of step 1.
  4. Put an Image element on the page with the source Current cell's Listing's screenshot.

For long lists or slow pages, run the capture in a backend workflow and schedule it, so the user does not wait on the page and a closed tab does not stop the capture.

Parameter mapping

Bubble input API query parameter API field
url url url
preset preset preset
width, height (optional, add as keys) width, height viewport.width, viewport.height
full_page (optional) full_page=true capture.mode = full_page
delay (optional) delay (ms, max 10000) wait.delay
dark_mode (optional) dark_mode=true browser.dark_mode

The GET endpoint takes these flat parameters. Options with nested structure, such as cookies or custom scripts, need the POST endpoint. In Bubble that is a second call with Method: POST and a JSON body; see POST /v1/screenshot.

Errors and retries in Bubble

When the API returns an error, the action fails and Bubble stops the workflow. Add an An unhandled error occurs event to show the user a message, and use a JSON test call to read the error body while you debug.

Status and code Cause Fix in Bubble
400 invalid_url The user typed acme.com Prefix https:// in the expression: https:// + Input's value when it has no scheme
401 invalid_api_key Wrong key, or Bearer missing in the header Fix the shared header. Do not retry.
403 insufficient_credits Monthly credits used Hide the capture button and notify an admin
422 screenshot_failed The page did not load in time Retry once from a scheduled backend workflow, with delay added
429 too_many_requests Many users clicked at once, or a "Schedule API workflow on a list" ran too fast Space out the scheduled items by a few seconds

Failed renders use no credits. A successful render that runs twice uses two, unless cache_available is true. The error handling guide lists every code.

Limits and costs

  • Credits. One credit per fresh render; see pricing. Never run the capture on Page is loaded: every visitor would start a render.
  • Bubble workload. API calls and file storage count toward your Bubble plan's workload and storage.
  • Rate limits. Requests per minute depend on your RenderScreenshot plan; see rate limits.

Troubleshooting

  • "There was an issue setting up your call" on initialize. The response was an error, not an image. Test the same URL with Accept: application/json to read the message.
  • The image field stays empty. The call's data type is JSON, not Image, so the result has no file.
  • The page in the image is the mobile layout. Set preset to desktop_hd, or set width to 1280 or more.

For no-code site builders that only need a social card URL in their SEO settings, see the Webflow OG image setup. For automations outside your app, see Zapier screenshots.

Frequently asked questions

Can a Bubble app take a screenshot of a website?
Yes. Add a call in the API Connector that sends the page URL to a screenshot API, then use the call as a workflow action and save its result into an image field on your data type.
Should the call return an image or JSON?
Return the image and set the call's data type to Image. Bubble then stores the file in your app's own storage, so the field keeps working after the API's cache link expires. Use JSON only when you need the width, height or credit fields.
Is my API key visible to users of my Bubble app?
Not if you mark the Authorization header as Private and run the call as a backend action. Private parameters stay on Bubble's server and are not sent to the browser.

Related in this topic

Try RenderScreenshot free

150 free credits every month, no credit card required.