import { useMemo, useState } from "react"; import { useNavigate, useParams } from "react-router-dom"; import { AlertCircle, ArrowLeft, Braces, Clipboard, Code2, FileJson, FileSpreadsheet, FileText, RefreshCw, } from "lucide-react"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { buttonVariants } from "@/components/ui/button"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Select } from "@/components/ui/select"; import { Skeleton } from "@/components/ui/skeleton"; import { useExportJson } from "@/hooks/usePlatform"; import { useProject } from "@/hooks/useProjects"; import { platformApi } from "@/lib/api/platform"; import { formatDateTime, formatPercent, humanizeValue } from "@/lib/display"; import { cn } from "@/lib/utils"; const statusOptions = [ { value: "validated_claim", label: "Validated claims" }, { value: "active", label: "Active claims" }, { value: "candidate_claim", label: "Candidate claims" }, { value: "rule_candidate", label: "Rule candidates" }, { value: "rejected", label: "Rejected claims" }, { value: "all", label: "All statuses" }, ]; function valueFrom(row: Record, key: string): string { return humanizeValue(row[key]); } export default function ExportApiPage() { const navigate = useNavigate(); const { projectId } = useParams<{ projectId: string }>(); const projectName = projectId ?? ""; const { data: project } = useProject(projectName); const [status, setStatus] = useState("validated_claim"); const [includeEvidence, setIncludeEvidence] = useState(true); const [limit, setLimit] = useState(1000); const [copied, setCopied] = useState(null); const exportData = useExportJson(projectName, { status, includeEvidence, limit, }); const urls = useMemo( () => ({ json: platformApi.exportUrl( projectName, "json", status, includeEvidence, limit, ), csv: platformApi.exportUrl( projectName, "csv", status, includeEvidence, limit, ), turtle: platformApi.exportUrl( projectName, "turtle", status, includeEvidence, limit, ), }), [includeEvidence, limit, projectName, status], ); const origin = typeof window !== "undefined" && window.location?.origin ? window.location.origin : ""; const absoluteJsonUrl = `${origin}${urls.json}`; const curlSnippet = `curl -L "${absoluteJsonUrl}"`; const fetchSnippet = `const response = await fetch("${urls.json}");\nconst ontology = await response.json();`; const previewRows = exportData.data?.claims.slice(0, 8) ?? []; const avgConfidence = exportData.data?.claims.length ? exportData.data.claims.reduce((sum, row) => { const confidence = row.confidence; return sum + (typeof confidence === "number" ? confidence : 0); }, 0) / exportData.data.claims.length : 0; async function copy(text: string, key: string) { try { await navigator.clipboard.writeText(text); setCopied(key); window.setTimeout(() => setCopied(null), 1600); } catch { setCopied("failed"); } } return (

Export / API Center

{project?.name ?? projectName} exports, endpoint settings, and integration snippets.

{exportData.isError && ( {(exportData.error as Error).message} )}
setLimit(Math.max(1, Math.min(5000, Number(event.target.value) || 1))) } aria-label="Export row limit" /> {exportData.data?.count ?? 0} rows
Export rows
{(exportData.data?.count ?? 0).toLocaleString()}
Status scope
{statusOptions.find((option) => option.value === status)?.label}
Avg confidence
{formatPercent(avgConfidence)}
Export Preview First rows from the JSON export endpoint.
{exportData.isLoading ? (
{Array.from({ length: 5 }).map((_, index) => ( ))}
) : previewRows.length === 0 ? (
No export rows match the current settings.
) : (
{previewRows.map((row, index) => ( ))}
Claim Subject Predicate Object Confidence Last seen
#{valueFrom(row, "claim_id")} {valueFrom(row, "subject")} {valueFrom(row, "predicate")} {valueFrom(row, "object")} {typeof row.confidence === "number" ? formatPercent(row.confidence) : "-"} {formatDateTime( typeof row.last_seen_at === "string" ? row.last_seen_at : undefined, )}
)}
); } function DownloadLink({ href, icon: Icon, label, }: { href: string; icon: React.ComponentType<{ className?: string }>; label: string; }) { return ( {label} ); } function CodeBlock({ value }: { value: string }) { return (
      {value}
    
); } function Snippet({ title, value, copied, onCopy, }: { title: string; value: string; copied: boolean; onCopy: () => void; }) { return (
{title}
); } function FormatRow({ label, detail }: { label: string; detail: string }) { return (
{label}
{detail}
); }