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

@nova-sdk/api

v0.2.0

Published

TypeScript SDK for the Nova Embed API

Readme

@nova-sdk/api

TypeScript SDK for the Nova Embed API.

Installation

npm install @nova-sdk/api

Quick start

import { Nova } from '@nova-sdk/api';

const nova = new Nova({
  apiKey: 'sk_live_...',
  tenantId: 'acme-corp',
});

// Generate criteria for a job
const criteria = await nova.jobs.criteria.generate.create({
  jobId: 'job_123',
  body: {
    jobContext: {
      jobTitle: 'Senior Engineer',
      companyName: 'Acme Corp',
      jobDescription: 'We are looking for...',
    },
  },
});

// Submit a scoring job
const score = await nova.jobs.applications.scoringJobs.submit({
  jobId: 'job_123',
  applicationId: 'app_456',
  body: {
    resume: { type: 'url', url: 'https://example.com/resume.pdf' },
    jobDescription: 'We are looking for...',
  },
});

// Get the latest score for an application
const latest = await nova.jobs.applications.getLatestScore({
  jobId: 'job_123',
  applicationId: 'app_456',
});

Configuration

const nova = new Nova({
  // Required
  apiKey: 'sk_live_...',
  tenantId: 'acme-corp',

  // Optional
  baseUrl: 'https://embed.nova.dweet.com', // default
  retry: {
    maxRetries: 2,         // default: 2 (set to 0 to disable)
    initialDelayMs: 500,   // default: 500
    maxDelayMs: 30_000,    // default: 30,000
    backoffMultiplier: 2,  // default: 2
    retryableStatusCodes: [429, 500, 502, 503, 504], // default
  },
  fetch: customFetch,      // custom fetch implementation
});

Resource hierarchy

nova.criteriaLibrary.list(query?, opts?)
nova.criteriaLibrary.create(body, opts?)
nova.criteriaLibrary.get(criterionId, opts?)
nova.criteriaLibrary.update({ criterionId, body }, opts?)
nova.criteriaLibrary.delete(criterionId, opts?)

nova.jobs.criteria.getBatch(jobIds, opts?)
nova.jobs.criteria.list(jobId, opts?)
nova.jobs.criteria.set({ jobId, body }, opts?)
nova.jobs.criteria.archive(jobId, opts?)
nova.jobs.criteria.generate.create({ jobId, body }, opts?)
nova.jobs.criteria.generate.get({ jobId, criteriaGenerationId }, opts?)
nova.jobs.criteria.items.add({ jobId, body }, opts?)
nova.jobs.criteria.items.update({ jobId, criterionId, body }, opts?)
nova.jobs.criteria.items.remove({ jobId, criterionId }, opts?)
nova.jobs.criteria.versions.getCurrent(jobId, opts?)
nova.jobs.criteria.versions.list(jobId, opts?)
nova.jobs.criteria.versions.get({ jobId, criteriaVersionId }, opts?)

nova.jobs.applications.getLatestScore({ jobId, applicationId }, opts?)
nova.jobs.applications.scoringJobs.submit({ jobId, applicationId, body }, opts?)
nova.jobs.applications.scoringJobs.get({ jobId, applicationId, scoringJobId }, opts?)

nova.jobs.scoringBatches.submit({ jobId, body }, opts?)
nova.jobs.scoringBatches.getStatus({ jobId, scoringBatchId }, opts?)

nova.jobs.questionSets.create({ jobId, body }, opts?)
nova.jobs.questionSets.getCurrent(jobId, opts?)
nova.jobs.questionSets.get({ jobId, questionSetId }, opts?)

nova.rateLimitStatus()

Per-request tenant override

All methods accept an optional RequestOptions object as the last argument to override the tenant ID for that specific request:

await nova.criteriaLibrary.list({}, { tenantId: 'other-tenant' });

Error handling

All methods throw NovaApiError on non-2xx responses:

import { Nova, NovaApiError } from '@nova-sdk/api';

try {
  await nova.jobs.criteria.list('nonexistent-job');
} catch (err) {
  if (err instanceof NovaApiError) {
    console.log(err.code);      // 'JOB_NOT_FOUND'
    console.log(err.status);    // 404
    console.log(err.retryable); // false
    console.log(err.traceId);   // 'trace-abc-123'
    console.log(err.message);   // 'Job not found'
    console.log(err.details);   // field validation errors (on 400s)
  }
}

Retries

The SDK retries requests that fail with 429 (rate limited) or 5xx (server error) status codes using exponential backoff with jitter. The Retry-After response header is respected when present.

For other error responses (4xx), the SDK also checks the response body's retryable field — set by the API per the OpenAPI spec — and retries if true. The retryableStatusCodes config is a fast-path for well-known status codes; body-driven retryability covers the rest automatically.

Disable retries:

const nova = new Nova({
  apiKey: 'sk_live_...',
  tenantId: 'acme-corp',
  retry: { maxRetries: 0 },
});

Development

Generated code

src/generated/ contains the typed API client generated from docs/embed-api/openapi.json via @hey-api/openapi-ts. These files are committed to the repo so that workspace consumers and npm users don't need to run the generator.

To regenerate after OpenAPI spec changes:

cd packages/embed-sdk
pnpm generate

Workspace consumption

Within the monorepo, apps import source directly (./src/index.ts) via the exports field. Both apps/nova and apps/embed include "@nova-sdk/api" in their transpilePackages config. The publishConfig.exports override switches to dist/ for npm publishing.

Types

All request/response types and enums are exported from the package root:

import {
  type Criterion,
  type ScoringJob,
  type JobContext,
  CriterionImportance,
  ScoringJobStatus,
  ErrorCode,
} from '@nova-sdk/api';