← back to Ventura Claw

server/connectors/aic.js

44 lines

// Art Institute of Chicago — Public API. No key.
// https://api.artic.edu/docs/
const BASE = "https://api.artic.edu/api/v1";
async function call(path) {
  const r = await fetch(`${BASE}${path}`, {
    headers: { "User-Agent": "VenturaClaw/1.0", Accept: "application/json", "AIC-User-Agent": "VenturaClaw (steve@venturaclaw.com)" },
    signal: AbortSignal.timeout(15_000),
  });
  if (!r.ok) throw new Error(`aic ${r.status}`);
  return r.json();
}
module.exports = {
  meta: { id: "aic", name: "Art Institute of Chicago", category: "data", docsUrl: "https://api.artic.edu/docs/", auth: "none", realImpl: true },
  fields: [],
  configured() { return true; },
  async health() {
    try {
      const d = await call("/artworks?limit=1");
      return { ok: true, label: `${(d.pagination?.total ?? 0).toLocaleString()} artworks · public-domain images via IIIF` };
    } catch (e) { return { ok: false, reason: e.message }; }
  },
  actions: {
    async "search"({ q, limit }) {
      if (!q) throw new Error("q required");
      const qs = new URLSearchParams({ q, limit: String(Math.min(limit || 20, 100)), fields: "id,title,artist_display,date_display,image_id,is_public_domain,thumbnail" });
      const d = await call(`/artworks/search?${qs}`);
      return {
        total: d.pagination?.total || 0,
        artworks: (d.data || []).map(a => ({
          id: a.id, title: a.title, artist: a.artist_display, date: a.date_display,
          is_public_domain: a.is_public_domain,
          thumbnail: a.thumbnail?.lqip,
          image: a.image_id ? `https://www.artic.edu/iiif/2/${a.image_id}/full/843,/0/default.jpg` : null,
        })),
      };
    },
    async "artwork"({ id }) {
      if (!id) throw new Error("id required");
      const d = await call(`/artworks/${id}`);
      return d.data;
    },
  },
};