---
title: "How to Analyze Sales Rep Performance with Unified's CRM API"
img: https://s3.us-east-2.amazonaws.com/unified-article-images/how_to_analyze_sales_rep_performance_with_unified_crm_api-icon.png
date: 2026-01-10T00:00:00.000Z
tag: Product
description: "Sales performance features often start life as dashboards. They fail when the underlying data contract isn't stable."
url: "https://unified.to/blog/how_to_analyze_sales_rep_performance_with_unified_crm_api"
---

# How to Analyze Sales Rep Performance with Unified's CRM API
------
_January 10, 2026_

Sales performance features often start life as dashboards. They fail when the underlying data contract isn't stable.


Once you support multiple CRMs, 'rep performance' stops meaning one thing. Ownership can be a user, a team, or reassigned mid-deal. Deal status isn't always explicit. Probability may be inferred from stage, overridden manually, or ignored entirely. Historical context may or may not exist depending on how the CRM was configured.


For a PM, this creates sharp edges:

- Can performance metrics be trusted across Salesforce, HubSpot, and Zoho?
- Are reps being measured on closed revenue, pipeline, or a mix of both?
- Can you explain why a number changed if the CRM didn't record history?

Many products quietly blur these distinctions. Metrics are computed from cached data, undocumented fields, or assumptions that only hold for one CRM. The result looks correct—until a customer asks how it was calculated.


Unified's [CRM API](/crm) is designed to make those boundaries explicit. It exposes a real-time, normalized view of deals and ownership, without storing snapshots or inventing state. What you compute is always based on the current CRM truth, using documented fields only.


This guide shows how to analyze sales rep performance using that model—attributing deals to reps, calculating revenue and weighted pipeline, and optionally enriching reps via HRIS—while staying honest about what can and cannot be computed without your own storage layer.


## Prerequisites

- Node.js 18+
- A Unified account
- An API key
- A CRM `connection_id`
- `@unified-api/typescript-sdk` (v2.82.14)

```bash
npm install @unified-api/typescript-sdk
```


## Initialize the SDK


```typescript
import { UnifiedTo } from '@unified-api/typescript-sdk';

const sdk = new UnifiedTo({
  security: {
    jwt: process.env.UNIFIED_API_KEY!,
  },
});
```


## Step 1: Fetch Deals (Real-Time)


Unified's CRM API is real-time passthrough. Every request hits the source CRM live; there are no cached snapshots.


We'll fetch only the fields required for performance analysis.


```typescript
const connectionId = 'YOUR_CONNECTION_ID';

const deals = await sdk.crm.listCrmDeals({
  connectionId,
  limit: 100,
  offset: 0,
  // Optional incremental fetch:
  // updated_gte: '2026-01-11T00:00:00Z',
  fields: [
    'id',
    'user_id',
    'amount',
    'currency',
    'probability',
    'closed_at',
    'closing_at',
    'stage',
    'pipeline',
    'won_reason',
    'lost_reason',
  ],
});
```


**Notes**

- Returns a **`CrmDeal[]`** **array** (no cursor wrapper).
- [Pagination](/docs/reference/pagination) uses `limit` + `offset`.
- Filtering by rep is supported via `user_id`.
- There is no status filter; infer open/won/lost from fields.

## Step 2: Attribute Deals to Reps


Each deal has `user_id`, which references an HRIS employee.


```typescript
type Deal = typeof deals[number];

function filterDealsByRep(allDeals: Deal[], repId: string): Deal[] {
  return allDeals.filter(d => d.user_id === repId);
}
```


## Step 3: Aggregate Revenue (Currency-Safe)


Unified does **not** convert currencies. Aggregate per rep **per currency**.


```typescript
type RevenueByCurrency = Record<string, number>;
type RevenueByRep = Record<string, RevenueByCurrency>;

function aggregateRevenueByRep(allDeals: Deal[]): RevenueByRep {
  const result: RevenueByRep = {};

  for (const d of allDeals) {
    if (!d.user_id || typeof d.amount !== 'number' || !d.currency) continue;

    result[d.user_id] ??= {};
    result[d.user_id][d.currency] ??= 0;
    result[d.user_id][d.currency] += d.amount;
  }

  return result;
}
```


## Step 4: Weighted Pipeline (Optional)


Use `amount × probability` for open deals.


```typescript
type WeightedByRep = Record<string, RevenueByCurrency>;

function aggregateWeightedPipeline(allDeals: Deal[]): WeightedByRep {
  const result: WeightedByRep = {};

  for (const d of allDeals) {
    if (
      !d.user_id ||
      typeof d.amount !== 'number' ||
      typeof d.probability !== 'number' ||
      !d.currency ||
      d.closed_at // skip closed deals
    ) continue;

    const weighted = d.amount * d.probability;

    result[d.user_id] ??= {};
    result[d.user_id][d.currency] ??= 0;
    result[d.user_id][d.currency] += weighted;
  }

  return result;
}
```


## Step 5: Resolve Rep Names (Optional, HRIS)


Deals only carry `user_id`. To show rep names/emails, resolve via HRIS.


### Retrieve a Single Employee


```typescript
const rep = await sdk.hris.getHrisEmployee({
  connectionId,
  id: 'EMPLOYEE_ID',
  fields: ['id', 'name', 'emails', 'title'],
});
```


### Or List Employees (Bulk Join)


```typescript
const employees = await sdk.hris.listHrisEmployees({
  connectionId,
  limit: 100,
  offset: 0,
  fields: ['id', 'name', 'emails'],
});
```


Build a lookup map by `id` and join to your aggregates.


## What You Can Compute Reliably


Based on documented fields and real-time semantics:

- Total revenue per rep (by currency)
- Average deal size per rep
- Deal counts per rep
- Weighted pipeline (amount × probability)
- Sales cycle length (for closed deals: `closed_at - created_at`)
- Current pipeline distribution by stage

## What You Cannot Compute (Without Your Own Storage)


These are constrained by documented behavior:

- **Stage velocity / conversion rates** (no stage history)
- **Historical trends** (no snapshots; current-state only)
- **Cross-currency rollups** (no conversion)
- **Explicit status filtering** (no status enum)

If you need these, persist deal snapshots on your side.


## Summary


Using Unified's CRM API, you can analyze sales rep performance with live, normalized data:

- Fetch deals in real time
- Attribute to reps via `user_id`
- Aggregate revenue and weighted pipeline safely
- Optionally enrich reps via HRIS

→ [Start your 30-day free trial](https://app.unified.to/login)


→ [Book a demo](https://calendly.com/d/cph9-g8n-jzg/connect-with-unified)