Skip to main content

General

TinyFish Web Agent is an AI-powered web automation API that lets you automate any website using natural language. Instead of writing brittle selectors, you describe what you want to do, and our AI handles the rest.
Any publicly accessible website. For authenticated sites, use Vault Credentials or a saved Browser Context Profile instead of putting passwords in your goal. For sites with bot protection, use stealth mode and a proxy.
Typically 3-10 seconds for simple pages, 30-60 seconds for complex multi-step automations. Time depends on page load speed and task complexity.
Yes. Runs provide a streaming_url where you can watch the browser execute live. With the SSE API, listen for the STREAMING_URL event; for queued runs, retrieve the run with client.runs.get(run_id) or GET /v1/runs/:id.

API Usage

The REST API uses the X-API-Key header:
X-API-Key: $TINYFISH_API_KEY
The Python SDK, TypeScript SDK, and CLI also use your API key. The MCP endpoint uses OAuth 2.1 for AI assistant integrations. CLI run IDs and MCP run IDs are scoped to different tokens, so a CLI lookup for an MCP-created run can return 404 by design.
Yes, configure proxy routing:
{
  proxy_config: {
    enabled: true,
    country_code: "US"
  }
}
Supported countries: US, GB, CA, DE, FR, JP, AU.
For a few immediate results, use concurrent sync requests with asyncio.gather(), Promise.all(), or shell background jobs. For larger or long-running sets, use agent.queue() in SDKs, POST /v1/automation/run-batch in REST, or tinyfish agent batch run in the CLI.See Concurrent Requests and Async Bulk Requests.

Technical

We use Chromium-based browsers. Choose between:
  • Lite: Standard Chromium (fast)
  • Stealth: Modified Chromium with anti-detection (slower but bypasses bot protection)
We fully support SPAs (React, Vue, Angular). Pages are rendered and JavaScript is executed before extraction.
Yes! For password-manager login, connect your password manager (1Password or Bitwarden) in Settings → Vault. Select credentials per run and TinyFish handles login securely — the AI agent never sees your actual passwords. For sites where saved session state matters, create a Browser Context Profile after signing in once, then use that profile on future runs.See the Connect Your Vault guide for setup, Vault Credentials for how credential access works, and Browser Context Profiles for reusing cookies, MFA state, and trusted-device sessions.API example:
const run = await client.agent.run({
  url: "https://app.example.com/dashboard",
  goal: "Log in and summarize the account dashboard",
  use_vault: true,
  use_profile: true,
});
If you haven’t connected a vault or saved profile, you can still include login steps in your goal:
goal: `
  1. Login with username "user@example.com" and password "pass123"
  2. Navigate to dashboard
  3. Extract account balance
`
Including credentials directly in goals is less secure — they appear in run logs and AI context. Use vault credentials when possible.
Yes, describe pagination in your goal:
goal: `Click "Next Page" button 5 times, extracting products from each page`

Troubleshooting

status: "COMPLETED" means the infrastructure succeeded - the browser launched, navigated, and the automation finished without crashing.It does NOT mean the goal was achieved. You must check the result field to determine if the goal succeeded.Scenario 1: Goal achieved
{
  "status": "COMPLETED",
  "result": {
    "products": [
      { "name": "iPhone 15", "price": "$799" }
    ]
  },
  "error": null
}
The result contains the extracted data - goal succeeded.Scenario 2: Infrastructure succeeded, goal failed
{
  "status": "COMPLETED",
  "result": {
    "status": "failure",
    "reason": "Could not find any products on the page",
    "product_price": null
  },
  "error": null
}
Status is COMPLETED (browser worked), but result.status is “failure” indicating the goal wasn’t achieved.Scenario 3: Infrastructure failed
{
  "status": "FAILED",
  "result": null,
  "error": {
    "message": "Browser crashed during execution"
  }
}
The automation couldn’t complete due to infrastructure issues.Best Practice: Always validate result content, not just status:
if (run.status === "COMPLETED" && run.result) {
  // Check if result indicates goal failure
  if (run.result.status === "failure" || run.result.error) {
    console.log("Goal not achieved:", run.result.reason || run.result.error);
  } else {
    console.log("Data extracted:", run.result);
  }
} else if (run.status === "FAILED") {
  console.log("Automation failed:", run.error?.message);
}
Common causes:
  1. Timeout - Site is slow or down
    • Solution: Retry or use stealth mode
  2. Access Denied - Anti-bot protection
    • Solution: Use stealth mode + proxy
  3. Element Not Found - Goal is too specific
    • Solution: Make goal more flexible (describe visually)
  4. Invalid URL - URL is malformed
    • Solution: Ensure URL includes https://
// Use stealth mode
browser_profile: "stealth"

// Add proxy
proxy_config: {
  enabled: true,
  country_code: "US"
}

// Reduce speed (add delays in goal)
goal: "Wait 3 seconds, then click button"

Best Practices

Good (specific, actionable):
goal: "Extract product name, price, and stock status from the product details section"
Bad (vague):
goal: "Get data"
Use stealth when:
  • Site shows CAPTCHA
  • Getting “Access Denied” errors
  • Site uses Cloudflare or anti-bot protection
Otherwise use lite mode (faster).

Getting Help

Email Support

Discord Community

Join our community

Quick Start

Get started in 5 minutes

API Reference

Complete endpoint docs