Skip to main content

Fetch a Single Page

Extract content from any URL as clean Markdown:
from tinyfish import TinyFish

client = TinyFish()
result = client.fetch.get_contents(
    urls=["https://example.com"],
    format="markdown",
)

page = result.results[0]
print(f"Title: {page.title}")
print(page.text)
import { TinyFish } from "@tiny-fish/sdk";

const client = new TinyFish();
const result = await client.fetch.getContents({
  urls: ["https://example.com"],
  format: "markdown",
});

const page = result.results[0];
console.log(`Title: ${page.title}`);
console.log(page.text);
curl -s -X POST https://api.fetch.tinyfish.ai \
  -H "X-API-Key: $TINYFISH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://example.com"], "format": "markdown"}'
Output:
{
  "results": [
    {
      "url": "https://example.com",
      "final_url": "https://example.com/",
      "language": "en",
      "text": "This domain is for use in documentation examples without needing permission...",
      "format": "markdown"
    }
  ],
  "errors": []
}

Batch Fetch

Fetch up to 10 URLs in a single request. Failed URLs appear in errors[] without affecting the rest:
from tinyfish import TinyFish

client = TinyFish()
result = client.fetch.get_contents(
    urls=[
        "https://example.com",
        "https://httpbin.org/html",
        "https://nonexistent.invalid",
    ],
    format="markdown",
)

for page in result.results:
    print(f"OK: {page.url}{page.text[:80]}")

for err in result.errors:
    print(f"FAIL: {err.url}{err.error}")
import { TinyFish } from "@tiny-fish/sdk";

const client = new TinyFish();
const result = await client.fetch.getContents({
  urls: [
    "https://example.com",
    "https://httpbin.org/html",
    "https://nonexistent.invalid",
  ],
  format: "markdown",
});

for (const page of result.results) {
  console.log(`OK: ${page.url}${page.text.slice(0, 80)}`);
}

for (const err of result.errors) {
  console.log(`FAIL: ${err.url}${err.error}`);
}
curl -s -X POST https://api.fetch.tinyfish.ai \
  -H "X-API-Key: $TINYFISH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": [
      "https://example.com",
      "https://httpbin.org/html",
      "https://nonexistent.invalid"
    ],
    "format": "markdown"
  }'

Control Cache Freshness

Use ttl when you need to bound how old a cached page can be. Set ttl to 0 when you want a live fetch, or to a positive number of seconds to accept cached entries younger than that window.
from tinyfish import TinyFish

client = TinyFish()
result = client.fetch.get_contents(
    urls=["https://example.com"],
    ttl=0,
)
print(result.results[0].text)
import { TinyFish } from "@tiny-fish/sdk";

const client = new TinyFish();
const result = await client.fetch.getContents({
  urls: ["https://example.com"],
  ttl: 0,
});
console.log(result.results[0].text);
curl -s -X POST https://api.fetch.tinyfish.ai \
  -H "X-API-Key: $TINYFISH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://example.com"], "ttl": 0}'

Detect Page Changes with Conditional Requests

Save a page’s etag, then replay it on your next fetch to skip re-processing content that hasn’t changed. Conditional requests are a stateless pass-through — Fetch doesn’t store the validators for you. 1. Bootstrap: fetch once and save the etag
curl -s -X POST https://api.fetch.tinyfish.ai \
  -H "X-API-Key: $TINYFISH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": ["https://example.com"],
    "include_etag_and_last_modified": true
  }'
Output:
{
  "results": [
    {
      "url": "https://example.com",
      "final_url": "https://example.com/",
      "text": "This domain is for use in documentation examples without needing permission...",
      "format": "markdown",
      "etag": "W/\"abc123\"",
      "last_modified": "Wed, 21 Oct 2015 07:28:00 GMT"
    }
  ],
  "errors": []
}
Save etag (or last_modified) somewhere durable, keyed by URL. 2. Later: replay the etag to check for changes
curl -s -X POST https://api.fetch.tinyfish.ai \
  -H "X-API-Key: $TINYFISH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": ["https://example.com"],
    "if_none_match": "W/\"abc123\"",
    "include_etag_and_last_modified": true
  }'
The origin confirms nothing changed — skip re-processing:
{
  "results": [
    {
      "url": "https://example.com",
      "final_url": "https://example.com/",
      "text": null,
      "format": "markdown",
      "not_modified": true,
      "etag": "W/\"abc123\"",
      "last_modified": "Wed, 21 Oct 2015 07:28:00 GMT"
    }
  ],
  "errors": []
}
Get all hyperlinks and image URLs from a page:
from tinyfish import TinyFish

client = TinyFish()
result = client.fetch.get_contents(
    urls=["https://www.tinyfish.ai/"],
    format="markdown",
    links=True,
    image_links=True,
)

page = result.results[0]
print(f"Found {len(page.links)} links and {len(page.image_links)} images")

for link in page.links[:5]:
    print(f"  → {link}")
import { TinyFish } from "@tiny-fish/sdk";

const client = new TinyFish();
const result = await client.fetch.getContents({
  urls: ["https://www.tinyfish.ai/"],
  format: "markdown",
  links: true,
  image_links: true,
});

const page = result.results[0];
console.log(`Found ${page.links.length} links and ${page.image_links.length} images`);

for (const link of page.links.slice(0, 5)) {
  console.log(`  → ${link}`);
}
curl -s -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/"],
    "format": "markdown",
    "links": true,
    "image_links": true
  }'

Fetch as HTML

Get semantic HTML instead of Markdown — useful for preserving structure:
from tinyfish import TinyFish

client = TinyFish()
result = client.fetch.get_contents(
    urls=["https://httpbin.org/html"],
    format="html",
)

page = result.results[0]
print(page.text[:300])
import { TinyFish } from "@tiny-fish/sdk";

const client = new TinyFish();
const result = await client.fetch.getContents({
  urls: ["https://httpbin.org/html"],
  format: "html",
});

const page = result.results[0];
console.log(page.text.slice(0, 300));
curl -s -X POST https://api.fetch.tinyfish.ai \
  -H "X-API-Key: $TINYFISH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://httpbin.org/html"], "format": "html"}'

Fetch Reference

Full parameter, response, and content type docs

Search Examples

Web search with geo-targeting