Every endpoint takes a JSON POST body and returns JSON, except the export endpoint, which returns a file. There is no authentication. Responses are computed live and are not cached.
Conventions
- All request bodies are
application/json. Sendcontent-type: application/json. - All timestamps and years are plain numbers or ISO strings. Weights are fractions between 0 and 1.
- Fields that could not be determined are
nullrather than absent or zero. Anullmeans "unknown", not "none". - Every scoring threshold used to produce a verdict is echoed back in the response, so a grade can be reproduced without reading the source.
- Both pipelines degrade rather than fail. If the language model is unreachable you still get a graded result, with
meta.aiDegraded: true.
Rate limits
This is an open API with no key. It is rate limited per IP address. Treat it as a courtesy service rather than infrastructure: a claim check makes several upstream calls to NCBI and OpenAlex on your behalf, and those services have their own limits.
| Endpoint | Cost | Guidance |
|---|---|---|
/api/check-claim | High. 3 upstream PubMed calls plus up to 5 model calls. | Sequential use only. Do not run in parallel. |
/api/inspect-study | Medium. 1 to 4 OpenAlex calls, 1 PubMed call, 1 model call. | Pass record to skip the PubMed call. |
/api/extract-query | Low. 1 model call, no upstream data calls. | Cheap way to preview a query. |
/api/export | None. Pure formatting of a result you already hold. | Unrestricted in practice. |
Exceeding the limit returns 429 with a Retry-After header. If you
need volume beyond this, run your own instance: the whole thing deploys to a free
Cloudflare Pages account. Key-based access could be added if usage warrants it, but no key
system exists today.
POST /api/check-claim
Grades a health claim against the published literature.
Request
| Field | Type | Notes |
|---|---|---|
claim | string | Required. Free text, up to 4000 characters. A sentence, a headline, or a pasted paragraph. |
query | string | Optional. A PubMed query used verbatim, including field tags and boolean operators. Supplying it skips AI query extraction entirely. |
useAi | boolean | Optional, defaults true. When false, no model is called: direction is not assessed and the summary is assembled from study metadata. |
curl -X POST https://your-host/api/check-claim \
-H 'content-type: application/json' \
-d '{"claim": "Turmeric reduces arthritis pain"}'
Response
{
"claim": "Turmeric reduces arthritis pain",
"query": "turmeric arthritis pain",
"queryMode": "auto-extracted",
"summary": "Several meta-analyses report...",
"verdict": {
"label": "strong",
"labelText": "Strong evidence",
"score": 298.8,
"topTier": "meta-analysis",
"counts": { "meta-analysis": 6, "rct": 3, "observational": 2 },
"rationale": ["Capped below Strong: ..."],
"thresholds": { "strong": 140, "moderate": 50, "weak": 15 },
"oldestYear": 2015, "newestYear": 2026
},
"direction": {
"direction": "mixed",
"directionText": "Mixed evidence",
"supportWeight": 121.4, "contradictWeight": 98.2,
"decisiveShare": 0.75,
"counts": { "supports": 5, "contradicts": 5, "neutral": 2, "unassessed": 8 },
"assessed": 12
},
"fundingBreakdown": {
"industryWeight": 0.26, "nonIndustryWeight": 0.17, "undisclosedWeight": 0.57,
"coverage": 0.43, "sufficient": false,
"amongSupporting": { "industry": 1, "total": 4 }
},
"timeline": [
{ "year": 2019, "strength": "moderate", "strengthText": "Moderate evidence",
"direction": "supported", "directionText": "Supported by the evidence",
"score": 73.5, "studyCount": 3 }
],
"spotlight": { "for": { "pmid": "...", "excerpt": "..." }, "against": { "pmid": "..." } },
"studies": [
{
"pmid": "35935936", "title": "...", "journal": "...", "year": 2022,
"type": "meta-analysis", "typeLabel": "Meta-analysis",
"sampleSize": 2396, "stance": "supports", "partialRead": true,
"fundingSource": "undisclosed", "fundingLabel": "Funding not disclosed",
"retraction": { "retracted": false, "noticeUrl": null },
"authors": ["Zeng L", "Yang T"], "doi": "10.3389/...", "abstract": "...",
"volume": "13", "issue": "", "pages": "891822",
"url": "https://pubmed.ncbi.nlm.nih.gov/35935936/"
}
],
"meta": {
"totalMatches": 445, "shown": 20, "searchError": null,
"aiDegraded": false, "aiDisabled": false, "stanceDegraded": false,
"partialReads": 9, "timelineSkipped": null, "elapsedMs": 19300
}
}
Field notes
verdictgrades how strong the research on the topic is. It is not a ruling on the claim.labelis one ofstrong,moderate,weak,insufficient.directiongrades which way that research points, weighted by the same quality tiers.directionis one ofsupported,leans-supported,mixed,leans-contradicted,contradicted,unassessed. It staysunassessedunless studies carrying at least 30% of total weight received a for-or-against stance.verdict.rationalelists any structural gate that demoted the grade, in plain English. Empty when no gate applied.fundingBreakdown.sufficientisfalsewhen most of the weighted evidence did not disclose funding. Do not present the weights as meaningful when this isfalse.timelineis an empty array when there is too little history. The reason is inmeta.timelineSkipped.spotlightisnullunlessdirectionismixedand both sides have at least one study.studies[].partialReadmeans the stance was judged from a truncated abstract. It is a transparency flag and never affects any score.studies[].retraction.retractedis carried for display. It does not currently reduce a study's contribution to the grade.queryModeisauto-extracted,user-edited, orkeyword-fallback, so a reviewer can tell how the search was built.
POST /api/inspect-study
Appraises a single study: summary, credibility signals, citation and venue statistics, and citations in five formats.
Request
| Field | Type | Notes |
|---|---|---|
ref | string | Required. A PubMed URL, a bare PMID, or a DOI. pmid is accepted as an alias. |
record | object | Optional. A study object from a check-claim response. When its pmid matches and it carries an abstract, PubMed is not called again. |
useAi | boolean | Optional, defaults true. When false, summary is empty and the abstract stands in. |
curl -X POST https://your-host/api/inspect-study \
-H 'content-type: application/json' \
-d '{"ref": "https://pubmed.ncbi.nlm.nih.gov/9500320/"}'
Response
{
"record": {
"pmid": "9500320", "title": "...", "abstract": "...",
"journal": "Lancet (London, England)", "journalAbbrev": "Lancet",
"year": 1998, "volume": "351", "issue": "9103", "pages": "637-41",
"doi": "10.1016/s0140-6736(97)11096-0",
"authors": [{ "name": "A J Wakefield", "last": "Wakefield", "initials": "AJ",
"affiliation": "..." }],
"type": "other", "typeLabel": "Other",
"pubTypes": ["Journal Article", "Retracted Publication"],
"meshTerms": ["Child", "Measles Vaccine"],
"sampleSize": null,
"fundingSource": "undisclosed", "fundingLabel": "Funding not disclosed",
"retraction": { "retracted": true, "expressionOfConcern": true,
"isRetractionNotice": false,
"noticeUrl": "https://pubmed.ncbi.nlm.nih.gov/15016483/" },
"url": "https://pubmed.ncbi.nlm.nih.gov/9500320/"
},
"summary": "The study tested...",
"partialRead": false,
"credibility": {
"label": "retracted", "labelText": "Retracted", "composite": 0.12,
"retracted": true, "expressionOfConcern": true,
"retractionNoticeUrl": "https://pubmed.ncbi.nlm.nih.gov/15016483/",
"signals": [
{ "key": "design", "label": "Study design", "score": 0.25,
"available": true, "detail": "Other" },
{ "key": "sample", "label": "Sample size", "score": null,
"available": false, "detail": "No enrollment figure found in the abstract" }
],
"coverage": { "scored": 5, "total": 6 },
"note": "This paper has been retracted...",
"measures": "Credibility signals only: ..."
},
"metrics": {
"available": true, "source": "openalex",
"citations": 2953, "citationsPerYear": 105.5, "ageYears": 28,
"relativeToVenue": 5.25,
"venue": { "name": "The Lancet", "journalCitationRate": 20.11,
"hIndex": 1209, "worksCount": 475874, "isOpenAccess": false },
"authors": [{ "role": "first", "name": "A J Wakefield", "matched": true,
"hIndex": 34, "worksCount": 83, "citedByCount": 6966 }],
"authorsMatched": true, "openAlexRetracted": true, "note": null
},
"citations": { "apa": "...", "mla": "...", "chicago": "...",
"bibtex": "...", "ris": "..." },
"meta": { "fromCache": false, "aiDegraded": false, "aiDisabled": false,
"elapsedMs": 5005 }
}
Field notes
credibilitymeasures research credibility signals: retraction status, study design, sample size, citation traction, venue standing, author track record, funding disclosure. It does not measure whether the findings are correct, and the response says so inmeasures.- Retraction is a hard override. A retracted paper is capped near the floor regardless of every other signal, and
signalsstill reports what was measured so you can see what was overridden. - Signals with no data have
available: falseandscore: null, and are excluded from the composite rather than counted as zero.coveragereports how many of the six had data. metrics.venue.journalCitationRateis OpenAlex mean citedness. It is not Impact Factor, which is a different, proprietary metric.metrics.authors[].matched: falsemeans no confident match to an indexed profile. The figures arenullrather than guessed.metrics.available: falsemeans neither OpenAlex nor Semantic Scholar had a record. This is normal for very new or unindexed papers.
POST /api/extract-query
Builds the PubMed query for a claim without running the pipeline. Useful for previewing or editing a query before committing to a full check.
curl -X POST https://your-host/api/extract-query \
-H 'content-type: application/json' \
-d '{"claim": "Vitamin D cures depression"}'
{ "claim": "Vitamin D cures depression",
"query": "vitamin D supplementation depressive symptoms",
"mode": "auto-extracted",
"degraded": false }
Pass the returned query back to /api/check-claim, edited or not, to control the search exactly.
POST /api/export
Formats a result you already have. It fetches nothing and computes no scores.
| Field | Values |
|---|---|
kind | claim, study, or collection |
format | ris, csv, or html (a printable report) |
result | The response object from check-claim or inspect-study. For collection, { "items": [{ "kind", "result" }] }. |
The response body is the file itself, with the matching content type. CSV columns are: title, authors, journal, year, study type, sample size, direction, funding, retracted, DOI, PMID, PubMed link. RIS uses standard tags (TY, AU, TI, JO, PY, VL, IS, SP, EP, DO, AB, AN, UR, KW, ER) and imports into Zotero, EndNote, and Mendeley.
GET /api/health
{ "ok": true, "aiBackend": "workers-ai",
"model": "@cf/meta/llama-3.1-8b-instruct",
"workersAiBindingPresent": true, "ncbiApiKey": true }
Reports which model backend is configured. It does not call the model.
Errors
Errors are JSON with a single human-readable error field. There are no error codes to switch on.
| Status | Meaning |
|---|---|
400 | Malformed JSON, a missing required field, or an unreadable reference. |
404 | No PubMed record for that PMID or DOI. |
405 | Wrong method. Every data endpoint is POST except health. |
413 | Claim longer than 4000 characters. |
429 | Rate limited. Check Retry-After. |
502 | An upstream service failed in a way the pipeline could not absorb. |
A zero-result search is not an error. It returns 200 with
verdict.label: "insufficient" and an empty studies array.
Attribution and limits of use
Study data comes from PubMed via NCBI E-utilities. Citation, venue, and author statistics come from OpenAlex, with Semantic Scholar as a fallback. If you build on this API, cite those sources directly rather than crediting Kanshiki for the underlying data.
Kanshiki grades published evidence, not anyone's situation. It is not medical advice, and responses must not be presented as a clinical recommendation.