Chanl

Scorecards Module

Create scorecards, evaluate calls, and retrieve results with the SDK

The Scorecards module provides methods for the full evaluation lifecycle: create scorecards with categories and criteria, evaluate calls, and retrieve detailed results.

Installation

npm install @chanl/sdk

Setup

import { Chanl } from '@chanl/sdk';

const chanl = new Chanl({
  apiKey: process.env.CHANL_API_KEY,
});

list

Retrieve all scorecards, optionally filtered by status.

const { scorecards, pagination } = await chanl.scorecard.list();

// Filter by status
const { scorecards } = await chanl.scorecard.list({
  status: 'active',
});

scorecards.forEach((scorecard) => {
  console.log(`${scorecard.name}: ${scorecard.categories.length} categories`);
});

Parameters:

ParameterTypeRequiredDescription
statusstringNoactive or inactive

Returns: Promise<{ scorecards: Scorecard[]; pagination: Pagination }>

get

Retrieve a single scorecard with its categories and criteria.

const scorecard = await chanl.scorecard.get('scorecard_abc123');

console.log('Name:', scorecard.name);
console.log('Passing threshold:', scorecard.passingThreshold);

scorecard.categories.forEach((category) => {
  console.log(`\n${category.name} (${category.weight}%)`);
  category.criteria.forEach((criterion) => {
    console.log(`  - ${criterion.name} (${criterion.type})`);
  });
});

Parameters:

ParameterTypeRequiredDescription
scorecardIdstringYesThe scorecard ID

Returns: Promise<Scorecard>

create

Create a new scorecard.

const scorecard = await chanl.scorecard.create({
  name: 'Customer Service Quality',
  description: 'Evaluates customer service call quality',
  status: 'active',
  passingThreshold: 75,
});

console.log('Created:', scorecard.id);

Parameters:

ParameterTypeRequiredDescription
namestringYesScorecard name
descriptionstringNoWhat this scorecard evaluates
statusstringNoactive or inactive (default: active)
passingThresholdnumberNoMinimum score to pass (0-100)

Returns: Promise<Scorecard>

createCategory

Add a weighted category to a scorecard.

const category = await chanl.scorecard.createCategory(scorecard.id, {
  name: 'Communication',
  description: 'Evaluates communication skills',
  weight: 40,
});

Parameters:

ParameterTypeRequiredDescription
scorecardIdstringYesParent scorecard ID
namestringYesCategory name
descriptionstringNoWhat this category measures
weightnumberYesPercentage weight (categories should sum to 100)

Returns: Promise<ScorecardCategory>

createCriteria

Add a criterion to a scorecard under a specific category.

// AI-evaluated criterion
await chanl.scorecard.createCriteria(scorecard.id, {
  categoryId: category.id,
  key: 'proper_greeting',
  name: 'Proper Greeting',
  type: 'prompt',
  settings: {
    description: 'Agent greeted the customer professionally with name and company',
  },
});

// Keyword-based criterion
await chanl.scorecard.createCriteria(scorecard.id, {
  categoryId: category.id,
  key: 'recording_disclosure',
  name: 'Recording Disclosure',
  type: 'keyword',
  settings: {
    matchType: 'must_contain',
    keywords: ['this call may be recorded', 'call is being recorded'],
  },
});

Parameters:

ParameterTypeRequiredDescription
scorecardIdstringYesParent scorecard ID
categoryIdstringYesParent category ID
keystringYesUnique key within the scorecard
namestringYesDisplay name
typestringYesprompt, keyword, response_time, talk_time, silence, interruptions
settingsobjectYesType-specific configuration (see criteria types below)

Returns: Promise<ScorecardCriteria>

Criteria type settings

TypeSettings
prompt{ description: string } -- natural language description for AI evaluation
keyword{ matchType: 'must_contain' | 'must_not_contain', keywords: string[] }
response_time{ maxMs: number }
talk_time{ minAgentPercent: number, maxAgentPercent: number }
silence{ maxSilenceMs: number, maxSilenceCount: number }
interruptions{ maxCount: number }

update

Update a scorecard's name, description, status, or passing threshold.

const updated = await chanl.scorecard.update('scorecard_abc123', {
  name: 'Updated Quality Scorecard',
  passingThreshold: 80,
  status: 'active',
});

Parameters:

ParameterTypeRequiredDescription
scorecardIdstringYesThe scorecard to update
namestringNoNew name
descriptionstringNoNew description
statusstringNoactive or inactive
passingThresholdnumberNoNew passing threshold

Returns: Promise<Scorecard>

delete

Remove a scorecard.

await chanl.scorecard.delete('scorecard_abc123');

Parameters:

ParameterTypeRequiredDescription
scorecardIdstringYesThe scorecard to delete

Returns: Promise<void>

evaluate

Run a scorecard against a call. The call must have finished processing (status ended).

const result = await chanl.scorecard.evaluate(
  '695d6957e21c0ceb325c394d',
  {
    scorecardId: 'scorecard_abc123',
    force: false, // Set true to re-evaluate
  }
);

console.log('Score:', result.score);
console.log('Passed:', result.passed);
console.log('Status:', result.status);
console.log('Category Scores:', result.categoryScores);

Parameters:

ParameterTypeRequiredDescription
callIdstringYesThe call to evaluate
scorecardIdstringYesThe scorecard to grade against
forcebooleanNoRe-evaluate even if already scored

Returns: Promise<EvaluationResult>

The evaluation result includes:

FieldTypeDescription
idstringEvaluation result ID
callIdstringThe evaluated call
scorecardIdstringThe scorecard used
scorenumberOverall score (0-100)
passedbooleanWhether it met the passing threshold
statusstringEvaluation status
categoryScoresRecord<string, number>Score per category

getResults

Retrieve detailed evaluation results for a call, including per-criteria scores, evidence, and suggestions.

const { results } = await chanl.scorecard.getResults(
  '695d6957e21c0ceb325c394d'
);

results.forEach((result) => {
  console.log(`${result.scorecardName}: ${result.score}%`);

  result.criteriaResults.forEach((cr) => {
    const status = cr.passed ? 'PASS' : 'FAIL';
    console.log(`  ${status} ${cr.name}: ${cr.score}`);
    if (cr.evidence) {
      console.log(`    Evidence: ${cr.evidence}`);
    }
  });
});

// Filter to a specific scorecard
const { results: filtered } = await chanl.scorecard.getResults(
  '695d6957e21c0ceb325c394d',
  { scorecardId: 'scorecard_abc123' }
);

Parameters:

ParameterTypeRequiredDescription
callIdstringYesThe call to get results for
scorecardIdstringNoFilter to a specific scorecard

Returns: Promise<{ results: ScorecardResult[] }>

Types

import type {
  Scorecard,
  ScorecardCategory,
  ScorecardCriteria,
  ScorecardResult,
  ScorecardStatus,
  CriteriaType,
  CreateScorecardRequest,
  UpdateScorecardRequest,
  EvaluateOptions,
} from '@chanl/sdk';

Next steps

On this page