← back to Ventura Claw
server/connectors/cleveland.js
47 lines
// Cleveland Museum of Art — Open Access. No API key.
// https://openaccess-api.clevelandart.org/
const BASE = "https://openaccess-api.clevelandart.org/api";
async function call(path) {
const r = await fetch(`${BASE}${path}`, {
headers: { "User-Agent": "VenturaClaw/1.0", Accept: "application/json" },
signal: AbortSignal.timeout(15_000),
});
if (!r.ok) throw new Error(`cleveland ${r.status}`);
return r.json();
}
module.exports = {
meta: { id: "cleveland", name: "Cleveland Museum of Art", category: "data", docsUrl: "https://openaccess-api.clevelandart.org/", auth: "none", realImpl: true },
fields: [],
configured() { return true; },
async health() {
try {
const d = await call("/artworks?limit=1");
return { ok: true, label: `${(d.info?.total ?? 0).toLocaleString()} artworks · CC0 + open access` };
} catch (e) { return { ok: false, reason: e.message }; }
},
actions: {
async "search"({ q, hasImage, cc0only, limit }) {
const qs = new URLSearchParams();
if (q) qs.set("q", q);
if (hasImage) qs.set("has_image", "1");
if (cc0only) qs.set("cc0", "1");
qs.set("limit", String(Math.min(limit || 25, 100)));
const d = await call(`/artworks?${qs}`);
return {
total: d.info?.total || 0,
artworks: (d.data || []).map(a => ({
id: a.id, accession_number: a.accession_number,
title: a.title, creators: (a.creators || []).map(c => c.description).join(" · "),
date: a.creation_date, medium: a.technique, image: a.images?.web?.url || a.images?.print?.url,
url: a.url, license: a.share_license_status,
})),
};
},
async "artwork"({ id }) {
if (!id) throw new Error("id required");
const d = await call(`/artworks/${id}`);
return d.data;
},
},
};