Skip to main content

Scoring API

The scoring router provides procedures for executing scoring runs and querying scored entity data. All procedures are tenant-scoped. Scoring execution requires admin access.

Router namespace: scoring

Source: src/server/trpc/routers/scoring.ts

Procedures

ProcedureTypeAccessDescription
getMatrixDataquerytenantFetch scored entities for matrix visualization
getEntityListquerytenantPaginated, sortable entity list with tier filtering
getEntityDetailquerytenantDetailed scores for a single entity
runScoringmutationadminExecute a full scoring run
getLastScoringRunquerytenantGet timestamp and counts from the last scoring run

getMatrixData

Retrieves scored entities for the fit/engagement quadrant matrix visualization.

scoring.getMatrixData.queryOptions(input)

Input

FieldTypeRequiredDefaultDescription
entityTypes("person" | "account" | "opportunity")[]Noall typesFilter by entity type
limitnumber (1-5000)No500Maximum entities to return

Response

[
{
"id": "eng_abc123",
"entityType": "account",
"entityId": "acc_456",
"fitScore": 82.5,
"engagementScore": 67.3,
"combinedScore": 74.9,
"tier": "warm"
}
]

Example

const trpc = useTRPC();
const { data } = useQuery(
trpc.scoring.getMatrixData.queryOptions({
entityTypes: ["person", "account"],
limit: 1000,
})
);

getEntityList

Returns a paginated, sortable list of scored entities with optional tier filtering.

scoring.getEntityList.queryOptions(input)

Input

FieldTypeRequiredDefaultDescription
entityType"person" | "account" | "opportunity"Yes--Entity type to list
pagenumber (min 1)No1Page number
pageSizenumber (1-100)No50Items per page
sortBy"fitScore" | "engagementScore" | "combinedScore" | "name"No"combinedScore"Sort column
sortDir"asc" | "desc"No"desc"Sort direction
tierFilter("hot" | "warm" | "cool" | "cold")[]Noall tiersFilter by score tier

Response

{
"items": [
{
"id": "eng_abc123",
"entityType": "account",
"entityId": "acc_456",
"fitScore": 82.5,
"engagementScore": 67.3,
"combinedScore": 74.9,
"tier": "warm",
"scoreBreakdown": { "...": "..." },
"scoredAt": "2026-03-05T10:30:00.000Z"
}
],
"total": 248,
"page": 1,
"pageSize": 50
}

Example

const trpc = useTRPC();
const { data } = useQuery(
trpc.scoring.getEntityList.queryOptions({
entityType: "person",
page: 1,
pageSize: 25,
sortBy: "combinedScore",
sortDir: "desc",
tierFilter: ["hot", "warm"],
})
);

getEntityDetail

Returns detailed scoring data for a single entity including score breakdown.

scoring.getEntityDetail.queryOptions(input)

Input

FieldTypeRequiredDescription
entityType"person" | "account" | "opportunity"YesEntity type
entityIdstringYesEntity identifier

Response

{
"entityType": "account",
"entityId": "acc_456",
"fitScore": 82.5,
"engagementScore": 67.3,
"combinedScore": 74.9,
"tier": "warm",
"scoreBreakdown": {
"fit": { "industry": 20, "employeeCount": 15, "revenue": 25 },
"engagement": { "emailOpens": 30, "pageViews": 20, "meetings": 17.3 }
},
"scoredAt": "2026-03-05T10:30:00.000Z"
}
Not Found

Throws NOT_FOUND if no scored record exists for the given entity type and ID.

Example

const trpc = useTRPC();
const { data } = useQuery(
trpc.scoring.getEntityDetail.queryOptions({
entityType: "account",
entityId: "acc_456",
})
);

runScoring

Executes a full scoring run for the current tenant. This invokes the ScoringOrchestrator which computes fit scores, engagement scores, combined scores, and tier assignments for all entities.

scoring.runScoring.mutationOptions(options)

Access: Admin only

Input

FieldTypeRequiredDefaultDescription
entityTypes("person" | "account" | "opportunity")[]Noall typesLimit scoring to specific entity types

Response

The orchestrator returns a summary of the scoring run with counts per entity type.

Example

const trpc = useTRPC();
const queryClient = useQueryClient();

const mutation = useMutation(
trpc.scoring.runScoring.mutationOptions({
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: trpc.scoring.getMatrixData.queryKey(),
});
},
})
);

mutation.mutate({ entityTypes: ["person", "account"] });
tip

After a scoring run completes, invalidate related queries to refresh dashboards with the latest data.


getLastScoringRun

Returns the timestamp of the most recent scoring run and the count of scored entities by type.

scoring.getLastScoringRun.queryOptions()

Input

None.

Response

{
"lastScoredAt": "2026-03-05T10:30:00.000Z",
"entityCounts": {
"people": 1250,
"accounts": 340,
"opportunities": 89
}
}

If no scoring run has occurred, lastScoredAt is null and all counts are 0.

Example

const trpc = useTRPC();
const { data } = useQuery(trpc.scoring.getLastScoringRun.queryOptions());