Skip to main content
Criteria define what makes a candidate a good fit for a role. Nova stores criteria server-side and automatically uses them when scoring candidates - you don’t need to store or pass criteria yourself.

Why Server-Side Criteria?

We chose to manage criteria server-side for several reasons:

Simpler Integration

No need to store criteria in your database or pass them with every score request. Just reference the job ID.

Strong Traceability

Every score is automatically linked to the exact criteria version used, enabling full audit trails.

Easy Updates

Update criteria via API when requirements are refined. Changes apply to future scores only.

Reduced Errors

No risk of criteria drift between your system and ours, or accidentally scoring with outdated criteria.

Criteria Lifecycle

Criteria Replacement & Versioning

Criteria Replacement: Calling Generate Criteria for a job that already has criteria will replace the existing criteria with the newly generated set. Previous criteria versions are tracked internally for audit purposes - all historical scores retain their original criteria for full traceability.

Importance Levels

Each criterion includes an importance level that affects scoring:
LevelImpact on ScoringExample
MUST_HAVEDisqualifier if unmet”Valid work authorization”
PREFERREDSignificant concern if missing”5+ years experience”
NICE_TO_HAVEMinor concern only”Open source contributions”

Criteria Quality

Generated criteria are:
  • Concise: 8-16 words each
  • Verifiable: Can be assessed from a resume
  • Specific: Clear enough for consistent evaluation
  • Balanced: Mix of technical and soft requirements

Answer Validation

When providing answers to clarification questions, the API validates:
CheckError CodeDescription
questionSetId requiredVALIDATION_ERRORIf answers provided, questionSetId is required
Valid question setQUESTION_SET_NOT_FOUNDMust be a valid, existing question set
Answer IDs matchANSWER_MISMATCHEach answer ID must match a question in the set
Answer types matchANSWER_MISMATCHAnswer type must match question type
You don’t need to answer every question. Partial answers are allowed - provide answers for whichever questions were completed.

Available Operations

Criteria Library

Build a library of reusable criteria at the tenant level. Save commonly-used requirements once and add them to any job with a single API call.

Criteria Library

Learn how to store and reuse criteria across jobs

Example Integration

// 1. Generate criteria when job is created
const generateResponse = await fetch(
  'https://embed.nova.dweet.com/v1/criteria/generate',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'X-Tenant-Id': tenantId,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      jobContext: {
        jobId: job.id,
        jobTitle: job.title,
        companyName: company.name,
        jobDescription: job.description,
      },
    }),
  }
);

const { criteria, status } = await generateResponse.json();
console.log(`Generated ${criteria.length} criteria for job ${job.id}`);

// 2. Later, view criteria to show in your UI
const getResponse = await fetch(
  `https://embed.nova.dweet.com/v1/criteria/${job.id}`,
  {
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'X-Tenant-Id': tenantId,
    },
  }
);

const currentCriteria = await getResponse.json();
displayCriteria(currentCriteria);

// 3. Add a new criterion discovered during interviews
const addResponse = await fetch(
  `https://embed.nova.dweet.com/v1/criteria/${job.id}`,
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'X-Tenant-Id': tenantId,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      text: 'Experience with distributed systems',
      importance: 'PREFERRED',
    }),
  }
);

// 4. Edit a criterion to adjust importance
const editResponse = await fetch(
  `https://embed.nova.dweet.com/v1/criteria/${job.id}/${criterionId}`,
  {
    method: 'PATCH',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'X-Tenant-Id': tenantId,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      importance: 'MUST_HAVE',
    }),
  }
);

// 5. Remove a criterion that's no longer relevant
const removeResponse = await fetch(
  `https://embed.nova.dweet.com/v1/criteria/${job.id}/${criterionId}`,
  {
    method: 'DELETE',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'X-Tenant-Id': tenantId,
    },
  }
);

// 6. Archive when job closes
const archiveResponse = await fetch(
  `https://embed.nova.dweet.com/v1/criteria/${job.id}`,
  {
    method: 'DELETE',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'X-Tenant-Id': tenantId,
    },
  }
);

Next Step

Once you have criteria, you’re ready to Score Candidates.