Go: Zero to first 200
A Go console program that prequalifies John Doe for Final Expense coverage. Under 60 minutes for a backend developer with no insurance domain knowledge.
Go: Zero to first 200
Target: A Go program that prequalifies John Doe (NC, 64, male, no conditions) for Final Expense coverage, printing each qualifying plan and its monthly premium. Time: under 60 minutes from a blank directory.
Language requirement: Go 1.22 or newer. No framework, no dependencies beyond the SDK.
What you'll build
A single main.go — prequalify/main.go — 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 demographics and a coverage request; the engine returns every qualifying plan with a bucketed monthly premium. Not a binding quote.
Prerequisites
| Requirement | Why |
|---|---|
| Go 1.22 or newer | The SDK uses generics and errors.As patterns available in Go 1.22+. |
go on $PATH | go mod init, go get, go 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 an isa_test_… token (and an isa_live_… token for production). 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 module
mkdir prequalify && cd prequalify
go mod init prequalify2. Install the SDK
go get github.com/isa-sdk/sdk3. Hello world
Create main.go:
package main
import (
"context"
"fmt"
"log"
sdk "github.com/isa-sdk/sdk"
"github.com/isa-sdk/sdk/catalog"
"github.com/isa-sdk/sdk/zyins"
)
func main() {
// sdk.WithBearer("") reads ISA_TOKEN from the environment.
isa, err := sdk.WithBearer("")
if err != nil {
log.Fatalf("init: %v", err)
}
// Products.Fex.AetnaAccendo carries the stable prod_<uuid> used on the wire.
// Always use catalog constants — never hardcode prod_ strings or slugs.
products, err := zyins.NewProductSelectionOf(catalog.Products.Fex.AetnaAccendo())
if err != nil {
log.Fatalf("products: %v", err)
}
height, err := zyins.NewHeight(5, 10) // 5 ft 10 in
if err != nil {
log.Fatalf("height: %v", err)
}
weight, err := zyins.NewWeight(195) // pounds
if err != nil {
log.Fatalf("weight: %v", err)
}
coverage, err := zyins.NewFaceValueCoverage(25_000) // dollars — $25,000 face value
if err != nil {
log.Fatalf("coverage: %v", err)
}
result, err := isa.Zyins.Prequalify.Run(context.Background(), &zyins.PrequalifyRequest{
Applicant: zyins.Applicant{
DOB: "1962-04-18",
Sex: zyins.SexMale,
Height: height,
Weight: weight,
State: catalog.StateNorthCarolina,
NicotineUse: zyins.NicotineUsageInput{LastUsed: zyins.NicotineNever},
},
Coverage: coverage,
Products: products,
})
if err != nil {
log.Fatalf("prequalify: %v", err)
}
for _, offer := range result.Plans {
for _, row := range offer.Pricing {
if row.Primary && row.Premium != nil {
fmt.Printf("%-24s %-40s category=%-10s premium=%-10s (%d cents)\n",
offer.Carrier.Name,
offer.Product.Name,
row.Eligibility.Category, // "immediate" | "graded" | "rop"
row.Premium.Amount.Display, // verbatim carrier string
row.Premium.Amount.Cents, // integer cents
)
}
}
}
}Run it:
go run main.goYou should see a list of qualifying plans. No plans printed means the applicant
did not qualify — confirm that ISA_TOKEN is set correctly.
Money inputs are integer dollars.
zyins.NewFaceValueCoverage(25_000)means $25,000 of death benefit, not 25,000 cents. Outputs always carry bothCents(integer minor units) andDisplay(the verbatim carrier string), so you never have to format on the way out.
4. Add idempotency
The SDK auto-mints a UUID v4 idempotency key for every call — fine for a stateless script. For production jobs that replay calls safely, mint the key once at job dispatch and reuse it on retry:
import (
"context"
"github.com/google/uuid"
sdk "github.com/isa-sdk/sdk"
"github.com/isa-sdk/sdk/zyins"
)
func ExampleIdempotency(isa *sdk.Isa, ctx context.Context, input *zyins.PrequalifyRequest) {
key := uuid.New().String() // mint once; reuse on retry
resp, err := isa.Zyins.Prequalify.Run(ctx, input,
zyins.WithIdempotencyKey(key),
)
_ = resp
_ = err
}Same key + same body within 24 hours = cached response. Same key + different body = 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 so retries
are safe. You do not need to write retry logic.
6. Handle errors
Use errors.As to match typed SDK errors:
import (
"context"
"errors"
"log"
"time"
"github.com/isa-sdk/sdk/zyins"
)
func handleError(err error) {
var conflict *zyins.IdempotencyConflictError
var rateLimit *zyins.RateLimitError
var apiErr *zyins.APIError
switch {
case errors.As(err, &conflict):
// Key was reused with a different body — this is a bug in your call site.
log.Printf("idempotency conflict: key=%s first_seen=%s", conflict.Key, conflict.FirstSeenAt)
case errors.As(err, &rateLimit):
// SDK already retried; honor the retry-after window.
time.Sleep(rateLimit.RetryAfter)
case errors.As(err, &apiErr):
// Any other API error — log request_id for support.
log.Printf("api error: code=%s request_id=%s", apiErr.Code, apiErr.RequestID)
default:
log.Fatalf("unexpected: %v", err)
}
}Log RequestID alongside every business record. It is the correlation ID that
links your log line to the server-side trace.
7. Run it
go run main.goExpected output (exact plans depend on carrier availability in NC):
Aetna Accendo Aetna Accendo Final Expense category=immediate premium=$87.42 (8742 cents)
All amounts are integer cents — never floats. 8742 cents is $87.42/month.
8. What just happened
When you called Prequalify.Run, the SDK:
- Read
ISA_TOKENfrom the environment and initialized the HTTP client. - Minted a UUID v4 and sent it as
Idempotency-Key: 550e8400-.... - Returned a typed response struct with
RequestID,IdempotencyKey,Livemode: false, andPlans— no JSON parsing needed.
The Livemode: false field 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: Gin — wiring the SDK into a Gin HTTP server
- API Reference — every endpoint, every parameter, every response field
Updated about 10 hours ago