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
| Procedure | Type | Access | Description |
|---|---|---|---|
getMatrixData | query | tenant | Fetch scored entities for matrix visualization |
getEntityList | query | tenant | Paginated, sortable entity list with tier filtering |
getEntityDetail | query | tenant | Detailed scores for a single entity |
runScoring | mutation | admin | Execute a full scoring run |
getLastScoringRun | query | tenant | Get timestamp and counts from the last scoring run |
getMatrixData
Retrieves scored entities for the fit/engagement quadrant matrix visualization.
scoring.getMatrixData.queryOptions(input)
Input
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
entityTypes | ("person" | "account" | "opportunity")[] | No | all types | Filter by entity type |
limit | number (1-5000) | No | 500 | Maximum 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
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
entityType | "person" | "account" | "opportunity" | Yes | -- | Entity type to list |
page | number (min 1) | No | 1 | Page number |
pageSize | number (1-100) | No | 50 | Items per page |
sortBy | "fitScore" | "engagementScore" | "combinedScore" | "name" | No | "combinedScore" | Sort column |
sortDir | "asc" | "desc" | No | "desc" | Sort direction |
tierFilter | ("hot" | "warm" | "cool" | "cold")[] | No | all tiers | Filter 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
| Field | Type | Required | Description |
|---|---|---|---|
entityType | "person" | "account" | "opportunity" | Yes | Entity type |
entityId | string | Yes | Entity 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"
}
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
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
entityTypes | ("person" | "account" | "opportunity")[] | No | all types | Limit 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"] });
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());
Related Pages
- Scoring Config API -- Configure fit/engagement weights and thresholds
- Buying Groups API -- Buying group scoring with completeness multiplier
- tRPC Overview -- Client setup and procedure types