"use client" import * as React from "react" import { cn } from "@/lib/utils" import { Badge } from "@/components/ui/badge" import { ApiPlayground } from "@/components/ApiPlayground" interface Field { name: string type: string required?: boolean description?: string children?: Field[] } interface Endpoint { id: string method: "GET" | "POST" path: string summary: string description: string requestFields?: Field[] responseFields?: Field[] curlPrefix: string defaultBody?: string defaultParams?: string buildPath?: (body: string, params: string) => string } const endpoints: Endpoint[] = [ { id: "search", method: "POST", path: "/search", summary: "Search for visually similar tiles", description: "Submit one or more queries (text, image, or embedding) and retrieve the top matching tiles. Each hit returns article_id, tile_index, and chunk_index — pass these to GET /tile/... to fetch the actual screenshot.", requestFields: [ { name: "queries", type: "Query[]", required: true, description: "Array of query objects", children: [ { name: "text", type: "string", description: "Text search query" }, { name: "image", type: "string", description: "Base64-encoded image" }, { name: "embedding", type: "number[]", description: "Pre-computed embedding vector" }, ]}, { name: "n_docs", type: "number", description: "Number of results to return (default: 20)" }, { name: "nprobe", type: "number", description: "FAISS nprobe override" }, { name: "min_tile_height", type: "number", description: "Filter out tiles shorter than this" }, { name: "articles_only", type: "boolean", description: "Drop Wikipedia meta pages (Portal:, List_of_, disambiguation, …) — keeps real articles" }, { name: "instruction", type: "string", description: "Custom embedding instruction" }, ], responseFields: [ { name: "results", type: "QueryResult[]", required: true, description: "One result per query", children: [ { name: "hits", type: "Hit[]", required: true, description: "Ranked list of matches", children: [ { name: "score", type: "number", required: true, description: "Cosine similarity" }, { name: "vector_id", type: "number", required: true, description: "FAISS vector index" }, { name: "article_id", type: "number", required: true, description: "Wikipedia article ID" }, { name: "tile_index", type: "number", required: true, description: "Which 8192px tile" }, { name: "chunk_index", type: "number", required: true, description: "Which 1024px chunk within tile" }, { name: "y_offset", type: "number", required: true, description: "Y position in page (px)" }, { name: "tile_height", type: "number", required: true, description: "Chunk height (px)" }, { name: "path", type: "string", required: true, description: "Tile file path on server" }, { name: "url", type: "string", required: true, description: "Wikipedia article slug" }, ]}, ]}, ], curlPrefix: `curl -X POST https://pixelrag.ai/api/search \\ -H "Content-Type: application/json"`, defaultBody: JSON.stringify({ queries: [{ text: "solar system" }], n_docs: 5 }, null, 2), }, { id: "tile", method: "GET", path: "/tile/{article_id}/{tile_index}/{chunk_index}", summary: "Retrieve a tile image", description: "Fetches the screenshot image for a /search hit — pass the article_id, tile_index, and chunk_index straight from a search result. Returns PNG binary data; embed it with an tag. The example below is the top of the Albert Einstein article.", requestFields: [ { name: "article_id", type: "number", required: true, description: "Wikipedia article ID" }, { name: "tile_index", type: "number", required: true, description: "Which 8192px tile (0-based)" }, { name: "chunk_index", type: "number", required: true, description: "Which 1024px chunk within tile (0-based)" }, ], responseFields: [ { name: "(binary)", type: "image/png", required: true, description: "PNG image data" }, ], curlPrefix: `curl https://pixelrag.ai/api/tile`, defaultParams: "article_id=698618&tile_index=0&chunk_index=0", buildPath: (_body, params) => { const p = new URLSearchParams(params) return `/tile/${p.get("article_id") || "698618"}/${p.get("tile_index") || "0"}/${p.get("chunk_index") || "0"}` }, }, { id: "status", method: "GET", path: "/status", summary: "Get index status and configuration", description: "Returns metadata about the FAISS index including vector count, dimension, model, and configuration.", responseFields: [ { name: "total_vectors", type: "number", required: true, description: "Total indexed vectors" }, { name: "dimension", type: "number", required: true, description: "Embedding dimension" }, { name: "nlist", type: "number", required: true, description: "IVF cluster count" }, { name: "nprobe", type: "number", required: true, description: "Search probe count" }, { name: "model", type: "string", required: true, description: "Embedding model name" }, { name: "index_dir", type: "string", required: true, description: "Index directory path" }, { name: "tiles_dir", type: "string", required: true, description: "Tiles directory path" }, { name: "index_built_at", type: "string", required: true, description: "ISO 8601 timestamp" }, { name: "index_size_bytes", type: "number", required: true, description: "FAISS index file size" }, { name: "metadata_size_bytes", type: "number", required: true, description: "Metadata NPZ size" }, ], curlPrefix: `curl https://pixelrag.ai/api/status`, }, { id: "health", method: "GET", path: "/health", summary: "Health check", description: "Returns {\"status\": \"ok\"} when the server is running.", responseFields: [ { name: "status", type: "string", required: true, description: "Always \"ok\"" }, ], curlPrefix: `curl https://pixelrag.ai/api/health`, }, ] export default function DocsPage() { const initialId = typeof window !== "undefined" ? window.location.hash.slice(1) : "" const [activeId, setActiveId] = React.useState( endpoints.find((e) => e.id === initialId)?.id ?? "overview" ) const active = endpoints.find((e) => e.id === activeId) function selectEndpoint(id: string) { setActiveId(id) window.history.replaceState(null, "", `#${id}`) } return (
{/* Sidebar */} {/* Mobile endpoint selector */}
{/* Main content */}
{active ? ( <>

{active.path}

{active.summary}

{/* Description */}

{active.description}

{/* Try it — most useful, put first */} {/* Schema — Request + Response side by side when both exist */} {active.requestFields ? (
{active.responseFields && (
)}
) : active.responseFields ? (
) : null}
) : ( )}
) } function Code({ children }: { children: React.ReactNode }) { return ( {children} ) } // Minimal, dependency-free shell highlighter for the curl examples — colors // comments, commands, flags, quoted strings, and URLs. function ShellBlock({ code }: { code: string }) { const TOKEN = /(#.*)|("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')|(https?:\/\/[^\s'"]+)|(\bcurl\b)|(\s-{1,2}[A-Za-z][\w-]*)/g const nodes: React.ReactNode[] = [] let last = 0 let m: RegExpExecArray | null let key = 0 while ((m = TOKEN.exec(code)) !== null) { if (m.index > last) nodes.push(code.slice(last, m.index)) const [full, comment, str, url, cmd] = m const cls = comment ? "italic text-muted-foreground/60" : str ? "text-green-600 dark:text-green-400" : url ? "text-blue-600 dark:text-blue-400" : cmd ? "font-medium text-purple-600 dark:text-purple-400" : "text-amber-600 dark:text-amber-400" // flag nodes.push( {full} ) last = m.index + full.length } if (last < code.length) nodes.push(code.slice(last)) return (
      {nodes}
    
) } function FlowStep({ n, method, path, title, onSelect, children, }: { n: number method: "GET" | "POST" path: string title: string onSelect: () => void children: React.ReactNode }) { return ( ) } function OverviewSection({ onSelect }: { onSelect: (id: string) => void }) { return (

API Overview

PixelRAG indexes 8.28M Wikipedia articles as{" "} screenshot tiles and retrieves over the images directly. Using the API is a two-step flow: search for the tiles that match your query, then fetch each tile's screenshot.

onSelect("search")} > Send a natural-language question or an image. Each hit comes back with{" "} article_id, tile_index, and chunk_index. onSelect("tile")} > Pass those three IDs straight from a search hit to get the PNG — embed it with an{" "} <img> tag.

Example

Search, then fetch the top hit's screenshot:

Base URL

https://pixelrag.ai/api — or query the index server directly at{" "} https://api.pixelrag.ai.

Endpoints

{endpoints.map((ep) => ( ))}

Connect your own agent

The search API is a plain HTTP endpoint — wire it into any agent framework (Claude tool-use, OpenAI function calling, LangChain, custom harness) as a tool. A typical agent loop: search with text and/or an image, fetch tiles to read the screenshots, then answer from what they show.

) } function MethodBadge({ method }: { method: "GET" | "POST" }) { return ( {method} ) } function Section({ title, children, }: { title: string children: React.ReactNode }) { return (

{title}

{children}
) } function TypeBadge({ type }: { type: string }) { const color = type.includes("[]") ? "text-amber-400 bg-amber-400/10" : type === "number" ? "text-blue-400 bg-blue-400/10" : type === "string" || type.startsWith("image/") ? "text-green-400 bg-green-400/10" : "text-purple-400 bg-purple-400/10" return ( {type} ) } function FieldRow({ field, depth = 0 }: { field: Field; depth?: number }) { return ( <>
{field.name} {!field.required && ( optional )}
{field.description && ( {field.description} )}
{field.children?.map((child) => ( ))} ) } function FieldTable({ fields }: { fields: Field[] }) { return (
{fields.map((field) => ( ))}
) }