Python SDK
Official Verity SDK for Python with type hints and modern async support
The Verity Python SDK gives you clean, typed access to Medicare coverage intelligence. Built for data science workflows and backend services.
Installation
pip install verity-pythonRequires Python 3.8+. Works with any HTTP client under the hood (uses httpx).
Quick start
from verity import VerityClient
client = VerityClient(api_key="vrt_live_YOUR_API_KEY")
# Make your first request
health = client.health()
print(health["data"]["status"]) # "healthy"Get your API key from the Developer Console.
Authentication
from verity import VerityClient
import os
# Pass directly
client = VerityClient(api_key="vrt_live_YOUR_API_KEY")
# Or from environment
client = VerityClient(api_key=os.getenv("VERITY_API_KEY"))
# Custom base URL for testing
client = VerityClient(
api_key="vrt_live_YOUR_API_KEY",
base_url="https://staging.verity.backworkai.com/api/v1"
)Common scenarios
Check if a procedure needs prior auth
Most prior auth checks fail because you don't know what documentation to include. The API tells you exactly what's required.
result = client.check_prior_auth(
procedure_codes=["27447"], # Total knee replacement
diagnosis_codes=["M17.11"], # Unilateral primary osteoarthritis, right knee
state="TX"
)
if result["data"]["pa_required"]:
print(f"Warning: Prior authorization required")
print(f"Confidence: {result['data']['confidence']}")
print(f"Reason: {result['data']['reason']}")
# Show exact documentation requirements
print("\nYou need:")
for item in result["data"]["documentation_checklist"]:
print(f" • {item}")
# Show which policies triggered this
print(f"\nBased on {len(result['data']['matched_policies'])} policies:")
for policy in result["data"]["matched_policies"][:3]:
print(f" • {policy['policy_id']}: {policy['title']}")Output:
Warning: Prior authorization required
Confidence: high
Reason: Procedure requires review of medical necessity
You need:
• X-ray documentation showing degenerative joint disease
• Conservative treatment history (6+ weeks)
• Functional assessment scores
• BMI documentation
Based on 8 policies:
• L33822: Total Knee Replacement
• A57305: Billing and Coding: Joint ReplacementThe confidence field tells you how reliable this is. high means multiple policies agree. low means it's ambiguous or jurisdiction-dependent.
Look up codes with reimbursement data
result = client.lookup_code(
code="76942",
include=["rvu", "policies"]
)
code_data = result["data"]
print(f"{code_data['code']}: {code_data['description']}")
# RVU data is current year (2026)
if code_data.get("rvu"):
rvu = code_data["rvu"]
print(f"\nReimbursement:")
print(f" Work RVU: {rvu['work_rvu']}")
print(f" Facility: ${rvu['facility_price']}")
print(f" Non-facility: ${rvu['non_facility_price']}")
# Coverage policies show disposition by jurisdiction
if code_data.get("policies"):
print(f"\nCoverage: {len(code_data['policies'])} policies found")
covered = sum(1 for p in code_data["policies"] if p["disposition"] == "covered")
not_covered = sum(1 for p in code_data["policies"] if p["disposition"] == "not_covered")
print(f" Covered: {covered}")
print(f" Not covered: {not_covered}")
print(f" Conditional: {len(code_data['policies']) - covered - not_covered}")Search policies by keyword or semantically
# Keyword search (fast, exact matches)
result = client.list_policies(
q="continuous glucose monitoring",
policy_type="LCD",
status="active",
limit=10
)
print(f"Found {len(result['data'])} active LCDs\n")
for policy in result["data"]:
print(f"{policy['policy_id']}: {policy['title']}")
print(f" Jurisdiction: {policy.get('jurisdiction', 'National')}")
print(f" Effective: {policy.get('effective_date', 'N/A')}")Semantic search (slower but finds related concepts):
result = client.list_policies(
q="devices that monitor blood sugar levels",
mode="semantic", # Uses embedding similarity
limit=10
)Semantic search finds policies about CGM devices even though you didn't use the exact term. It's slower (~2-3x) but more flexible.
Compare coverage across MACs
Medicare coverage isn't national. A procedure covered in Texas (JM) might not be covered in Pennsylvania (J05).
result = client.compare_policies(
procedure_codes=["76942"],
jurisdictions=["J05", "J06", "J12", "JM"]
)
for juris in result["data"]["comparison"]:
print(f"\n{juris['jurisdiction']} - {juris['mac_name']}")
print(f"States: {', '.join(juris['states'])}")
print(f"Policies: {len(juris['policies'])}")
for policy in juris["policies"]:
print(f" • {policy['policy_id']}: {policy['disposition']}")This shows you exactly where coverage differs. Useful for multi-state practices or national payers.
Monitor policy changes
Policies change constantly. New LCDs get published, existing ones get retired, criteria get updated.
from datetime import datetime, timedelta
# Get changes from the last 7 days
seven_days_ago = (datetime.now() - timedelta(days=7)).isoformat() + "Z"
result = client.get_policy_changes(
since=seven_days_ago,
change_type="updated",
limit=20
)
print(f"Policy updates in the last 7 days: {len(result['data'])}\n")
for change in result["data"]:
print(f"{change['policy_id']}: {change['change_type']}")
print(f" {change.get('change_summary', 'No summary available')}")
print(f" {change['timestamp']}\n")Use this to stay current without manually checking payer portals.
Get full policy details with criteria
result = client.get_policy(
policy_id="L33831",
include=["criteria", "codes", "attachments"]
)
policy = result["data"]
print(f"{policy['title']}")
print(f"Type: {policy['policy_type']} | Status: {policy['status']}")
print(f"Effective: {policy.get('effective_date', 'N/A')}\n")
# Coverage criteria are AI-extracted from the PDF
if policy.get("criteria"):
print("Coverage Criteria:")
for section, blocks in policy["criteria"].items():
print(f"\n{section.upper()}:")
for block in blocks[:3]:
print(f" • {block.get('text', '')[:100]}...")
# Show which codes this policy covers
if policy.get("codes"):
print(f"\nCovers {len(policy['codes'])} codes:")
for code in policy["codes"][:10]:
print(f" • {code['code']} ({code['code_system']}): {code['disposition']}")The criteria field contains structured text blocks extracted from the policy PDF. They're tagged by section (indications, limitations, documentation, etc.) and searchable via the /coverage/criteria endpoint.
Search specific coverage criteria
Sometimes you need to find policies with specific requirements (e.g., BMI cutoffs, frequency limits).
result = client.search_criteria(
q="BMI greater than 40",
section="indications",
policy_type="LCD",
limit=10
)
print("Policies with BMI > 40 requirement:\n")
for criteria in result["data"]:
print(f"{criteria['policy_id']} ({criteria['section']})")
print(f" {criteria['text'][:150]}...")
print(f" Tags: {', '.join(criteria.get('tags', []))}\n")This is useful for finding policies with specific clinical criteria without reading every LCD.
List MAC jurisdictions
result = client.list_jurisdictions()
print("Medicare Administrative Contractors:\n")
for juris in result["data"]:
print(f"{juris['jurisdiction_code']}: {juris['mac_name']}")
print(f" States: {', '.join(juris.get('states', []))}")
print(f" Type: {juris.get('mac_type', 'N/A')}\n")Error handling
The SDK raises structured exceptions. Catch them specifically, not just generic Exception.
from verity import (
VerityClient,
VerityError,
AuthenticationError,
ValidationError,
NotFoundError,
RateLimitError
)
client = VerityClient(api_key="vrt_live_YOUR_API_KEY")
try:
result = client.lookup_code(code="INVALID")
except AuthenticationError:
print("Invalid API key")
except ValidationError as e:
print(f"Bad request: {e.message}")
if e.details:
print(f"Details: {e.details}")
except NotFoundError:
print("Code not found")
except RateLimitError as e:
print(f"Rate limited. Resets in {e.reset - time.time():.0f}s")
except VerityError as e:
print(f"API error: {e.message} (code: {e.code})")Don't catch VerityError at the top level unless you're doing generic error handling. Catch specific exceptions first.
Response format
All methods return dictionaries matching this structure:
{
"success": True,
"data": { ... }, # The actual response
"meta": {
"request_id": "req_...",
"timestamp": "2026-01-25T12:00:00Z"
}
}Error responses:
{
"success": False,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid parameter: code",
"hint": "Code must be a valid CPT, HCPCS, or ICD-10 code"
}
}Type hints
The SDK includes type hints for IDE autocomplete. Use them.
from verity import VerityClient
from typing import Dict, Any
client = VerityClient(api_key="vrt_live_YOUR_API_KEY")
# Type checker knows what parameters are valid
result: Dict[str, Any] = client.lookup_code(
code="76942",
include=["rvu", "policies"], # IDE suggests valid values
jurisdiction="JM",
fuzzy=True
)
# Access with confidence
if result["success"]:
description: str = result["data"]["description"]
found: bool = result["data"]["found"]Advanced configuration
Custom timeout
client = VerityClient(
api_key="vrt_live_YOUR_API_KEY",
timeout=60 # seconds
)Automatic retries
The SDK retries transient failures (rate limits, timeouts) with exponential backoff. Max 3 retries by default. This is automatic—you don't need to configure it.
What the SDK doesn't do
The SDK wraps the REST API. It doesn't:
- Cache responses (build your own cache if needed)
- Batch requests (send them concurrently if you need parallelism)
- Make coverage decisions (it returns what's in the policies, you interpret them)
These are intentional design choices. The SDK is low-level and unopinionated.
Resources
- PyPI: verity-python
- GitHub: Tylerbryy/verity-python
- API Reference: All Endpoints
- Issues: Report a bug