Binding vs REST
NEWThe same Quick Action called two ways: over the REST API with a bearer token, and directly through the Workers browser binding. Same result, materially less setup.
env.BROWSER.quickAction() vs POST /markdown
// Needs CF_ACCOUNT_ID + CF_API_TOKEN as secrets, and the // request leaves Cloudflare's network and comes back. const resp = await fetch( `https://api.cloudflare.com/client/v4/accounts/${accountId}/browser-rendering/markdown`, { method: 'POST', headers: { Authorization: `Bearer ${apiToken}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ url }), } ); const { result } = await resp.json();
// No account id, no token, no external hop. const resp = await env.BROWSER.quickAction('markdown', { url }); const { result } = await resp.json();
Runs sequentially, not in parallel — two concurrent renders of the same URL would double the billed browser time for no extra insight.
Use Cases
No Credential to Manage
The binding authenticates implicitly. There is no API token to provision, rotate, scope, or accidentally commit.
No External Hop
The Worker talks to Browser Run over Cloudflare’s own network instead of making an outbound HTTPS request to the public API.
Same Surface
Eight of the Quick Actions are available on the binding. /crawl stays REST-only, and it is the one place you still need a token.
BrowserRun type declares eight actions and does not yet include accessibilityTree, nor formats on the snapshot options — both of which the REST API accepts today. Until the types catch up, reach for those two over REST.Both paths hit the same service and return the same envelope. The binding removes the API token, the account id, and the outbound HTTP request. Treat the timings as illustrative rather than a benchmark — see the note below the results.