# TinyFish — Orthogonal API

> Pay-per-use API on Orthogonal. Each call is billed to your Orthogonal balance.
> Base API: `https://api.orthogonal.com/v1/run` · [llms.txt](https://orthogonal.com/llms.txt) · [browse all APIs](https://orthogonal.com/discover)

AI-powered web automation, search, fetch, and research. Automate browser tasks with natural language, search the web, extract content from URLs, and generate source-backed research reports.

**Verified:** no

## Access

**Run API:** `POST https://api.orthogonal.com/v1/run`
**Auth:** `Authorization: Bearer $ORTHOGONAL_API_KEY`
Get an API key at https://orthogonal.com/dashboard/settings/api-keys

Every call goes through the unified Run API: send the API `slug`, the endpoint `path`, and the `query`/`body` parameters. The response is `{ "success": true, "price": "<usd>", "data": { ... } }`.

## Endpoints

### Get run by ID

Get detailed information about a specific automation run including status, result, steps, and video URL. Use to poll for async run completion.

`GET /v1/runs/{id}`

**Estimated cost:** Dynamic — use `"dryRun": true` in the Run API request to check the exact cost before calling.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |
| `screenshots` | string | No | Screenshot mode: url (default), base64, or none |
| `html` | string | No | HTML snapshot mode: url (default) or none |

```bash
# Replace {id} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"tinyfish","path":"/v1/runs/{id}","method":"GET","query":{"screenshots":"<string>","html":"<string>"}}'
```

### Cancel run

Cancel a running automation. Idempotent: returns current status if already terminal. Only works for async/SSE runs, not synchronous.

`POST /v1/runs/{id}/cancel`

**Estimated cost:** $0

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |

```bash
# Replace {id} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"tinyfish","path":"/v1/runs/{id}/cancel"}'
```

### Cancel research run

Cancel a running research task. Idempotent: returns current status if already terminal.

`POST /v1/research-run/{research_run_id}/cancel`

**Estimated cost:** $0

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `research_run_id` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |

```bash
# Replace {research_run_id} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"tinyfish","path":"/v1/research-run/{research_run_id}/cancel"}'
```

### Run research

Execute a source-backed research report with SSE streaming. Returns a comprehensive report with citations from web sources. Supports standard, deep, and max research modes.

`POST /v1/automation/run-research`

**Estimated cost:** $0

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `query` | string | Yes | Research question |
| `mode` | string | No | Depth: standard, deep (default), or max (enables browser agents) |
| `stream` | boolean | No | Emit report text through synthesis_delta events as written |
| `output_language` | string | No | BCP 47 language tag for the report (e.g. en, es, ja) |
| `browser_enabled` | boolean | No | Max mode only. Defaults true in max mode. |
| `weak_sources_enabled` | boolean | No | Allow relevant social and community sources |
| `domain_type` | string | No | Source pool to research over |
| `after_date` | string | No | Include results on or after this date (YYYY-MM-DD) |
| `before_date` | string | No | Include results on or before this date (YYYY-MM-DD) |
| `recency_minutes` | integer | No | Include results from the last N minutes (1-5256000) |
| `domain_filter` | object | No | Domain preferences with include/exclude lists (max 150 entries each) |
| `prior_run_id` | string | No | Seed this run with a completed report and its evidence |
| `session_id` | string | No | Continue a standard-mode session. Mutually exclusive with prior_run_id. |

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"tinyfish","path":"/v1/automation/run-research","body":{"query":"<string>","mode":"<string>","stream":"<boolean>","output_language":"<string>","browser_enabled":"<boolean>","weak_sources_enabled":"<boolean>","domain_type":"<string>","after_date":"<string>","before_date":"<string>","recency_minutes":"<integer>","domain_filter":"<object>","prior_run_id":"<string>","session_id":"<string>"}}'
```

### Get research run

Get detailed information about a specific research run including status, report content, and sources.

`GET /v1/research-run/{research_run_id}`

**Estimated cost:** Dynamic — use `"dryRun": true` in the Run API request to check the exact cost before calling.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `research_run_id` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |

```bash
# Replace {research_run_id} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"tinyfish","path":"/v1/research-run/{research_run_id}","method":"GET"}'
```

### Start automation (async)

Start a browser automation task asynchronously. Returns a run_id immediately without waiting for completion. Use GET /v1/runs/{id} to poll for results.

`POST /v1/automation/run-async`

**Estimated cost:** $0

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `url` | string | Yes | Target website URL to automate |
| `goal` | string | Yes | Natural language description of what to accomplish on the website |
| `browser_profile` | string | No | Browser profile: lite (standard) or stealth (anti-detection) |
| `agent_config` | object | No | Agent behavior config: mode (default/strict), max_duration_seconds, cursor_style. Note: max_steps requires beta access and will return 403 if used without it. |
| `capture_config` | object | No | Configure data capture: elements, snapshots, screenshots, recording, html |
| `webhook_url` | string | No | HTTPS URL for webhook notifications on run lifecycle events |
| `use_vault` | boolean | No | Opt-in to vault credentials for this run |
| `use_profile` | boolean | No | Opt-in to default Browser Context Profile |
| `profile_id` | string | No | Browser Context Profile ID to use |
| `proxy_config` | object | No | Proxy config: enabled (bool), country_code (US, GB, CA, DE, FR, JP, AU) |
| `output_schema` | object | No | Structured-output schema for the run result |

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"tinyfish","path":"/v1/automation/run-async","body":{"url":"<string>","goal":"<string>","browser_profile":"<string>","agent_config":"<object>","capture_config":"<object>","webhook_url":"<string>","use_vault":"<boolean>","use_profile":"<boolean>","profile_id":"<string>","proxy_config":"<object>","output_schema":"<object>"}}'
```

### Search the web

Search the web and get structured results. Returns ranked results with titles, snippets, and URLs. Supports location/language targeting, domain include/exclude filters, date range filters, and search types (web, news, research_paper).

`GET /`

**Estimated cost:** $0

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `query` | string | Yes | Search query (1-2000 chars) |
| `purpose` | string | No | Why this search is being run. Used to better rank results against your intent. |
| `location` | string | No | Country code for geo-targeted results (e.g. US, GB, DE) |
| `language` | string | No | Language code for result language (e.g. en, es, de) |
| `include_domains` | string | No | Comma-separated list of domains to restrict results to |
| `exclude_domains` | string | No | Comma-separated list of domains to exclude from results |
| `domain_type` | string | No | Type of search: web (default), news, or research_paper |
| `after_date` | string | No | Return results after this date (YYYY-MM-DD) |
| `before_date` | string | No | Return results before this date (YYYY-MM-DD) |
| `recency_minutes` | integer | No | Return results from the past N minutes (1-5256000) |
| `pub_year_min` | integer | No | Min publication year for research_paper type (0-9999) |
| `pub_year_max` | integer | No | Max publication year for research_paper type (0-9999) |
| `page` | integer | No | Page number for pagination, starting from 0 (max 10) |
| `include_thumbnail` | string | No | When true, results include thumbnail_url when available |

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"tinyfish","path":"/","method":"GET","query":{"query":"<string>","purpose":"<string>","location":"<string>","language":"<string>","include_domains":"<string>","exclude_domains":"<string>","domain_type":"<string>","after_date":"<string>","before_date":"<string>","recency_minutes":"<integer>","pub_year_min":"<integer>","pub_year_max":"<integer>","page":"<integer>","include_thumbnail":"<string>"}}'
```

### Fetch and extract content

Fetch web pages and extract clean content. Submit up to 10 URLs, returns structured content in markdown (default) or HTML. Supports link/image extraction, CSS selector scoping, per-URL timeouts, and conditional requests via ETag/Last-Modified.

`POST /`

**Estimated cost:** $0

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `urls` | array | Yes | Array of URLs to fetch (1-10). All fetched in parallel. |
| `purpose` | string | No | Why these URLs are being fetched. Used to optimize content extraction. |
| `format` | string | No | Output format: markdown (default) or html |
| `links` | boolean | No | Extract all outbound links from each page |
| `image_links` | boolean | No | Extract all image URLs from each page |
| `page_metadata` | boolean | No | Return page-head metadata (canonical URL, title, description, etc.) |
| `ttl` | integer | No | Cache freshness tolerance in seconds. Omit for unlimited tolerance. |
| `per_url_timeout_ms` | integer | No | Per-URL timeout in milliseconds |
| `include_selectors` | array | No | CSS selectors (1-20) to scope extracted content to |
| `exclude_selectors` | array | No | CSS selectors (1-20) for elements to remove before extraction |

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"tinyfish","path":"/","body":{"urls":"<array>","purpose":"<string>","format":"<string>","links":"<boolean>","image_links":"<boolean>","page_metadata":"<boolean>","ttl":"<integer>","per_url_timeout_ms":"<integer>","include_selectors":"<array>","exclude_selectors":"<array>"}}'
```

---

Full details and an interactive quickstart: https://orthogonal.com/discover/tinyfish
