API Reference

Complete reference for the Talon API. Base URL: https://talonapi.dev

Authentication

Most endpoints require an API key passed via the X-API-Key header. Get your key from the developer dashboard.

Example
curl -H "X-API-Key: tln_live_abc123..." \
  "https://talonapi.dev/api/v1/rules?payer=aetna&cpt_code=27447"

Key format: Production keys start with tln_live_, sandbox keys with tln_test_.

Public endpoints (no authentication required): /api/v1/health, /api/v1/metrics, /api/v1/rules/payers, /api/v1/rules/cpt-codes, /api/v1/formulary, and /api/v1/openapi.

Rate Limits

All authenticated endpoints are rate-limited to 100 requests per minute per API key using a sliding window.

When you exceed the limit, the API returns 429 Too Many Requests with a Retry-After header indicating when to retry (in seconds).

Retry Safety

GET endpoints are safe to retry on timeout or network failure. POST endpoints (analyze-gaps, appeals/generate, rules/check, formulary/check) are NOT idempotent — retrying may consume additional credits. If a POST request times out, check your credit balance in the dashboard before retrying.

Sandbox Environment

API keys starting with tln_test_ operate in sandbox mode. Sandbox keys are designed for integration development and testing.

What sandbox keys do

  • Return realistic mock responses for all endpoints including gap analysis
  • Accept outcome reports (but do not affect intelligence signals)
  • Log usage to your dashboard
  • Enforce the same validation rules as production
  • Apply the same payer normalization as production

What sandbox keys do not do

  • Consume credits
  • Call the AI analysis engine (gap analysis returns mock data)
  • Trigger real Bedrock API calls
  • Affect production intelligence signals

Sandbox gap analysis behavior

Mock responses vary based on the length and apparent completeness of the clinical_text you submit. Longer, more detailed notes return higher scores and fewer flagged requirements. This lets you test how your application handles different result states without using live credits.

To test specific scenarios, use notes of these approximate lengths:

Note lengthScoreTraffic light
Short incomplete (<200 chars)~40red
Medium (200–500 chars)~65yellow
Detailed (500–1000 chars)~78yellow
Comprehensive (>1000 chars)~91green

Sandbox mode enforces the same payer normalization as production. Submitting an unknown payer name will return a payer_not_found error, just like production. PHI scanning is skipped for sandbox requests, making it safe to test with sample clinical notes.

Data Trust

Talon API sources data from official payer policy documents and public CMS datasets. All rule data used in calculations, approval rates, and readiness checks comes from verified, authoritative sources.

Every API response that returns rule data includes a metadata object so you always know where the data came from and when it was last verified.

metadata in response
"metadata": {
  "source": "Aetna Clinical Policy Bulletin",
  "last_verified": "2026-02-15T00:00:00.000Z"
}

Errors & Handling

All errors follow a consistent JSON structure with an error code, message, and optional fix suggestion.

Error response
{
  "error": {
    "code": "invalid_api_key",
    "message": "The provided API key is invalid or has been revoked.",
    "request_id": "req_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "suggestion": "Check that your API key is correct. Keys start with tln_live_ or tln_test_."
  }
}
CodeStatusDescription
invalid_api_key401API key is missing, invalid, or revoked
api_key_expired401API key has expired — generate a new one from the dashboard
insufficient_credits402Not enough credits for this request
not_found404Requested resource not found
payer_not_found404Unknown or unsupported payer name — check /v1/rules/payers
validation_failed422Missing or invalid parameters
phi_detected422Request contains HIPAA identifiers (appeals and analyze-gaps endpoints)
rate_limit_exceeded429Too many requests — check Retry-After header
internal_error500Unexpected server error

PHI Detection

The appeals and gap analysis endpoints scan clinical_text and clinical_summary fields for HIPAA identifiers before processing. Detected identifiers cause an immediate 422 rejection — no credits are charged.

  • Patient names (first, last, full)
  • Dates of birth
  • Social Security numbers
  • Medical record numbers (MRN)
  • Health plan beneficiary numbers
  • Phone numbers and email addresses
  • Street addresses

To test your de-identification pipeline, use sandbox mode (tln_test_ keys). Sandbox requests skip PHI scanning, so you can verify your workflow end-to-end before switching to live keys.

Handling Errors in Code

Always check the HTTP status code before parsing the response body. Here are patterns for common error scenarios:

JavaScript — error handling
async function callTalon(path, apiKey) {
  const res = await fetch(`https://talonapi.dev${path}`, {
    headers: { "X-API-Key": apiKey }
  });

  if (!res.ok) {
    const body = await res.json();
    const err = body.error;

    switch (res.status) {
      case 401:
        throw new Error(`Auth failed: ${err.message}`);
      case 402:
        // Redirect user to purchase credits
        throw new Error("Insufficient credits");
      case 429:
        // Retry after the specified delay
        const retryAfter = res.headers.get("Retry-After") || "60";
        await new Promise(r => setTimeout(r, parseInt(retryAfter) * 1000));
        return callTalon(path, apiKey); // retry once
      default:
        throw new Error(`Talon API error: ${err.code} — ${err.message}`);
    }
  }

  return res.json();
}
Python — error handling
import requests
import time

def call_talon(path, api_key, retry=True):
    res = requests.get(
        f"https://talonapi.dev{path}",
        headers={"X-API-Key": api_key}
    )

    if res.status_code == 429 and retry:
        wait = int(res.headers.get("Retry-After", 60))
        time.sleep(wait)
        return call_talon(path, api_key, retry=False)

    if not res.ok:
        err = res.json().get("error", {})
        raise Exception(f"Talon API {err.get('code')}: {err.get('message')}")

    return res.json()

Rate limit headers: Every authenticated response includes these headers:

HeaderDescription
X-RateLimit-LimitMax requests per window (100)
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp when the window resets
Retry-AfterSeconds to wait (only on 429 responses)

Endpoints

GET/api/v1/health

Returns API status. No authentication required.

No AuthFree
curl
curl https://talonapi.dev/api/v1/health
JavaScript
const res = await fetch("https://talonapi.dev/api/v1/health");
const data = await res.json();
console.log(data.status); // "ok"
Python
import requests

res = requests.get("https://talonapi.dev/api/v1/health")
print(res.json()["status"])  # "ok"
Response
{
  "status": "ok",
  "version": "1.0.0",
  "timestamp": "2026-02-28T12:00:00.000Z"
}

GET/api/v1/rules

Look up payer requirements for a specific CPT code. Returns documentation requirements, blocking rules, approval rates, and denial patterns.

Auth Required
ParameterTypeRequiredDescription
payerstringRequiredPayer name (e.g. "aetna", "unitedhealthcare")
cpt_codestringRequiredCPT procedure code (e.g. "27447"). Also accepts "cpt" as a backward-compatible alias.
clinical_contextstringOptionalOne of "elective" (default), "urgent", or "emergency". Urgent/emergency may suppress blocking requirements for exempt procedures.
curl
curl -H "X-API-Key: tln_live_abc123..." \
  "https://talonapi.dev/api/v1/rules?payer=aetna&cpt_code=27447"
curl (emergency context)
curl -H "X-API-Key: tln_live_abc123..." \
  "https://talonapi.dev/api/v1/rules?payer=aetna&cpt_code=29877&clinical_context=emergency"
JavaScript
const res = await fetch(
  "https://talonapi.dev/api/v1/rules?payer=aetna&cpt_code=27447",
  { headers: { "X-API-Key": "tln_live_abc123..." } }
);
const data = await res.json();
console.log(data.approval_rate);       // 0.84
console.log(data.required_docs);       // ["Clinical notes", ...]
Python
import requests

res = requests.get(
    "https://talonapi.dev/api/v1/rules",
    params={"payer": "aetna", "cpt_code": "27447"},
    headers={"X-API-Key": "tln_live_abc123..."}
)
print(res.json()["required_docs"])  # ["Clinical notes", ...]
Response
{
  "payer": "Aetna",
  "cpt_code": "27447",
  "description": "Total Knee Replacement",
  "required_docs": [
    "Clinical notes",
    "Conservative treatment history",
    "Imaging reports"
  ],
  "blocking_requirements": [
    "6+ weeks documented conservative treatment",
    "BMI documented",
    "Functional limitation score"
  ],
  "soft_requirements": [
    "Physical therapy notes",
    "Failed medication list"
  ],
  "typical_turnaround_days": 5,
  "approval_rate": 0.84,
  "common_denial_reasons": [
    {
      "reason": "Insufficient conservative treatment documentation"
    }
  ],
  "last_updated": "2026-02-15T00:00:00.000Z",
  "conservative_treatment_required": true,
  "conservative_treatment_weeks": 6,
  "clinical_context": "elective",
  "emergency_exempt": false,
  "urgent_exempt": false
}

Context suppression: When clinical_context=emergency and the procedure is emergency-exempt, blocking_requirements and soft_requirements are cleared and typical_turnaround_days is set to 0. When clinical_context=urgent and the procedure is urgent-exempt, blocking_requirements are cleared and turnaround is capped at 2 days.

GET/api/v1/rules/payers

List all supported payer names. Public discovery endpoint — no authentication required.

No AuthFree
curl
curl "https://talonapi.dev/api/v1/rules/payers"
JavaScript
const res = await fetch("https://talonapi.dev/api/v1/rules/payers");
const { payers, count } = await res.json();
Python
import requests

res = requests.get("https://talonapi.dev/api/v1/rules/payers")
payers = res.json()["payers"]
Response
{
  "payers": ["Aetna", "Blue Cross Blue Shield", "Cigna", "Humana", "UnitedHealthcare"],
  "count": 5
}

GET/api/v1/rules/cpt-codes

List all supported CPT codes with descriptions. Public discovery endpoint — no authentication required.

No AuthFree
curl
curl "https://talonapi.dev/api/v1/rules/cpt-codes"
JavaScript
const res = await fetch("https://talonapi.dev/api/v1/rules/cpt-codes");
const { cpt_codes } = await res.json();
Python
import requests

res = requests.get("https://talonapi.dev/api/v1/rules/cpt-codes")
codes = res.json()["cpt_codes"]
Response
{
  "cpt_codes": [
    { "cpt_code": "27447", "description": "Total Knee Replacement" },
    { "cpt_code": "29881", "description": "Knee Arthroscopy with Meniscectomy" },
    { "cpt_code": "63030", "description": "Lumbar Discectomy" }
  ],
  "count": 3
}

GET/api/v1/compare

Compare approval rates across all payers for a specific CPT code.

Auth Required
ParameterTypeRequiredDescription
cpt_codestringRequiredCPT procedure code (e.g. "27447"). Also accepts "cpt" as a backward-compatible alias.
curl
curl -H "X-API-Key: tln_live_abc123..." \
  "https://talonapi.dev/api/v1/compare?cpt_code=27447"
JavaScript
const res = await fetch(
  "https://talonapi.dev/api/v1/compare?cpt_code=27447",
  { headers: { "X-API-Key": "tln_live_abc123..." } }
);
const { payers } = await res.json();
Python
import requests

res = requests.get(
    "https://talonapi.dev/api/v1/compare",
    params={"cpt_code": "27447"},
    headers={"X-API-Key": "tln_live_abc123..."}
)
payers = res.json()["payers"]
Response
{
  "cpt_code": "27447",
  "payers": [
    {
      "payer": "Aetna",
      "approval_rate": 0.84,
      "conservative_treatment_weeks": 6
    },
    {
      "payer": "UnitedHealthcare",
      "approval_rate": 0.78,
      "conservative_treatment_weeks": 12
    },
    {
      "payer": "Cigna",
      "approval_rate": 0.81,
      "conservative_treatment_weeks": 8
    }
  ],
  "count": 3
}

GET/api/v1/metrics

CMS-mandated payer prior authorization metrics. Public data, no authentication required, no credits charged.

No AuthFree
ParameterTypeRequiredDescription
payerstringOptionalFilter by payer name (partial match, case-insensitive)
curl
curl "https://talonapi.dev/api/v1/metrics?payer=aetna"
JavaScript
const res = await fetch("https://talonapi.dev/api/v1/metrics?payer=aetna");
const { metrics } = await res.json();
Python
import requests

res = requests.get(
    "https://talonapi.dev/api/v1/metrics",
    params={"payer": "aetna"}
)
metrics = res.json()["metrics"]
Response
{
  "metrics": [
    {
      "payer_name": "Aetna",
      "reporting_year": 2025,
      "pct_approved_standard": 85.3,
      "pct_denied_standard": 14.7,
      "pct_approved_after_appeal": 42.1,
      "avg_days_to_decision": 4.8,
      "source_url": "https://www.aetna.com/about-us/prior-authorization-metrics.html",
      "scraped_at": "2026-02-28T00:00:00.000Z"
    }
  ],
  "count": 1
}

POST/api/v1/appeals/generate

Generate an AI-powered appeal letter for a denied prior authorization. Uses historical denial pattern data for context.

Auth Required

PHI Policy: The clinical_summary must be de-identified. Requests containing patient names, dates of birth, SSNs, or member IDs will be rejected with a phi_detected error.

ParameterTypeRequiredDescription
payerstringRequiredPayer name (e.g. "UnitedHealthcare")
cpt_codestringRequiredCPT code of the denied procedure
denial_reasonstringRequiredReason for denial from the payer
denial_codestringOptionalPayer denial code (e.g. "J1")
clinical_summarystringRequiredDe-identified clinical summary
curl
curl -X POST "https://talonapi.dev/api/v1/appeals/generate" \
  -H "X-API-Key: tln_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "payer": "UnitedHealthcare",
    "cpt_code": "27447",
    "denial_reason": "Insufficient documentation of conservative treatment",
    "denial_code": "J1",
    "clinical_summary": "Patient is 67yo female with severe bilateral knee OA, Kellgren-Lawrence Grade IV. Failed 6 months PT, NSAIDs, and corticosteroid injections."
  }'
JavaScript
const res = await fetch("https://talonapi.dev/api/v1/appeals/generate", {
  method: "POST",
  headers: {
    "X-API-Key": "tln_live_abc123...",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    payer: "UnitedHealthcare",
    cpt_code: "27447",
    denial_reason: "Insufficient documentation of conservative treatment",
    denial_code: "J1",
    clinical_summary: "Patient is 67yo female with severe bilateral knee OA..."
  })
});
const data = await res.json();
Python
import requests

res = requests.post(
    "https://talonapi.dev/api/v1/appeals/generate",
    headers={"X-API-Key": "tln_live_abc123..."},
    json={
        "payer": "UnitedHealthcare",
        "cpt_code": "27447",
        "denial_reason": "Insufficient documentation of conservative treatment",
        "denial_code": "J1",
        "clinical_summary": "Patient is 67yo female with severe bilateral knee OA..."
    }
)
letter = res.json()["appeal_letter"]
Response
{
  "appeal_letter": "Dear Medical Director, I am writing to appeal the denial...",
  "key_arguments": [
    "6 months PT documented",
    "Failed NSAID therapy",
    "Kellgren-Lawrence Grade IV"
  ],
  "success_probability": 0.72
}

POST/api/v1/analyze-gaps

Send a clinical note and get a detailed gap analysis against payer-specific requirements. Returns a readiness status, flagged items with fix suggestions, and contraindication screens.

Auth Required

PHI Policy: The clinical_text must be de-identified. Requests containing patient names, dates of birth, Social Security numbers, medical record numbers, health plan beneficiary numbers, or other HIPAA identifiers will be rejected with a phi_detected error.

ParameterTypeRequiredDescription
clinical_textstringRequiredDe-identified clinical note content (max 50,000 characters)
payerstringRequiredPayer name (e.g. "aetna", case-insensitive)
cpt_codestringRequiredCPT procedure code (e.g. "27447")
submission_datestringOptionalISO date (YYYY-MM-DD). Defaults to today.
curl
curl -X POST "https://talonapi.dev/api/v1/analyze-gaps" \
  -H "X-API-Key: tln_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "clinical_text": "67yo female presenting with severe bilateral knee OA, Kellgren-Lawrence Grade IV. BMI 28.3. Failed 8 weeks physical therapy, 6 weeks NSAIDs (ibuprofen 800mg TID), and 2 corticosteroid injections. Functional limitation: unable to walk >1 block. VAS pain score 8/10.",
    "payer": "aetna",
    "cpt_code": "27447"
  }'
JavaScript
const res = await fetch("https://talonapi.dev/api/v1/analyze-gaps", {
  method: "POST",
  headers: {
    "X-API-Key": "tln_live_abc123...",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    clinical_text: "67yo female presenting with severe bilateral knee OA...",
    payer: "aetna",
    cpt_code: "27447"
  })
});
const data = await res.json();
console.log(data.analysis.status); // readiness status
console.log(data.analysis.flagged_items); // items needing attention
Python
import requests

res = requests.post(
    "https://talonapi.dev/api/v1/analyze-gaps",
    headers={"X-API-Key": "tln_live_abc123..."},
    json={
        "clinical_text": "67yo female presenting with severe bilateral knee OA...",
        "payer": "aetna",
        "cpt_code": "27447"
    }
)
analysis = res.json()["analysis"]
print(analysis["status"])  # readiness status
Response
{
  "payer": "Aetna",
  "cpt_code": "27447",
  "procedure": "Total Knee Replacement",
  "analysis": {
    "status": "yellow",
    "recommendation": "Most requirements met. Address 1 missing item before submission.",
    "summary": {
      "met": 5,
      "missing": 1,
      "partial": 1,
      "not_applicable": 0
    },
    "flagged_items": [
      {
        "requirement": "Functional limitation score documented",
        "status": "partial",
        "found_instead": "VAS pain score 8/10, unable to walk >1 block",
        "why_insufficient": "VAS is a pain scale, not a functional limitation instrument (e.g. WOMAC, KOOS)",
        "fix": "Add a standardized functional assessment score (WOMAC, KOOS-JR, or similar)"
      },
      {
        "requirement": "Failed medication list with dosages and durations",
        "status": "missing",
        "fix": "Document each failed medication with exact dosage, frequency, duration, and reason for discontinuation"
      }
    ],
    "full_analysis": [
      {
        "requirement": "Conservative treatment >= 6 weeks",
        "status": "met",
        "evidence": "Failed 8 weeks physical therapy",
        "confidence": "high"
      },
      {
        "requirement": "BMI documented",
        "status": "met",
        "evidence": "BMI 28.3",
        "confidence": "high"
      }
    ]
  },
  "requirements_count": 7,
  "latency_ms": 2340
}

Readiness status: The status field indicates overall submission readiness. Use the flagged_items array to show clinicians exactly what needs to be added or corrected, with specific fix suggestions.

POST/api/v1/rules/check

Moment 1 readiness check. Given a payer, CPT code, and available documentation, returns whether the submission is ready, what gaps exist, and approval probability.

Auth Required
ParameterTypeRequiredDescription
payerstringRequiredPayer name (e.g. "Aetna")
cpt_codestringRequiredCPT procedure code
available_documentationobjectOptionalObject with boolean/number fields: has_clinical_notes, has_imaging, has_conservative_treatment_docs, conservative_treatment_weeks, has_bmi, has_functional_score, has_failed_medication_list
curl
curl -X POST "https://talonapi.dev/api/v1/rules/check" \
  -H "X-API-Key: tln_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "payer": "Aetna",
    "cpt_code": "27447",
    "available_documentation": {
      "has_clinical_notes": true,
      "has_imaging": true,
      "has_conservative_treatment_docs": true,
      "conservative_treatment_weeks": 8,
      "has_bmi": false
    }
  }'
JavaScript
const res = await fetch("https://talonapi.dev/api/v1/rules/check", {
  method: "POST",
  headers: {
    "X-API-Key": "tln_live_abc123...",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    payer: "Aetna",
    cpt_code: "27447",
    available_documentation: {
      has_clinical_notes: true,
      has_imaging: true,
      has_conservative_treatment_docs: true,
      conservative_treatment_weeks: 8
    }
  })
});
const data = await res.json();
console.log(data.ready_to_submit); // true
Python
import requests

res = requests.post(
    "https://talonapi.dev/api/v1/rules/check",
    headers={"X-API-Key": "tln_live_abc123..."},
    json={
        "payer": "Aetna",
        "cpt_code": "27447",
        "available_documentation": {
            "has_clinical_notes": True,
            "has_imaging": True,
            "has_conservative_treatment_docs": True,
            "conservative_treatment_weeks": 8
        }
    }
)
print(res.json()["ready_to_submit"])  # True
Response
{
  "ready_to_submit": true,
  "readiness_score": 0.75,
  "blocking_gaps": [],
  "satisfied_requirements": [
    "Clinical notes included",
    "Imaging documentation included",
    "Conservative treatment documented (8 weeks)"
  ],
  "recommended_additions": [
    "Include functional limitation score",
    "Include failed medication list"
  ],
  "approval_probability": 0.84,
  "estimated_turnaround_days": 5,
  "common_denial_reasons": [
    { "reason": "Insufficient conservative treatment documentation" }
  ],
  "metadata": {
    "source": "Aetna Clinical Policy Bulletin",
    "last_verified": "2026-02-15T00:00:00.000Z"
  }
}

GET/api/v1/formulary

Look up medication formulary data. Returns coverage tier, prior auth requirements, step therapy requirements, and quantity limits. Public endpoint, no authentication required.

No AuthFree
ParameterTypeRequiredDescription
payerstringOptionalFilter by payer name (partial match)
drugstringOptionalFilter by drug or generic name (partial match)
ndcstringOptionalFilter by exact NDC code
curl
curl "https://talonapi.dev/api/v1/formulary?payer=aetna&drug=humira"
Response
{
  "formulary": [
    {
      "payer_name": "Aetna",
      "drug_name": "Humira",
      "ndc_code": "00074-4339-02",
      "generic_name": "adalimumab",
      "formulary_tier": "specialty",
      "prior_auth_required": true,
      "step_therapy_required": true,
      "step_therapy_drugs": [
        { "drug": "methotrexate", "status": "must_have_tried" },
        { "drug": "sulfasalazine", "status": "must_have_tried" }
      ],
      "quantity_limit": "2 pens per 28 days",
      "clinical_criteria": "Diagnosis of RA, PsA, or Crohn disease with documented failure of conventional DMARDs",
      "exception_process": "Submit exception request with clinical documentation",
      "source_url": "https://www.aetna.com/formulary/2026",
      "last_verified": "2026-02-20T00:00:00.000Z"
    }
  ],
  "count": 1
}

POST/api/v1/formulary/check

Moment 1 formulary readiness check. Given a payer, drug, and patient medication history, returns whether the drug is ready to prescribe and what step therapy requirements remain.

Auth Required
ParameterTypeRequiredDescription
payerstringRequiredPayer name
drug_namestringOptionalDrug name (required if no ndc_code)
ndc_codestringOptionalNDC code (required if no drug_name)
patient_medication_historyarrayOptionalArray of { drug, status, reason } objects
curl
curl -X POST "https://talonapi.dev/api/v1/formulary/check" \
  -H "X-API-Key: tln_live_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "payer": "Aetna",
    "drug_name": "Humira",
    "patient_medication_history": [
      { "drug": "methotrexate", "status": "failed", "reason": "Inadequate response after 12 weeks" }
    ]
  }'
Response
{
  "covered": true,
  "prior_auth_required": true,
  "step_therapy_required": true,
  "step_therapy_status": {
    "steps_required": [
      { "drug": "methotrexate", "status": "must_have_tried" },
      { "drug": "sulfasalazine", "status": "must_have_tried" }
    ],
    "steps_completed": ["methotrexate"],
    "steps_remaining": [
      { "drug": "sulfasalazine", "action": "Trial of sulfasalazine required before Humira" }
    ]
  },
  "quantity_limits": "2 pens per 28 days",
  "ready_to_prescribe": false,
  "recommendation": "Step therapy required: complete trial of sulfasalazine before requesting Humira.",
  "metadata": {
    "source": "Aetna Formulary",
    "last_verified": "2026-02-20T00:00:00.000Z"
  }
}