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/sdkSetup
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:
| Parameter | Type | Required | Description |
|---|---|---|---|
status | string | No | active 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:
| Parameter | Type | Required | Description |
|---|---|---|---|
scorecardId | string | Yes | The 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:
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Scorecard name |
description | string | No | What this scorecard evaluates |
status | string | No | active or inactive (default: active) |
passingThreshold | number | No | Minimum 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:
| Parameter | Type | Required | Description |
|---|---|---|---|
scorecardId | string | Yes | Parent scorecard ID |
name | string | Yes | Category name |
description | string | No | What this category measures |
weight | number | Yes | Percentage 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:
| Parameter | Type | Required | Description |
|---|---|---|---|
scorecardId | string | Yes | Parent scorecard ID |
categoryId | string | Yes | Parent category ID |
key | string | Yes | Unique key within the scorecard |
name | string | Yes | Display name |
type | string | Yes | prompt, keyword, response_time, talk_time, silence, interruptions |
settings | object | Yes | Type-specific configuration (see criteria types below) |
Returns: Promise<ScorecardCriteria>
Criteria type settings
| Type | Settings |
|---|---|
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:
| Parameter | Type | Required | Description |
|---|---|---|---|
scorecardId | string | Yes | The scorecard to update |
name | string | No | New name |
description | string | No | New description |
status | string | No | active or inactive |
passingThreshold | number | No | New passing threshold |
Returns: Promise<Scorecard>
delete
Remove a scorecard.
await chanl.scorecard.delete('scorecard_abc123');Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
scorecardId | string | Yes | The 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:
| Parameter | Type | Required | Description |
|---|---|---|---|
callId | string | Yes | The call to evaluate |
scorecardId | string | Yes | The scorecard to grade against |
force | boolean | No | Re-evaluate even if already scored |
Returns: Promise<EvaluationResult>
The evaluation result includes:
| Field | Type | Description |
|---|---|---|
id | string | Evaluation result ID |
callId | string | The evaluated call |
scorecardId | string | The scorecard used |
score | number | Overall score (0-100) |
passed | boolean | Whether it met the passing threshold |
status | string | Evaluation status |
categoryScores | Record<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:
| Parameter | Type | Required | Description |
|---|---|---|---|
callId | string | Yes | The call to get results for |
scorecardId | string | No | Filter to a specific scorecard |
Returns: Promise<{ results: ScorecardResult[] }>
Types
import type {
Scorecard,
ScorecardCategory,
ScorecardCriteria,
ScorecardResult,
ScorecardStatus,
CriteriaType,
CreateScorecardRequest,
UpdateScorecardRequest,
EvaluateOptions,
} from '@chanl/sdk';