C#: Zero to first 200
Build a .NET console app that prequalifies John Doe for Final Expense coverage in under 60 minutes with no insurance domain knowledge required.
C#: Zero to first 200
Target: A .NET console application that prequalifies John Doe (NC, 64, male, no conditions) for Final Expense coverage and prints every qualifying plan with its monthly premium. Time budget: under 60 minutes from a blank directory.
Language requirement: .NET 8 SDK. No ASP.NET, no DI container — a plain console app.
What you'll build
A console project — prequalify/Program.cs — that:
- Reads your API bearer token from an environment variable.
- Asks the ISA underwriting engine whether John Doe qualifies for Final Expense coverage.
- Prints each qualifying plan: carrier name, plan tier, and monthly premium in cents.
"Prequalify" is a fast eligibility screen. You send an applicant's demographics and a coverage request; the engine returns every plan the applicant qualifies for with a bucketed monthly premium. It is not a binding quote.
Prerequisites
| Requirement | Why |
|---|---|
| .NET 8 SDK | The SDK targets net8.0. Run dotnet --version to verify. |
dotnet CLI | dotnet new, dotnet add package, dotnet run. |
| An ISA API bearer token | See "Getting your test token" below. |
Getting your test token
Your ISA API token arrives by email within minutes of completing checkout at
checkout.isaapi.com. The email contains both an
isa_test_… and an isa_live_… token. Set the test token as an environment
variable:
export ISA_TOKEN="<paste your isa_test_… key here>"Windows (PowerShell):
$env:ISA_TOKEN = "<paste your isa_test_… key here>"Test vs live. Every call made with a test token runs against the real engine with real carrier rules, but no binding decisions are issued. Switch to your live token when you are ready to ship.
1. Create the project
dotnet new console -n prequalify
cd prequalify2. Install the SDK
dotnet add package IsaSdk3. Hello world
Replace the contents of Program.cs:
using Isa.Sdk;
using Isa.Sdk.Catalog;
using Isa.Sdk.Zyins;
// IsaClient.WithBearer reads ISA_TOKEN from the environment.
var isa = IsaClient.WithBearer();
// Products.Fex.AetnaAccendo carries the stable prod_<uuid> used on the wire.
// Always use catalog constants — never hardcode prod_ strings or slugs.
var result = await isa.Zyins.Prequalify.RunAsync(new PrequalifyRequest(
Applicant: new Applicant
{
Dob = "1962-04-18",
Sex = Sex.Male,
HeightInches = 70,
WeightPounds = 195,
State = "NC",
NicotineUse = new NicotineUsageInput { LastUsed = NicotineDuration.Never },
},
Coverage: Coverage.ByFaceValue(25_000),
Products: new[] { Products.Fex.AetnaAccendo }));
foreach (var offer in result.Plans)
{
var headline = offer.Pricing.FirstOrDefault(r => r.Primary);
if (headline?.Premium is not null)
{
Console.WriteLine(
$"{offer.Carrier.Name,-24} {offer.Product.Name,-40} " +
$"category={headline.Eligibility.Category,-10} " +
$"premium={headline.Premium.Amount.Display,-10} ({headline.Premium.Amount.Cents} cents)");
}
}Run it:
dotnet runYou should see a list of qualifying plans. No plans means the applicant did not
qualify — confirm that ISA_TOKEN is set.
4. Add idempotency
The SDK auto-mints a UUID v4 idempotency key for every call. That works fine for one-off scripts. For production jobs where you retry the same request, mint the key once at dispatch and reuse it:
// The SDK auto-mints a UUID v4 per call.
// For replay safety across retries, generate the key at job dispatch
// and hold it stable. Pass it via RequestOptions if the SDK exposes that
// parameter, or rely on the auto-minted key for single-process use.
var result = await isa.Zyins.Prequalify.RunAsync(request, CancellationToken.None);If the server receives the same key with the same body within 24 hours, it returns the cached response. If the body differs, the server returns 409 idempotency_conflict.
5. Retries
The SDK automatically retries 5xx and 429 rate_limit_exceeded responses on
exponential backoff with jitter, reusing the same idempotency key. You do not
need to write retry logic.
6. Handle errors
All exceptions inherit from IsaException. Match on the typed subclass:
using Isa.Sdk;
using Isa.Sdk.Catalog;
using Isa.Sdk.Core;
using Isa.Sdk.Zyins;
var isa = IsaClient.WithBearer();
var request = new PrequalifyRequest(
Applicant: new Applicant
{
Dob = "1962-04-18",
Sex = Sex.Male,
HeightInches = 70,
WeightPounds = 195,
State = "NC",
NicotineUse = new NicotineUsageInput { LastUsed = NicotineDuration.Never },
},
Coverage: Coverage.ByFaceValue(25_000),
Products: new[] { Products.Fex.AetnaAccendo });
try
{
var result = await isa.Zyins.Prequalify.RunAsync(request, CancellationToken.None);
}
catch (IsaIdempotencyConflictException ex)
{
// Key reused with different body — bug in call site.
Console.Error.WriteLine($"Idempotency conflict: key={ex.Key} first_seen={ex.FirstSeenAt}");
throw;
}
catch (IsaRateLimitException ex)
{
// SDK already retried; honor the retry-after window.
var delay = ex.RetryAfter ?? TimeSpan.FromSeconds(1);
Console.Error.WriteLine($"Rate limited; retry after {delay.TotalSeconds:F1}s");
await Task.Delay(delay);
throw;
}
catch (IsaException ex)
{
// Any other API error — log request_id for support.
Console.Error.WriteLine($"API error: code={ex.Code} request_id={ex.RequestId}");
throw;
}Log RequestId alongside every business record. It is the correlation ID that
links your log line to the server-side trace.
7. Run it
dotnet runExpected output (exact plans depend on carrier availability in NC):
Aetna Accendo Aetna Accendo Final Expense category=immediate premium=$87.42 (8742 cents)
Premium.Amount.Cents is the integer in US cents (always); Premium.Amount.Display is the verbatim
carrier-formatted string. Render Display, do arithmetic on Cents.
8. What just happened
When you called Prequalify.RunAsync(request), the SDK:
- Read
ISA_TOKENfrom the environment and set up the HTTP client. - Minted a UUID v4 and sent
Idempotency-Key: <uuid>on the request. - Received a typed
PrequalifyResultwithPlans,RequestId, andLivemode. - Returned a typed C# record — no JSON deserialization needed on your side.
A non-empty result.Plans means the applicant qualifies. result.Livemode == false confirms you ran against the test sandbox.
9. What's next
- Authentication guide — bearer tokens, test vs. live, rotation
- Prequalify guide — the response envelope, eligibility, and the pricing table
- Idempotency guide — how the SDK mints keys, when to bring your own
- Error catalog — every
codevalue, HTTP status, and remediation - Webhooks guide — receiving signed callbacks
- Framework guide: ASP.NET Core — wiring the SDK into ASP.NET Core with DI
- Framework guide: Azure Functions — wiring the SDK into Azure Functions
- API Reference — every endpoint, every parameter, every response field
Updated about 10 hours ago