Copy & paste

SDKs & Client Libraries

Drop-in client wrappers for TypeScript, Python, and cURL. These aren't npm packages — just well-structured code you copy into your project and start using immediately.

Every client wraps the full Talon API with typed methods, consistent error handling, and sensible defaults. Base URL defaults to https://talonapi.dev.

TSTypeScript / Node.js

Requires Node.js 18+ (built-in fetch) or any environment with a global fetch. No dependencies.

Copy this into your project as talon-client.ts.

talon-client.ts
// talon-client.ts — Talon API Client for TypeScript/Node.js
// Copy this file into your project. Requires: fetch (Node 18+ or polyfill)

export class TalonError extends Error {
  code: string;
  suggestion?: string;
  status: number;

  constructor(code: string, message: string, status: number, suggestion?: string) {
    super(message);
    this.name = "TalonError";
    this.code = code;
    this.status = status;
    this.suggestion = suggestion;
  }
}

interface TalonClientOptions {
  apiKey: string;
  baseUrl?: string;
}

export class TalonClient {
  private apiKey: string;
  private baseUrl: string;

  constructor({ apiKey, baseUrl = "https://talonapi.dev" }: TalonClientOptions) {
    this.apiKey = apiKey;
    this.baseUrl = baseUrl.replace(/\/$/, "");
  }

  private async _request(
    method: "GET" | "POST",
    path: string,
    params?: Record<string, string>,
    body?: Record<string, unknown>
  ) {
    const url = new URL(`${this.baseUrl}${path}`);
    if (params) {
      Object.entries(params).forEach(([k, v]) => {
        if (v !== undefined) url.searchParams.set(k, v);
      });
    }

    const res = await fetch(url.toString(), {
      method,
      headers: {
        "X-API-Key": this.apiKey,
        ...(body ? { "Content-Type": "application/json" } : {}),
      },
      ...(body ? { body: JSON.stringify(body) } : {}),
    });

    const data = await res.json();

    if (!res.ok) {
      const err = data.error ?? {};
      throw new TalonError(
        err.code ?? "unknown_error",
        err.message ?? res.statusText,
        res.status,
        err.suggestion
      );
    }

    return data;
  }

  health() {
    return this._request("GET", "/api/v1/health");
  }

  getRules(payer: string, cpt: string, clinicalContext?: string) {
    return this._request("GET", "/api/v1/rules", {
      payer,
      cpt,
      ...(clinicalContext ? { clinical_context: clinicalContext } : {}),
    });
  }

  listPayers() {
    return this._request("GET", "/api/v1/rules/payers");
  }

  listCptCodes() {
    return this._request("GET", "/api/v1/rules/cpt-codes");
  }

  comparePayers(cpt: string) {
    return this._request("GET", "/api/v1/compare", { cpt });
  }

  getMetrics(payer?: string) {
    return this._request("GET", "/api/v1/metrics", payer ? { payer } : undefined);
  }

  generateAppeal(params: {
    payer: string;
    cptCode: string;
    denialReason: string;
    denialCode?: string;
    clinicalSummary: string;
  }) {
    return this._request("POST", "/api/v1/appeals/generate", undefined, {
      payer: params.payer,
      cpt_code: params.cptCode,
      denial_reason: params.denialReason,
      ...(params.denialCode ? { denial_code: params.denialCode } : {}),
      clinical_summary: params.clinicalSummary,
    });
  }

  checkReadiness(params: {
    payer: string;
    cptCode: string;
    documentation: Record<string, unknown>;
  }) {
    return this._request("POST", "/api/v1/rules/check", undefined, {
      payer: params.payer,
      cpt_code: params.cptCode,
      available_documentation: params.documentation,
    });
  }

  getFormulary(params?: { payer?: string; drug?: string; ndc?: string }) {
    const query: Record<string, string> = {};
    if (params?.payer) query.payer = params.payer;
    if (params?.drug) query.drug = params.drug;
    if (params?.ndc) query.ndc = params.ndc;
    return this._request("GET", "/api/v1/formulary", Object.keys(query).length ? query : undefined);
  }

  checkFormulary(params: {
    payer: string;
    drugName: string;
    medicationHistory?: Array<{ drug: string; status: string; reason?: string }>;
  }) {
    return this._request("POST", "/api/v1/formulary/check", undefined, {
      payer: params.payer,
      drug_name: params.drugName,
      ...(params.medicationHistory
        ? { patient_medication_history: params.medicationHistory }
        : {}),
    });
  }
}

Usage

example.ts
import { TalonClient, TalonError } from "./talon-client";

async function main() {
  const talon = new TalonClient({ apiKey: "tln_test_abc123..." });

  // Look up payer rules
  const rules = await talon.getRules("aetna", "27447");
  console.log(rules.approval_rate); // 0.84

  // Check submission readiness
  const readiness = await talon.checkReadiness({
    payer: "Aetna",
    cptCode: "27447",
    documentation: {
      has_clinical_notes: true,
      has_imaging: true,
      conservative_treatment_weeks: 8,
    },
  });
  console.log(readiness.ready_to_submit); // true

  // Generate an appeal letter
  try {
    const appeal = await talon.generateAppeal({
      payer: "UnitedHealthcare",
      cptCode: "27447",
      denialReason: "Insufficient conservative treatment documentation",
      denialCode: "J1",
      clinicalSummary: "67yo female, severe bilateral knee OA, KL Grade IV...",
    });
    console.log(appeal.appeal_letter);
  } catch (err) {
    if (err instanceof TalonError) {
      console.error(`[${err.code}] ${err.message}`);
      if (err.suggestion) console.error("Suggestion:", err.suggestion);
    }
  }
}
main();

PYPython

Requires the requests library (pip install requests).

Copy this into your project as talon_client.py.

talon_client.py
# talon_client.py — Talon API Client for Python
# Copy this file into your project. Requires: requests (pip install requests)

import requests as _requests
from typing import Optional, List, Dict, Any


class TalonError(Exception):
    def __init__(self, code: str, message: str, status: int, suggestion: Optional[str] = None):
        super().__init__(message)
        self.code = code
        self.status = status
        self.suggestion = suggestion


class TalonClient:
    def __init__(self, api_key: str, base_url: str = "https://talonapi.dev"):
        self.api_key = api_key
        self.base_url = base_url.rstrip("/")

    def _request(self, method: str, path: str, params: Optional[Dict[str, str]] = None, json: Optional[Dict[str, Any]] = None):
        url = f"{self.base_url}{path}"
        headers = {"X-API-Key": self.api_key}
        resp = _requests.request(method, url, headers=headers, params=params, json=json)
        data = resp.json()

        if not resp.ok:
            err = data.get("error", {})
            raise TalonError(
                code=err.get("code", "unknown_error"),
                message=err.get("message", resp.reason),
                status=resp.status_code,
                suggestion=err.get("suggestion"),
            )
        return data

    def health(self) -> Dict[str, Any]:
        return self._request("GET", "/api/v1/health")

    def get_rules(self, payer: str, cpt: str, clinical_context: Optional[str] = None) -> Dict[str, Any]:
        params = {"payer": payer, "cpt": cpt}
        if clinical_context:
            params["clinical_context"] = clinical_context
        return self._request("GET", "/api/v1/rules", params=params)

    def list_payers(self) -> Dict[str, Any]:
        return self._request("GET", "/api/v1/rules/payers")

    def list_cpt_codes(self) -> Dict[str, Any]:
        return self._request("GET", "/api/v1/rules/cpt-codes")

    def compare_payers(self, cpt: str) -> Dict[str, Any]:
        return self._request("GET", "/api/v1/compare", params={"cpt": cpt})

    def get_metrics(self, payer: Optional[str] = None) -> Dict[str, Any]:
        params = {"payer": payer} if payer else None
        return self._request("GET", "/api/v1/metrics", params=params)

    def generate_appeal(self, payer: str, cpt_code: str, denial_reason: str,
                        clinical_summary: str, denial_code: Optional[str] = None) -> Dict[str, Any]:
        body: Dict[str, Any] = {
            "payer": payer,
            "cpt_code": cpt_code,
            "denial_reason": denial_reason,
            "clinical_summary": clinical_summary,
        }
        if denial_code:
            body["denial_code"] = denial_code
        return self._request("POST", "/api/v1/appeals/generate", json=body)

    def check_readiness(self, payer: str, cpt_code: str, documentation: Dict[str, Any]) -> Dict[str, Any]:
        return self._request("POST", "/api/v1/rules/check", json={
            "payer": payer,
            "cpt_code": cpt_code,
            "available_documentation": documentation,
        })

    def get_formulary(self, payer: Optional[str] = None, drug: Optional[str] = None, ndc: Optional[str] = None) -> Dict[str, Any]:
        params: Dict[str, str] = {}
        if payer: params["payer"] = payer
        if drug: params["drug"] = drug
        if ndc: params["ndc"] = ndc
        return self._request("GET", "/api/v1/formulary", params=params or None)

    def check_formulary(self, payer: str, drug_name: str, medication_history: Optional[List[Dict[str, str]]] = None) -> Dict[str, Any]:
        body: Dict[str, Any] = {"payer": payer, "drug_name": drug_name}
        if medication_history:
            body["patient_medication_history"] = medication_history
        return self._request("POST", "/api/v1/formulary/check", json=body)

Usage

example.py
from talon_client import TalonClient, TalonError

talon = TalonClient(api_key="tln_test_abc123...")

# Look up payer rules
rules = talon.get_rules("aetna", "27447")
print(rules["approval_rate"])  # 0.84

# Check submission readiness
readiness = talon.check_readiness(
    payer="Aetna",
    cpt_code="27447",
    documentation={
        "has_clinical_notes": True,
        "has_imaging": True,
        "conservative_treatment_weeks": 8,
    },
)
print(readiness["ready_to_submit"])  # True

# Generate an appeal letter
try:
    appeal = talon.generate_appeal(
        payer="UnitedHealthcare",
        cpt_code="27447",
        denial_reason="Insufficient conservative treatment documentation",
        denial_code="J1",
        clinical_summary="67yo female, severe bilateral knee OA, KL Grade IV...",
    )
    print(appeal["appeal_letter"])
except TalonError as e:
    print(f"[{e.code}] {e}")
    if e.suggestion:
        print(f"Suggestion: {e.suggestion}")

SHcURL

For quick testing, scripts, and CI pipelines. Works with any system that has curl and optionally jq.

Set up your environment once, then copy any of the patterns below.

Setup

~/.bashrc or ~/.zshrc
# Save your API key as an environment variable
export TALON_API_KEY="tln_test_abc123..."

# Optional: create a shorthand alias
alias talon='curl -s -H "X-API-Key: $TALON_API_KEY"'

Common Patterns

curl examples
# Look up payer rules (pipe to jq for pretty output)
curl -s -H "X-API-Key: $TALON_API_KEY" \
  "https://talonapi.dev/api/v1/rules?payer=aetna&cpt=27447" | jq .

# List all supported payers
curl -s -H "X-API-Key: $TALON_API_KEY" \
  "https://talonapi.dev/api/v1/rules/payers" | jq '.payers[]'

# Compare payers for a CPT code
curl -s -H "X-API-Key: $TALON_API_KEY" \
  "https://talonapi.dev/api/v1/compare?cpt=27447" | jq '.payers[] | {payer, approval_rate}'

# Readiness check (one-liner)
curl -s -X POST "https://talonapi.dev/api/v1/rules/check" \
  -H "X-API-Key: $TALON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"payer":"Aetna","cpt_code":"27447","available_documentation":{"has_clinical_notes":true,"has_imaging":true,"conservative_treatment_weeks":8}}' \
  | jq '{ready: .ready_to_submit, score: .readiness_score, gaps: .blocking_gaps}'

# Check formulary coverage
curl -s "https://talonapi.dev/api/v1/formulary?payer=aetna&drug=humira" | jq .

With Alias

shorthand
# With the alias from above:
talon "https://talonapi.dev/api/v1/rules?payer=cigna&cpt=29881" | jq .

Need help?

These clients cover every endpoint in the Talon API. If you run into issues or want to see another language, reach out at support@talonapi.dev.