Skip to main content

Recommendations API

The recommendations router generates context-aware next-best-action recommendations for scored entities. Combines system rules (tier-based, signal-based) with admin-defined custom rules. Supports one-click action execution.

Router namespace: recommendations

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

Procedures

ProcedureTypeAccessDescription
getForEntityquerytenantContext-aware recommendations for an entity
listRulesqueryadminAll system and custom recommendation rules
upsertRulemutationadminCreate or update a custom rule
deleteRulemutationadminDelete a custom rule (system rules protected)
executeActionmutationtenantExecute a one-click recommendation action

getForEntity

Returns prioritized recommendations for a specific entity based on its current scores, tier, engagement signals, and buying group status.

recommendations.getForEntity.queryOptions(input)

Input

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

Response

[
{
"id": "rec_001",
"priority": 1,
"type": "engagement",
"title": "Schedule executive meeting",
"description": "Account is hot-tier with cooling champion engagement. Re-engage the decision maker.",
"action": "assign_to_rep",
"actionPayload": { "repId": "rep_123", "accountId": "acc_456" },
"ruleId": "rule_sys_hot_cooling",
"confidence": 0.88
},
{
"id": "rec_002",
"priority": 2,
"type": "buying_group",
"title": "Fill missing technical evaluator role",
"description": "Buying group is 75% complete. 2 candidates identified for technical evaluator.",
"action": "add_to_crm",
"actionPayload": { "email": "tech.lead@example.com", "role": "technical_evaluator" },
"ruleId": "rule_sys_missing_role",
"confidence": 0.75
}
]

Example

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

listRules

Returns all recommendation rules including built-in system rules and admin-created custom rules.

recommendations.listRules.queryOptions()

Access: Admin only

Input

None.

Response

[
{
"id": "rule_sys_hot_cooling",
"name": "Hot account with cooling engagement",
"isSystem": true,
"conditions": {
"tier": "hot",
"engagementVelocity": "decreasing"
},
"action": "assign_to_rep",
"priority": 1,
"enabled": true
},
{
"id": "rule_custom_001",
"name": "High-fit cold account outreach",
"isSystem": false,
"conditions": {
"tier": "cold",
"fitScore": { "min": 70 }
},
"action": "add_to_sequence",
"priority": 5,
"enabled": true
}
]

upsertRule

Creates a new custom rule or updates an existing one. System rules cannot be modified through this procedure.

recommendations.upsertRule.mutationOptions(options)

Access: Admin only

Input

FieldTypeRequiredDescription
ruleobjectYesRule definition
rule.idstringNoRule ID (omit to create new)
rule.namestringYesHuman-readable rule name
rule.conditionsobjectYesTrigger conditions (tier, score thresholds, signals)
rule.actionstringYesAction type to recommend
rule.prioritynumberNoPriority (lower = higher priority)
rule.enabledbooleanNoWhether the rule is active

Response

{
"id": "rule_custom_001",
"success": true
}

deleteRule

Deletes a custom recommendation rule. System rules are protected and cannot be deleted.

recommendations.deleteRule.mutationOptions(options)

Access: Admin only

Input

FieldTypeRequiredDescription
ruleIdstringYesRule identifier

Response

{ "success": true }
warning

Attempting to delete a system rule throws a FORBIDDEN error. System rules can only be disabled, not deleted.


executeAction

Executes a one-click action from a recommendation. Actions are dispatched to the appropriate integration (Salesforce, Customer.io, internal assignment).

recommendations.executeAction.mutationOptions(options)

Input

FieldTypeRequiredDescription
actionstringYesAction type (see table below)
payloadobjectYesAction-specific parameters

Supported Actions

ActionDescription
add_to_crmCreate or update a CRM record
assign_to_repAssign entity to a sales rep
add_to_sequenceAdd contact to a nurture sequence
create_taskCreate a CRM task for follow-up
send_alertSend a Slack notification
update_segmentUpdate Customer.io segment membership

Response

{
"executed": true,
"action": "assign_to_rep",
"result": {
"assignedTo": "rep_123",
"entityId": "acc_456"
}
}

Example

const trpc = useTRPC();

const mutation = useMutation(
trpc.recommendations.executeAction.mutationOptions({
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: trpc.recommendations.getForEntity.queryKey(),
});
},
})
);

mutation.mutate({
action: "assign_to_rep",
payload: { repId: "rep_123", accountId: "acc_456" },
});