Build with live web data

Build Your First Web Agent With TinyFish

The TinyFish team·
Build your web agent with TinyFish

You've written Playwright scripts that break every time a website redesigns its nav. You've managed headless Chrome on a server and watched it eat memory at 3 AM. You've set up proxies, handled CAPTCHAs, dealt with dynamic content that only exists in the DOM after six JavaScript events fire in the right order.

TinyFish is a different approach. You describe what you want in plain English. A remote agent handles the browser, the proxies, infrastructure-level handling, and the JavaScript. You get back clean JSON.

This guide gets you from zero to a working web agent in under 10 minutes. No browser setup. No proxy configuration. One API call.

How To Pick Your Path:

  1. Just want to try it → Start with the curl example in Step 2
  2. Building a Python script or pipeline → Jump to Step 3 (Python)
  3. Building a Node.js app → Jump to Step 3 (TypeScript)
  4. Running in production → Don't skip Step 4 — the failure handling section will save you hours

Requirements: Python 3.8+ or Node.js 18+ if using the SDK. The curl examples work with any shell.

Try TinyFish Without Code

The fastest way to try TinyFish is to install its plugin in ChatGPT or Claude. ChatGPT or Claude reasons about your request, while the TinyFish Web Agent opens and operates the live website.

  • ChatGPT: Open Settings, then Connectors or Apps and Connectors. Search for TinyFish, select Connect, complete the OAuth flow, and confirm that TinyFish appears under the composer's Tools menu.
  • Claude: Install the TinyFish plugin from the Claude directory and complete the OAuth sign-in. See the ++Claude plugin setup guide++.

OAuth connects the plugin, so you do not need to paste a TinyFish API key. Then copy and send this first task:

Create a Google Form titled “Team Lunch Preferences.” Add required fields for name (short answer), preferred day (multiple choice: Tuesday, Wednesday, or Thursday), and dietary requirements (paragraph). Do not publish or send the form until I review it. When finished, report what you completed and leave the form ready for review.

ChatGPT or Claude will plan the task, and TinyFish will open Google Forms and operate its interface. Google may ask you to authorize access; review and approve the request before continuing. When the task finishes, the agent returns a summary so you can review the form before publishing it.

For applications and production integrations, continue with the API steps below.

Why This is Different From Playwright, Selenium, or Browserbase

Playwright and Selenium automate a browser you control and maintain. You write selectors that break when sites redesign. You manage proxies separately. One task at a time unless you build your own concurrency layer. The infrastructure overhead is real, but you get maximum control and the lowest per-run cost on simple, static pages.

Browserbase gives you a managed cloud browser: you still write the automation logic yourself (typically using their Stagehand framework), but they handle provisioning. Good fit if you want raw browser control without the server management.

TinyFish takes it further: you pass a URL and a plain English goal, and the agent handles the full execution — navigation, dynamic content, infrastructure-level handling, and result extraction. The trade-off is meaningful: less fine-grained control per step, but dramatically less code to write and maintain.

The honest breakdown:

  • Scrapy or httpx if the page is static HTML, you control the site, or you're doing high-volume crawling where cost-per-page matters.
  • Playwright if you need fine-grained control over every interaction and can maintain selectors.
  • Browserbase if you want managed browsers and prefer to write your own automation logic.
  • TinyFish when sites are dynamic, have strict automation requirements, require multi-step navigation, or when you need to run dozens in parallel without building infrastructure.

Step 1: Get Your API Key

Go to ++agent.tinyfish.chat/sign-up++ and create a free account. No credit card is required. New accounts receive $8 in free Wallet funds.

Once you're in, go to the ++API Keys page++, click Create API Key, and copy it somewhere safe. Keys are shown only once.

Set it as an environment variable:

export TINYFISH_API_KEY="your_api_key"

On Powershell, run:

$env:TINYFISH_API_KEY="your_api_key"

export TINYFISH_API_KEY="your_api_key"

That's the only setup. Your first call works with just curl; no SDK needed yet.

Step 2: Run Your First Agent (30 Seconds)

This calls the agent on a demo e-commerce site. The -N flag streams events as they arrive:

You'll see events streaming in your terminal as the agent works:

Each SSE event follows the format documented in the ++Agent API Reference++. The event types arrive in this order: STARTED → STREAMING_URL → PROGRESS (one or more) → COMPLETE.

The streaming_url is a live browser preview — open it to watch the agent navigate in real time. It stays valid for 24 hours after the run completes.

A run using 3–5 Agent steps costs approximately $0.048–$0.08, deducted from your free $8 Wallet balance.

Step 3: Real Code — Python and TypeScript

The curl approach is fine for testing. For anything running in production, use the SDK. It handles SSE parsing, retries, and event routing.

Python

  • Mac users: If you see externally-managed-environment error, macOS doesn't allow installing packages into the system Python. Create a virtual environment first:

You'll see (venv) in your terminal prompt when the virtual environment is active. Use this every time you open a new terminal to run TinyFish scripts.

Run it: Requires Python 3.8+. On Mac, use python3 — the python command doesn't exist by default. This example uses the synchronous TinyFish client. For async usage (needed for batch processing in Step 6), use AsyncTinyFish instead — see the ++Async Bulk Requests example++.

TypeScript / Node.js

Requires Node.js 18+. The SDK also supports a callback style with onStarted, onProgress, and onComplete handlers — see the ++Endpoints documentation++ for that pattern.

Step 4: The COMPLETED Trap (Read This Before Going to Production)

Here's the thing most developers miss until they hit it in production: COMPLETED means the infrastructure worked — not that your goal succeeded.

TinyFish has two separate failure modes:

Layer 1 — Infrastructure failure (FAILED status): The browser couldn't launch, network timeout, or an unrecoverable error. You'll see status: "FAILED" and a message in the error field. The error object includes a code, message, and category (one of SYSTEM_FAILURE, AGENT_FAILURE, BILLING_FAILURE, or UNKNOWN). Some errors include a retry_after value suggesting when to retry.

Layer 2 — Goal failure (COMPLETED status, failure in result): The browser ran fine, but the agent couldn't accomplish the goal — the login page was unexpected, the product wasn't found, a CAPTCHA blocked the extraction. The run returns COMPLETED, but the result object looks like this:

If you only check status = "COMPLETED" and print result, you'll silently consume a successful API call that returned nothing useful. In a batch job running across 50 URLs, this is hard to notice and expensive to debug.

The correct pattern — always check both layers:

This is from the ++Runs documentation++, which covers the full run lifecycle, the result object schema, and a more comprehensive handleRunResult switch pattern in TypeScript.

Step 5: Writing Goals That Actually Work

The goal parameter is where most first-time users get inconsistent results. According to TinyFish's ++Goal Prompting Guide++, specific goals complete 4.9x faster and return 16x less unnecessary data than vague goals for the same task.

The difference is the output schema. If you don't specify it, the agent makes its own choices about structure, field names, and what counts as relevant.

Weak goal: Get the products

Production-ready goal:

Extract all products visible on this page. For each product return: - name: string (full product title) - price: number (no currency symbol) - currency: string (3-letter code, e.g. "USD") - in_stock: boolean  If a cookie banner appears, close it first. Do not click any purchase or add-to-cart buttons. Do not proceed to checkout or enter any payment details. If price shows "Contact us", set price to null.  Return as JSON array: [{"name": str, "price": number|null, "currency": str, "in_stock": bool}]

Seven components make goals reliable, according to the prompting guide:

Simple tasks need only 2–3 components. Production extractions benefit from all seven. The guardrails component is especially important for e-commerce and transactional sites — always include explicit instructions like "Do not proceed to checkout" or "Do not modify or cancel any orders" to prevent the agent from triggering unintended actions.

For multi-step workflows, number your steps explicitly:

  1. Search for "standing desk" in the search bar
  2. Filter results by price: under $500
  3. Sort by "Best Seller"
  4. Extract the top 5 results: name, price, rating (number), review count, URL Return as JSON array.

Numbered steps give the agent a clear checklist. Each step must complete before the next one starts. For longer workflows, you can also tell the agent to remember data across steps: "Note the confirmation number from step 3 — you'll need it in step 5."

Runs have an approximate 5-minute timeout. For complex multi-step workflows, ensure your goal can complete within this window or break it into smaller runs.

Step 6: Choosing the Right Endpoint

Three endpoints, three different situations:

/run-sse is the right default for development — you see every action the agent takes, plus the live preview URL. The examples above all use it.

One important difference: runs created via /run cannot be cancelled — the request blocks until completion. If you need the ability to cancel a run mid-execution, use /run-async or /run-sse instead. See the ++Endpoints documentation++ for the full comparison.

For production batch jobs, /run-async is cleaner. Submit all tasks at once, get run IDs back immediately, poll for results as they complete. This example submits three URLs in parallel using the async client:

This pattern matches the official ++Async Bulk Requests example++ in the TinyFish docs. The key differences from the synchronous examples in Steps 3–4: you use AsyncTinyFish instead of TinyFish, and client.agent.queue() instead of client.agent.stream().

Full async examples with webhook-based notification (instead of polling) are in the ++TinyFish Cookbook on GitHub++.

What to Build Next

Add proxy routing. For geo-restricted sites or country-specific content, add proxy_config to your request body. The country_code field accepts US, GB, CA, DE, FR, JP, or AU. Residential proxies are included at no extra charge on all plans.

See the ++Proxy documentation++ for the full list of supported countries and custom proxy setup.

Handle sites with strict automation requirements. For sites that block standard automation, set "browser_profile": "stealth" to enable infrastructure-level handling. The default is "lite". You can combine this profile with proxy routing for maximum coverage. See the ++Infrastructure Handling Guide++.

Connect to your AI agent stack. TinyFish has an ++MCP integration++ that lets Claude and Cursor call web agents directly. The ++n8n node++ adds it to no-code workflows without any code at all.

Try It Now

$8 in free usage. No credit card. Run your first Agent automation in minutes → Get your API key at ++agent.tinyfish.chat++

New accounts receive $8 in free Wallet funds, with no credit card required. After using that balance, you can add funds with a minimum $10 top-up—there is no subscription or monthly minimum.

Agent usage costs $0.016 per step, while Browser sessions cost $0.002 per minute. Search and Fetch remain free, even when your Wallet balance reaches $0, with standard limits of 30 Search requests per minute and 150 fetched URLs per minute. Standard accounts support 2 concurrent Agent runs and 5 concurrent Browser sessions. Enterprise customers can request higher limits based on their workloads. See ++TinyFish pricing++for full details.

Extend your integration

Add proxy routing. For geo-restricted sites or country-specific content, add proxy_config to your request body. Set country_code to a country supported by the current ++proxy documentation++.  See the ++Proxy documentation++ for the full list of supported countries and custom proxy setup.

Handle sites with strict automation requirements. For sites with stricter access requirements, use the documented Browser profile intended for those sites. The default is "lite". You can combine the supported Browser profile with proxy routing when the target site and region require both. See the ++Infrastructure Handling Guide++.

Connect to your AI agent stack. TinyFish has an ++MCP integration++ that lets Claude and Cursor call web agents directly. The ++n8n node++ adds it to no-code workflows without any code at all.

Troubleshooting

command not found: python or command not found: pip (Mac) macOS doesn't include python or pip by default. Use python3 and pip3 instead. If pip3 also fails with an externally-managed-environment error, create a virtual environment first:

ModuleNotFoundError: No module named 'tinyfish' You haven't installed the SDK yet, or your virtual environment isn't activated. Run pip install tinyfish (or pip3 install tinyfish). If you're using a virtual environment, make sure you see (venv) in your terminal prompt before running the script.

Invalid API key or 401 Unauthorized Your TINYFISH_API_KEY environment variable isn't set or has the wrong value. Double-check with echo $TINYFISH_API_KEY in your terminal. The key should start with sk-tinyfish-. If you're using a .env file, make sure there are no extra spaces or quotes around the value.

npm: command not found (TypeScript) Node.js isn't installed. Download it from ++nodejs.org++ — the LTS version is fine. Restart your terminal after installing.

AI disclosure

Content on this website may be created or refined with the assistance of AI tools and is subject to human editorial review.

FAQ

Questions, answered.

What is a “step” in TinyFish billing?

Does TinyFish work on sites that require login?

How do I scrape a different website — for example, a retail site?

My run returned COMPLETED but the result is empty or wrong — what happened?

How is this different from Playwright or Browserbase?

Can I run multiple agents at the same time?

What happens if the agent fails mid-task?

What if I need to stop a run that's already started?

Get started

Start building.

No credit card. No setup. Run your first operation in under a minute.

Get $8 in Wallet fundsRead the docs