Your Agent's Browser
The Script API
Write Playwright. Send it to Riddle. Get results.
const result = await fetch("https://api.riddledc.com/v1/run", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
script: `
await page.goto("https://app.example.com/login");
await page.fill("input[name=email]", "user@example.com");
await page.fill("input[name=password]", "password123");
await page.click("button[type=submit]");
await page.waitForURL("**/dashboard");
await saveScreenshot("dashboard");
`,
include: ["screenshot", "console", "har"]
})
}).then(r => r.json());
// result.screenshot — base64 PNG of the dashboard
// result.console — every console.log, warn, error
// result.har — full network traceFull Playwright API
Use any Playwright method—selectors, waits, assertions, network interception. No proprietary DSL to learn.
Rich results
Get back screenshots, console logs, network HAR, assertion results, and downloaded files—not just pixels.
Pack work into sessions
30s minimum per job. Do multiple navigations and screenshots in one call for maximum value.
No infrastructure
No Chrome to manage, no memory leaks, no Docker containers. Just an API call from anywhere.
Assert Before You Screenshot
The key differentiator: Check page state in your script before screenshotting. Vision API calls cost $0.01-0.02 per image. Assert with selectors and URLs first—only screenshot when you need human-level understanding.
const result = await fetch("https://api.riddledc.com/v1/run", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
script: `
await page.goto("https://example.com/checkout");
// Check page state without screenshotting
const hasForm = await page.locator(".checkout-form").count() > 0;
if (!hasForm) {
await saveScreenshot("error-state");
throw new Error("Checkout form not found");
}
// Fill and submit
await page.fill("#card-number", "4242424242424242");
await page.fill("#expiry", "12/25");
await page.click("button.submit-payment");
// Assert success, screenshot only on failure or at the end
await page.waitForURL("**/confirmation");
await saveScreenshot("confirmation");
`
})
}).then(r => r.json());
// Happy path: 1 screenshot (confirmation)
// Error path: 1 screenshot (error state) + thrown errorOptimize Your Vision Loop
The screenshot-per-action pattern is expensive and slow:
Each call starts at ~$0.004 + vision API costs. A 50-step task can cost $0.20+ in browser time alone. The fix: batch deterministic steps into single scripts, screenshot only at decision points.
Your agent reasons about what to do, then sends a Playwright script with multiple actions. One API call instead of ten. Browser costs become noise, not a line item.
Skip the Login Loop
Inject cookies or localStorage. Your agent authenticates once, screenshots forever.
const result = await fetch("https://api.riddledc.com/v1/run", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
script: `
await page.goto("https://app.example.com/dashboard");
await saveScreenshot("dashboard");
await page.click("[data-tab=analytics]");
await page.waitForSelector(".analytics-loaded");
await saveScreenshot("analytics");
`,
options: {
cookies: [
{name: "session_id", value: "abc123", domain: "app.example.com"}
]
}
})
}).then(r => r.json());
// 2 authenticated screenshots, zero login overheadPython Integration
No SDK needed. Standard HTTP requests work with any vision LLM.
import requests
import base64
def screenshot_for_vision(url, api_key, cookies=None):
"""Take screenshot, return base64 for vision LLM."""
body = {"url": url}
if cookies:
body["options"] = {"cookies": cookies}
response = requests.post(
"https://api.riddledc.com/v1/run",
headers={"Authorization": f"Bearer {api_key}"},
json=body
)
return base64.b64encode(response.content).decode()
# Use with GPT-4V, Claude, or any vision model
screenshot_b64 = screenshot_for_vision(
"https://example.com",
API_KEY,
cookies=[{"name": "session", "value": "abc123", "domain": "example.com"}]
)
response = openai.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "What actions are available on this page?"},
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{screenshot_b64}"}}
]
}]
)Works With Your Stack
Browser-Use
Replace local Chrome with Riddle API calls. Same observe-think-act loop, no infrastructure.
LangChain
Custom tool wrapper for PlayWrightBrowserToolkit. Simpler than managing browser pools.
CrewAI
Screenshot tool for your crew's web research and verification tasks.
Custom Agents
Simple REST API. Works with any language, any framework. No SDK required.
For Simple Automation: Steps Mode
For simple workflows, send JSON steps instead of Playwright code. Great for LLM-generated actions where you want structured output without code syntax.
// JSON steps — no Playwright syntax needed
const result = await fetch("https://api.riddledc.com/v1/run", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
steps: [
{ goto: "https://example.com/login" },
{ fill: { selector: "#email", value: "user@example.com" } },
{ click: "button[type=submit]" },
{ waitForUrl: "**/dashboard**" },
{ screenshot: "dashboard" }
]
})
}).then(r => r.json());Use script mode for full control. Use steps mode for simple, structured workflows. Or use MCP tools →
Agent Guide
Building an agent? Get the complete technical reference—copy-paste ready for your agent's context.
From $0.004 per job. Under $0.001 per screenshot when batched. See pricing →
Give Your Agent a Browser
Create an account and start making requests in minutes.