Python: Zero to first 200
A Python script that prequalifies John Doe for Final Expense coverage. Under 60 minutes for a backend developer with no insurance domain knowledge.
Python: Zero to first 200
Target: A Python script 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: Python 3.10 or newer with pip.
What you'll build
A single script — prequalify.py — 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, product, eligibility category, and monthly premium.
What "prequalify" means: It's 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 |
|---|---|
| Python 3.10 or newer | The SDK uses match statements and dataclasses(slots=True) available in 3.10+. |
pip | Package installation. |
| An ISA API bearer token | See "Getting your test token" below. |
Getting your test token
Complete checkout at checkout.isaapi.com and you'll receive an email with two tokens: isa_test_… and isa_live_…. Set the test token as an environment variable:
export 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 a project directory
mkdir prequalify && cd prequalify
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate2. Install the SDK
pip install isa-sdk3. Hello world
Create prequalify.py:
from isa_sdk import Isa
from isa_sdk.zyins import (
Applicant, NicotineDuration, NicotineUsageInput, Sex, Coverage, ProductSelection,
)
from isa_sdk.catalog import Products
def main() -> None:
# Isa.with_bearer() reads ISA_TOKEN from the environment.
isa = Isa.with_bearer()
result = isa.zyins.prequalify(
applicant=Applicant(
dob="1962-04-18",
sex=Sex.MALE,
height_inches=70,
weight_pounds=195,
state="NC",
nicotine_use=NicotineUsageInput(last_used=NicotineDuration.NEVER),
),
coverage=Coverage.face_value(25_000),
# Products.Fex.AetnaAccendo carries the stable prod_<uuid> used on the wire.
products=ProductSelection.of(Products.Fex.AetnaAccendo),
)
for offer in result.data.plans:
headline = next((row for row in offer.pricing if row.primary), None)
if headline is not None and headline.premium is not None:
print(
f"{offer.carrier.name:<24} {offer.product.name:<40} "
f"category={headline.eligibility.category:<10} "
f"premium={headline.premium.amount.display:<10} ({headline.premium.amount.cents} cents)"
)
if __name__ == "__main__":
main()Run it:
python prequalify.pyYou should see a list of qualifying plans. No plans printed 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. For a stateless script, that is fine. For production jobs where you want to replay a specific call safely, mint the key at job dispatch and reuse it on retry:
import uuid
key = str(uuid.uuid4()) # mint once; reuse on retry
result = isa.zyins.prequalify(request, idempotency_key=key)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.
If you are wrapping the SDK in your own job queue, mint the idempotency key at enqueue time, not at execution time. That way if the worker crashes and replays, the key is stable across attempts.
6. Handle errors
Use except to catch typed SDK errors:
import logging
import time
from isa_sdk.zyins import (
IsaIdempotencyConflictError,
RateLimitError,
IsaApiError,
)
log = logging.getLogger(__name__)
try:
result = isa.zyins.prequalify(request)
except IsaIdempotencyConflictError as e:
# Key reused with different body — bug in call site.
log.error("idempotency conflict: key=%s first_seen=%s", e.key, e.first_seen_at)
raise
except RateLimitError as e:
# SDK already retried; honor the retry-after window.
retry_after = e.retry_after_seconds or 1.0
log.warning("rate limited; retry after %.1fs", retry_after)
time.sleep(retry_after)
raise
except IsaApiError as e:
# Any other API error — log request_id for support.
log.error("api error: code=%s request_id=%s", e.code, e.request_id)
raiseSave request_id with every log entry: It is the correlation ID that links your log line to the server-side trace, critical for debugging.
7. Run it
python prequalify.pyExpected 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. premium.default_mode names
which premium.modes key the headline amount came from.
8. What just happened
When you called isa.zyins.prequalify(request), the SDK:
- Read
ISA_TOKENfrom the environment and set up the HTTP client. - Minted a UUID v4 and sent
Idempotency-Key: 550e8400-...on the request. - Received an envelope response with
request_id,idempotency_key,livemode: False, anddata.plans. - Returned a typed pydantic model — no JSON parsing needed on your side.
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 full response envelope, eligibility, and 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: FastAPI — wiring the SDK into a FastAPI app
- Framework guide: Django — wiring the SDK into a Django project
- API Reference — every endpoint, every parameter, every response field
Updated about 10 hours ago