npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@instabrain-sdks/api-client

v2.2.1

Published

Official Node.js SDK for InstaBrain APIs - Insurance quotes and application processing

Readme

@instabrain-sdks/api-client

npm version

TypeScript/Node.js SDK for integrating with the InstaBrain insurance platform. Covers three products: GIGDB (Guaranteed Issue Graded Death Benefit), ADB (Accidental Death Benefit), and IB Term life insurance.

Primary products for third-party integration: GIGDB and ADB.

Credentials (userId and accessToken) are provisioned during onboarding.


Table of Contents

  1. Installation
  2. Requirements
  3. Authentication
  4. Product Comparison
  5. GIGDB Flow
  6. ADB Flow
  7. IB Term Flow
  8. Secure Sign Flow
  9. Final Submit
  10. Reporting API
  11. Request Type Reference
  12. Response Type Reference
  13. Enums and Constants
  14. Beneficiary Reference
  15. Error Handling
  16. APIErrorCode Reference
  17. Environment Configuration
  18. Token Management
  19. Examples Directory
  20. Changelog
  21. Support

Installation

npm install @instabrain-sdks/api-client

Note: This is a restricted-access package. Access must be granted during the InstaBrain onboarding process.


Requirements

  • Node.js >= 14.0.0
  • TypeScript >= 4.0 (optional - the SDK ships with full type definitions)

Authentication

Credentials are issued during onboarding:

| Credential | Type | Description | | ------------- | --------------- | ------------------------ | | userId | number | Your account user ID | | accessToken | string (UUID) | Your secret access token |

import { InstaBrainClient } from '@instabrain-sdks/api-client';

const client = InstaBrainClient.forEnvironment('sandbox');
const jwt = await client.authenticate(userId, accessToken);
// JWT is stored internally and automatically attached to all subsequent calls
// No need to manually set it after authenticate()

Call authenticate() once at startup. The returned JWT is stored internally - every subsequent API call uses it automatically.


Product Comparison

| Feature | GIGDB | ADB | IB Term | | -------------------- | ------------------------- | ------------------------------- | --------------------------------------------- | | Eligible ages | 50–85 | 20–59 | 18–60 | | Face amount | $5,000–$25,000 | $50,000-$300,000 | $50,000–$1,000,000 (age-scaled) | | Medical exam | No | No | No (build chart used) | | Smoker/tobacco field | isSmoker (required) | N/A | flagTobaccoUse (required) | | Birth jurisdiction | Yes (birthJurisdiction) | No | No | | App response type | ThirdPartyStartAppResp | ThirdPartyAdbStartAppResp | ThirdPartyStartAppResp | | isDeclined | Yes | Yes | No | | isQuoteChanged | Yes | No | No | | Response links | None | None | agentLink, eAppAgentLink, applicantLink | | EFT method | saveEftPayment() | saveEftPayment() | N/A | | Unavailable states | NY, MT | MA, NH, AK (CA: next release) | WY, NY | | Status | Primary | Primary | Secondary (not fully live yet) |


GIGDB Flow

Not available in: NY, MT

GIGDB (Guaranteed Issue Graded Death Benefit) is a simplified-issue whole life product for ages 50–85 with no medical exam.

Complete flow

getGigdbQuote()
    ↓
startGigdbApplication()
    ↓
[if isDeclined = true] → stop - applicant not eligible
[if isQuoteChanged = true] → getExistingGigdbQuote()   (conditional)
    ↓
updateGigdbQuote()        ← optional; MUST be called before saveEftPayment
    ↓
saveEftPayment()          ← quote cannot be updated after this point
    ↓
prepareDocsAndGetDeliveryChannels()
    ↓
sendPinAndGetDocumentsLink() → verifyPin()
    ↓
finalSubmit()

Step 1 - getGigdbQuote(request: ThirdPartyGigdbQuoteRequest)

import { InstaBrainClient, Gender, PaymentFrequency } from '@instabrain-sdks/api-client';

const quoteResp = await client.getGigdbQuote({
  faceAmount: 15000,
  gender: Gender.Female,
  stateCode: 'TX',
  age: 65,
  dateOfBirth: null,
  paymentFreq: PaymentFrequency.Monthly,
  isSmoker: false,
  firstName: 'Jane',
  lastName: 'Doe',
  email: '[email protected]',
  phoneNum: null
});

const { quoteResponseId, quoteAmount } = quoteResp.selectedQuote;

Step 2 - startGigdbApplication(request: ThirdPartyGigdbAppReq)

import { BeneficiaryType, BeneficiaryRelationship } from '@instabrain-sdks/api-client';

const appResp = await client.startGigdbApplication({
  quoteResponseId: quoteResp.selectedQuote.quoteResponseId,
  firstName: 'Jane',
  lastName: 'Doe',
  email: '[email protected]',
  phoneNumber: '5551234567',
  isUsCitizen: true,
  isPayerAlsoOwnerAndInsured: true,
  isLegalUsResident: true,
  address: {
    addressLine1: '123 Main St',
    city: 'Austin',
    state: 'TX',
    zipcode: '73301'
  },
  dateOfBirth: '1958-06-15',
  socialSecurityNumber: '123-45-6789',
  birthJurisdiction: {
    state: 'TX',
    country: 'US'
  },
  isSmoker: false,
  nicotineInfo: null,
  hasExistingCoverage: false,
  willOtherCoverageBeReplacedOrFinanced: null,
  existingCoverageData: null,
  beneficiaryDetails: {
    beneficiaryType: BeneficiaryType.Person,
    beneficiaryPerson: {
      firstName: 'John',
      lastName: 'Doe',
      relationship: BeneficiaryRelationship.Spouse
    }
  }
});

if (appResp.isDeclined) {
  // Valid knockout - the applicant did not meet eligibility criteria.
  // This is NOT an error - do not throw.
  console.log('Application declined');
  return;
}

const { opportunityId, isQuoteChanged } = appResp;

**isDeclined: true** - the applicant did not meet eligibility criteria. This is a valid response, not an error. Stop the flow.

**isQuoteChanged: true** - the carrier adjusted the premium based on application data. Proceed to Step 3.

State-specific Other Insurance fields (Q-08)

Third-party integrations must display the exact regulated question text below to applicants — paraphrasing is not sufficient. Source: Confluence page 687800321 (GIGDB Start Application API).

When hasExistingCoverage === true, the following per-coverage flags are required for specific states:

| State | Field on existingCoverages[] | Type | Exact applicant-facing question text | |-----------|------------------------------------|-----------|---------------------------------------| | MA | requestsYieldIndices | boolean | Would you like to request yield indices for cash value policies? | | OK | notifyPresentInsurer | boolean | Please notify my present insurer(s) regarding this transaction? | | DE / GA | wantsPolicySummary | boolean | Do you want a policy summary statement from your existing insurer? | | FL | wantsComparativeInformationForm | boolean | Indicate whether or not you wish a Comparative Information Form from the proposed company and your existing insurer or insurers? |

For RI or WV, set existingCoverageData.areExistingPoliciesIssuedByFidelity: boolean.

Question text: "Are any of your existing policies issued by Fidelity Life Association?"

When willOtherCoverageBeReplacedOrFinanced === true and the state is KS or WA, populate the new top-level willOtherCoverageBeReplacedOrFinancedData object:

  • KSareReplacedPoliciesIssuedByFidelity: boolean

    Question text: "Are any of the policies you are considering replacing issued by Fidelity Life Association?"

  • WAotherInsuranceReplacementData — all 7 booleans are required; each specify* string is required when its boolean is true. See GigdbOtherInsuranceReplacementData for the full field list.
WA otherInsuranceReplacementData — exact question text per field

| Field | Exact applicant-facing question text | |---|---| | mayReduceBenefitsIncreasePremiums | Can there be reduced benefits or increased premiums in later years? | | specifyReduceBenefitsIncreasePremiums | Please explain | | hasNewPolicyCharges | Are there penalties, set up or surrender charges for the new policy? | | specifyNewPolicyCharges | Please explain, emphasizing any extra cost for early withdrawal. | | hasPriorPolicyCharges | Will there be penalties or surrender charges under the existing insurance as a result of the proposed transaction? | | specifyPriorPolicyCharges | Please explain | | hasTaxConsequences | Are there adverse tax consequences from the replacement under current tax law? | | specifyTaxConsequences | Please explain | | hasInterestConsiderations | Are interest earnings a consideration in this replacement? | | specifyInterestConsiderations | Please explain what portions of premiums or contributions will produce limited or no earnings. As pertinent, include the need for minimum deposits to enhance earnings, and the reduction of earnings that may result from set up charges, policy fees, and other factors. | | hasMinRequirementsBeforeInterest | Are minimum amounts required to be on deposit before excess interest will be paid? | | specifyMinRequirementsBeforeInterest| Please explain | | hasOtherAdverseEffects | Are there other short or long term effects from the replacement that might be materially adverse? | | specifyOtherAdverseEffects | Please explain |

Example WA payload (replacement disclosure):

willOtherCoverageBeReplacedOrFinancedData: {
  otherInsuranceReplacementData: {
    mayReduceBenefitsIncreasePremiums: true,
    specifyReduceBenefitsIncreasePremiums: 'Premiums may rise after year 5',
    hasNewPolicyCharges: true,
    specifyNewPolicyCharges: 'Surrender charges in years 1-3',
    hasPriorPolicyCharges: false,
    hasTaxConsequences: false,
    hasInterestConsiderations: true,
    specifyInterestConsiderations: 'Lower guaranteed rate on new policy',
    hasMinRequirementsBeforeInterest: false,
    hasOtherAdverseEffects: false
  }
}

Step 3 - Handle quote change (conditional)

let currentQuote = quoteResp.selectedQuote;

if (isQuoteChanged) {
  const updatedQuoteResp = await client.getExistingGigdbQuote(opportunityId);
  currentQuote = updatedQuoteResp.selectedQuote;
  // Show the updated premium to the applicant before continuing
}

Step 4 - updateGigdbQuote (optional - must be called BEFORE saveEftPayment)

If the applicant wants to change the face amount or payment frequency after the application has started:

const updatedQuoteResp = await client.updateGigdbQuote({
  opportunityId,
  faceAmount: 20000,
  paymentFreq: PaymentFrequency.Annually
});
// updatedQuoteResp.selectedQuote.quoteAmount reflects the new premium

Important: The quote cannot be updated after EFT payment details are saved. updateGigdbQuote() must be called before saveEftPayment().

Step 5 - saveEftPayment(request: ThirdPartyEftPaymentReq)

await client.saveEftPayment({
  opportunityId,
  accountHolderName: 'Jane Doe',
  routingNumber: '021000021',
  accountNumber: '123456789'
});
// After this point, the quote can no longer be updated.

Steps 6–7 - Secure Sign → Final Submit

See Secure Sign Flow and Final Submit.


ADB Flow

Not available in: MA, NH, AK

CA: Supported. The ADB application requires the occupation field for California residents — populate it via getAdbOccupationOptions().

ADB (Accidental Death Benefit) provides coverage for accidental deaths for ages 20–59.

Complete flow

getAdbRiderDetails()   ← check state availability & collect riderCodes
    ↓
getAdbOccupationOptions()  ← CA only — lookup occupation labels for the application
    ↓
getAdbQuote()
    ↓
startAdbApplication()
    ↓
[if isDeclined = true] → stop - applicant not eligible
    ↓
updateAdbQuote()       ← optional — MUST be before saveEftPayment
    ↓
getExistingAdbQuote()  ← optional — fetch the current quote after update
    ↓
saveEftPayment()          ← shared with GIGDB; quote cannot be updated after this point
    ↓
prepareDocsAndGetDeliveryChannels()
    ↓
sendPinAndGetDocumentsLink() → verifyPin()
    ↓
finalSubmit()

Step 0 - getAdbRiderDetails(stateCode: string) (optional pre-step)

Call before getAdbQuote() to check whether ADB is available in the applicant's state and to retrieve the riderCode values to pass into the quote request. Skip this step only if you already know which riders (if any) are available for the state.

Note: California (CA) is not supported — the API will return a 400 error for stateCode = "CA".

import { InstaBrainClient } from '@instabrain-sdks/api-client';

const riderDetails = await client.getAdbRiderDetails('TX');

if (riderDetails.flagProductNotAvailableForState) {
  // ADB not available in this state — do not proceed to quote
  return;
}

// Collect riderCodes the user wants to include (may be an empty array)
const selectedRiderCodes = riderDetails.riders.map(r => r.riderCode);
// Pass selectedRiderCodes into ThirdPartyAdbQuoteRequest.riders

Note: riders may be an empty array even when flagProductNotAvailableForState = false — this means no optional riders are configured for that state.

Step 0a - getAdbOccupationOptions(query?: string) (CA only)

Search occupation labels for the ADB product. Required only when address.state === "CA" on the application — the occupation field on ThirdPartyAdbAppReq must be populated with one or more labels returned by this endpoint.

// Filter to a short list
const matches = await client.getAdbOccupationOptions('nurse');
// ['Registered Nurse', 'Nurse Practitioner', 'Licensed Practical Nurse', ...]

// Or fetch the full list (omit the query)
const allOccupations = await client.getAdbOccupationOptions();

Skip this call entirely for non-CA states — occupation should be omitted from the application request when the state is not CA.

Step 1 - getAdbQuote(request: ThirdPartyAdbQuoteRequest)

import { InstaBrainClient, Gender, PaymentFrequency, AdbRiderType } from '@instabrain-sdks/api-client';

const quoteResp = await client.getAdbQuote({
  faceAmount: 100000,
  gender: Gender.Male,
  stateCode: 'TX',
  age: 35,
  paymentFreq: PaymentFrequency.Monthly,
  riders: [AdbRiderType.FamilyADB],
  firstName: 'John',
  lastName: 'Smith',
  email: '[email protected]'
});

const { quoteResponseId } = quoteResp.selectedQuote;

Rider notes:

  • riders is AdbRiderType[] - use the ADB-specific enum: AdbRiderType.FamilyADB, AdbRiderType.ReturnOfPremium, AdbRiderType.InflationBenefit
  • Do not reuse the Term product's RiderType enum — those values ('ADB Rider', 'Dependent Child Rider') are display titles, not ADB rider codes
  • Rider availability varies by state - see ADB Rider Availability

Step 2 - startAdbApplication(request: ThirdPartyAdbAppReq)

import { BeneficiaryType, BeneficiaryRelationship } from '@instabrain-sdks/api-client';

const appResp = await client.startAdbApplication({
  quoteResponseId: quoteResp.selectedQuote.quoteResponseId,
  firstName: 'John',
  lastName: 'Smith',
  email: '[email protected]',
  phoneNumber: '5559876543',
  isUsCitizen: true,
  isPayerAlsoOwnerAndInsured: true,  // must be true - knockout if false
  address: {
    addressLine1: '456 Oak Ave',
    city: 'Dallas',
    state: 'TX',
    zipcode: '75201'
  },
  dateOfBirth: '1988-03-20',
  socialSecurityNumber: '987-65-4321',
  hasExistingCoverage: false,
  beneficiaryDetails: {
    beneficiaryType: BeneficiaryType.Person,
    beneficiaryPerson: {
      firstName: 'Mary',
      lastName: 'Smith',
      relationship: BeneficiaryRelationship.Spouse
    }
  }
});

if (appResp.isDeclined) {
  // Valid knockout - stop the flow
  return;
}

const { opportunityId } = appResp;

Knockout rules - returns isDeclined: true (not an error, not thrown):

  • isPayerAlsoOwnerAndInsured === false → declined
  • isUsCitizen === false AND isLegalUsResident === false → declined

California residents — occupation field required:

const appResp = await client.startAdbApplication({
  // ...same fields as above, with CA address...
  address: { addressLine1: '...', city: 'Los Angeles', state: 'CA', zipcode: '90001' },
  occupation: ['Registered Nurse'],   // populate from getAdbOccupationOptions()
  // ...
});
  • occupation is an optional string[] on ThirdPartyAdbAppReq
  • Required only when address.state === "CA" — omit for all other states
  • Values must come from getAdbOccupationOptions()

District of Columbia residents — three top-level ACA acknowledgement booleans required:

Third-party integrations must display the exact regulated question text below to applicants — paraphrasing is not sufficient. Source: Confluence page 699924481 (ADB Start Application API).

| Field | Exact applicant-facing question text | |---|---| | hasMedicalCoverage | Do you have comprehensive medical coverage including the minimum essential coverage required by the Affordable Care Act (ACA) or are you treated as having minimum essential coverage due to your status as a bona fide resident of any possession of the United States? | | understandsBenefits | Do you understand most supplemental only policies may not pay full benefits if your ACA compliant minimum essential coverage plan is not in force? | | understandsLimitedBenefits| Do you understand that the benefits provided under this policy may be limited? |

await client.startAdbApplication({
  // ...same fields as above...
  address: { addressLine1: '100 7th St NW', city: 'Washington', state: 'DC', zipcode: '20001' },
  hasMedicalCoverage: true,        // ACA minimum essential coverage
  understandsBenefits: true,       // supplemental policy benefits acknowledgement
  understandsLimitedBenefits: true // limited benefits acknowledgement
});

OK / FL / DE residents with existing coverage — per-coverage acknowledgement:

When hasExistingCoverage === true, set the corresponding flag on each existingCoverages[] item. Display the exact regulated question text:

| State | Field on existingCoverages[] | Exact applicant-facing question text | |-------|------------------------------------|---------------------------------------| | OK | notifyPresentInsurer | Please notify my present insurer(s) regarding this transaction? | | FL | wantsComparativeInformationForm | Indicate whether or not you wish a Comparative Information Form from the proposed company and your existing insurer or insurers? | | DE | wantsPolicySummary | Do you want a policy summary statement from your existing insurer? |

ADB response differences from GIGDB/IB Term:

  • Response type is ThirdPartyAdbStartAppResp - contains only opportunityId and isDeclined
  • No agentLink, eAppAgentLink, applicantLink
  • No isQuoteChanged
  • No birthJurisdiction field in the application request (unlike GIGDB)

Step 3 - updateAdbQuote(request: ThirdPartyAdbUpdateQuoteReq) (optional - must be called BEFORE saveEftPayment)

Re-quote an in-flight ADB opportunity with a new faceAmount, paymentFreq, or riders list. The quote cannot be updated after EFT payment details are saved — the API returns "Quote update is not allowed when payment is already made".

import { PaymentFrequency } from '@instabrain-sdks/api-client';

const updatedQuote = await client.updateAdbQuote({
  opportunityId,
  faceAmount: 150000,
  paymentFreq: PaymentFrequency.Monthly,
  riders: []                     // pass [] to clear all riders
});

const { quoteResponseId, quoteAmount } = updatedQuote.selectedQuote;

Step 3a - getExistingAdbQuote(opportunityId: string) (optional)

Retrieve the current quote for an in-flight ADB opportunity. Useful any time you need to display or re-read the current premium after updateAdbQuote() or in the agent portal.

const currentQuote = await client.getExistingAdbQuote(opportunityId);
console.log(currentQuote.selectedQuote.quoteAmount);

Step 4 - saveEftPayment(request: ThirdPartyEftPaymentReq)

Same shared method as GIGDB — both products use the same POST /api/ThirdPartyPayment/save-eft-payment endpoint.

await client.saveEftPayment({
  opportunityId,
  accountHolderName: 'John Smith',
  routingNumber: '021000021',
  accountNumber: '987654321'
});
// After this point, the quote can no longer be updated.

Steps 5–6 - Secure Sign → Final Submit

See Secure Sign Flow and Final Submit.


IB Term Flow

Note: IB Term is not yet fully available in this SDK release. This section is provided for reference only. Primary products for integration are GIGDB and ADB.

Not available in: WY, NY

Complete flow

getQuote()
    ↓
startApplication()
    ↓
prepareDocsAndGetDeliveryChannels()
    ↓
sendPinAndGetDocumentsLink() → verifyPin()
    ↓
finalSubmit()

Step 1 - getQuote(request: ThirdPartyQuoteReq)

Provide exactly one of three mutually exclusive rating inputs:

  • rateClass - use RateClass enum
  • healthClass - use HealthClass enum (note: HealthClass.Preferred does not exist; valid values: Excellent, Great, Good, Average)
  • height + weightInLbs - build chart rating
import { Gender, PaymentFrequency, HealthClass } from '@instabrain-sdks/api-client';

const quoteResp = await client.getQuote({
  faceAmount: 500000,
  benefitPeriod: 20,
  flagTobaccoUse: false,
  gender: Gender.Male,
  stateCode: 'TX',
  zipCode: null,
  healthClass: HealthClass.Great,
  rateClass: null,
  height: { feet: 5, inches: 10 },
  weightInLbs: null,
  age: 40,
  dateOfBirth: null,
  riders: null,
  paymentFreq: PaymentFrequency.Monthly,
  firstName: 'John',
  lastName: null,
  email: null,
  phoneNum: null
});

const { quoteResponseId } = quoteResp.selectedQuote;

Field priority rules:

  • zipCode takes priority over stateCode if both are provided
  • dateOfBirth takes priority over age if both are provided

Step 2 - startApplication(request: ThirdPartyStartApplicationReq)

const appResp = await client.startApplication({
  quoteResponseId: quoteResp.selectedQuote.quoteResponseId,
  firstName: 'John',
  lastName: 'Smith',
  email: '[email protected]',
  phoneNumber: '5559876543'
});

const { opportunityId, agentLink, eAppAgentLink, applicantLink } = appResp;

Response links:

| Field | Description | | --------------- | -------------------------------------------------------------------- | | agentLink | URL for the agent to complete their section in the InstaBrain portal | | eAppAgentLink | Alternate agent URL used in eApp mode (some partner configurations) | | applicantLink | URL sent to the proposed insured for their self-service section |

Steps 3–4 - Secure Sign → Final Submit

See Secure Sign Flow and Final Submit.


Secure Sign Flow

Shared across all products. Used to electronically sign application documents after EFT payment.

Complete flow

prepareDocsAndGetDeliveryChannels(opportunityId)
    ↓
[if isSignCompleted = true] → skip directly to finalSubmit()
    ↓
sendPinAndGetDocumentsLink()
    ↓
[agent reads script aloud; applicant reviews and signs documents via link]
    ↓
verifyPin()     [or resendPin() if PIN was not received]
    ↓
finalSubmit()

Step 1 - prepareDocsAndGetDeliveryChannels(opportunityId: string)

Always call this first in the signing flow. If isSignCompleted is true, skip directly to finalSubmit().

const prepResp = await client.prepareDocsAndGetDeliveryChannels(opportunityId);

if (prepResp.isSignCompleted) {
  // Documents already signed - go to finalSubmit()
} else {
  console.log('SMS available:', prepResp.isSmsAvailable);
  console.log('Email available:', prepResp.isEmailAvailable);
}

Step 2 - sendPinAndGetDocumentsLink(request: ThirdPartySendPinReq)

At least one of flagSendSms or flagSendEmail must be true.

const pinResp = await client.sendPinAndGetDocumentsLink({
  opportunityId,
  flagSendSms: true,
  flagSendEmail: false
});

// pinResp.link          - URL for the applicant to review and sign documents
// pinResp.scriptHeader  - header for the disclosure section
// pinResp.script        - array of disclosure statements to read aloud
// pinResp.consentMessage - consent statement with the applicant's name

Step 3 - Agent reads script; applicant signs

  1. The agent reads each item in pinResp.script aloud to the proposed insured
  2. The applicant opens pinResp.link in their browser to review and sign documents
  3. (Non-code step - the SDK does not manage the applicant's browser session)

Step 4 - verifyPin(request: ThirdPartyVerifyPinReq)

isScriptReadConfirmed: true is required - confirms the agent has read the disclosure aloud.

const verifyResp = await client.verifyPin({
  opportunityId,
  pin: '123456',
  isScriptReadConfirmed: true
});

if (verifyResp.isVerified) {
  // Signing complete - proceed to finalSubmit()
}

Optional - resendPin (if PIN was not received):

await client.resendPin({
  opportunityId,
  flagSendSms: true,
  flagSendEmail: false
});

Final Submit

Shared across all products. Submits the completed application to the carrier for underwriting.

const submitResp = await client.finalSubmit(opportunityId);
console.log('Policy number:', submitResp.policyNumber);

**policyNumber: null** is normal - the carrier may not issue a policy number immediately (pending underwriting decision). This is not an error.

Throws PaymentNotMade if saveEftPayment() was not called before this step.


Reporting API

Three methods for retrieving data from the agent portal. pageSize and pageIndex are required.

import { AgentPortalReq } from '@instabrain-sdks/api-client';

const request: AgentPortalReq = {
  pageSize: 20,   // required
  pageIndex: 0    // required, 0-based
};

Methods

// Quotes not yet converted to applications
const prospects = await client.getProspects(request);
// Returns: { prospectCount: number, prospects: ThirdPartyProspectsDetails[] }

// Completed / sold policies
const sales = await client.getSales(request);
// Returns: { applicationCount: number, salesReport: ThirdPartySalesReport[], totalPremiumAmount: number }

// Applications in progress
const applications = await client.getApplications(request);
// Returns: { applicationCount: number, applications: ThirdPartyApplicationsReport[] }

Full AgentPortalReq field reference

| Field | Type | Required | Description | | -------------- | ------------------------- | -------- | --------------------------------------------- | | pageSize | number | Yes | Items per page | | pageIndex | number | Yes | Page index, 0-based | | startDate | string (ISO) | No | Start of date range | | endDate | string (ISO) | No | End of date range | | dayCount | number | No | Alternative to date range - fetch last N days | | userTimeZone | string | No | IANA timezone (e.g., 'America/Chicago') | | sort | AgentPortalReqSorting | No | Sort configuration | | filters | AgentPortalReqFilters[] | No | Array of filters | | searchParam | string | No | Text search |

Sorting (AgentPortalReqSorting)

sort: {
  value: 'createdOn',
  sortDescending: true
}

Filtering (AgentPortalReqFilters[])

import { SQLOperator } from '@instabrain-sdks/api-client';

filters: [
  {
    field: 'stateCode',
    operator: SQLOperator.Equal,
    value: 'TX'
  }
]

**SQLOperator enum values:**

| Enum Member | Numeric Value | Description | | -------------------- | ------------- | --------------------- | | Equal | 0 | Exact match | | NotEqual | 1 | Not equal | | GreaterThan | 2 | Greater than | | GreaterThanOrEqual | 3 | Greater than or equal | | LessThan | 4 | Less than | | LessThanOrEqual | 5 | Less than or equal | | Contains | 6 | Contains substring | | StartsWith | 7 | Starts with | | EndsWith | 8 | Ends with | | In | 9 | In list | | NotIn | 10 | Not in list |


Request Type Reference

ThirdPartyGigdbQuoteRequest

| Field | Type | Required | Constraints | | ------------- | ------------------ | -------- | ----------- | | faceAmount | number | null | Yes | | gender | Gender | Yes | | | stateCode | string | null | Yes | | age | number | null | Yes* | | dateOfBirth | string | null | Yes* | | paymentFreq | PaymentFrequency | Yes | | | isSmoker | boolean | null | Yes | | firstName | string | null | No | | lastName | string | null | No | | email | string | null | No | | phoneNum | string | null | No |

ThirdPartyGigdbAppReq

| Field | Type | Required | Constraints | | --------------------------------------- | -------------------------- | -------- | --------------------------------------------------- | | quoteResponseId | string | Yes | UUID from quote response | | firstName | string | null | No | | lastName | string | null | No | | email | string | null | No | | phoneNumber | string | null | No | | isUsCitizen | boolean | null | Yes | | isPayerAlsoOwnerAndInsured | boolean | null | Yes | | isLegalUsResident | boolean | null | No | | address | GigdbAddress | Yes | See sub-fields below | | dateOfBirth | string | null | Yes | | socialSecurityNumber | string | null | Yes | | birthJurisdiction | GigdbBirthJurisdiction | Yes | See sub-fields below | | isSmoker | boolean | null | Yes | | nicotineInfo | GigdbNicotineInfo | null | No | | hasExistingCoverage | boolean | null | Yes | | willOtherCoverageBeReplacedOrFinanced | boolean | null | No | | existingCoverageData | GigdbExistingCoverageData | null | No | | willOtherCoverageBeReplacedOrFinancedData | GigdbWillOtherCoverageBeReplacedOrFinancedData | null | No | Required when address.state is "KS" or "WA" AND willOtherCoverageBeReplacedOrFinanced === true | | beneficiaryDetails | BeneficiaryDetails | Yes | See Beneficiary Reference |

**GigdbAddress:**

| Field | Type | | -------------- | ------- | | addressLine1 | string | | city |string | | state | string | | zipcode |string |

**GigdbBirthJurisdiction:**

| Field | Type | Description | | --------- | ------- | ----------- | | state | string | null | | country | string | null |

**GigdbExistingCoverageData:**

| Field | Type | Required | Notes | | --------------------------------------- | ---------------------------- | -------- | ----- | | isExistingPolicyBeingTerminated | boolean | null | No | | existingCoverages | GigdbExistingCoverageInfo[] | null | Yes (when hasExistingCoverage === true) | | areExistingPoliciesIssuedByFidelity | boolean | null | No | Required when address.state is "RI" or "WV" |

**GigdbExistingCoverageInfo:**

| Field | Type | Required | Notes | | --------------------------------- | ---------------- | -------- | ----- | | nameOfTheCompany | string | null | Yes | | | insuranceAmount | string | null | Yes | | | dateOfIssue | string | null | Yes | YYYY-MM | | toBeReplaced | boolean | null | Yes | | | toBeFinanced | boolean | null | Yes | | | requestsYieldIndices | boolean | null | No | Required when address.state === "MA" (per-coverage Q-08) | | notifyPresentInsurer | boolean | null | No | Required when address.state === "OK" (per-coverage Q-08) | | wantsPolicySummary | boolean | null | No | Required when address.state is "DE" or "GA" (per-coverage Q-08) | | wantsComparativeInformationForm | boolean | null | No | Required when address.state === "FL" (per-coverage Q-08) |

**GigdbWillOtherCoverageBeReplacedOrFinancedData:** (new — IBS-63)

| Field | Type | Required | Notes | | -------------------------------------- | ------------------------------------- | -------- | ----- | | areReplacedPoliciesIssuedByFidelity | boolean | null | No | Required when address.state === "KS" AND willOtherCoverageBeReplacedOrFinanced === true | | otherInsuranceReplacementData | GigdbOtherInsuranceReplacementData | null | No | Required when address.state === "WA" AND willOtherCoverageBeReplacedOrFinanced === true |

**GigdbOtherInsuranceReplacementData:** (new — IBS-63, WA-only)

All 7 booleans are server-required (must be non-null). For each boolean set to true, the paired specify* string must be a non-empty explanation. When the boolean is false, the paired specify* may be omitted or null.

| Field | Type | Required when | Exact applicant-facing question text | | ------------------------------------------- | ---------------- | ------------------------------------------------- | --- | | mayReduceBenefitsIncreasePremiums | boolean | Always (WA) | Can there be reduced benefits or increased premiums in later years? | | specifyReduceBenefitsIncreasePremiums | string | null | When mayReduceBenefitsIncreasePremiums === true | Please explain | | hasNewPolicyCharges | boolean | Always (WA) | Are there penalties, set up or surrender charges for the new policy? | | specifyNewPolicyCharges | string | null | When hasNewPolicyCharges === true | Please explain, emphasizing any extra cost for early withdrawal. | | hasPriorPolicyCharges | boolean | Always (WA) | Will there be penalties or surrender charges under the existing insurance as a result of the proposed transaction? | | specifyPriorPolicyCharges | string | null | When hasPriorPolicyCharges === true | Please explain | | hasTaxConsequences | boolean | Always (WA) | Are there adverse tax consequences from the replacement under current tax law? | | specifyTaxConsequences | string | null | When hasTaxConsequences === true | Please explain | | hasInterestConsiderations | boolean | Always (WA) | Are interest earnings a consideration in this replacement? | | specifyInterestConsiderations | string | null | When hasInterestConsiderations === true | Please explain what portions of premiums or contributions will produce limited or no earnings. As pertinent, include the need for minimum deposits to enhance earnings, and the reduction of earnings that may result from set up charges, policy fees, and other factors. | | hasMinRequirementsBeforeInterest | boolean | Always (WA) | Are minimum amounts required to be on deposit before excess interest will be paid? | | specifyMinRequirementsBeforeInterest | string | null | When hasMinRequirementsBeforeInterest === true | Please explain | | hasOtherAdverseEffects | boolean | Always (WA) | Are there other short or long term effects from the replacement that might be materially adverse? | | specifyOtherAdverseEffects | string | null | When hasOtherAdverseEffects === true | Please explain |

ThirdPartyGigdbUpdateQuoteReq

| Field | Type | Required | Constraints | | --------------- | ------------------ | -------- | ------------------------------------ | | opportunityId | string | Yes | UUID from start application response | | faceAmount | number | Yes | $5,000–$25,000 | | paymentFreq | PaymentFrequency | Yes | |

Must be called before saveEftPayment(). Cannot update after EFT payment is saved.

ThirdPartyAdbQuoteRequest

| Field | Type | Required | Constraints | | ------------- | ------------------ | -------- | --------------------------------------------------------- | | faceAmount | number | Yes | | | gender | Gender | Yes | | | stateCode | string | Yes | 2-char US state; not MA, NH, AK; CA not yet supported | | age | number | Yes* | 20–59; required if dateOfBirth not provided | | dateOfBirth | string | Yes* | ISO 8601; required if age not provided | | paymentFreq | PaymentFrequency | Yes | | | riders | AdbRiderType[] | No | Use AdbRiderType enum values; availability varies by state | | firstName | string | No | Max 35 chars | | lastName | string | No | Max 35 chars | | email | string | No | Valid email format | | phoneNum | string | No | 10-digit numeric |

ThirdPartyAdbAppReq

| Field | Type | Required | Constraints | | --------------------------------------- | ------------------------- | -------- | --------------------------------------------------- | | quoteResponseId | string | Yes | UUID from ADB quote response | | firstName | string | Yes | Max 35 chars | | lastName | string | Yes | Max 35 chars | | email | string | Yes | Valid email format | | phoneNumber | string | Yes | 10-digit numeric | | isUsCitizen | boolean | Yes | | | isLegalUsResident | boolean | No | Required when isUsCitizen = false | | isPayerAlsoOwnerAndInsured | boolean | Yes | Must be true; knockout if false | | address | AdbAddress | Yes | See sub-fields below | | dateOfBirth | string | Yes | ISO 8601; age must be 20–59 | | socialSecurityNumber | string | Yes | Format: XXXXXXXXX (9 digits, no dashes) | | hasExistingCoverage | boolean | Yes | | | willOtherCoverageBeReplacedOrFinanced | boolean | No | Required if hasExistingCoverage = true | | existingCoverageData | AdbExistingCoverageData | No | Required if hasExistingCoverage = true | | occupation | string[] | No | Required when address.state === "CA"; values from getAdbOccupationOptions() | | hasMedicalCoverage | boolean | No | Required when address.state === "DC" (ACA acknowledgement) | | understandsBenefits | boolean | No | Required when address.state === "DC" (ACA acknowledgement) | | understandsLimitedBenefits | boolean | No | Required when address.state === "DC" (ACA acknowledgement) | | beneficiaryDetails | BeneficiaryDetails | Yes | See Beneficiary Reference |

**AdbAddress:**

| Field | Type | Constraints | | -------------- | -------- | ------------------------------------------- | | addressLine1 | string | | | city | string | | | state | string | 2-char; must match state used at quote time | | zipcode | string | 5-digit numeric |

**AdbExistingCoverageData:**

| Field | Type | Required | Notes | | --------------------------------- | -------------------------- | -------- | ----- | | isExistingPolicyBeingTerminated | boolean | Yes | | | existingCoverages | AdbExistingCoverageInfo[]| Yes | At least one entry required when present |

**AdbExistingCoverageInfo:**

| Field | Type | Required | Notes | | --------------------------------- | --------- | -------- | ----- | | nameOfTheCompany | string | Yes | | | insuranceAmount | string | Yes | | | dateOfIssue | string | Yes | YYYY-MM | | toBeReplaced | boolean | Yes | | | toBeFinanced | boolean | Yes | | | notifyPresentInsurer | boolean | No | Required when address.state === "OK" AND hasExistingCoverage === true | | wantsComparativeInformationForm | boolean | No | Required when address.state === "FL" AND hasExistingCoverage === true | | wantsPolicySummary | boolean | No | Required when address.state === "DE" AND hasExistingCoverage === true |

ThirdPartyEftPaymentReq (shared - GIGDB and ADB)

| Field | Type | Required | Description | | ------------------- | -------- | -------- | ------------------------------------ | | opportunityId | string | Yes | UUID from start application response | | accountHolderName | string | null | Yes | | routingNumber | string | null | Yes | | accountNumber | string | null | Yes |

Use saveEftPayment() for both GIGDB and ADB — both products share the same POST /api/ThirdPartyPayment/save-eft-payment endpoint.

ThirdPartyQuoteReq (IB Term - Secondary)

| Field | Type | Required | Constraints | | ---------------- | ---------------------------------- | -------- | ----------------------------------------------- | | faceAmount | number | Yes | See age-based limits below | | benefitPeriod | number | Yes | 10, 20, or 30 (age-dependent - see table below) | | flagTobaccoUse | boolean | Yes | | | gender | Gender | Yes | | | stateCode | string | null | Yes* | | zipCode | string | null | Yes* | | rateClass | RateClass | null | Yes* | | healthClass | HealthClass | null | Yes* | | height | { feet: number, inches: number } | Yes* | Required if weightInLbs provided | | weightInLbs | number | null | Yes* | | age | number | null | Yes* | | dateOfBirth | string | null | Yes* | | riders | ThirdPartyQuoteReqRider[] | null | No | | paymentFreq | PaymentFrequency | Yes | | | firstName | string | null | No | | lastName | string | null | No | | email | string | null | No | | phoneNum | string | null | No |

Face amount limits (age-based):

| Age | Min | Max | | -------- | ------- | ---------- | | Up to 55 | $50,000 | $1,000,000 | | 56 | $50,000 | $900,000 | | 57 | $50,000 | $800,000 | | 58 | $50,000 | $700,000 | | 59 | $50,000 | $600,000 | | 60 | $50,000 | $500,000 |

Benefit period availability:

| Age | Tobacco use | Available periods | | -------- | ----------- | ----------------- | | Up to 45 | Any | 10, 20, 30 | | 45–50 | Non-tobacco | 10, 20, 30 | | 45–50 | Tobacco | 10, 20 | | 51–60 | Any | 10, 20 |

ThirdPartySendPinReq

| Field | Type | Required | Constraints | | --------------- | --------- | -------- | --------------------------------------------------------------- | | opportunityId | string | Yes | | | flagSendSms | boolean | Yes | At least one of flagSendSms or flagSendEmail must be true | | flagSendEmail | boolean | Yes | At least one of flagSendSms or flagSendEmail must be true |

ThirdPartyResendPinReq

| Field | Type | Required | Constraints | | --------------- | --------- | -------- | ----------------------------------------- | | opportunityId | string | Yes | | | flagSendSms | boolean | Yes | At least one delivery flag must be true | | flagSendEmail | boolean | Yes | At least one delivery flag must be true |

ThirdPartyVerifyPinReq

| Field | Type | Required | Constraints | | ----------------------- | --------- | -------- | -------------------------------------------------- | | opportunityId | string | Yes | | | pin | string | Yes | PIN entered by the signer | | isScriptReadConfirmed | boolean | Yes | Must be true; confirms disclosure was read aloud |


Response Type Reference

BaseResponse<T>

All InstaBrain API responses are wrapped in this envelope:

interface BaseResponse<T> {
  flagStatus: boolean;    // true = success, false = API-level error
  value: T;              // the actual response data
  error: string | null;  // error message when flagStatus = false
  errorCode?: string;    // error code when flagStatus = false
}

The SDK unwraps this envelope automatically - integrators receive value directly. When flagStatus = false, the SDK throws APIValidationError. You never check flagStatus manually.

ThirdPartyQuoteResp

Returned by getGigdbQuote(), getAdbQuote(), getQuote(), updateGigdbQuote(), getExistingGigdbQuote().

interface ThirdPartyQuoteResp {
  productName: string | null;
  selectedQuote: Quote;
}

Key Quote fields:

| Field | Type | Description | | ------------------- | ------------- | -------------------------------------- | | quoteResponseId | string | UUID - pass to startXxxApplication() | | quoteAmount | number | null | | faceAmount | number | Coverage amount | | benefitPeriod | number | null | | paymentFrequency | string | null | | isMedicalRequired | boolean | Whether a medical exam is required | | selectedRiders | RidersList[] | null |

ThirdPartyStartAppResp (GIGDB, IB Term)

Returned by startGigdbApplication() and startApplication().

| Field | Type | Description | | ---------------- | --------- | --------------------------------------------- | | opportunityId | string | UUID - used for all subsequent calls | | agentLink | string | null | | eAppAgentLink | string | null | | applicantLink | string | null | | isDeclined | boolean | true = valid knockout (GIGDB); not an error | | isQuoteChanged | boolean | true = premium was adjusted (GIGDB) |

AdbRiderDetailsResp (ADB only)

Returned by getAdbRiderDetails().

| Field | Type | Description | |---|---|---| | riders | AdbRiderResp[] | Available riders for the state. May be empty even when product is available. | | flagProductNotAvailableForState | boolean | true = ADB not available in this state; stop. false = available; proceed to quote. |

AdbRiderResp

| Field | Type | Description | |---|---|---| | riderCode | AdbRiderType | Pass into ThirdPartyAdbQuoteRequest.riders to include this rider in the quote. Values: FamilyADB, ReturnOfPremium, InflationBenefit. | | riderTitle | string | Display title for UI rendering. | | riderDescription | string | Display description for UI rendering. |

ThirdPartyAdbStartAppResp (ADB only)

Returned by startAdbApplication(). Contains only two fields - no links, no isQuoteChanged:

| Field | Type | Description | | --------------- | --------- | ------------------------------------------ | | opportunityId | string | UUID - empty GUID when isDeclined = true | | isDeclined | boolean | true = knockout; stop the flow |

ThirdPartyPrepareDocsResp

| Field | Type | Description | | ------------------ | --------- | ---------------------------------- | | isSignCompleted | boolean | If true, skip to finalSubmit() | | isSmsAvailable | boolean | SMS delivery channel available | | isEmailAvailable | boolean | Email delivery channel available | | productName | string | null |

ThirdPartySendPinResp

| Field | Type | Description | | ---------------- | --------- | ----------- | | link | string | null | | scriptHeader | string | null | | script | string[] | null | | consentMessage | string | null |

ThirdPartyResendPinResp

| Field | Type | Description | | ------------- | --------- | ----------------------------------- | | flagPinSent | boolean | true when PIN resent successfully |

ThirdPartyVerifyPinResp

| Field | Type | Description | | ------------ | --------- | ------------------------------------------------ | | isVerified | boolean | true when PIN matched and documents are signed |

ThirdPartyFinalSubmitResp

| Field | Type | Description | | -------------- | ------- | ----------- | | policyNumber | string | null |


Enums and Constants

Gender

| Enum Member | Value | | --------------- | ---------- | | Gender.Male | 'Male' | | Gender.Female | 'Female' |

PaymentFrequency

| Enum Member | Value | | --------------------------- | ------------ | | PaymentFrequency.Monthly | 'Monthly' | | PaymentFrequency.Annually | 'Annually' |

HealthClass

| Enum Member | Value | | ----------------------- | ------------- | | HealthClass.Excellent | 'Excellent' | | HealthClass.Great | 'Great' | | HealthClass.Good | 'Good' | | HealthClass.Average | 'Average' |

Note: HealthClass.Preferred does not exist and will cause an API error if used.

RateClass

| Enum Member | Value | | ------------------------- | ------------------ | | RateClass.PreferredPlus | 'Preferred Plus' | | RateClass.Preferred | 'Preferred' | | RateClass.Standard | 'Standard' | | RateClass.StandardExtra | 'Standard Extra' |

Note: Values contain spaces - always use enum members, not raw strings.

RiderType

| Enum Member | Value | Coverage Range | | ------------------------------- | ------------------------- | ---------------- | | RiderType.ADBRider | 'ADB Rider' | $25,000–$250,000 | | RiderType.DependentChildRider | 'Dependent Child Rider' | $5,000–$25,000 |

Note: Values contain spaces - always use enum members.

AdbRiderType (ADB product only)

Rider codes accepted by ThirdPartyAdbQuoteRequest.riders and ThirdPartyAdbUpdateQuoteReq.riders, and returned by getAdbRiderDetails() as AdbRiderResp.riderCode.

| Enum Member | Value | | ------------------------------ | -------------------- | | AdbRiderType.FamilyADB | 'FamilyADB' | | AdbRiderType.ReturnOfPremium | 'ReturnOfPremium' | | AdbRiderType.InflationBenefit | 'InflationBenefit' |

Note: ADB has its own rider enum. Do NOT reuse the Term product's RiderType — those values ('ADB Rider', 'Dependent Child Rider') are display titles, not the codes the ADB API expects.

State

All 50 US states + DC and 12 Canadian provinces/territories:

US: AK, AL, AR, AZ, CA, CO, CT, DC, DE, FL, GA, HI, IA, ID, IL, IN, KS, KY, LA, MA, MD, ME, MI, MN, MO, MS, MT, NC, ND, NE, NH, NJ, NM, NV, NY, OH, OK, OR, PA, RI, SC, SD, TN, TX, UT, VA, VT, WA, WI, WV, WY

Canadian provinces/territories: AB, BC, MB, NB, NS, NT, NUNAVUT, ON, PE, PQ, SK, YT

Country

Full ISO country code enum. Common values: Country.UnitedStates ('US'), Country.Canada ('CA'). Used in GIGDB's birthJurisdiction.country.

BeneficiaryType

| Enum Member | Value | | --------------------------------- | ---------------------------------------- | | Person | 'Person' | | AllChildrenOfTheInsuredEqually | 'All Children Of The Insured Equally' | | AllChildrenOfTheMarriageEqually | 'All Children Of The Marriage Equally' | | InsuredEstate | 'Insured Estate' | | Business | 'Business' | | Corporation | 'Corporation' | | CharitableOrganization | 'Charitable Organization' | | Employer | 'Employer' | | Other | 'Other' | | Trust | 'Trust' |

BeneficiaryRelationship

36 values: Aunt, Boyfriend, Brother, BrotherInLaw, CommonLawHusband, CommonLawWife, Cousin, Daughter, DaughterInLaw, DomesticPartner, Father, FatherInLaw, FatherOfChild, Fiance, Fiancee, FormerSpouse, Friend, Girlfriend, Granddaughter, Grandfather, Grandmother, Grandson, Husband, LifePartner, Mother, MotherInLaw, MotherOfChild, Nephew, Niece, Sister, SisterInLaw, Son, SonInLaw, Spouse, Uncle, Wife

ADB Rider Availability

ADB_RIDER_AVAILABLE_STATES

ADB Rider available in: AL, AZ, AR, CA*, CO, CT, DC, DE, FL, GA, HI, ID, IL, IN, IA, KS, KY, LA, ME, MD, MI, MN, MS, MO, MT, NE, NV, NJ, NM, NC, ND, OH, OK, OR, PA, RI, SC, SD, TN, TX, UT, VT, VA, WV, WI

CA: ADB product support is coming in the next SDK release and is not yet available.

CHILD_RIDER_AVAILABLE_STATES

Dependent Child Rider available in: AL, AK, AZ, AR, CO, CT, DC, DE, GA, HI, ID, IL, IN, IA, KS, KY, LA, MD, MA, MI, MN, MS, MO, MT, NE, NV, NH, NJ, NM, NC, OH, OK, OR, PA, RI, SC, TN, TX, UT, VA, WV, WI

NO_RIDERS_AVAILABLE_STATES

No riders available in: WA

Coming in a future release: getAvailableRidersForState(stateCode) - programmatically query rider availability for a given state.


Beneficiary Reference

The beneficiaryDetails field uses a TypeScript discriminated union. Required fields differ by beneficiaryType. TypeScript enforces the correct shape at compile time.

Variant 1 - No extra fields

Used for InsuredEstate, AllChildrenOfTheInsuredEqually, AllChildrenOfTheMarriageEqually:

beneficiaryDetails: {
  beneficiaryType: BeneficiaryType.InsuredEstate
}

Variant 2 - Named person

Used when beneficiaryType = Person:

beneficiaryDetails: {
  beneficiaryType: BeneficiaryType.Person,
  beneficiaryPerson: {
    firstName: 'Jane',
    lastName: 'Doe',
    relationship: BeneficiaryRelationship.Spouse
  }
}