Skip to content

Repository files navigation

@iplweb/radon-opendata

CI npm license: MIT

Zero-dependency, framework-agnostic client for the Polish RAD-on OpenData API (radon.nauka.gov.pl) — look up a scientist by name and pull their academic degrees, titles, employment, research projects, patents and artistic achievements, keyed and verified by ORCID.

Works in the browser (RAD-on serves permissive CORS on these endpoints) and in Node ≥ 18. Ships ESM + CJS + type declarations. No runtime dependencies.

Why

RAD-on's public OpenData API is searchable by name, not by ORCID — but the records it returns carry the person's ORCID. This library turns that into reliable matching: search by surname, then keep only the records whose ORCID equals the one you already hold. Two Jan Kowalskis stop being a problem.

Data comes from these live, CORS-open endpoints (verified 2026-07-07):

Dataset Endpoint Person filter ORCID field used to verify
CV (degrees/titles/employment) POST /scientist/search firstName/lastName personalData.orcid
Research projects GET /polon/projects project manager name projectManagers[].ORCID
Patents / protection rights GET /polon/products inventor name inventors[].persons[].relatedOrcid
Artistic achievements GET /polon/artisticAchievements author name authors[].orcid

Publications are intentionally not included — RAD-on can serve them (GET /polon/publications?orcidId=…), but most bibliography systems already hold their own. Add that endpoint yourself if you need it.

Install

npm install @iplweb/radon-opendata

Quick start

One call does search → ORCID-verify → normalize for every dataset in parallel, degrading gracefully if any single endpoint is down:

import {
  createRadonClient,
  fetchAchievementsByOrcid,
} from "@iplweb/radon-opendata";

const client = createRadonClient(); // defaults to https://radon.nauka.gov.pl/opendata

const result = await fetchAchievementsByOrcid(
  client,
  {
    firstName: "Przemysław",
    lastName: "Kowalczewski",
    orcid: "0000-0002-0153-4624",
  },
  { onError: (endpoint, err) => console.debug("[radon]", endpoint, err) },
);

if (result.hasAny) {
  console.log(result.cv?.degrees); // [{ name: "Doktor", year: "2016", institution: "…" }, …]
  console.log(result.projects); // [{ title, competition, funds, startDate, endDate, … }]
  console.log(result.patents); // [{ title, type, publicationNumber, … }]
  console.log(result.artisticAchievements);
}

fetchAchievementsByOrcid never rejects on a single endpoint failure: the failing dataset comes back empty and onError is called; the rest still load.

Browser usage

The RAD-on endpoints reflect the request Origin, so you can call them directly from a page — no proxy, no key, no login:

<script type="module">
  import {
    createRadonClient,
    fetchAchievementsByOrcid,
  } from "https://esm.sh/@iplweb/radon-opendata";

  const el = document.querySelector("#radon");
  const result = await fetchAchievementsByOrcid(createRadonClient(), {
    firstName: el.dataset.firstName,
    lastName: el.dataset.lastName,
    orcid: el.dataset.orcid,
  });
  // …render result.cv / result.projects / … (use textContent, not innerHTML)
</script>

Low-level API

Prefer to drive it yourself? Every piece is exported and independently usable.

import {
  createRadonClient,
  pickScientistByOrcid,
  filterProjectsByOrcid,
  extractScientistCv,
  extractProject,
  orcidMatches,
} from "@iplweb/radon-opendata";

const client = createRadonClient({
  // baseUrl: "https://your-proxy.example/rad",  // e.g. a same-origin proxy
  // fetch: customFetch,                          // inject fetch (tests, Node < 18)
});

const scientists = await client.searchScientist({ lastName: "Kowalczewski" });
const me = pickScientistByOrcid(scientists, "0000-0002-0153-4624");
const cv = me ? extractScientistCv(me) : null;

const projects = filterProjectsByOrcid(
  await client.fetchProjects({ lastName: "Kowalczewski" }),
  "0000-0002-0153-4624",
).map(extractProject);

Exports

  • Client: createRadonClient(options?){ searchScientist, fetchProjects, fetchPatents, fetchArtisticAchievements }. Options: baseUrl, fetch.
  • ORCID: normalizeOrcid(value), orcidMatches(a, b).
  • Selectors: pickScientistByOrcid, filterProjectsByOrcid, filterPatentsByOrcid, filterAchievementsByOrcid.
  • Extractors: extractScientistCv, extractProject, extractPatent, extractArtisticAchievement.
  • Aggregate: fetchAchievementsByOrcid(client, query, options?).
  • Types: all API and result shapes are exported.

Matching rules & caveats

  • Verification is by ORCID. CV, projects and artistic achievements are returned only when the embedded ORCID matches — no fuzzy name guessing.
  • Patents may lack ORCID in POL-on. filterPatentsByOrcid drops unverifiable patents by design; loosen it in your own code if you accept name-only matching.
  • No caching / persistence. Calls hit RAD-on live. Cache upstream if needed.
  • Best-effort data. RAD-on may change field shapes; unknown/missing fields normalize to null/[] rather than throwing.

Development

npm install
npm test          # vitest
npm run typecheck
npm run build     # tsup → dist (ESM + CJS + d.ts)

License

MIT © IPLWeb. Not affiliated with OPI PIB / the RAD-on system; consumes public open data.

About

Zero-dependency browser/Node client for the Polish RAD-on OpenData API — scientists, projects, patents, artistic achievements, verified by ORCID.

Resources

Stars

Watchers

Forks

Releases

Sponsor this project

Packages

Contributors

Languages