KERNIT Documentation

API version2026-05-12Version policy

Python SDK-style client

Use this SDK-style Python client when your integration needs a reusable class around scan, resolve, and apply instead of one-off requests code.

Client Shape#

This is not a published PyPI package yet. It is the official docs-side client shape KERNIT will keep aligned with the OpenAPI contract until a packaged SDK is released.

import base64
import json
import os
import requests

class KernitHyperlinker:
    def __init__(self, api_key, base_url="https://api.kernit.org"):
        if not api_key:
            raise ValueError("api_key is required")
        self.api_key = api_key
        self.base_url = base_url.rstrip("/")

    def multipart(self, endpoint, file_path, **fields):
        with open(file_path, "rb") as docx:
            files = {"file": (file_path, docx, "application/vnd.openxmlformats-officedocument.wordprocessingml.document")}
            data = {key: value if isinstance(value, str) else json.dumps(value) for key, value in fields.items() if value is not None}
            response = requests.post(
                self.base_url + endpoint,
                headers={"Authorization": f"Bearer {self.api_key}"},
                files=files,
                data=data,
                timeout=480,
            )
        if response.status_code >= 400:
            raise RuntimeError(f"{endpoint} failed: {response.status_code} {response.text}")
        return response.json()

    def scan(self, file_path, settings):
        return self.multipart("/hyperlink-scan", file_path, settings=settings)

    def resolve(self, file_path, settings, scan_fingerprint):
        return self.multipart("/hyperlink-crossref", file_path, settings=settings, scanFingerprint=scan_fingerprint)

    def apply(self, file_path, settings, scan_fingerprint, scan_token, decisions, resolved_works=None):
        return self.multipart(
            "/hyperlink-apply",
            file_path,
            settings=settings,
            scanFingerprint=scan_fingerprint,
            scanToken=scan_token,
            decisions=decisions,
            resolvedWorks=resolved_works or {},
        )

kernit = KernitHyperlinker(os.environ["KERNIT_API_KEY"])
settings = json.loads("{\n  \"refs\": true,\n  \"figures\": \"number\",\n  \"tables\": \"number\",\n  \"equations\": \"number\",\n  \"sections\": \"number\",\n  \"doi\": true,\n  \"crossref\": true,\n  \"refTitleLink\": false,\n  \"linkColor\": \"#0077BD\",\n  \"xrefLinkColor\": \"#0077BD\"\n}")
scan = kernit.scan("paper.docx", settings)
resolved = kernit.resolve("paper.docx", settings, scan["scanFingerprint"])
decisions = [
    {"refId": match["refId"], "status": "approved" if match.get("confidence", 0) >= 0.9 else "skipped", "targetId": match.get("targetId")}
    for match in scan.get("matches", [])
]
applied = kernit.apply("paper.docx", settings, scan["scanFingerprint"], scan["scanToken"], decisions, resolved.get("resolvedWorks", {}))
with open("paper.linked.docx", "wb") as output:
    output.write(base64.b64decode(applied["docx"]))

Method Contract#

MethodEndpointPurpose
scan(file_path, settings)/hyperlink-scanCreate review rows and scan state.
resolve(file_path, settings, scan_fingerprint)/hyperlink-crossrefResolve bibliography evidence.
apply(file_path, settings, scan_fingerprint, scan_token, decisions)/hyperlink-applyWrite approved links into the DOCX.
Was this page useful?Send a lightweight docs feedback event.
Last updated: May 12, 2026Canonical: https://kernit.org/docs/api/sdk/python/