> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tinyfish.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# For Coding Agents

> Single-page TinyFish context for Claude, Codex, Cursor, and other coding agents

This page is the shortest high-signal context dump for coding agents integrating TinyFish. **Always use the official SDKs** — they handle authentication, SSE streaming, retries, and typed responses so you don't have to.

<Note>
  For complete API reference in a single file, use [llms-full.txt](https://docs.tinyfish.ai/llms-full.txt) (218KB, includes all code examples). Note that `llms.txt` is just an index — agents should use `llms-full.txt` for full context.
</Note>

## MCP Server (Recommended for AI Assistants)

If you're running inside an MCP-compatible host (Codex, Claude Code, Claude Desktop, Cursor, Windsurf, ChatGPT), connect via MCP instead of the REST API — no API key management needed, OAuth handles auth automatically.

<Tabs>
  <Tab title="Codex">
    ```bash theme={null}
    codex mcp add tinyfish --url https://agent.tinyfish.ai/mcp
    ```
  </Tab>

  <Tab title="Claude Code">
    ```bash theme={null}
    npx -y install-mcp@latest https://agent.tinyfish.ai/mcp --client claude-code
    ```
  </Tab>

  <Tab title="ChatGPT">
    ```text theme={null}
    https://agent.tinyfish.ai/mcp/chatgpt
    ```
  </Tab>
</Tabs>

See the [MCP Integration guide](/mcp-integration) for all supported clients and available tools.

## Install the SDK

<CodeGroup>
  ```bash Python theme={null}
  pip install -U tinyfish
  ```

  ```bash TypeScript theme={null}
  npm install @tiny-fish/sdk@latest
  ```
</CodeGroup>

| API              | Typical Latency    | Suggested Timeout |
| ---------------- | ------------------ | ----------------- |
| Agent (sync)     | 15-60s             | 120s              |
| Agent (SSE)      | 15-60s (streaming) | N/A (SSE)         |
| Search           | 1-3s               | 10s               |
| Fetch            | 1-20s              | 150s              |
| Browser (create) | 10-30s             | 60s               |

*Fetch: backend timeout is 110s per URL; requests are also subject to a 120s CDN ceiling. Set client timeout to 150s to receive timeout errors cleanly.*

## Authentication

Set your API key (get one from [agent.tinyfish.ai/api-keys](https://agent.tinyfish.ai/api-keys)):

```bash theme={null}
export TINYFISH_API_KEY="your_api_key_here"
```

Both SDKs read `TINYFISH_API_KEY` from the environment automatically. See [Authentication](/authentication) for more details.

## Choose the Right TinyFish API

| API     | Use it when                                                         | Docs                                    |
| ------- | ------------------------------------------------------------------- | --------------------------------------- |
| Agent   | You want TinyFish to execute a goal on a real website               | [Agent reference](/agent-api/reference) |
| Search  | You want ranked web results for a query                             | [Search overview](/search-api)          |
| Fetch   | You want extracted page content from one or more URLs               | [Fetch overview](/fetch-api)            |
| Browser | You want a remote browser session for direct Playwright/CDP control | [Browser overview](/browser-api)        |

### Quick Decision Tree

* **Need data from a URL?** -- Agent API (goal-based extraction) or Fetch API (raw page content)
* **Need search results?** -- Search API
* **Need browser control?** -- Browser API (direct Playwright/CDP access)
* **Need logged-in state across recurring runs?** -- Create a [Browser Context Profile](/agent-api/browser-context-profiles), then run with `use_profile: true`

## Authenticated or Recurring Runs

When a task should reuse a login session, use **Browser Context Profiles** first. Do not make the agent log in from scratch every run unless the task explicitly needs a fresh browser. Browser Context Profiles are saved browser state for a site or account. They are different from `browser_profile: "lite" | "stealth"`, which only chooses the browser runtime mode.

<Steps>
  <Step title="Create and set up a profile">
    Use the [Browser Context Profiles API](/agent-api/browser-context-profiles) to create a profile, start a setup session, connect to `cdp_url` with Playwright/Puppeteer/CDP, sign in, and save with `session_id`. The dashboard setup UI is a manual helper.
  </Step>

  <Step title="Run with saved state">
    Pass `use_profile: true` to use the default profile, or add `profile_id` for a specific profile.
  </Step>

  <Step title="Repair stale sessions with Vault">
    For long-lived workflows, pair profiles with `use_vault: true` so TinyFish can sign in again when cookies expire.
  </Step>
</Steps>

<CodeGroup>
  ```python Python theme={null}
  result = client.agent.run(
      url="https://app.example.com/dashboard",
      goal="Summarize the account health dashboard.",
      use_profile=True,
      use_vault=True,
  )
  ```

  ```typescript TypeScript theme={null}
  const run = await client.agent.run({
    url: "https://app.example.com/dashboard",
    goal: "Summarize the account health dashboard.",
    use_profile: true,
    use_vault: true,
  });
  ```
</CodeGroup>

`use_profile: true` uses the default Browser Context Profile. Use `profile_id` when the user names a specific Browser Context Profile; `profile_id` requires `use_profile: true`:

<CodeGroup>
  ```python Python theme={null}
  result = client.agent.run(
      url="https://app.example.com/dashboard",
      goal="Download the latest invoice.",
      use_profile=True,
      profile_id="prof_abc123def4567890",
  )
  ```

  ```typescript TypeScript theme={null}
  const run = await client.agent.run({
    url: "https://app.example.com/dashboard",
    goal: "Download the latest invoice.",
    use_profile: true,
    profile_id: "prof_abc123def4567890",
  });
  ```
</CodeGroup>

## SDK Examples

### Agent — Streaming (Recommended)

<CodeGroup>
  ```python Python theme={null}
  from tinyfish import TinyFish, CompleteEvent

  client = TinyFish()

  with client.agent.stream(
      url="https://scrapeme.live/shop",
      goal="Extract the first 2 product names and prices. Return as JSON.",
  ) as stream:
      for event in stream:
          if isinstance(event, CompleteEvent):
              print(event.result_json)
  ```

  ```typescript TypeScript theme={null}
  import { TinyFish } from "@tiny-fish/sdk";

  const client = new TinyFish();

  const stream = await client.agent.stream({
    url: "https://scrapeme.live/shop",
    goal: "Extract the first 2 product names and prices. Return as JSON.",
  });

  for await (const event of stream) {
    if (event.type === "COMPLETE") {
      console.log(event.result);
    }
  }
  ```
</CodeGroup>

### Agent — Synchronous

<CodeGroup>
  ```python Python theme={null}
  from tinyfish import TinyFish, RunStatus

  client = TinyFish()

  result = client.agent.run(
      url="https://scrapeme.live/shop",
      goal="Extract the first 2 product names and prices. Return as JSON.",
  )
  if result.status == RunStatus.COMPLETED:
      print(result.result)
  ```

  ```typescript TypeScript theme={null}
  import { TinyFish, RunStatus } from "@tiny-fish/sdk";

  const client = new TinyFish();

  const run = await client.agent.run({
    url: "https://scrapeme.live/shop",
    goal: "Extract the first 2 product names and prices. Return as JSON.",
  });

  if (run.status === RunStatus.COMPLETED) {
    console.log(run.result);
  }
  ```
</CodeGroup>

### Search

<CodeGroup>
  ```python Python theme={null}
  result = client.search.query("web automation tools", location="US", language="en")
  print(result)
  ```

  ```typescript TypeScript theme={null}
  const result = await client.search.query({
    query: "web automation tools",
    location: "US",
    language: "en",
  });
  console.log(result);
  ```
</CodeGroup>

Use `recency_minutes` for a freshness window and `after_date` / `before_date` for calendar date filters:

* `recency_minutes`: integer `1..5256000`
* `after_date` / `before_date`: `YYYY-MM-DD`
* do not combine `recency_minutes` with date filters
* if both dates are present, `after_date <= before_date`

### Fetch

<CodeGroup>
  ```python Python theme={null}
  result = client.fetch.get_contents(urls=["https://www.tinyfish.ai/"])
  print(result)
  ```

  ```typescript TypeScript theme={null}
  const result = await client.fetch.getContents({
    urls: ["https://www.tinyfish.ai/"],
  });
  console.log(result);
  ```
</CodeGroup>

Omit `ttl` for the default cache behavior. Add `ttl` only when freshness matters: set it to `0` when you want a live fetch, or to a positive number of seconds to accept cached entries younger than that window.

### Anti-Detection Mode

For sites with bot protection, add stealth mode and a proxy:

<CodeGroup>
  ```python Python theme={null}
  from tinyfish import TinyFish, BrowserProfile, ProxyConfig, ProxyCountryCode

  client = TinyFish()

  result = client.agent.run(
      url="https://protected-site.com",
      goal="Extract pricing data. Return as JSON.",
      browser_profile=BrowserProfile.STEALTH,
      proxy_config=ProxyConfig(enabled=True, country_code=ProxyCountryCode.US),
  )
  ```

  ```typescript TypeScript theme={null}
  import { TinyFish, BrowserProfile, ProxyCountryCode } from "@tiny-fish/sdk";

  const client = new TinyFish();

  const run = await client.agent.run({
    url: "https://protected-site.com",
    goal: "Extract pricing data. Return as JSON.",
    browser_profile: BrowserProfile.STEALTH,
    proxy_config: {
      enabled: true,
      country_code: ProxyCountryCode.US,
    },
  });
  ```
</CodeGroup>

## Expected Latency

| API              | Typical Latency    | Suggested Timeout |
| ---------------- | ------------------ | ----------------- |
| Agent (sync)     | 15-60s             | 120s              |
| Agent (SSE)      | 15-60s (streaming) | N/A (SSE)         |
| Search           | 1-3s               | 10s               |
| Fetch            | 1-20s              | 150s              |
| Browser (create) | 10-30s             | 60s               |

## Prompting

Goal quality determines success rate. Vague goals like "get the data" fail; crafted goals with explicit fields, output format, and edge-case handling succeed consistently.

<Tip>
  See the full [Prompting Guide](/prompting-guide) for tested patterns, templates, and examples.
</Tip>

## Common Gotchas

1. **Browser API session creation takes 10-30s** -- set `timeout=60` on your HTTP client.
2. **TypeScript needs `"type": "module"`** in `package.json` for top-level `await`, or wrap code in `async function main() { ... }; main()`.
3. **`COMPLETED` status does not mean the goal succeeded** -- always check `result_json` for failure signals like "captcha", "blocked", or "access denied".
4. **Fetch API has a 110s per-URL backend timeout** — requests are also subject to a 120s CDN ceiling for the full batch. Set your client timeout to at least 150s.

<Accordion title="Raw API Endpoints (cURL)">
  If you can't use the SDKs, here are the raw endpoints. All use the `X-API-Key` header for authentication.

  ### Agent

  ```bash theme={null}
  curl -N -X POST https://agent.tinyfish.ai/v1/automation/run-sse \
    -H "X-API-Key: $TINYFISH_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://scrapeme.live/shop",
      "goal": "Extract the first 2 product names and prices. Return JSON."
    }'
  ```

  ### Search

  ```bash theme={null}
  curl "https://api.search.tinyfish.ai?query=web+automation+tools&location=US&language=en" \
    -H "X-API-Key: $TINYFISH_API_KEY"
  ```

  ### Fetch

  ```bash theme={null}
  curl -X POST https://api.fetch.tinyfish.ai \
    -H "X-API-Key: $TINYFISH_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"urls": ["https://www.tinyfish.ai/"]}'
  ```

  ### Browser

  ```bash theme={null}
  curl -X POST https://api.browser.tinyfish.ai \
    -H "X-API-Key: $TINYFISH_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"url": "https://www.tinyfish.ai"}'
  ```
</Accordion>

## What to Read Next

<CardGroup cols={2}>
  <Card title="Agent reference" icon="sparkles" href="/agent-api/reference">
    Goal-based automation, endpoint choice, runs, profiles, and proxies
  </Card>

  <Card title="Authentication" icon="key" href="/authentication">
    API key setup and troubleshooting
  </Card>

  <Card title="Search overview" icon="magnifying-glass" href="/search-api">
    Search query parameters and result shape
  </Card>

  <Card title="Fetch overview" icon="bolt" href="/fetch-api">
    Fetch multiple URLs and choose output formats
  </Card>

  <Card title="Browser overview" icon="browser" href="/browser-api">
    Create a remote browser session and connect via CDP
  </Card>

  <Card title="Examples" icon="code" href="/examples/scraping">
    Copy-paste examples for common workflows
  </Card>

  <Card title="llms-full.txt" icon="file-lines" href="https://docs.tinyfish.ai/llms-full.txt">
    Complete API reference in a single file (218KB)
  </Card>
</CardGroup>
