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

@insurup/sdk

v0.1.22

Published

Type-safe TypeScript SDK for the InsurUp insurance platform with GraphQL support. Tree-shakeable, works everywhere.

Readme

InsurUp TypeScript SDK

npm version TypeScript License: MIT Zero Dependencies

Type-safe TypeScript SDK for the InsurUp insurance platform with GraphQL support. Zero dependencies, tree-shakeable, works everywhere.


Table of Contents


Installation

npm install @insurup/sdk
pnpm add @insurup/sdk
yarn add @insurup/sdk

Quick Start

import { DefaultInsurUpClient } from '@insurup/sdk';

const client = new DefaultInsurUpClient({
  tokenProvider: () => getAccessToken(),
});

const result = await client.customers.getCustomer('customer-id');

if (result.isSuccess) {
  console.log(result.data);
}

Architecture

graph TB
    subgraph SDK[DefaultInsurUpClient]
        direction TB
        HTTP[HttpTransport]
        GQL[GraphQLTransport]

        subgraph Clients[Specialized Clients]
            direction LR
            C1[customers]
            C2[policies]
            C3[proposals]
            C4[vehicles]
            C5[properties]
            C6[coverage]
            C7[cases]
            C8[agents]
            C9[webhooks]
            C10[...]
        end
    end

    App[Your Application] --> SDK
    HTTP --> API[InsurUp REST API]
    GQL --> GQLAPI[InsurUp GraphQL API]
    Clients --> HTTP
    Clients --> GQL

The SDK uses a compositional architecture:

  • DefaultInsurUpClient aggregates 17 specialized clients
  • All clients share HttpTransport and GraphQLTransport instances
  • GraphQL queries support filtering, searching, sorting, and type-safe field selection
  • Request/response interceptors hook into the transport layer
  • Results use discriminated unions for type-safe error handling

Result Handling

Every API call returns an InsurUpResult<T> — a discriminated union that's either a success or an error:

const result = await client.customers.getCustomer('id');

// Pattern 1: Boolean check
if (result.isSuccess) {
  console.log(result.data); // fully typed
} else {
  console.error(result.message);
}

// Pattern 2: Switch on kind
switch (result.kind) {
  case 'success':
    return result.data;
  case 'server-error':
    throw new Error(`${result.type}: ${result.message}`);
  case 'client-error':
    throw new Error(`Network error: ${result.message}`);
}

// Pattern 3: Throw on error
import { getDataOrThrow } from '@insurup/sdk';

const customer = getDataOrThrow(await client.customers.getCustomer('id'));

Error Types

| Kind | Types | | -------------- | ------------------------------------------------------------------------------------------------------- | | server-error | Unauthorized, AccessDenied, ResourceNotFound, InputValidation, BusinessValidation, Upstream | | client-error | Timeout, HttpRequestFailed, JsonDeserialization, NullResponse |


GraphQL Queries

The SDK includes built-in GraphQL support for querying entities with advanced filtering, searching, sorting, and type-safe field selection.

Available GraphQL Methods

| Client | Method | Description | | ------------ | -------------------------- | --------------------------------- | | customers | getCustomers() | Query customers with filters | | policies | getPolicies() | Query policies with filters | | policies | getPolicyTransfers() | Query policy transfers | | policies | getFilePolicyTransfers() | Query file-based policy transfers | | proposals | getProposals() | Query proposals with filters | | cases | getCases() | Query cases with filters | | agentUsers | getAgentUsers() | Query agent users with filters | | webhooks | getWebhookDeliveries() | Query webhook deliveries |

Basic Usage

// Query with pagination
const result = await client.customers.getCustomers({
  first: 10,
  after: 'cursor-string',
});

if (result.isSuccess) {
  console.log(result.data.nodes); // Customer[]
  console.log(result.data.totalCount); // Total count
  console.log(result.data.pageInfo); // Pagination info
}

Type-Safe Field Selection

Select only the fields you need — the return type automatically narrows:

const result = await client.policies.getPolicies({
  select: ['id', 'productBranch', 'grossPremium', 'state'] as const,
  first: 10,
});

// result.data.nodes[0] is typed as:
// { id: string; productBranch: ProductBranch; grossPremium: number | null; state: PolicyState }

Filtering and Searching (unified)

Every list query takes a single filter: field carrying the unified input shape. Each per-field entry is either a plain filter operator or, with a $search: true marker, a search clause. The SDK splits the unified input into the server's filter: and search: slots at request time.

Operator names match the wire (notContains, notStartsWith, notEndsWith). Search-side text ops (textSearch, wildcard, autocomplete, etc.) take both string shorthand and { value, score? } long form; in/nin take string[] shorthand or { values, score? }.

import { CustomerType, ProductBranch } from '@insurup/sdk';

// 1. Pure filter — every entry without `$search: true` routes to the wire filter slot
const filtered = await client.policies.getPolicies({
  first: 20,
  filter: {
    productBranch: { eq: ProductBranch.Traffic },
    grossPremium: { gte: 1000 },
    insuredCustomerName: { notContains: 'TEST' },
  },
});

// 2. Pure search — `$search: true` promotes a field, unlocking search-only operators
const searched = await client.customers.getCustomers({
  first: 10,
  filter: {
    // Shorthand string — SDK normalizes to { value: 'John' }
    name: { $search: true, textSearch: 'John' },
  },
});

// 3. Mixed — splits across both wire slots in one call
const both = await client.customers.getCustomers({
  first: 20,
  filter: {
    type: { eq: CustomerType.Individual }, // → wire `filter:`
    name: { $search: true, textSearch: 'John' }, // → wire `search:`
    identityNumber: { $search: true, in: ['123', '456'] }, // → wire `search:` (string[] shorthand)
  },
});

// 4. Relevance score boost / constant — long-form SearchTextInput
const boosted = await client.customers.getCustomers({
  first: 10,
  filter: {
    name: { $search: true, textSearch: { value: 'John', score: { boost: 2 } } },
    primaryEmail: { $search: true, contains: { value: '@acme.com', score: { constant: 5 } } },
  },
});

// 5. Combinators — and/or recursively
const compound = await client.customers.getCustomers({
  first: 20,
  filter: {
    and: [
      { type: { eq: CustomerType.Individual } },
      { name: { $search: true, textSearch: 'John' } },
    ],
  },
});

The $search marker is type-checked: it's only allowed on fields the server actually exposes as searchable. Marking a filter-only field is a compile error, as is using a search-only operator (like textSearch) without the marker.

If you're consuming the table adapter (@insurup/table-adapter-core), setFilter takes the exact same unified shape. The adapter forwards it to the SDK as-is; the SDK does the split.

Sorting

import { SortEnumType } from '@insurup/sdk';

const result = await client.cases.getCases({
  first: 20,
  order: [{ priorityScore: SortEnumType.Desc }, { createdAt: SortEnumType.Desc }],
});

Configuration

const client = new DefaultInsurUpClient({
  baseUrl: 'https://api.insurup.com/api/',
  tokenProvider: () => getAccessToken(),
  timeoutMs: 30000,
  customHeaders: { 'X-Request-Source': 'my-app' },
  retry: { retries: 3, backoffStrategy: 'exponential' },
  onRequest: (config) => config,
  onResponse: (result, config) => result,
});

| Option | Type | Default | Description | | --------------- | --------------------------------- | ------------------------------ | ------------------------ | | baseUrl | string | https://api.insurup.com/api/ | API base URL | | tokenProvider | () => string \| Promise<string> | — | OAuth token provider | | timeoutMs | number | 30000 | Request timeout | | customHeaders | Record<string, string> | — | Headers for all requests | | retry | RetryOptions | — | Retry configuration | | onRequest | RequestInterceptor | — | Pre-request hook | | onResponse | ResponseInterceptor | — | Post-response hook |


Interceptors

Add logging, correlation IDs, or transform requests/responses:

const client = new DefaultInsurUpClient({
  tokenProvider: () => token,

  onRequest: (config) => {
    console.log(`→ ${config.method} ${config.url}`);
    return {
      ...config,
      headers: { ...config.headers, 'X-Correlation-ID': crypto.randomUUID() },
    };
  },

  onResponse: (result, config) => {
    console.log(`← ${config.url} ${result.isSuccess ? '✓' : '✗'}`);
    return result;
  },
});

API Clients

Access specialized clients through the main client instance:

| Client | Description | | ---------------------- | -------------------------------------------- | | client.customers | Customer profiles, contact info, health data | | client.policies | Policy details, documents, representatives | | client.proposals | Insurance proposals, comparisons, purchasing | | client.vehicles | Vehicle data, brand/model lookups | | client.properties | Property data, DASK earthquake insurance | | client.coverage | Coverage configuration, coverage groups | | client.cases | Service requests, claims, complaints | | client.agents | Agent profiles, company connections | | client.agentBranches | Branch management | | client.agentRoles | Role-based access control | | client.agentUsers | Agency staff management | | client.agentSetup | Agent onboarding | | client.webhooks | Event notifications, integrations | | client.insurance | Companies, products, resource keys | | client.files | File uploads and management | | client.languages | Localization support | | client.templates | Document and email templates |


Compatibility

| Environment | Support | | ----------- | --------------------------------------------- | | Node.js | 18+ | | Browsers | ES2022+ (Chrome 94+, Firefox 93+, Safari 15+) | | Bun | ✓ | | Deno | ✓ |

Dual ESM/CJS builds included. Full tree-shaking support.


License

MIT