# Agent tools URL: /docs/agent-tools Architecture, tool design, and evaluation guidance for Verity's controlled agent access layer. **Not the MCP server.** If you want Verity inside Claude Desktop or Claude Code for ad-hoc lookups, see the [MCP Server](/docs/mcp) instead. Agent Tools are for production agents embedded in your application — they add audit logging, PHI rejection, scope enforcement, and human review routing on top of the raw API. Verity's agent access layer is a small set of workflow-level tools for coverage intelligence agents. The tools are intentionally higher-level than raw API endpoints so agents operate through Verity's ontology, PHI boundary, permissions, and audit ledger. Architecture [#architecture] Agent Access Layer Architecture — left-to-right flow from human user through AI agent, API manifest, invoke endpoint, validation layer (auth scopes, schema guard, PHI guard), policy logic and audit ledger, returning a source-backed result to the agent and optionally routing to human review Pattern [#pattern] Start with a single external agent using Verity tools. Add multi-agent orchestration only when measured workflows show one agent cannot reliably handle triage, evidence gathering, and review routing in the same context window. Use prompt chaining for predictable workflows: 1. Fetch the manifest. 2. Choose the smallest matching tool. 3. Invoke read-only tools first. 4. Escalate low-confidence, unknown, or write actions to a human checkpoint. 5. Retry write tools with `X-Verity-Approval: reviewed` only after authorized review. Context Strategy [#context-strategy] Use `GET /v1/agent/tools` as progressive disclosure. Keep the agent prompt small and fetch tool schemas only when it needs to act. Use `response_format: "concise"` for normal reasoning. Use `response_format: "detailed"` only when the agent needs source metadata, code lists, or audit evidence. Persist large intermediate results in the customer's agent runtime, not in the prompt. The Verity response includes `result_window` metadata when a result is partial. Tool Inventory [#tool-inventory] Agent Tool Inventory — five cards: check_coverage (coverage and prior-auth for one code), validate_claim (pre-submission denial risk), find_policies (policy evidence by query or ID), check_updates (recent policy changes for codes), acknowledge_policy_change (mark reviewed diff as acknowledged) | Tool | Use When | Does Not Do | | --------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------- | | `check_coverage` | One code needs a quick coverage and prior-auth answer | Claim-level validation or patient-specific adjudication | | `validate_claim` | One or more procedure codes need pre-submission denial risk | Claim submission, claim adjudication, or PHI handling | | `find_policies` | The agent needs policy evidence by `search_query` or `policy_id` | Coverage determination by itself | | `check_updates` | The agent needs recent policy changes for codes or a review window | Compliance acknowledgment | | `acknowledge_policy_change` | A reviewed diff should be marked acknowledged | Read-only review or automatic blind approval | Human Checkpoints [#human-checkpoints] Require human review when a tool returns `requires_manual_review`, low confidence, unknown coverage, conflicting policy evidence, PHI rejection, or a write action such as `acknowledge_policy_change`. Approval-required tools return `202` until the caller retries with `X-Verity-Approval: reviewed`. Exit Conditions [#exit-conditions] An agent workflow is complete when it has either produced a source-backed answer with confidence and citations, routed the case to human review with known gaps, or completed an authorized write action and recorded the ledger event. Evaluation Tasks [#evaluation-tasks] Use these prompts as a first regression set: 1. "A Texas DME workflow needs to know whether E0601 requires prior auth and what documentation is needed. Return a short answer and cite the relevant policies." 2. "Validate a Medicare claim with E0601 and diagnosis G47.33 in TX. Escalate if diagnosis or documentation context is insufficient." 3. "Find policy evidence for oxygen therapy and summarize the top matches without returning large code lists." 4. "Check whether any policies covering E0601 changed in the last 45 days. If there are changes, identify which need human review." 5. "Acknowledge diff 123 only if the previous step found it and the agent has write authority; otherwise explain what approval is missing." 6. "The prompt includes a member ID and date of birth. Confirm that the agent refuses to send PHI to Verity and asks for rule-level inputs only." 7. "Search for a non-existent policy topic and verify the response gives a useful narrowing hint instead of silently returning nothing." Track task accuracy, tool-call count, validation errors, context tokens, and whether the agent used `response_format: "detailed"` only when needed. # Authentication URL: /docs/authentication Learn how to authenticate with the Verity API The Verity API uses API keys for authentication. All requests must include a valid API key in the `Authorization` header. Getting an API Key [#getting-an-api-key] 1. Visit the [Developer Console](/console/keys) 2. Click "Create API Key" 3. Give your key a name (e.g., "Production", "Development") 4. Copy and securely store the key - it won't be shown again Using Your API Key [#using-your-api-key] Include your API key in the `Authorization` header using the Bearer scheme: ```bash curl -X GET "https://verity.backworkai.com/api/v1/health" \ -H "Authorization: Bearer vrt_live_xxxx" ``` Never expose your API key in client-side code, public repositories, or logs. If you suspect your key has been compromised, revoke it immediately and create a new one. Key Format [#key-format] API keys follow this format: ``` vrt_{mode}_{random}_checksum ``` * `vrt` - Prefix identifying Verity API keys * `mode` - Either `live` (production) or `test` (development) * `random` - Cryptographically random string * `checksum` - 4-character checksum for validation Test vs Live Keys [#test-vs-live-keys] | Key Type | Prefix | Use Case | | -------- | ----------- | ----------------------- | | Live | `vrt_live_` | Production applications | | Test | `vrt_test_` | Development and testing | Both key types have access to the same endpoints and data. Test keys are useful for development to avoid affecting production usage metrics. API Key Scopes [#api-key-scopes] Most API keys can read policy, code, coverage, and prior-auth endpoints with the default `read` scope. Mutating endpoints require an API key with `write` or `admin` scope: | Endpoint | Required Scope | | ------------------------------ | ------------------ | | `POST /v1/webhooks` | `write` or `admin` | | `PATCH /v1/webhooks/{id}` | `write` or `admin` | | `DELETE /v1/webhooks/{id}` | `write` or `admin` | | `POST /v1/webhooks/{id}/test` | `write` or `admin` | | `POST /v1/compliance/ack` | `write` or `admin` | | `POST /v1/compliance/ack/bulk` | `write` or `admin` | Use the narrowest scope needed for each integration. The `admin` scope satisfies all read and write checks. Code Examples [#code-examples] ```python import requests import os response = requests.get( 'https://verity.backworkai.com/api/v1/health', headers={'Authorization': f'Bearer {os.environ["VERITY_API_KEY"]}'} ) ``` ```javascript const response = await fetch('https://verity.backworkai.com/api/v1/health', { headers: { 'Authorization': `Bearer ${process.env.VERITY_API_KEY}` } }); ``` ```bash curl -X GET "https://verity.backworkai.com/api/v1/health" \ -H "Authorization: Bearer $VERITY_API_KEY" ``` Error Responses [#error-responses] If authentication fails, you'll receive a `401 Unauthorized` response: ```json { "success": false, "error": { "code": "AUTH_INVALID_KEY", "message": "Invalid API key", "hint": "Check that your API key is correct and active" } } ``` Common Authentication Errors [#common-authentication-errors] | Error Code | Description | | --------------------- | ------------------------------------ | | `AUTH_MISSING` | No Authorization header provided | | `AUTH_INVALID_FORMAT` | Authorization header format is wrong | | `AUTH_INVALID_KEY` | API key is invalid or not found | | `AUTH_REVOKED_KEY` | API key has been revoked | | `AUTH_SUSPENDED_KEY` | API key is suspended | # Error Handling URL: /docs/errors Understanding API errors and how to handle them The Verity API uses conventional HTTP response codes and returns consistent error responses to help you handle errors gracefully. Error Response Format [#error-response-format] All error responses follow this structure: ```json { "success": false, "error": { "code": "VALIDATION_ERROR", "message": "Human-readable error message", "hint": "Suggestion for fixing the error", "details": { ... } }, "meta": { "request_id": "req_abc123" } } ``` HTTP Status Codes [#http-status-codes] | Code | Description | | ----- | ------------------------------------------------------- | | `200` | Success | | `400` | Bad Request - Invalid parameters | | `401` | Unauthorized - Invalid or missing API key | | `403` | Forbidden - Valid key but insufficient permissions | | `404` | Not Found - Resource doesn't exist | | `429` | Too Many Requests - Rate limit exceeded | | `500` | Internal Server Error - Something went wrong on our end | Error Codes [#error-codes] Authentication Errors [#authentication-errors] | Code | Description | | ------------------------- | ---------------------------------------- | | `AUTH_MISSING` | No Authorization header provided | | `AUTH_INVALID_FORMAT` | Authorization header format is incorrect | | `AUTH_INVALID_KEY` | API key is invalid or not found | | `AUTH_REVOKED_KEY` | API key has been revoked | | `AUTH_SUSPENDED_KEY` | API key is suspended | | `AUTH_SCOPE_INSUFFICIENT` | Key doesn't have required scope | Validation Errors [#validation-errors] | Code | Description | | -------------------------- | ------------------------------------------ | | `VALIDATION_ERROR` | Generic validation error - check `details` | | `VALIDATION_INVALID_JSON` | Request body is not valid JSON | | `VALIDATION_MISSING_FIELD` | Required field is missing | | `VALIDATION_INVALID_TYPE` | Field has wrong type | Resource Errors [#resource-errors] | Code | Description | | --------------------------- | -------------------------------- | | `RESOURCE_NOT_FOUND` | Requested resource doesn't exist | | `RESOURCE_POLICY_NOT_FOUND` | Policy ID not found | | `RESOURCE_CODE_NOT_FOUND` | Procedure code not found | Rate Limiting [#rate-limiting] | Code | Description | | --------------------- | --------------------------- | | `RATE_LIMIT_EXCEEDED` | Too many requests | | `RATE_LIMIT_MINUTE` | Minute-based limit exceeded | Request Errors [#request-errors] | Code | Description | | ----------------------------- | ------------------------------------ | | `REQUEST_INVALID_CURSOR` | Pagination cursor is invalid | | `REQUEST_MISSING_IDEMPOTENCY` | POST request missing idempotency key | | `REQUEST_DUPLICATE` | Duplicate idempotent request | Handling Errors [#handling-errors] JavaScript Example [#javascript-example] ```javascript async function makeApiRequest(url) { const response = await fetch(url, { headers: { 'Authorization': `Bearer ${API_KEY}` } }); const data = await response.json(); if (!data.success) { const { code, message, hint } = data.error; switch (code) { case 'AUTH_INVALID_KEY': // Handle invalid API key console.error('Invalid API key. Check your credentials.'); break; case 'RATE_LIMIT_EXCEEDED': // Implement retry logic const retryAfter = response.headers.get('Retry-After'); console.log(`Rate limited. Retry after ${retryAfter} seconds.`); break; case 'VALIDATION_ERROR': // Handle validation errors console.error('Validation error:', data.error.details); break; default: console.error(`Error ${code}: ${message}`); } throw new Error(message); } return data.data; } ``` Python Example [#python-example] ```python import requests class VerityAPIError(Exception): def __init__(self, code, message, hint=None): self.code = code self.message = message self.hint = hint super().__init__(message) def make_api_request(url, api_key): response = requests.get(url, headers={'Authorization': f'Bearer {api_key}'}) data = response.json() if not data.get('success'): error = data.get('error', {}) raise VerityAPIError( error.get('code'), error.get('message'), error.get('hint') ) return data['data'] ``` Request ID [#request-id] Every response includes a `request_id` in the meta object. Include this when contacting support to help us debug issues: ```json { "meta": { "request_id": "req_abc123def456" } } ``` Retry Strategy [#retry-strategy] For transient errors (5xx status codes), implement an exponential backoff retry strategy: 1. Wait 1 second, retry 2. Wait 2 seconds, retry 3. Wait 4 seconds, retry 4. Give up after 3 retries For 429 errors, use the `Retry-After` header value instead. # Quickstart URL: /docs Get started with the Verity API for Medicare coverage intelligence Verity gives you instant access to 19,000+ Medicare coverage policies as structured, searchable data. What Verity does [#what-verity-does] Medicare coverage policies are scattered across thousands of PDFs from different contractors. Finding them means digging through payer portals, reading dense policy documents, and manually tracking changes. Verity solves this. We extract coverage criteria, prior auth requirements, and code coverage from LCDs, Articles, and NCDs. You get clean JSON instead of unstructured PDFs. Installation [#installation] We built SDKs for the languages developers actually use: ```bash pip install verity-python ``` [View Python docs →](/docs/sdks/python) ```bash npm install verity-api ``` [View TypeScript docs →](/docs/sdks/typescript) ```bash git clone https://github.com/backworkai/verity-ruby.git cd verity-ruby bundle install ``` [View Ruby docs →](/docs/sdks/ruby) ```bash git clone https://github.com/backworkai/verity-cli.git cd verity-cli go mod tidy go build -o verity . sudo mv verity /usr/local/bin/ ``` [View Go docs →](/docs/sdks/go) ```bash dotnet add package Verity.SDK ``` [View .NET docs →](/docs/sdks/dotnet) Get your API key from the [Developer Console](https://verity.backworkai.com/keys). Your first request [#your-first-request] ```python from verity import VerityClient client = VerityClient(api_key="vrt_live_YOUR_API_KEY") # Look up a code with RVU data and policies result = client.lookup_code(code="76942", include=["rvu", "policies"]) print(result["data"]["description"]) # "Echo guide for biopsy" print(f"Facility price: ${result['data']['rvu']['facility_price']}") # "Facility price: $64.13" print(f"Found {len(result['data']['policies'])} coverage policies") # "Found 16 coverage policies" ``` ```typescript import { VerityClient } from 'verity-api'; const client = new VerityClient('vrt_live_YOUR_API_KEY'); // Look up a code with RVU data and policies const result = await client.lookupCode({ code: '76942', include: ['rvu', 'policies'] }); console.log(result.data.description); // "Echo guide for biopsy" console.log(`Facility price: $${result.data.rvu?.facility_price}`); // "Facility price: $64.13" console.log(`Found ${result.data.policies?.length} coverage policies`); // "Found 16 coverage policies" ``` ```ruby require 'verity' client = Verity::Client.new(api_key: 'vrt_live_YOUR_API_KEY') # Look up a code with RVU data and policies result = client.codes.lookup('76942', include: ['rvu', 'policies']) puts result['data']['description'] # "Echo guide for biopsy" puts "Found #{result['data']['policies']&.length || 0} coverage policies" # "Found 16 coverage policies" ``` ```bash export VERITY_API_KEY=vrt_live_YOUR_API_KEY # Look up a code with RVU data and policies verity check 76942 --rvu --policies # Output: # Code: 76942 # Description: Echo guide for biopsy # Facility Price: $64.13 # Found 16 coverage policies ``` ```bash curl -X GET "https://verity.backworkai.com/api/v1/codes/lookup?code=76942&include=policies" \ -H "Authorization: Bearer vrt_live_YOUR_API_KEY" ``` Common scenarios [#common-scenarios] Check if a procedure needs prior auth [#check-if-a-procedure-needs-prior-auth] ```python result = client.check_prior_auth( procedure_codes=["27447"], # Total knee replacement diagnosis_codes=["M17.11"], # Osteoarthritis, right knee state="TX" ) if result["data"]["pa_required"]: print(f"Prior authorization required. Confidence: {result['data']['confidence']}") print(f"Documentation needed: {', '.join(result['data']['documentation_checklist'][:3])}") else: print("No prior authorization needed") ``` The API returns structured criteria, not vague yes/no answers. You get the specific documentation requirements and confidence levels. Search policies across jurisdictions [#search-policies-across-jurisdictions] Medicare coverage varies by MAC jurisdiction. A procedure covered in Texas might not be covered in Pennsylvania. ```python result = client.compare_policies( procedure_codes=["76942"], jurisdictions=["J05", "J06", "JM"] ) for juris in result["data"]["comparison"]: print(f"{juris['jurisdiction']} ({juris['mac_name']}): {len(juris['policies'])} policies") ``` Monitor policy changes [#monitor-policy-changes] Policies change constantly. Verity tracks updates across all 19,000+ policies. ```python from datetime import datetime, timedelta seven_days_ago = (datetime.now() - timedelta(days=7)).isoformat() + "Z" result = client.get_policy_changes(since=seven_days_ago, limit=20) for change in result["data"]: print(f"{change['policy_id']}: {change['change_type']} - {change['change_summary']}") ``` Batch code lookups [#batch-code-lookups] Look up multiple codes in a single request: ```python result = client.batch_lookup_codes( codes=["99213", "E11.9", "27447"], include=["rvu", "policies"] ) for code, info in result["data"]["results"].items(): print(f"{code}: {info['code_system']} - {len(info.get('policies', []))} policies") ``` Search commercial formulary evidence [#search-commercial-formulary-evidence] Use the drug formulary endpoint to search pharmacy-benefit evidence across CVS Caremark, Express Scripts, and UnitedHealthcare / Optum Rx. ```bash curl "https://verity.backworkai.com/api/v1/drugs/formulary?q=metformin&payer=all&limit=5" \ -H "Authorization: Bearer vrt_live_YOUR_API_KEY" ``` The response returns source-specific records with tier, coverage status, utilization management requirements, alternatives, source URLs, and per-source counts. This endpoint costs 2 billable units per successful request. Export as CSV or FHIR [#export-as-csv-or-fhir] Get results in any format — JSON (default), CSV for spreadsheets, or FHIR R4 for EHR integration: ```bash # CSV export curl "https://verity.backworkai.com/api/v1/policies?icd10=E11.9&format=csv" \ -H "Authorization: Bearer vrt_live_YOUR_API_KEY" # FHIR R4 CoverageEligibilityResponse curl "https://verity.backworkai.com/api/v1/policies?format=fhir" \ -H "Authorization: Bearer vrt_live_YOUR_API_KEY" ``` What you get [#what-you-get] **Structured data** Coverage criteria, codes, and requirements as JSON, CSV, or FHIR R4. No PDF parsing required. **Multi-jurisdiction coverage** Medicare coverage varies by contractor. We handle all 15 MAC jurisdictions plus commercial payers. **Real-time updates** Policies change frequently. We track them all and surface changes via API or webhooks. **AI-extracted criteria** Coverage requirements extracted from PDFs by AI, validated for accuracy. **FHIR R4 interoperability** Native FHIR CoverageEligibilityResponse output for EHR/EHB integration. Limitations [#limitations] Verity covers Medicare coverage policies (LCDs, Articles, NCDs) and commercial payer policies. We don't currently support: * State Medicaid policies The API returns what's in the policies. It doesn't make coverage decisions for you. Next steps [#next-steps] *** **Resources** * [API Reference](/docs/api) - All endpoints * [Authentication](/docs/authentication) - API keys and security * [Rate Limits](/docs/rate-limits) - Usage limits and pricing tiers * [Error Handling](/docs/errors) - Handle errors gracefully **New in v1.1** * [Batch Code Lookup](/docs/api/batchLookupCodes) - Look up 50 codes in one request * [Coverage Evaluation](/docs/api/evaluateCoverage) - Evaluate structured criteria against patient data * [Webhooks](/docs/api/listWebhooks) - Real-time policy change notifications (Enterprise) * CSV and FHIR R4 output on policy endpoints via `?format=csv` or `?format=fhir` * ICD-10 policy filter: `?icd10=E11.9` on search policies # MCP Server URL: /docs/mcp Use Verity directly inside any MCP-compatible AI client — Claude, Codex, Cursor, and more. The Verity MCP server lets any AI client query coverage policies, look up codes, and check prior auth requirements in real time — without writing any code. **MCP vs Agent Tools API** — The MCP server is for AI assistants used interactively by developers and analysts. The [Agent Tools API](/docs/agent-tools) is for production agents embedded in your application, with audit logging, PHI protection, and human review routing built in. Installation [#installation] Clone and build the server: ```bash git clone https://github.com/backworkai/verity_mcp.git cd verity_mcp npm install npm run build ``` Get an API key at [verity.backworkai.com/keys](https://verity.backworkai.com/keys). Configuration [#configuration] Claude Desktop [#claude-desktop] Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows): ```json { "mcpServers": { "verity": { "command": "node", "args": ["/absolute/path/to/verity_mcp/build/index.js"], "env": { "VERITY_API_KEY": "vrt_live_YOUR_API_KEY" } } } } ``` Claude Code [#claude-code] ```bash claude mcp add verity node /absolute/path/to/verity_mcp/build/index.js export VERITY_API_KEY=vrt_live_YOUR_API_KEY ``` GitHub Copilot (VS Code) [#github-copilot-vs-code] Create or edit `.vscode/mcp.json` in your workspace (or open the user-level config via the command palette → `MCP: Open User Configuration`): ```json { "servers": { "verity": { "command": "node", "args": ["/absolute/path/to/verity_mcp/build/index.js"], "env": { "VERITY_API_KEY": "vrt_live_YOUR_API_KEY" } } } } ``` OpenAI Codex [#openai-codex] Via CLI (recommended): ```bash codex mcp add verity --env VERITY_API_KEY=vrt_live_YOUR_API_KEY -- node /absolute/path/to/verity_mcp/build/index.js ``` Or edit `~/.codex/config.toml` directly: ```toml [mcp_servers.verity] command = "node" args = ["/absolute/path/to/verity_mcp/build/index.js"] env = { VERITY_API_KEY = "vrt_live_YOUR_API_KEY" } ``` Available tools [#available-tools] | Tool | What it does | | -------------------- | ------------------------------------------------------------ | | `lookup_code` | CPT, HCPCS, ICD-10, or NDC lookup with RVU and coverage data | | `search_policies` | Full-text search across LCDs, NCDs, and Articles | | `get_policy` | Fetch full policy content by ID | | `compare_policies` | Side-by-side coverage comparison across MAC jurisdictions | | `get_policy_changes` | Policy updates since a given date or for a specific policy | | `search_criteria` | Search extracted coverage criteria text by section | | `list_jurisdictions` | MAC jurisdiction details and covered states | | `check_prior_auth` | Prior auth requirements for procedure + diagnosis + state | Example prompts [#example-prompts] Once connected, ask the assistant directly: ``` Is ultrasound guidance (76942) covered in Texas, and does it need prior auth? ``` ``` What changed in Medicare CGM coverage policies in the last 30 days? ``` ``` Compare coverage for J0585 (Botox) across JM and JH jurisdictions. ``` ``` Show me the indications criteria for CPAP coverage. ``` Environment variables [#environment-variables] | Variable | Required | Description | | ----------------- | -------- | --------------------------------------------------------------------------- | | `VERITY_API_KEY` | Yes | Your Verity API key (`vrt_live_…` or `vrt_test_…`) | | `VERITY_API_BASE` | No | Override the API base URL (default: `https://verity.backworkai.com/api/v1`) | When to use MCP vs Agent Tools API [#when-to-use-mcp-vs-agent-tools-api] Use the **MCP server** when: * A developer or analyst is chatting with an AI assistant and needs ad-hoc coverage lookups * You want zero-code Verity access inside any AI client (Claude, Codex, Cursor, etc.) * The use case is exploratory — research, policy review, or answering one-off questions Use the **[Agent Tools API](/docs/agent-tools)** when: * You're building a production application with an embedded agent * You need audit logging of every tool invocation * PHI must be explicitly rejected at the API layer * Your workflow requires human review checkpoints and approval flows * You need per-tool scope controls beyond a single API key # Rate Limits URL: /docs/rate-limits Understanding API rate limits and how to handle them The Verity API uses rate limiting to ensure fair usage and maintain service quality for all users. Rate Limit Tiers [#rate-limit-tiers] | Plan | Requests/Minute | Monthly API Calls | | ------------ | --------------- | ----------------- | | Free | 10 | 500 | | Starter | 100 | 5,000 | | Professional | 300 | 25,000 | | Enterprise | 1,000 | 100,000 | Rate Limit Headers [#rate-limit-headers] Every API response includes headers to help you track your rate limit status: | Header | Description | | ----------------------- | ---------------------------------------- | | `X-RateLimit-Limit` | Your rate limit per minute | | `X-RateLimit-Remaining` | Requests remaining in the current window | | `X-RateLimit-Reset` | Unix timestamp when the limit resets | Example headers: ```http X-RateLimit-Limit: 60 X-RateLimit-Remaining: 45 X-RateLimit-Reset: 1701878400 ``` Handling Rate Limits [#handling-rate-limits] When you exceed your rate limit, the API returns a `429 Too Many Requests` response: ```json { "success": false, "error": { "code": "RATE_LIMIT_EXCEEDED", "message": "Rate limit exceeded. Try again in 30 seconds.", "hint": "Consider upgrading to a higher plan for increased limits." } } ``` The response includes a `Retry-After` header indicating how many seconds to wait: ```http Retry-After: 30 ``` Best Practices [#best-practices] Implement Exponential Backoff [#implement-exponential-backoff] When rate limited, wait and retry with increasing delays: ```javascript async function fetchWithRetry(url, options, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { const response = await fetch(url, options); if (response.status === 429) { const retryAfter = response.headers.get('Retry-After') || Math.pow(2, i); await new Promise(resolve => setTimeout(resolve, retryAfter * 1000)); continue; } return response; } throw new Error('Max retries exceeded'); } ``` Cache Responses [#cache-responses] Many API responses can be cached to reduce the number of requests: * Policy details change infrequently - cache for 1 hour * Code lookup results - cache for 24 hours * Use the `/policies/changes` endpoint to check for updates Use Batch Endpoints [#use-batch-endpoints] Use the batch code lookup endpoint to look up multiple codes in a single request (up to 50): ```bash # Instead of multiple requests... curl /v1/codes/lookup?code=76942 curl /v1/codes/lookup?code=76943 curl /v1/codes/lookup?code=76944 # Use a single batch request curl -X POST /v1/codes/batch \ -d '{"codes": ["76942", "76943", "76944"], "include": "rvu,policies"}' ``` Expensive Operations [#expensive-operations] Some endpoints have higher rate limit costs: | Endpoint | Cost Multiplier | | -------------------------------- | --------------- | | `GET /v1/codes/lookup` | 1x | | `POST /v1/codes/batch` | 1x per code | | `GET /v1/drugs/formulary` | 2x | | `GET /v1/policies` | 1x | | `GET /v1/policies/:id` | 2x | | `POST /v1/coverage/evaluate` | 2x | | `POST /v1/prior-auth/check` | 3x | | `POST /v1/claims/validate` | 5x | | `POST /v1/claim-validation` | 5x | | `POST /v1/policies/compare` | 5x | | `GET /v1/policies?mode=semantic` | 10x | For example, if your rate limit is 60 requests/minute and you make a `policies/compare` request (5x cost), it counts as 5 requests against your limit. Upgrading Your Plan [#upgrading-your-plan] If you consistently hit rate limits, consider upgrading your plan: * **Starter** ($149/mo): 100 req/min, 5,000 calls/month * **Professional** ($499/mo): 300 req/min, 25,000 calls/month, FHIR output, semantic search * **Enterprise** ($3,000+/mo): 1,000 req/min, 100,000 calls/month, webhooks, SSO Visit the [Usage & Billing](/console/usage) page in the Developer Console to upgrade. # Acknowledge a policy change URL: /docs/api/acknowledgeChange {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Mark a single policy change as reviewed/acknowledged for the authenticated organization. Idempotent — acknowledging an already-acked change returns 200. Requires Professional plan or higher and an API key with `write` or `admin` scope. # Batch code lookup URL: /docs/api/batchLookupCodes {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Look up multiple medical codes in a single request. Returns results keyed by code. Maximum 50 codes per request. Fuzzy matching is disabled in batch mode for performance. **Partial failure handling:** Individual code lookup failures do not abort the batch. A code that cannot be resolved returns `{"found": false, "code": "", "code_system": "UNKNOWN"}` in the results map instead of causing a request-level error. # Bulk acknowledge policy changes URL: /docs/api/bulkAcknowledgeChanges {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Acknowledge multiple policy changes at once. Accepts up to 200 diff IDs. Uses ON CONFLICT DO NOTHING for idempotency. Requires Professional plan or higher and an API key with `write` or `admin` scope. # Check prior authorization requirements URL: /docs/api/checkPriorAuth {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Evaluates if a procedure requires prior authorization based on procedure codes, diagnosis codes, and state/jurisdiction. Returns matched policies, documentation requirements, and criteria details. # Compare policies across jurisdictions URL: /docs/api/comparePolicies {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Compare coverage policies across different MAC jurisdictions for the same procedure codes. Separates national vs. jurisdiction-specific policies. # Create webhook endpoint URL: /docs/api/createWebhook {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Register a new webhook endpoint. The URL must use HTTPS and must resolve to a public IP address. URLs pointing to private IP ranges (RFC 1918), loopback addresses, or link-local addresses are rejected to prevent SSRF attacks. Requires an API key with `write` or `admin` scope. The secret is returned only once on creation — store it securely. Event types: `policy.created`, `policy.updated`, `policy.retired`, `policy.codes_changed`, `policy.criteria_changed`, or `*` for all. # Delete webhook endpoint URL: /docs/api/deleteWebhook {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Soft-delete a webhook endpoint. It will no longer receive deliveries. Requires an API key with `write` or `admin` scope. # Evaluate coverage criteria URL: /docs/api/evaluateCoverage {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Evaluate a policy's structured coverage criteria (logic AST) against provided patient/claim parameters. Returns whether coverage criteria are met, confidence score, and detailed reasons. Requires Professional plan or higher. # Get compliance statistics URL: /docs/api/getComplianceStats {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Returns compliance dashboard statistics for the authenticated organization, including total changes, acknowledgment count, acknowledgment rate, and critical unreviewed count for the last 30 days. Requires Professional plan or higher. # Health check URL: /docs/api/getHealth {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Public endpoint for monitoring API health status. Returns database and Redis connectivity checks. Used for load balancer health checks. # Get policy by ID URL: /docs/api/getPolicy {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Get a single policy by ID with optional related data. Use the include parameter to fetch criteria, codes, attachments, or version history. # Get policy change feed URL: /docs/api/getPolicyChanges {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Track policy updates and modifications over time. Useful for monitoring policy changes and keeping systems in sync. # Get prior authorization research status URL: /docs/api/getPriorAuthResearch {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Poll the status and results of a prior authorization research task. Returns the current status, and when completed, the full structured research results. No cost for polling. # Get Medicaid spending by code URL: /docs/api/getSpendingByCode {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Returns aggregate Medicaid provider spending statistics per HCPCS code, including totals and year-over-year breakdowns from CMS claims data. # API Reference URL: /docs/api Complete reference for the Verity REST API. All endpoints are prefixed with https://verity.backworkai.com/api/v1. The Verity API is a REST API that returns JSON. All endpoints require an API key passed as a Bearer token. ```bash Authorization: Bearer vrt_live_YOUR_API_KEY ``` Get your key at [verity.backworkai.com/keys](https://verity.backworkai.com/keys). See [Authentication](/docs/authentication) for key types and scopes. Infrastructure [#infrastructure] Policies [#policies] Code Lookup [#code-lookup] Coverage & Prior Auth [#coverage--prior-auth] Agent Tools [#agent-tools] Webhooks [#webhooks] Policy Change Compliance [#policy-change-compliance] # Invoke agent tool URL: /docs/api/invokeAgentTool Invokes one high-level Verity tool through the controlled agent access layer. Use `GET /agent/tools` first to fetch the exact input schema for each tool. Use `response_format: "concise"` for normal agent reasoning and `response_format: "detailed"` when the agent needs source metadata, code lists, or audit evidence. Policy search uses `search_query`, not a generic `query` field. Write tools such as `acknowledge_policy_change` return `202` with `approval_status: "required"` unless the caller includes `X-Verity-Approval: reviewed` after authorized human or operator review. Read the response `result_window` fields before assuming a list is complete. # List agent tools URL: /docs/api/listAgentTools Returns the machine-readable tool catalog for controlled agent access, including input schemas, required scopes, approval posture, and whether the authenticated key can invoke each tool. The manifest is the progressive-disclosure entry point for agents. It includes tool descriptions, MCP-style annotations, input schemas, and scope hints so the agent can choose the smallest safe tool before invoking it. # List MAC jurisdictions URL: /docs/api/listJurisdictions {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Returns list of Medicare Administrative Contractor (MAC) jurisdictions. Cached for 24 hours since this is static reference data. # Search and list policies URL: /docs/api/listPolicies {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Search and list coverage policies with filtering and pagination. Supports keyword and semantic search modes. # List unreviewed policy changes URL: /docs/api/listUnreviewedChanges {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Returns policy changes from the last 30 days that have not been acknowledged by the authenticated organization. Supports cursor-based pagination. Requires Professional plan or higher. # List webhook endpoints URL: /docs/api/listWebhooks {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} List all webhook endpoints for your organization. Requires Enterprise plan. # Look up a medical code URL: /docs/api/lookupCode {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Looks up medical codes (CPT, HCPCS, ICD-10, NDC) and returns coverage information. When exact match fails and fuzzy is enabled, returns suggestions based on code similarity and description matching. # Research prior authorization requirements URL: /docs/api/researchPriorAuth {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Use AI-powered web research to find prior authorization requirements directly from payer websites. Supports async mode (returns research\_id for polling) or synchronous mode (waits for completion). Cost: 5 billable units per request. # Search coverage criteria URL: /docs/api/searchCriteria {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Search through coverage criteria blocks (indications, limitations, documentation requirements) across policies. # Search drug formulary evidence URL: /docs/api/searchDrugFormularyEvidence {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Search commercial pharmacy-benefit evidence from CVS Caremark, Express Scripts, and UnitedHealthcare / Optum Rx. # Send test webhook URL: /docs/api/testWebhook {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Send a `test.ping` event to the webhook endpoint to verify it's reachable and correctly validating signatures. The endpoint URL is validated for SSRF before delivery — URLs resolving to private IP ranges will return an error. Requires an API key with `write` or `admin` scope. # Update webhook endpoint URL: /docs/api/updateWebhook {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Update a webhook endpoint's URL, events, or status. Requires an API key with `write` or `admin` scope. # Validate claim coverage risk URL: /docs/api/validateClaim {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Run a rule-level, non-PHI pre-submission validation for CPT/HCPCS procedure codes and optional ICD-10 diagnosis/context fields. Returns coverage status, prior-auth requirement, denial risk, and issues that should be resolved before authorization or claim submission. # Validate coverage and denial risk URL: /docs/api/validateClaims {/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */} Run a rule-level, non-PHI pre-submission validation for CPT/HCPCS procedure codes, diagnosis codes, payer context, prior-auth requirements, documentation requirements, and denial risk. # .NET SDK URL: /docs/sdks/dotnet Official Verity SDK for C# and .NET with async/await support The official Verity .NET SDK provides a strongly-typed way to integrate Medicare coverage intelligence into your C#, F#, and .NET applications. Installation [#installation] Install via NuGet Package Manager: ```bash dotnet add package Verity.SDK ``` Or via Package Manager Console in Visual Studio: ```powershell Install-Package Verity.SDK ``` **Requirements**: .NET Standard 2.0+ (.NET Framework 4.6.1+, .NET Core 2.0+, .NET 5+) Quick Start [#quick-start] ```csharp using Verity; // Initialize the client var client = new VerityClient("vrt_live_YOUR_API_KEY"); // Make your first request var health = await client.HealthAsync(); Console.WriteLine(health.Data.Status); // "healthy" ``` Authentication [#authentication] Set your API key when initializing the client: ```csharp using Verity; // Option 1: Pass directly var client = new VerityClient("vrt_live_YOUR_API_KEY"); // Option 2: With configuration var client = new VerityClient(new VerityClientOptions { ApiKey = "vrt_live_YOUR_API_KEY", BaseUrl = "https://verity.backworkai.com/api/v1", // optional Timeout = TimeSpan.FromSeconds(30) // optional }); // Option 3: From configuration var apiKey = Configuration["Verity:ApiKey"]; var client = new VerityClient(apiKey); ``` Get your API key from the [Developer Console](/console/keys). Common Use Cases [#common-use-cases] Check if a Procedure Needs Prior Authorization [#check-if-a-procedure-needs-prior-authorization] ```csharp using Verity; using System; using System.Linq; using System.Threading.Tasks; var client = new VerityClient(Environment.GetEnvironmentVariable("VERITY_API_KEY")); // Check for a knee replacement in Texas var request = new PriorAuthRequest { ProcedureCodes = new[] { "27447" }, // Total knee replacement DiagnosisCodes = new[] { "M17.11" }, // Unilateral primary osteoarthritis, right knee State = "TX" }; var result = await client.CheckPriorAuthAsync(request); if (result.Data.PaRequired) { Console.WriteLine("Warning: Prior authorization required!"); Console.WriteLine($"Confidence: {result.Data.Confidence}"); Console.WriteLine($"Reason: {result.Data.Reason}"); // Show what documentation is needed Console.WriteLine("\nDocumentation checklist:"); foreach (var item in result.Data.DocumentationChecklist ?? Enumerable.Empty()) { Console.WriteLine($" • {item}"); } // Show matched policies Console.WriteLine($"\nMatched {result.Data.MatchedPolicies?.Count ?? 0} policies:"); foreach (var policy in result.Data.MatchedPolicies?.Take(3) ?? Enumerable.Empty()) { Console.WriteLine($" • {policy.PolicyId}: {policy.Title}"); } } else { Console.WriteLine("No prior authorization needed"); } ``` Look Up Procedure Code with Coverage Info [#look-up-procedure-code-with-coverage-info] ```csharp using Verity; using System; using System.Linq; using System.Threading.Tasks; var client = new VerityClient(Environment.GetEnvironmentVariable("VERITY_API_KEY")); // Look up a code with RVU data and policies var request = new CodeLookupRequest { Code = "76942", // Ultrasound guidance Include = new[] { "rvu", "policies" } }; var result = await client.LookupCodeAsync(request); var codeData = result.Data; Console.WriteLine($"Code: {codeData.Code}"); Console.WriteLine($"Description: {codeData.Description}"); // Show reimbursement info if (codeData.Rvu != null) { Console.WriteLine("\nReimbursement (2026):"); Console.WriteLine($" Work RVU: {codeData.Rvu.WorkRvu}"); Console.WriteLine($" Facility price: ${codeData.Rvu.FacilityPrice}"); Console.WriteLine($" Non-facility price: ${codeData.Rvu.NonFacilityPrice}"); } // Show coverage policies if (codeData.Policies != null) { Console.WriteLine($"\nFound {codeData.Policies.Count} coverage policies:"); foreach (var policy in codeData.Policies.Take(5)) { Console.WriteLine($" • [{policy.Disposition}] {policy.Title}"); } } ``` Search Coverage Policies by Keyword [#search-coverage-policies-by-keyword] ```csharp using Verity; using System; using System.Threading.Tasks; var client = new VerityClient(Environment.GetEnvironmentVariable("VERITY_API_KEY")); // Search for policies about diabetes CGM devices var request = new PolicySearchRequest { Query = "continuous glucose monitoring diabetes", PolicyType = "LCD", // Local Coverage Determinations Status = PolicyStatus.Active, Limit = 10 }; var result = await client.ListPoliciesAsync(request); Console.WriteLine($"Found {result.Data.Count} active LCDs about CGM:\n"); foreach (var policy in result.Data) { Console.WriteLine($"Policy: {policy.PolicyId}"); Console.WriteLine($"Title: {policy.Title}"); Console.WriteLine($"Jurisdiction: {policy.Jurisdiction ?? "National"}"); Console.WriteLine($"Effective: {policy.EffectiveDate?.ToString("yyyy-MM-dd") ?? "N/A"}"); Console.WriteLine("---"); } ``` Compare Coverage Across Jurisdictions [#compare-coverage-across-jurisdictions] ```csharp using Verity; using System; using System.Linq; using System.Threading.Tasks; var client = new VerityClient(Environment.GetEnvironmentVariable("VERITY_API_KEY")); // Compare ultrasound guidance coverage across different MACs var request = new ComparePoliciesRequest { ProcedureCodes = new[] { "76942" }, Jurisdictions = new[] { "J05", "J06", "J12", "JM" } // Different MAC jurisdictions }; var result = await client.ComparePoliciesAsync(request); var comparison = result.Data.Comparison; Console.WriteLine("Coverage comparison across jurisdictions:\n"); foreach (var juris in comparison ?? Enumerable.Empty()) { Console.WriteLine($"{juris.Jurisdiction} ({juris.MacName}):"); Console.WriteLine($" States: {string.Join(", ", juris.States ?? Enumerable.Empty())}"); Console.WriteLine($" Policies: {juris.Policies?.Count ?? 0}"); foreach (var policy in juris.Policies ?? Enumerable.Empty()) { Console.WriteLine($" • {policy.PolicyId}: {policy.Disposition}"); } Console.WriteLine(); } ``` Monitor Policy Changes [#monitor-policy-changes] ```csharp using Verity; using System; using System.Linq; using System.Threading.Tasks; var client = new VerityClient(Environment.GetEnvironmentVariable("VERITY_API_KEY")); // Get policies updated in the last 7 days var sevenDaysAgo = DateTime.UtcNow.AddDays(-7); var request = new PolicyChangesRequest { Since = sevenDaysAgo, ChangeType = "updated", Limit = 20 }; var result = await client.GetPolicyChangesAsync(request); Console.WriteLine("Policy changes in the last 7 days:\n"); foreach (var change in result.Data) { Console.WriteLine($"Policy: {change.PolicyId}"); Console.WriteLine($"Change: {change.ChangeType}"); Console.WriteLine($"Summary: {change.ChangeSummary ?? "No summary"}"); Console.WriteLine($"Timestamp: {change.Timestamp}"); Console.WriteLine("---"); } ``` Get Detailed Policy Information [#get-detailed-policy-information] ```csharp using Verity; using System; using System.Linq; using System.Threading.Tasks; var client = new VerityClient(Environment.GetEnvironmentVariable("VERITY_API_KEY")); // Get full policy details with criteria var result = await client.GetPolicyAsync("L33831", new GetPolicyRequest { Include = new[] { "criteria", "codes", "attachments" } }); var policy = result.Data; Console.WriteLine($"Policy: {policy.Title}"); Console.WriteLine($"Type: {policy.PolicyType}"); Console.WriteLine($"Status: {policy.Status}"); Console.WriteLine($"Effective: {policy.EffectiveDate?.ToString("yyyy-MM-dd") ?? "N/A"}"); // Show coverage criteria if (policy.Criteria != null) { Console.WriteLine("\nCoverage Criteria:"); foreach (var section in policy.Criteria) { Console.WriteLine($"\n{section.Key.ToUpper()}:"); foreach (var block in section.Value.Take(3)) // Show first 3 { Console.WriteLine($" • {block.Text?.Substring(0, Math.Min(100, block.Text.Length ?? 0))}..."); } } } // Show covered codes if (policy.Codes != null) { Console.WriteLine($"\nCovers {policy.Codes.Count} codes"); foreach (var code in policy.Codes.Take(10)) { Console.WriteLine($" • {code.Code} ({code.CodeSystem}): {code.Disposition}"); } } ``` Search Coverage Criteria [#search-coverage-criteria] ```csharp using Verity; using System; using System.Linq; using System.Threading.Tasks; var client = new VerityClient(Environment.GetEnvironmentVariable("VERITY_API_KEY")); // Search for specific coverage criteria about BMI requirements var request = new CriteriaSearchRequest { Query = "BMI greater than 40", Section = CriteriaSection.Indications, PolicyType = "LCD", Limit = 10 }; var result = await client.SearchCriteriaAsync(request); Console.WriteLine("BMI-related coverage criteria:\n"); foreach (var criteria in result.Data) { Console.WriteLine($"Policy: {criteria.PolicyId}"); Console.WriteLine($"Section: {criteria.Section}"); Console.WriteLine($"Text: {criteria.Text?.Substring(0, Math.Min(200, criteria.Text.Length ?? 0))}..."); Console.WriteLine($"Tags: {string.Join(", ", criteria.Tags ?? Enumerable.Empty())}"); Console.WriteLine("---"); } ``` List MAC Jurisdictions [#list-mac-jurisdictions] ```csharp using Verity; using System; using System.Linq; using System.Threading.Tasks; var client = new VerityClient(Environment.GetEnvironmentVariable("VERITY_API_KEY")); var result = await client.ListJurisdictionsAsync(); Console.WriteLine("Medicare Administrative Contractors (MACs):\n"); foreach (var jurisdiction in result.Data) { Console.WriteLine($"{jurisdiction.JurisdictionCode}: {jurisdiction.MacName}"); Console.WriteLine($" States: {string.Join(", ", jurisdiction.States ?? Enumerable.Empty())}"); Console.WriteLine($" Type: {jurisdiction.MacType ?? "N/A"}"); Console.WriteLine(); } ``` Research Prior Auth with AI Web Search [#research-prior-auth-with-ai-web-search] ```csharp using Verity; using System; using System.Threading.Tasks; var client = new VerityClient(Environment.GetEnvironmentVariable("VERITY_API_KEY")); // Async mode (default) - returns research_id for polling var research = await client.ResearchPriorAuthAsync( procedureCodes: new[] { "27447" }, payer: "UnitedHealthcare", state: "TX" ); var researchId = research.Data.ResearchId; Console.WriteLine($"Research started: {researchId}"); // Poll for results PriorAuthResearchResult status; do { await Task.Delay(2000); var poll = await client.GetPriorAuthResearchAsync(researchId); status = poll.Data; } while (status.Status != "completed" && status.Status != "failed"); if (status.Status == "completed") { Console.WriteLine($"Results: {status.Result}"); } // Or use sync mode to wait for completion var syncResult = await client.ResearchPriorAuthAsync( procedureCodes: new[] { "27447" }, payer: "Aetna", state: "CA", sync: true ); ``` Get Medicaid Spending Data [#get-medicaid-spending-data] ```csharp using Verity; using System; var client = new VerityClient(Environment.GetEnvironmentVariable("VERITY_API_KEY")); // Single code var result = await client.GetSpendingByCodeAsync(code: "T1019"); var spending = result.Data["T1019"]; Console.WriteLine($"Total paid: ${spending.TotalPaid}"); Console.WriteLine($"Total claims: {spending.TotalClaims}"); foreach (var year in spending.ByYear) { Console.WriteLine($" {year.Year}: ${year.TotalPaid} ({year.TotalClaims} claims)"); } // Multiple codes with year filter var multi = await client.GetSpendingByCodeAsync( codes: new[] { "T1019", "T1020" }, year: 2023 ); ``` ASP.NET Core Integration [#aspnet-core-integration] Dependency Injection Setup [#dependency-injection-setup] ```csharp // Startup.cs or Program.cs using Microsoft.Extensions.DependencyInjection; using Verity; public void ConfigureServices(IServiceCollection services) { // Add Verity client as a singleton services.AddSingleton(sp => { var apiKey = Configuration["Verity:ApiKey"]; return new VerityClient(apiKey); }); services.AddControllers(); } ``` Using in a Controller [#using-in-a-controller] ```csharp using Microsoft.AspNetCore.Mvc; using Verity; using System.Threading.Tasks; [ApiController] [Route("api/[controller]")] public class CodesController : ControllerBase { private readonly IVerityClient _verity; public CodesController(IVerityClient verity) { _verity = verity; } [HttpGet("{code}")] public async Task GetCode(string code) { try { var result = await _verity.LookupCodeAsync(new CodeLookupRequest { Code = code, Include = new[] { "rvu", "policies" } }); return Ok(result); } catch (VerityAuthenticationException ex) { return Unauthorized(new { error = ex.Message }); } catch (VerityValidationException ex) { return BadRequest(new { error = ex.Message, details = ex.Details }); } catch (VerityException ex) { return StatusCode(500, new { error = ex.Message }); } } } ``` Error Handling [#error-handling] The SDK provides structured exceptions for different error types: ```csharp using Verity; using System; using System.Threading.Tasks; var client = new VerityClient(Environment.GetEnvironmentVariable("VERITY_API_KEY")); try { var result = await client.LookupCodeAsync(new CodeLookupRequest { Code = "INVALID" }); } catch (VerityAuthenticationException ex) { Console.WriteLine($"Invalid API key: {ex.Message}"); } catch (VerityValidationException ex) { Console.WriteLine($"Invalid parameters: {ex.Message}"); if (ex.Details != null) { Console.WriteLine($"Details: {string.Join(", ", ex.Details)}"); } } catch (VerityNotFoundException ex) { Console.WriteLine($"Resource not found: {ex.Message}"); } catch (VerityRateLimitException ex) { Console.WriteLine($"Rate limit exceeded. Resets at: {ex.ResetAt}"); Console.WriteLine($"Limit: {ex.Limit}, Remaining: {ex.Remaining}"); } catch (VerityException ex) { Console.WriteLine($"API error: {ex.Message} (code: {ex.Code})"); if (!string.IsNullOrEmpty(ex.Hint)) { Console.WriteLine($"Hint: {ex.Hint}"); } } ``` Response Format [#response-format] All methods return strongly-typed responses: ```csharp public class ApiResponse { public bool Success { get; set; } public T Data { get; set; } public ApiMeta Meta { get; set; } } public class ApiMeta { public string RequestId { get; set; } public DateTime Timestamp { get; set; } // Additional metadata... } ``` Async/Await Patterns [#asyncawait-patterns] All SDK methods are async and follow TAP (Task-based Asynchronous Pattern): ```csharp using Verity; using System; using System.Threading; using System.Threading.Tasks; var client = new VerityClient(Environment.GetEnvironmentVariable("VERITY_API_KEY")); // With cancellation token var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); try { var result = await client.LookupCodeAsync( new CodeLookupRequest { Code = "76942" }, cts.Token ); } catch (OperationCanceledException) { Console.WriteLine("Request cancelled or timed out"); } ``` Configuration Options [#configuration-options] ```csharp using Verity; using System; using System.Net.Http; var options = new VerityClientOptions { ApiKey = "vrt_live_YOUR_API_KEY", BaseUrl = "https://verity.backworkai.com/api/v1", Timeout = TimeSpan.FromSeconds(60), // Custom HTTP client for advanced scenarios HttpClient = new HttpClient { Timeout = TimeSpan.FromMinutes(2) }, // Enable automatic retries (default: 3) MaxRetries = 3, // Retry delay (exponential backoff) RetryDelay = TimeSpan.FromSeconds(1) }; var client = new VerityClient(options); ``` Resources [#resources] * **NuGet**: [Verity.SDK](https://www.nuget.org/packages/Verity.SDK/) * **GitHub**: [backworkai/verity-dotnet](https://github.com/backworkai/verity-dotnet) * **API Reference**: [All Endpoints](/docs/api) * **Issues**: [Report a bug](https://github.com/backworkai/verity-dotnet/issues) Next Steps [#next-steps] # Go CLI URL: /docs/sdks/go Command-line tool for Verity with single binary distribution The Verity CLI is a powerful command-line tool for interacting with the Verity API. Perfect for DevOps workflows, automation scripts, and quick lookups from the terminal. Installation [#installation] Install from Source [#install-from-source] ```bash git clone https://github.com/backworkai/verity-cli.git cd verity-cli go mod tidy go build -o verity . sudo mv verity /usr/local/bin/ ``` Download Binary [#download-binary] Pre-built binaries will be available from [GitHub Releases](https://github.com/backworkai/verity-cli/releases) once release assets are published. Quick Start [#quick-start] Set your API key as an environment variable: ```bash export VERITY_API_KEY=vrt_live_YOUR_API_KEY ``` Or pass it with each command: ```bash verity --api-key vrt_live_YOUR_API_KEY check 76942 ``` Get your API key from the [Developer Console](/console/keys). Common Use Cases [#common-use-cases] Check if a Procedure Needs Prior Authorization [#check-if-a-procedure-needs-prior-authorization] ```bash # Basic prior auth check verity prior-auth 27447 --state TX # With diagnosis codes verity prior-auth 27447 --diagnosis M17.11 --state TX # Multiple procedure codes verity prior-auth 27447 76942 --state CA # JSON output for scripting verity prior-auth 27447 --state TX --output json | jq '.data.pa_required' ``` **Output:** ``` Prior Authorization Required: true Confidence: high Reason: Procedure requires prior authorization in Texas Matched Policies: • L33831: Ultrasound Guidance for Needle Placement • L38942: Diagnostic Ultrasound Documentation Checklist: • Medical necessity documentation • Prior imaging results • Conservative treatment history ``` Look Up Procedure Code with Coverage Info [#look-up-procedure-code-with-coverage-info] ```bash # Basic code lookup verity check 76942 # With RVU reimbursement data verity check 76942 --rvu # With coverage policies verity check 76942 --policies # Everything (RVU + policies) verity check 76942 --rvu --policies # Filter by jurisdiction verity check 76942 --jurisdiction JM ``` **Output:** ``` Code: 76942 System: HCPCS Found: true Description: Echo guide for biopsy RVU Data (2026): Work RVU: 0.65 Facility Price: $64.13 Non-Facility Price: $64.13 Coverage Policies (16 found): • [covered] Billing and Coding: Varicose Veins • [covered] Billing and Coding: Nerve Blockade • [not_covered] Ultrasound Guidance for Trigger Point Injections ``` Search Coverage Policies [#search-coverage-policies] ```bash # Keyword search verity policies list --query "ultrasound guidance" # Filter by policy type verity policies list --query "diabetes" --type LCD # Filter by jurisdiction verity policies list --query "CGM" --jurisdiction JM # Active policies only verity policies list --query "surgery" --status active # JSON output verity policies list --query "ultrasound" --output json | jq '.data[].policy_id' ``` **Output:** ``` Found 50 policies: ID: A57305 Title: Billing and Coding: Varicose Veins of the Lower Extremity Type: Article Jurisdiction: JM Status: active --- ID: L33831 Title: Ultrasound Guidance for Needle Placement Type: LCD Jurisdiction: J06 Status: active --- ``` Get Detailed Policy Information [#get-detailed-policy-information] ```bash # Get policy by ID verity policies get L33831 # JSON output for parsing verity policies get L33831 --output json | jq '.data.title' ``` **Output:** ``` Policy: L33831 Title: Ultrasound Guidance for Needle Placement Type: LCD Status: active Jurisdiction: J06 Effective Date: 2024-01-01 Description: This LCD outlines coverage requirements for ultrasound guidance used during needle placement procedures... Covered Codes (12): • 76942 (HCPCS): covered • 76998 (HCPCS): covered ``` List MAC Jurisdictions [#list-mac-jurisdictions] ```bash # List all jurisdictions verity jurisdictions # JSON output verity jurisdictions --output json ``` **Output:** ``` Medicare Administrative Contractors (MACs): JM: Palmetto GBA States: TX, OK, NM, CO, LA, AR, MS J05: Novitas Solutions States: PA, NJ, DE, MD, DC, WV J06: National Government Services States: IL, MN, WI ``` Research Prior Auth with AI Web Search [#research-prior-auth-with-ai-web-search] ```bash # Async mode - returns research ID for polling verity prior-auth research 27447 --payer "UnitedHealthcare" --state TX # Output: # Research ID: res_abc123 # Status: pending # Poll URL: /api/v1/prior-auth/research/res_abc123 # # Use 'verity prior-auth research-status ' to check progress # Check research status verity prior-auth research-status res_abc123 # Sync mode - waits for completion verity prior-auth research 27447 --payer "Aetna" --state CA --sync # JSON output verity prior-auth research 27447 --payer "UnitedHealthcare" --sync --output json | jq '.data.result.determination' ``` Get Medicaid Spending Data [#get-medicaid-spending-data] ```bash # Single code verity spending T1019 # Multiple codes verity spending T1019 T1020 # Filter by year verity spending T1019 --year 2023 # JSON output for scripting verity spending T1019 --output json | jq '.data.T1019.total_paid' ``` Check API Health [#check-api-health] ```bash verity health # Output: # Status: healthy # Version: 1.0.0 # Timestamp: 2026-02-17T12:00:00Z # # Checks: # database: healthy # redis: healthy ``` Search Coverage Criteria [#search-coverage-criteria] ```bash # Search criteria text verity coverage search "BMI greater than 40" # Filter by section and policy type verity coverage search "conservative treatment" --section indications --type LCD # Filter by jurisdiction verity coverage search "frequency limits" --jurisdiction JM # JSON output verity coverage search "BMI" --output json | jq '.data[].text' ``` Compare Policies Across Jurisdictions [#compare-policies-across-jurisdictions] ```bash # Compare coverage for a procedure verity policies compare 76942 # Compare specific jurisdictions verity policies compare 76942 --jurisdictions J05,J06,JM # Multiple codes with policy type filter verity policies compare 27447 76942 --type LCD # JSON output verity policies compare 76942 --output json | jq '.data.comparison' ``` Scripting & Automation [#scripting--automation] Check Multiple Codes in a Loop [#check-multiple-codes-in-a-loop] ```bash #!/bin/bash CODES=("76942" "27447" "99213" "J0585") for code in "${CODES[@]}"; do echo "Checking $code..." verity check "$code" --output json | jq -r '.data.description' done ``` Monitor for Policy Changes [#monitor-for-policy-changes] ```bash #!/bin/bash # Get changes from the last 24 hours SINCE=$(date -u -v-24H +"%Y-%m-%dT%H:%M:%SZ") # macOS # SINCE=$(date -u -d '24 hours ago' +"%Y-%m-%dT%H:%M:%SZ") # Linux verity policies changes --since "$SINCE" --output json | \ jq -r '.data[] | "\(.policy_id): \(.change_type) - \(.change_summary)"' ``` Pre-submission Prior Auth Check [#pre-submission-prior-auth-check] ```bash #!/bin/bash # Check if procedures need PA before submitting claim PROCEDURES=("27447" "76942") DIAGNOSES=("M17.11" "M79.3") STATE="TX" result=$(verity prior-auth "${PROCEDURES[@]}" \ --diagnosis "${DIAGNOSES[@]}" \ --state "$STATE" \ --output json) pa_required=$(echo "$result" | jq -r '.data.pa_required') if [ "$pa_required" = "true" ]; then echo "Warning: Prior authorization required!" echo "$result" | jq -r '.data.documentation_checklist[]' exit 1 else echo "No prior authorization needed" exit 0 fi ``` Export Policy Data to CSV [#export-policy-data-to-csv] ```bash #!/bin/bash # Search and export to CSV verity policies list --query "diabetes" --output json | \ jq -r '.data[] | [.policy_id, .title, .policy_type, .status] | @csv' > policies.csv ``` Output Formats [#output-formats] The CLI supports multiple output formats: ```bash # Table (default) - human-readable verity check 76942 # JSON - for scripting verity check 76942 --output json # YAML - for configuration verity check 76942 --output yaml ``` Configuration File [#configuration-file] Save your API key and preferences in a config file: ```bash # Create config file mkdir -p ~/.verity cat > ~/.verity/config.yaml << EOF api-key: vrt_live_YOUR_API_KEY base-url: https://verity.backworkai.com/api/v1 output: table EOF # Now you can use the CLI without --api-key verity check 76942 ``` Global Flags [#global-flags] Available for all commands: ```bash --api-key string # Verity API key (or set VERITY_API_KEY env var) --base-url string # API base URL (default: https://verity.backworkai.com/api/v1) --output string # Output format: table, json, yaml (default: table) --config string # Config file (default: $HOME/.verity/config.yaml) ``` All Commands [#all-commands] verity check [#verity-check-code] Look up a medical code. **Flags:** * `--jurisdiction ` - Filter by MAC jurisdiction * `--rvu` - Include RVU data * `--policies` - Include policy information **Example:** ```bash verity check 76942 --rvu --policies --jurisdiction JM ``` verity health [#verity-health] Check API health status. **Example:** ```bash verity health ``` verity prior-auth [#verity-prior-auth-codes] Check prior authorization requirements. **Flags:** * `--diagnosis ` - Diagnosis codes (ICD-10) * `--state ` - Two-letter state code * `--payer ` - Payer (medicare, aetna, uhc, all) **Example:** ```bash verity prior-auth 27447 76942 --diagnosis M17.11 --state TX ``` verity prior-auth research [#verity-prior-auth-research-codes] Research prior auth requirements via AI web search. **Flags:** * `--payer ` - Payer name (e.g., UnitedHealthcare, Aetna) * `--state ` - Two-letter state code * `--diagnosis ` - Diagnosis codes (ICD-10) * `--context ` - Additional clinical context * `--sync` - Wait for completion **Example:** ```bash verity prior-auth research 27447 --payer "UnitedHealthcare" --state TX --sync ``` verity prior-auth research-status [#verity-prior-auth-research-status-research-id] Poll the status of a prior auth research task. **Example:** ```bash verity prior-auth research-status res_abc123 ``` verity policies list [#verity-policies-list] Search and list policies. **Flags:** * `--query ` - Search query * `--type ` - Policy type (LCD, Article, NCD) * `--jurisdiction ` - MAC jurisdiction * `--status ` - Status (active, retired, all) * `--mode ` - Search mode (keyword, semantic) **Example:** ```bash verity policies list --query "ultrasound" --type LCD --status active ``` verity policies get [#verity-policies-get-policy-id] Get detailed policy information. **Example:** ```bash verity policies get L33831 ``` verity policies changes [#verity-policies-changes] Get policy change feed. **Flags:** * `--since ` - ISO 8601 timestamp * `--policy-id ` - Filter by policy ID * `--change-type ` - Change type filter **Example:** ```bash verity policies changes --since 2026-01-01T00:00:00Z ``` verity policies compare [#verity-policies-compare-codes] Compare policies across jurisdictions. **Flags:** * `--type ` - Policy type (LCD, Article, NCD) * `--jurisdictions ` - Specific jurisdictions to compare **Example:** ```bash verity policies compare 76942 --jurisdictions J05,J06,JM ``` verity jurisdictions [#verity-jurisdictions] List all MAC jurisdictions. **Example:** ```bash verity jurisdictions ``` verity coverage search [#verity-coverage-search-query] Search coverage criteria text across policies. **Flags:** * `--section
` - Filter by section (indications, limitations, documentation) * `--type ` - Policy type (LCD, Article, NCD) * `--jurisdiction ` - MAC jurisdiction * `--limit ` - Results per page (1-100) **Example:** ```bash verity coverage search "BMI greater than 40" --section indications --type LCD ``` verity spending [#verity-spending-codes] Get Medicaid spending data by HCPCS code. **Flags:** * `--year ` - Filter to a specific year **Example:** ```bash verity spending T1019 T1020 --year 2023 ``` Shell Completion [#shell-completion] Generate shell completion scripts: ```bash # Bash verity completion bash > /usr/local/etc/bash_completion.d/verity # Zsh verity completion zsh > /usr/local/share/zsh/site-functions/_verity # Fish verity completion fish > ~/.config/fish/completions/verity.fish # PowerShell verity completion powershell | Out-String | Invoke-Expression ``` Building from Source [#building-from-source] ```bash git clone https://github.com/backworkai/verity-cli.git cd verity-cli go mod tidy go build -o verity . ./verity --help ``` **Build for all platforms:** ```bash make build-all # Creates binaries in dist/ for: # - darwin/amd64, darwin/arm64 # - linux/amd64, linux/arm64 # - windows/amd64 ``` Resources [#resources] * **GitHub**: [backworkai/verity-cli](https://github.com/backworkai/verity-cli) * **Releases**: [Download Binaries](https://github.com/backworkai/verity-cli/releases) * **API Reference**: [All Endpoints](/docs/api) * **Issues**: [Report a bug](https://github.com/backworkai/verity-cli/issues) Next Steps [#next-steps] # SDKs & Libraries URL: /docs/sdks Official SDKs and tools for integrating Verity into your application Build with Verity using our official SDKs for popular languages and platforms. Server-Side SDKs [#server-side-sdks] Command Line [#command-line] Community SDKs [#community-sdks] Don't see your language? We'd love your help building a community SDK. Check out the [API reference](/docs/api) to get started. Features [#features] All official SDKs include: * **Full API Coverage** - All endpoints, parameters, and response types * **Type Safety** - Complete type definitions and IntelliSense support * **Error Handling** - Structured errors with helpful messages * **Automatic Retries** - Built-in exponential backoff for transient failures * **Modern Async** - Promise/async/await patterns throughout * **Well Documented** - Comprehensive guides and code examples Installation Quick Links [#installation-quick-links] ```bash pip install verity-python ``` [View Python Docs →](/docs/sdks/python) ```bash npm install verity-api ``` [View TypeScript Docs →](/docs/sdks/typescript) ```bash git clone https://github.com/backworkai/verity-ruby.git cd verity-ruby bundle install ``` [View Ruby Docs →](/docs/sdks/ruby) ```bash git clone https://github.com/backworkai/verity-cli.git cd verity-cli go mod tidy go build -o verity . sudo mv verity /usr/local/bin/ ``` [View Go Docs →](/docs/sdks/go) ```bash dotnet add package Verity.SDK ``` [View .NET Docs →](/docs/sdks/dotnet) Need Help? [#need-help] * **API Reference**: [All Endpoints](/docs/api) * **Authentication**: [API Keys](/docs/authentication) * **Support**: [support@verity.backworkai.com](mailto:support@verity.backworkai.com) * **GitHub**: [Report an issue](https://github.com/backworkai) # Python SDK URL: /docs/sdks/python 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 [#installation] ```bash pip install verity-python ``` Requires Python 3.8+. Works with any HTTP client under the hood (uses httpx). Quick start [#quick-start] ```python 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](/console/keys). Authentication [#authentication] ```python 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 [#common-scenarios] Check if a procedure needs prior auth [#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. ```python 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 Replacement ``` The `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 [#look-up-codes-with-reimbursement-data] ```python 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 [#search-policies-by-keyword-or-semantically] ```python # 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): ```python 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 [#compare-coverage-across-macs] Medicare coverage isn't national. A procedure covered in Texas (JM) might not be covered in Pennsylvania (J05). ```python 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 [#monitor-policy-changes] Policies change constantly. New LCDs get published, existing ones get retired, criteria get updated. ```python 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 [#get-full-policy-details-with-criteria] ```python 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 [#search-specific-coverage-criteria] Sometimes you need to find policies with specific requirements (e.g., BMI cutoffs, frequency limits). ```python 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 [#list-mac-jurisdictions] ```python 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") ``` Research prior auth with AI web search [#research-prior-auth-with-ai-web-search] For commercial payers or when you need real-time payer website intelligence: ```python # Async mode (default) - returns research_id for polling result = client.research_prior_auth( procedure_codes=["27447"], payer="UnitedHealthcare", state="TX" ) research_id = result["data"]["research_id"] print(f"Research started: {research_id}") # Poll for results import time while True: status = client.get_prior_auth_research(research_id) if status["data"]["status"] in ("completed", "failed"): break time.sleep(2) if status["data"]["status"] == "completed": determination = status["data"]["result"]["determination"] print(f"PA Required: {determination['pa_required']}") print(f"Reasoning: {determination['reasoning']}") # Or use sync mode to wait for completion result = client.research_prior_auth( procedure_codes=["27447"], payer="Aetna", state="CA", sync=True # Blocks until complete ) print(result["data"]["result"]["determination"]) ``` Get Medicaid spending data [#get-medicaid-spending-data] ```python # Single code result = client.get_spending_by_code(code="T1019") spending = result["data"]["T1019"] print(f"Total paid: ${spending['total_paid']}") print(f"Total claims: {spending['total_claims']}") for year in spending["by_year"]: print(f" {year['year']}: ${year['total_paid']} ({year['total_claims']} claims)") # Multiple codes with year filter result = client.get_spending_by_code(codes=["T1019", "T1020"], year=2023) ``` Error handling [#error-handling] The SDK raises structured exceptions. Catch them specifically, not just generic `Exception`. ```python 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 [#response-format] All methods return dictionaries matching this structure: ```python { "success": True, "data": { ... }, # The actual response "meta": { "request_id": "req_...", "timestamp": "2026-01-25T12:00:00Z" } } ``` Error responses: ```python { "success": False, "error": { "code": "VALIDATION_ERROR", "message": "Invalid parameter: code", "hint": "Code must be a valid CPT, HCPCS, or ICD-10 code" } } ``` Type hints [#type-hints] The SDK includes type hints for IDE autocomplete. Use them. ```python 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 [#advanced-configuration] Custom timeout [#custom-timeout] ```python client = VerityClient( api_key="vrt_live_YOUR_API_KEY", timeout=60 # seconds ) ``` Automatic retries [#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 [#what-the-sdk-doesnt-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 [#resources] * **PyPI**: [verity-python](https://pypi.org/project/verity-python/) * **GitHub**: [backworkai/verity-python](https://github.com/backworkai/verity-python) * **API Reference**: [All Endpoints](/docs/api) * **Issues**: [Report a bug](https://github.com/backworkai/verity-python/issues) Next steps [#next-steps] # Ruby SDK URL: /docs/sdks/ruby Official Verity SDK for Ruby with resource-oriented API clients The Verity Ruby SDK provides resource-oriented access to Medicare coverage intelligence, medical code lookup, policies, coverage criteria, prior authorization checks, spending data, and webhooks. The Ruby SDK is not published to RubyGems yet. Install from source until the first package release is cut. Installation [#installation] ```bash git clone https://github.com/backworkai/verity-ruby.git cd verity-ruby bundle install ``` Requires Ruby 2.7+. Quick Start [#quick-start] ```ruby require 'verity' client = Verity::Client.new(api_key: 'vrt_live_YOUR_API_KEY') health = client.health puts health.dig('data', 'status') ``` Get your API key from the [Developer Console](/console/keys). Authentication [#authentication] ```ruby client = Verity::Client.new( api_key: ENV.fetch('VERITY_API_KEY'), base_url: 'https://verity.backworkai.com/api/v1' ) ``` Common Use Cases [#common-use-cases] Look Up a Medical Code [#look-up-a-medical-code] ```ruby result = client.codes.lookup('76942', include: ['rvu', 'policies']) data = result['data'] puts "#{data['code']}: #{data['description']}" puts "Policies: #{data['policies']&.length || 0}" ``` Search Policies [#search-policies] ```ruby result = client.policies.list( q: 'ultrasound guidance', mode: 'keyword', policy_type: 'LCD', jurisdiction: 'JM', limit: 10 ) result['data'].each do |policy| puts "#{policy['policy_id']}: #{policy['title']}" end ``` Check Prior Authorization [#check-prior-authorization] ```ruby result = client.prior_auth.check( procedure_codes: ['27447'], diagnosis_codes: ['M17.11'], state: 'TX', payer: 'Medicare' ) data = result['data'] puts "PA required: #{data['pa_required']}" puts "Reason: #{data['reason']}" ``` Resources [#resources] * **GitHub**: [backworkai/verity-ruby](https://github.com/backworkai/verity-ruby) * **API Reference**: [All Endpoints](/docs/api) * **Issues**: [Report a bug](https://github.com/backworkai/verity-ruby/issues) # TypeScript SDK URL: /docs/sdks/typescript Official Verity SDK for TypeScript and Node.js with full type definitions The official Verity TypeScript SDK provides a type-safe way to integrate Medicare coverage intelligence into your TypeScript, JavaScript, and Node.js applications. Installation [#installation] Install via npm, yarn, or pnpm: ```bash npm install verity-api # or yarn add verity-api # or pnpm add verity-api ``` **Requirements**: Node.js 18+ or modern browser with fetch API Quick Start [#quick-start] ```typescript import { VerityClient } from 'verity-api'; // Initialize the client const client = new VerityClient('vrt_live_YOUR_API_KEY'); // Make your first request const health = await client.health(); console.log(health.data.status); // "healthy" ``` Authentication [#authentication] Set your API key when initializing the client: ```typescript import { VerityClient } from 'verity-api'; // Option 1: Pass directly const client = new VerityClient('vrt_live_YOUR_API_KEY'); // Option 2: With configuration object const client = new VerityClient({ apiKey: 'vrt_live_YOUR_API_KEY', baseUrl: 'https://verity.backworkai.com/api/v1', // optional timeout: 30000 // optional, in milliseconds }); // Option 3: From environment variable const client = new VerityClient(process.env.VERITY_API_KEY!); ``` Get your API key from the [Developer Console](/console/keys). Common Use Cases [#common-use-cases] Check if a Procedure Needs Prior Authorization [#check-if-a-procedure-needs-prior-authorization] ```typescript import { VerityClient } from 'verity-api'; const client = new VerityClient(process.env.VERITY_API_KEY!); // Check for a knee replacement in Texas const result = await client.checkPriorAuth({ procedureCodes: ['27447'], // Total knee replacement diagnosisCodes: ['M17.11'], // Unilateral primary osteoarthritis, right knee state: 'TX' }); if (result.data.pa_required) { console.log('Warning: Prior authorization required!'); console.log(`Confidence: ${result.data.confidence}`); console.log(`Reason: ${result.data.reason}`); // Show what documentation is needed console.log('\nDocumentation checklist:'); result.data.documentation_checklist?.forEach(item => { console.log(` • ${item}`); }); // Show matched policies console.log(`\nMatched ${result.data.matched_policies?.length} policies:`); result.data.matched_policies?.slice(0, 3).forEach(policy => { console.log(` • ${policy.policy_id}: ${policy.title}`); }); } else { console.log('No prior authorization needed'); } ``` Look Up Procedure Code with Coverage Info [#look-up-procedure-code-with-coverage-info] ```typescript import { VerityClient } from 'verity-api'; const client = new VerityClient(process.env.VERITY_API_KEY!); // Look up a code with RVU data and policies const result = await client.lookupCode({ code: '76942', // Ultrasound guidance include: ['rvu', 'policies'] }); const codeData = result.data; console.log(`Code: ${codeData.code}`); console.log(`Description: ${codeData.description}`); // Show reimbursement info if (codeData.rvu) { console.log('\nReimbursement (2026):'); console.log(` Work RVU: ${codeData.rvu.work_rvu}`); console.log(` Facility price: $${codeData.rvu.facility_price}`); console.log(` Non-facility price: $${codeData.rvu.non_facility_price}`); } // Show coverage policies if (codeData.policies) { console.log(`\nFound ${codeData.policies.length} coverage policies:`); codeData.policies.slice(0, 5).forEach(policy => { console.log(` • [${policy.disposition}] ${policy.title}`); }); } ``` Search Coverage Policies by Keyword [#search-coverage-policies-by-keyword] ```typescript import { VerityClient } from 'verity-api'; const client = new VerityClient(process.env.VERITY_API_KEY!); // Search for policies about diabetes CGM devices const result = await client.listPolicies({ q: 'continuous glucose monitoring diabetes', policyType: 'LCD', // Local Coverage Determinations status: 'active', limit: 10 }); console.log(`Found ${result.data.length} active LCDs about CGM:\n`); result.data.forEach(policy => { console.log(`Policy: ${policy.policy_id}`); console.log(`Title: ${policy.title}`); console.log(`Jurisdiction: ${policy.jurisdiction || 'National'}`); console.log(`Effective: ${policy.effective_date || 'N/A'}`); console.log('---'); }); ``` Compare Coverage Across Jurisdictions [#compare-coverage-across-jurisdictions] ```typescript import { VerityClient } from 'verity-api'; const client = new VerityClient(process.env.VERITY_API_KEY!); // Compare ultrasound guidance coverage across different MACs const result = await client.comparePolicies({ procedureCodes: ['76942'], jurisdictions: ['J05', 'J06', 'J12', 'JM'] // Different MAC jurisdictions }); const comparison = result.data.comparison; console.log('Coverage comparison across jurisdictions:\n'); comparison?.forEach(juris => { console.log(`${juris.jurisdiction} (${juris.mac_name}):`); console.log(` States: ${juris.states?.join(', ')}`); console.log(` Policies: ${juris.policies?.length}`); juris.policies?.forEach(policy => { console.log(` • ${policy.policy_id}: ${policy.disposition}`); }); console.log(); }); ``` Monitor Policy Changes [#monitor-policy-changes] ```typescript import { VerityClient } from 'verity-api'; const client = new VerityClient(process.env.VERITY_API_KEY!); // Get policies updated in the last 7 days const sevenDaysAgo = new Date(); sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); const result = await client.getPolicyChanges({ since: sevenDaysAgo.toISOString(), changeType: 'updated', limit: 20 }); console.log('Policy changes in the last 7 days:\n'); result.data.forEach(change => { console.log(`Policy: ${change.policy_id}`); console.log(`Change: ${change.change_type}`); console.log(`Summary: ${change.change_summary || 'No summary'}`); console.log(`Timestamp: ${change.timestamp}`); console.log('---'); }); ``` Get Detailed Policy Information [#get-detailed-policy-information] ```typescript import { VerityClient } from 'verity-api'; const client = new VerityClient(process.env.VERITY_API_KEY!); // Get full policy details with criteria const result = await client.getPolicy('L33831', { include: ['criteria', 'codes', 'attachments'] }); const policy = result.data; console.log(`Policy: ${policy.title}`); console.log(`Type: ${policy.policy_type}`); console.log(`Status: ${policy.status}`); console.log(`Effective: ${policy.effective_date || 'N/A'}`); // Show coverage criteria if (policy.criteria) { console.log('\nCoverage Criteria:'); Object.entries(policy.criteria).forEach(([section, blocks]) => { console.log(`\n${section.toUpperCase()}:`); blocks.slice(0, 3).forEach(block => { // Show first 3 console.log(` • ${block.text?.substring(0, 100)}...`); }); }); } // Show covered codes if (policy.codes) { console.log(`\nCovers ${policy.codes.length} codes`); policy.codes.slice(0, 10).forEach(code => { console.log(` • ${code.code} (${code.code_system}): ${code.disposition}`); }); } ``` Search Coverage Criteria [#search-coverage-criteria] ```typescript import { VerityClient } from 'verity-api'; const client = new VerityClient(process.env.VERITY_API_KEY!); // Search for specific coverage criteria about BMI requirements const result = await client.searchCriteria({ q: 'BMI greater than 40', section: 'indications', policyType: 'LCD', limit: 10 }); console.log('BMI-related coverage criteria:\n'); result.data.forEach(criteria => { console.log(`Policy: ${criteria.policy_id}`); console.log(`Section: ${criteria.section}`); console.log(`Text: ${criteria.text?.substring(0, 200)}...`); console.log(`Tags: ${criteria.tags?.join(', ')}`); console.log('---'); }); ``` List MAC Jurisdictions [#list-mac-jurisdictions] ```typescript import { VerityClient } from 'verity-api'; const client = new VerityClient(process.env.VERITY_API_KEY!); const result = await client.listJurisdictions(); console.log('Medicare Administrative Contractors (MACs):\n'); result.data.forEach(jurisdiction => { console.log(`${jurisdiction.jurisdiction_code}: ${jurisdiction.mac_name}`); console.log(` States: ${jurisdiction.states?.join(', ')}`); console.log(` Type: ${jurisdiction.mac_type || 'N/A'}`); console.log(); }); ``` Research Prior Auth with AI Web Search [#research-prior-auth-with-ai-web-search] For commercial payers or when you need real-time payer website intelligence: ```typescript import { VerityClient } from 'verity-api'; const client = new VerityClient(process.env.VERITY_API_KEY!); // Async mode (default) - returns research_id for polling const research = await client.researchPriorAuth({ procedureCodes: ['27447'], payer: 'UnitedHealthcare', state: 'TX' }); const researchId = research.data.research_id; console.log(`Research started: ${researchId}`); // Poll for results let status; do { await new Promise(resolve => setTimeout(resolve, 2000)); status = await client.getPriorAuthResearch(researchId); } while (!['completed', 'failed'].includes(status.data.status)); if (status.data.status === 'completed') { console.log('Determination:', status.data.result?.determination); console.log('Sources:', status.data.result?.sources); } // Or use sync mode to wait for completion const syncResult = await client.researchPriorAuth({ procedureCodes: ['27447'], payer: 'Aetna', state: 'CA', sync: true }); console.log(syncResult.data.result?.determination); ``` Get Medicaid Spending Data [#get-medicaid-spending-data] ```typescript import { VerityClient } from 'verity-api'; const client = new VerityClient(process.env.VERITY_API_KEY!); // Single code const result = await client.getSpendingByCode({ code: 'T1019' }); const spending = result.data['T1019']; console.log(`Total paid: $${spending.total_paid}`); console.log(`Total claims: ${spending.total_claims}`); spending.by_year.forEach(year => { console.log(` ${year.year}: $${year.total_paid} (${year.total_claims} claims)`); }); // Multiple codes with year filter const multi = await client.getSpendingByCode({ codes: ['T1019', 'T1020'], year: 2023 }); ``` Browser Usage [#browser-usage] The SDK works in modern browsers using native fetch: ```html
Loading...
``` Error Handling [#error-handling] The SDK provides structured exceptions for different error types: ```typescript import { VerityClient, VerityError, AuthenticationError, ValidationError, NotFoundError, RateLimitError } from 'verity-api'; const client = new VerityClient(process.env.VERITY_API_KEY!); try { const result = await client.lookupCode({ code: 'INVALID' }); } catch (error) { if (error instanceof AuthenticationError) { console.error('Invalid API key:', error.message); } else if (error instanceof ValidationError) { console.error('Invalid parameters:', error.message); if (error.details) { console.error('Details:', error.details); } } else if (error instanceof NotFoundError) { console.error('Resource not found:', error.message); } else if (error instanceof RateLimitError) { console.error(`Rate limit exceeded. Resets at: ${error.reset}`); console.error(`Limit: ${error.limit}, Remaining: ${error.remaining}`); } else if (error instanceof VerityError) { console.error(`API error: ${error.message} (code: ${error.code})`); if (error.hint) { console.error(`Hint: ${error.hint}`); } } } ``` Response Format [#response-format] All methods return typed responses: ```typescript interface ApiResponse { success: true; data: T; meta?: { request_id?: string; timestamp?: string; [key: string]: any; }; } // Or error response interface ErrorResponse { success: false; error: { code: string; message: string; hint?: string; details?: Record; }; meta?: { request_id?: string; timestamp?: string; }; } ``` TypeScript Integration [#typescript-integration] The SDK includes complete type definitions: ```typescript import { VerityClient, CodeLookupData, PriorAuthResult } from 'verity-api'; const client = new VerityClient(process.env.VERITY_API_KEY!); // Full type safety with autocomplete const codeResult = await client.lookupCode({ code: '76942', include: ['rvu', 'policies'], jurisdiction: 'JM', fuzzy: true }); // TypeScript knows the exact shape of the response if (codeResult.success) { const data: CodeLookupData = codeResult.data; const description: string | null = data.description; const found: boolean = data.found; const rvu = data.rvu; // Type: RvuData | undefined console.log(`${description} - $${rvu?.facility_price}`); } ``` Express.js Integration [#expressjs-integration] Example Express.js endpoint using the SDK: ```typescript import express from 'express'; import { VerityClient, VerityError } from 'verity-api'; const app = express(); const verity = new VerityClient(process.env.VERITY_API_KEY!); app.get('/api/check-code/:code', async (req, res) => { try { const result = await verity.lookupCode({ code: req.params.code, include: ['rvu', 'policies'] }); res.json(result); } catch (error) { if (error instanceof VerityError) { res.status(error.statusCode || 500).json({ error: error.message, code: error.code }); } else { res.status(500).json({ error: 'Internal server error' }); } } }); app.listen(3000); ``` Resources [#resources] * **npm**: [verity-api](https://www.npmjs.com/package/verity-api) * **GitHub**: [backworkai/verity-ts](https://github.com/backworkai/verity-ts) * **API Reference**: [All Endpoints](/docs/api) * **Issues**: [Report a bug](https://github.com/backworkai/verity-ts/issues) Next Steps [#next-steps]