Case study
RefChecker
- Category
- Backend / Cloud
- Period
- Jun 2026 – Sep 2026
Reference metadata verification with streaming results across three academic APIs
- Next.js
- React
- TypeScript
- Crossref API
- OpenAlex API
- Semantic Scholar API
- Vitest
- Vercel
- NDJSON Streaming
Context
Checking a bibliography is manual and slow. You paste a reference into a search engine, read the publisher page, and judge whether the paper you cited is the paper you meant. For a thesis chapter with sixty references, that is hours of repetitive judgement, and the failure mode is quiet: a citation that does not exist in the public record looks exactly like one that does until someone checks.
Student reviewers face this on every bibliography they touch. Lab groups face it during literature review. Both need the same thing — a fast signal on which references deserve a human's attention, and the evidence behind that signal.
Problem
Bibliographic metadata is scattered across providers that disagree with each other and are all rate limited:
- Crossref is authoritative for anything with a registered DOI, but it knows nothing about works that never registered one.
- OpenAlex has broader coverage, with looser metadata.
- Semantic Scholar covers another slice again, and rate limits anonymous traffic hard.
Querying one provider means missing whatever only the others know. Querying them
naively in sequence means the slowest provider sets the latency for the entire
batch, and a 429 from the first one loses the reference entirely.
And the answer is not binary. A reference either matches or it does not, but the interesting cases are in between: the title matches but the year does not, the author list is a subset, or two sources disagree about the journal.
Solution
One endpoint that accepts a pasted bibliography, splits it into individual references, and verifies each one against a chained provider fallback — Crossref first, then OpenAlex, then Semantic Scholar — stopping at the first provider that returns usable metadata.
Parsing is first-party and format-aware. A style detector identifies APA, Harvard Elsevier, IEEE and MLA, then a parser normalises the DOI, title, authors and year out of each. Wrapped lines are rejoined rather than treated as new references, so a bibliography pasted straight out of Word or a PDF survives intact.
Results are returned as newline-delimited JSON. Each line is one event, so a reference appears on screen the instant it is verified instead of waiting for the slowest one in the batch. Results also export to CSV, with conflicting fields and the matching evidence included as columns.
Architecture
Next.js App Router with a single route handler at POST /api/verify. The whole
runtime dependency list is next, react and react-dom — the citation
parser, style detector, matcher, scorer and CSV writer are all first-party.
Providers sit behind one academic-provider interface, so the chain is a list
rather than branching logic. Crossref is called sequentially with retry on
429, and the verification service falls through to the next provider when one
returns nothing.
The matcher is field-level rather than a single similarity score. Title and
author similarity, year agreement and DOI equality are each evaluated
separately, journal names are compared after stopword removal, and abbreviations
are handled explicitly — J. Nat Commun has to match Journal of Natural Communications, which naive prefix matching gets wrong. A dedicated module
flags fields where sources contradict each other, which is usually the actual
reason a reference deserves review.
Input is bounded in verification-limits.ts: twenty unique references and
50,000 characters per request, with four concurrent verifications. Over-limit
input returns 413 with a plain JSON body rather than an open stream, so the
failure is legible instead of truncated mid-batch.
Tests use mocked provider responses, so the suite never depends on the network or on external credentials.
Challenges
Results arrive out of order. References verify concurrently, so result
events can land in any sequence. Each carries an index and the UI renders by
index, which is what keeps the display stable while the stream stays fast.
Streaming changes the error contract. Validation errors have to be plain
400/413 JSON responses, but a failure mid-stream cannot be — the status
line is already sent. Those are emitted as an error event instead.
"Verified" is an overclaim. The tool checks whether public metadata agrees with the citation, not whether the paper is genuine, sound, or peer reviewed. Saying so plainly in the README and in the interface was more useful than a cleaner-sounding claim that would mislead.
CSV has to survive Excel. Excel applies the locale's delimiter, so a comma
separated file can open as one giant column. Export follows RFC 4180, and the
joined author list uses and rather than a semicolon specifically so the
column stays intact whichever delimiter Excel decides on.
Results
Deployed and running at refchecker.vercel.app.
Four citation styles supported, three academic providers chained with fallback, and a confidence score with its supporting evidence attached to every result — the evidence matters as much as the verdict, since a reviewer needs to know why a reference was flagged.
Test coverage spans the parser, style detection, each provider adapter, the verification service, scoring, CSV export and the API endpoint, all against mocked responses.


