.NET SDK
Official Backwork SDK for C# and .NET with async/await support
The official Backwork .NET SDK provides a typed async client for Medicare and commercial coverage intelligence, medical code lookup, prior authorization checks, claim validation, policy search, spending data, and formulary evidence.
Installation
dotnet add package Backwork.SDK --version 2.0.0Requirements: .NET Standard 2.0+ (.NET Framework 4.6.1+, .NET Core 2.0+, .NET 5+)
Quick Start
using Backwork.SDK;
using var client = new BackworkClient("bwk_live_YOUR_API_KEY");
var health = await client.HealthAsync();
Console.WriteLine(health.Data?.Status);Get an API key from the Developer Console.
Authentication
Pass the API key directly, or read it from configuration or an environment variable.
using Backwork.SDK;
var apiKey = Environment.GetEnvironmentVariable("BACKWORK_API_KEY")
?? throw new InvalidOperationException("BACKWORK_API_KEY is required");
using var client = new BackworkClient(apiKey);The default base URL is https://backworkhealth.com/api/v1. You can override it for staging or local testing:
using var client = new BackworkClient(
apiKey,
baseUrl: "https://backworkhealth.com/api/v1"
);Common Workflows
Health Check
var health = await client.HealthAsync();
Console.WriteLine($"{health.Data?.Status} {health.Data?.Version}");Look Up a Medical Code
var result = await client.LookupCodeAsync(
code: "76942",
jurisdiction: "JM",
include: new[] { "rvu", "policies" }
);
var code = result.Data;
Console.WriteLine($"{code?.Code}: {code?.Description}");
Console.WriteLine($"Facility price: ${code?.Rvu?.FacilityPrice}");
Console.WriteLine($"Policies: {code?.Policies?.Count ?? 0}");Batch Code Lookup
var result = await client.BatchLookupCodesAsync(
codes: new[] { "76942", "27447", "NOPE999" },
include: new[] { "rvu", "policies" }
);
foreach (var item in result.Data?.Results ?? new())
{
Console.WriteLine($"{item.Key}: found={item.Value.Found}");
}NOPE999 returns an item with found=false instead of failing the whole batch.
Search Policies
var policies = await client.ListPoliciesAsync(
query: "ultrasound guidance",
policyType: "LCD",
status: "active",
limit: 10
);
foreach (var policy in policies.Data ?? new())
{
Console.WriteLine($"{policy.PolicyId}: {policy.Title}");
}Get a Policy
var policy = await client.GetPolicyAsync(
"L33831",
include: new[] { "criteria", "codes" }
);
Console.WriteLine(policy.Data?.Title);
Console.WriteLine(policy.Data?.PdfUrl);Check Prior Authorization
var result = await client.CheckPriorAuthAsync(
procedureCodes: new[] { "27447" },
diagnosisCodes: new[] { "M17.11" },
state: "TX",
payer: "medicare"
);
Console.WriteLine($"PA required: {result.Data?.PaRequired}");
Console.WriteLine($"Confidence: {result.Data?.Confidence}");
Console.WriteLine($"Reason: {result.Data?.Reason}");
foreach (var item in result.Data?.DocumentationChecklist ?? new())
{
Console.WriteLine($"- {item}");
}Validate Claim Risk
var claim = await client.ValidateClaimWithDateOfServiceAsync(
procedureCodes: new[] { "27447" },
diagnosisCodes: new[] { "M17.11" },
payer: "Medicare",
state: "TX",
dateOfService: "2026-05-23"
);
Console.WriteLine($"Coverage: {claim.Data?.CoverageStatus}");
Console.WriteLine($"Prior auth: {claim.Data?.PriorAuthRequired}");
Console.WriteLine($"Denial risk: {claim.Data?.DenialRisk}");Monitor Policy Changes
var since = DateTime.UtcNow.AddDays(-7).ToString("yyyy-MM-ddTHH:mm:ssZ");
var changes = await client.GetPolicyChangesAsync(
since: since,
limit: 20
);
foreach (var change in changes.Data ?? new())
{
Console.WriteLine($"{change.PolicyId}: {change.ChangeType}");
Console.WriteLine(change.ChangeSummary);
}Search Coverage Criteria
var criteria = await client.SearchCriteriaAsync(
query: "BMI greater than 40",
section: "indications",
policyType: "LCD",
limit: 10
);
foreach (var block in criteria.Data ?? new())
{
Console.WriteLine($"{block.PolicyId ?? block.Policy?.PolicyId}: {block.Text}");
}List Jurisdictions
var jurisdictions = await client.ListJurisdictionsAsync();
foreach (var jurisdiction in jurisdictions.Data ?? new())
{
Console.WriteLine($"{jurisdiction.JurisdictionCode}: {jurisdiction.MacName}");
}Compare Policies
var comparison = await client.ComparePoliciesAsync(
procedureCodes: new[] { "76942" },
jurisdictions: new[] { "J05", "J06", "JM" }
);
Console.WriteLine(comparison.Data);Medicaid Spending
var result = await client.GetSpendingByCodeAsync(
code: "T1019",
year: 2023
);
if (result.Data?.TryGetValue("T1019", out var spending) == true)
{
Console.WriteLine($"Total paid: ${spending.TotalPaid}");
Console.WriteLine($"Total claims: {spending.TotalClaims}");
}Drug Formulary Evidence
var formulary = await client.SearchDrugFormularyEvidenceAsync(
query: "metformin",
payer: "all",
limit: 5
);
foreach (var item in formulary.Data ?? new())
{
Console.WriteLine($"{item.Source}: {item.DrugName} {item.CoverageStatus}");
}Webhooks and Compliance
Webhook and compliance write operations require API keys with the right plan and scope. If the key does not have access, the SDK throws a BackworkException with the API status code and error code.
try
{
var webhooks = await client.ListWebhooksAsync();
Console.WriteLine(webhooks.Data?.Count ?? 0);
}
catch (BackworkException ex) when (ex.StatusCode == 403)
{
Console.WriteLine($"Scope or plan required: {ex.Code}");
}ASP.NET Core
Register BackworkClient as a singleton when your application uses one API key for outbound Backwork calls.
using Backwork.SDK;
builder.Services.AddSingleton(sp =>
{
var apiKey = builder.Configuration["Backwork:ApiKey"]
?? throw new InvalidOperationException("Backwork:ApiKey is required");
return new BackworkClient(apiKey);
});Then inject it into controllers or services:
using Microsoft.AspNetCore.Mvc;
using Backwork.SDK;
[ApiController]
[Route("api/codes")]
public class CodesController : ControllerBase
{
private readonly BackworkClient _backwork;
public CodesController(BackworkClient backwork)
{
_backwork = backwork;
}
[HttpGet("{code}")]
public async Task<IActionResult> GetCode(string code)
{
var result = await _backwork.LookupCodeAsync(
code,
include: new[] { "rvu", "policies" }
);
return Ok(result);
}
}Error Handling
using Backwork.SDK;
try
{
var result = await client.LookupCodeAsync("76942");
}
catch (BackworkException ex) when (ex.StatusCode == 401)
{
Console.WriteLine($"Authentication failed: {ex.Code}");
}
catch (BackworkException ex) when (ex.StatusCode == 429)
{
Console.WriteLine("Rate limited. Retry with backoff.");
}
catch (BackworkException ex)
{
Console.WriteLine($"Backwork API error {ex.StatusCode} ({ex.Code}): {ex.Message}");
}Response Format
All methods return ApiResponse<T>:
public class ApiResponse<T>
{
public bool Success { get; set; }
public T? Data { get; set; }
public object? Meta { get; set; }
}Error responses are raised as BackworkException.
Resources
- Release assets: Backwork .NET SDK releases
- GitHub: backworkhealth/backwork-dotnet
- API Reference: All Endpoints
- Issues: Report a bug
Next Steps
API Reference
Explore all available endpoints
Authentication
Learn about API keys
Rate Limits
Understand usage limits
Error Handling
Handle errors gracefully
Last updated on