Skip to main content

scholar-sidekick

Resolve, verify, format and audit scholarly citations from Python.

A thin client for the Scholar Sidekick REST API — citation formatting in 10,000+ CSL styles, bibliography export, retraction and open-access checks, and verification that a citation is real rather than fabricated.

pip install scholar-sidekick

Quick start

from scholar_sidekick import ScholarSidekick

client = ScholarSidekick()

# Format an identifier
print(client.format(text="10.1038/nphys1170", style="vancouver").text)

# Export a bibliography
print(client.export(text="10.1038/nphys1170", format="bibtex"))

Verifying citations

The dominant AI-fabrication pattern is a real, resolvable DOI paired with an invented title. Such citations resolve cleanly under doi.org, so "follow the link and see if it loads" does not catch them. Comparing the claimed title against the resolved record does.

# Add semantic_title=True (any tier) to also judge whether the cited and resolved
# titles describe the same work — catches a one-word swap in a long title that
# string similarity misses. A flagged match comes back "ambiguous" for review,
# never "mismatch". Not byte-deterministic; see result.provenance["semantic_title"].
result = client.verify(
    title="Quantum entanglement in biological systems",
    doi="10.1038/nphys1170",
)

print(result.verdict)  # matched | mismatch | ambiguous | not_found
print(result.confidence)  # high | medium | low

A mismatch is returned as a value, never raised as an exception — it is the expected outcome for a fabricated citation, and the reason this method exists.

Interpreting verdicts

verdict meaning
matched the claimed citation agrees with the resolved record
mismatch the identifier resolves to a different work — likely fabrication
ambiguous a discrepancy that needs human eyes, not an accusation
not_found no record found in the registries searched

not_found is not proof of fabrication. Standards documents, software repositories, model cards and institutional reports are frequently real but absent from the scholarly registries the API searches. Treat it as "could not confirm", not "invented".

Auditing a whole bibliography

The API audits up to 25 references per call and rate-limits those calls. audit_bibliography() handles both for you: it chunks, paces itself from the server's rate-limit headers, and sends chunks serially — the server already fans out internally, so parallelising here would compete with it for the same upstream budget.

report = client.audit_bibliography(
    references, progress=lambda done, total: print(f"{done}/{total}")
)

print(report.summary)  # verdict counts across every chunk
print(len(report.needs_review))  # entries a human should look at

for entry in report.needs_review:
    print(entry.input_index, entry.verdict, entry.claimed_title, entry.resolved_title)

entry.input_index is the 0-based position in the list you passed in, so it always points at the right reference regardless of how the work was chunked. An entry carries both claimed_title (what you sent) and resolved_title (what the identifier resolves to) — a mismatch is the gap between the two.

A chunk that fails is recorded rather than raised, so one transient upstream error does not discard several minutes of completed work:

if not report.complete:
    for failure in report.errors:
        print(f"entries {failure.start_index}-{failure.end_index} failed: {failure.error}")

With pandas installed (pip install 'scholar-sidekick[pandas]'):

df = report.to_dataframe()
df[df.verdict != "matched"]

There is a runnable end-to-end example in examples/systematic_review_audit.ipynb.

Authentication

Every endpoint works anonymously — no key, no signup. An API key raises the rate limit (about fivefold on the free tier) but is never required.

client = ScholarSidekick(api_key="ssk_…")

Or set SCHOLAR_SIDEKICK_API_KEY in the environment. Precedence is the explicit argument, then the environment variable, then anonymous. Free keys are issued at scholar-sidekick.com/account.

Async

Every method has an async equivalent:

from scholar_sidekick import AsyncScholarSidekick

async with AsyncScholarSidekick() as client:
    result = await client.verify(title="…", doi="10.1038/nphys1170")

Note that audit_bibliography() still issues its chunks serially in the async client — the constraint is the server's upstream budget, not this client's concurrency.

Errors

Exceptions are selected by the API's stable error code, not by HTTP status (the contract guarantees the code; statuses may change).

from scholar_sidekick import APIError, RateLimitError, UpstreamError

try:
    client.format(text="10.1038/nphys1170")
except RateLimitError as exc:
    print("retry after", exc.retry_after)
except UpstreamError as exc:
    print("a data source failed:", exc.code)
except APIError as exc:
    print(exc.code, exc.message, exc.request_id)
exception when
ValidationError the request was malformed or invalid
AuthError authentication or entitlement was refused
RateLimitError rate limit exceeded; carries .retry_after
UpstreamError a scholarly data source failed after the API's own retries
TransportError connection failure or timeout; no HTTP response

Every APIError carries .request_id — include it in bug reports.

API surface

method purpose
format() resolve identifiers and format them
format_items() format already-resolved CSL-JSON items
export() export to RIS, BibTeX, CSV, EndNote XML, …
verify() check one citation against the resolved record
audit() audit up to 25 references in one call
audit_bibliography() audit any number, chunked and paced
health() service liveness

format() returns whole-batch text/html strings covering every input, newline-joined — the API has no per-item formatted field, and this client does not invent one by splitting that string. format_items() names the same concept output. The difference is preserved deliberately rather than papered over.

Development

python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev,pandas]"
pytest --cov

License

MIT

Metadata

Release files for scholar-sidekick 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for scholar-sidekick 0.1.1
File Size Uploaded Provenance Actions
scholar_sidekick-0.1.1.tar.gz 45.5 kB With provenance Details for scholar_sidekick-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for scholar-sidekick 0.1.1
File Interpreter ABI Platform Actions
scholar_sidekick-0.1.1-py3-none-any.whl Python 3 none any Details for scholar_sidekick-0.1.1-py3-none-any.whl

Total release size: 70.0 kB

Release files / scholar_sidekick-0.1.1.tar.gz

Download URL scholar_sidekick-0.1.1.tar.gz
Size 45.5 kB
Tags Source
SHA-256 checksum
How to use checksums
a9881a87f4a6c65500608af20c02e075850a0ef42a71e860477d919d7f7ef893
BLAKE2b-256 checksum
How to use checksums
909d7214f9fc738251bd23f04541a2f6f0e3f977f132b114882ba18ffa8c1c1f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Release files / scholar_sidekick-0.1.1-py3-none-any.whl

Download URL scholar_sidekick-0.1.1-py3-none-any.whl
Size 24.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c46df372cdf421fd64c27244ef4fe48aead66e3b14e0505df25e4d5c73cbc761
BLAKE2b-256 checksum
How to use checksums
0432fb0da32e7a96a9cb319b08a33cdeeb8ea9b4576f75d9256e34694df24125
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Security for scholar-sidekick 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for scholar_sidekick-0.1.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page