> ## Documentation Index
> Fetch the complete documentation index at: https://docs.revyops.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Activities & Scoring

> Configure how activities from every connected tool roll up into an engagement score for each person and company.

## Overview

**Activities & Scoring** unifies activities from every connected integration — and anything you push in yourself — into a single engagement score for each person and company. An activity is any timestamped event on a contact's or company's timeline: an email reply, a LinkedIn connection accepted, a call, a form submission, or something specific to your business like "Demo Booked."

Each activity type has one or more **scoring rules**: a point weight (from -100 to 100) and an optional **decay profile** that shrinks the activity's contribution over time. A person's score is the sum of their rules' contributions; a company's score is the sum of its people's scores plus any activity scored directly against the company.

This page covers the settings screen where those rules are configured — **Settings → Activities & Scores**, at `/dashboard/activities-scoring` — and how the resulting scores show up elsewhere in the product. For the request/response shape of the endpoints that feed activity data in, see the [Activities API reference](/api-reference/activities).

<Note>
  Activities & Scoring requires the **admin** or **client** role. The settings page and the sidebar link under **Customization** only appear if scoring is enabled — see below.
</Note>

## Enabling scoring

Scoring sits behind a single permission, `hasScoringAccess`, set at the **agency level** — it isn't a per-client toggle you manage yourself. Every client under an agency shares the same on/off state. If it's off, selecting a client on the Activities & Scoring page shows "Activities & Scoring is not enabled for this client," and the sidebar link doesn't appear at all. If your agency needs scoring turned on, ask your RevyOps contact — there's no self-serve switch for it in the dashboard.

## The Activities & Scoring page

Once scoring is enabled and a client is selected, the page shows one table with two sections:

| Column             | Meaning                                                                                                                                                         |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Activity Type**  | The underlying category — Email, LinkedIn, Call, SMS, WhatsApp, Form, Meeting, or Custom Activity.                                                              |
| **Activity Event** | The specific rule, e.g. "Opened," "Replied," or a custom activity's name.                                                                                       |
| **Source**         | The origin(s) this rule scores activity from — a connected integration (HubSpot, Close CRM, Smartlead, Instantly, etc.) or a source you've registered yourself. |
| **Applies To**     | Contact or Company.                                                                                                                                             |
| **Score Weight**   | The point value, -100 to 100, or "—" if unset.                                                                                                                  |
| **Decay**          | The attached decay profile, or "—" for none.                                                                                                                    |
| **Scoring Status** | Active, Score disabled, or No Score Set Up — see [Configuring scoring rules](#configuring-scoring-rules).                                                       |

A search box filters by activity name, type, or source. Each row has a **⋯** menu with View, Edit Scoring Rule, Add a source, a bulk Enable/Disable, and — for custom activities only — Delete.

<Tip>
  If a rule's Source column shows more than one origin, it's actually several underlying rules — one per origin — grouped into a single row because they share the same activity name. Editing weight, decay, or enabled state from that row applies the change to every source in the group at once. If those rules ever disagree (for example, right after adding a new source), the row shows **Mixed** in place of the value until you save a shared setting through Edit Scoring Rule.
</Tip>

## Standard Activities

The **Standard Activities** section lists rules RevyOps generates automatically, one per connected integration:

* **Email** — Opened, Replied, Replied (Interested), Bounced
* **LinkedIn** — Replied, InMail Replied, Connection Request Accepted
* **SMS** — Replied
* **WhatsApp** — Replied
* **Call** — Replied, plus one rule per Close CRM call disposition/outcome value your workspace uses
* **Meeting** — one rule per Close CRM meeting outcome value
* **Form** — Submitted (Close CRM only)

All standard activities score the **Contact**; there's no company-scoped standard type. These rules can't be deleted — the Delete action is disabled with a tooltip explaining they're managed by the integration. You can only edit their weight/decay/enabled state or turn them off.

A rule for a newly connected integration lands **disabled with no weight set** — it shows "No Score Set Up" until you configure it. Rules aren't retroactively pre-filled with a default weight; every client starts from zero and opts each rule in deliberately.

<Note>
  A "revyops" rule (the built-in public-API origin) exists for every client automatically, even with no integrations connected — any client can push standard activities in through the public API. It starts disabled like any other new rule.
</Note>

## Custom Activities

The **Custom Activities** section lists activity types your team defined — a name, an optional field schema, and whether it scores a Contact or a Company. Click **Create Activity** to open the 4-step wizard.

<Steps>
  <Step title="Details">
    Name the activity (e.g. "Attended Webinar"), optionally pick or create a **Source**, and choose **Applies To**: Contact or Company. Contact-scoped activity automatically rolls up into the contact's company score in addition to the contact's own score; company-scoped activity only affects the company.
  </Step>

  <Step title="Fields">
    Add any properties you want to capture when this activity is logged. Each field has a name and a type: Text, Number, Date, Dropdown (single select), or Dropdown (multi select) — dropdown fields can define a fixed list of allowed options.
  </Step>

  <Step title="Scoring">
    Set the weight with the -100 to 100 slider (drag left of 0 to subtract, right to add — 0 means it doesn't affect the score), optionally attach a decay profile, and toggle **Active**.
  </Step>

  <Step title="Ingestion">
    On save, RevyOps shows the **Activity Key** (a generated UUID — this is the `activity_key` you send in every request for this type), the webhook endpoint (`POST /api/public/activities/custom/`), and a copy-pasteable code sample in cURL, Node.js, or Python. Any tool that can send an HTTP POST works here, including Zapier and n8n.
  </Step>
</Steps>

Full request/response details — required fields, identifier matching, property validation, and error codes — are documented in [Log a custom activity](/api-reference/activities#log-a-custom-activity).

Renaming a custom activity type also renames its scoring rule everywhere it appears in this table. Deleting one removes its scoring rule too, but only works if nothing has ever been logged against it — see the [delete endpoint's behavior](/api-reference/activities#delete-a-custom-activity-type) for the exact conflict case.

## Sources: attributing activity to where it came from

Every standard and custom activity rule can optionally track which tool sent it, using a **source** — a short key like `zapier` or `trigify` that you register once and then pass in the `source` field of your requests. This is the same mechanism the [Activities API's `source` field](/api-reference/activities#the-source-field) documents from the sending side.

To add a source to an existing rule, open its **⋯** menu and choose **Add a source**. This opens a dialog where you:

1. Pick an existing source, or type a new name and click **Add New Source** (the source's key is auto-generated by lowercasing the name and replacing spaces with underscores).
2. Copy the webhook endpoint and sample payload shown — for standard activities this is `POST /api/public/activities/standard/<type>/`; for custom activities it's the same `POST /api/public/activities/custom/` endpoint, with `source` set in the payload.
3. Click **Save** to bind the source to that specific activity type.

Until a source is bound to a given activity type, sending that source in a request returns a `422` — see the API reference for the exact error shape.

<Warning>
  **Add a source** is only available for five activity types: standard **Email, LinkedIn, Call, SMS, and WhatsApp** rules, and custom activities you created yourself (not ones mirrored from Close CRM or HubSpot). Form submissions and the Close CRM per-disposition Call/Meeting rules can't take a custom source — the menu item is grayed out for them.
</Warning>

## Configuring scoring rules

Open **Edit Scoring Rule** from a row's menu to change:

* **Weight** — a -100 to 100 slider. Positive weights add points, negative weights subtract them.
* **Decay Profile** — see below.
* **Active** — whether the rule counts toward scoring at all.

The **Scoring Status** pill reflects the combination of weight and enabled state:

| Status              | Meaning                                                                                                                 |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| **No Score Set Up** | No weight has ever been set (weight is empty, not zero). The Enable/Disable menu item is unavailable until you set one. |
| **Score disabled**  | A weight is set, but the rule is turned off.                                                                            |
| **Active**          | A weight is set and the rule is on.                                                                                     |

<Warning>
  A weight of **0** is treated as a real, set value — the rule shows **Active** if enabled, not "No Score Set Up." But the scoring engine excludes zero-weight rules from every calculation entirely, so a 0-weight rule contributes nothing regardless of its Active state. If you want a rule to genuinely stop affecting scores, disable it (or leave the weight unset) rather than setting it to 0 — 0 and "disabled" look different in the UI but behave the same at scoring time.
</Warning>

Saving a rule change (weight, decay, or enabled) triggers a rescore job for the client — scores update in the background, not instantly on save.

## Decay profiles

A decay profile controls how much of a rule's weight still counts as the activity ages. Every client gets four built-in profiles, created automatically the first time the page loads:

| Profile        | Period       | Editable?                                       |
| -------------- | ------------ | ----------------------------------------------- |
| **Fast**       | 14 days      | Period only — name is fixed                     |
| **Medium**     | 60 days      | Period only — name is fixed                     |
| **Long**       | 180 days     | Period only — name is fixed                     |
| **Persistent** | Never decays | Locked — neither name nor period can be changed |

None of the four built-in profiles can be deleted, even Fast/Medium/Long whose period you can edit — attempting to delete one returns an error. Only profiles you create yourself (via the decay picker in the Create/Edit Scoring Rule dialogs) can be renamed, have their period changed, or be deleted; a custom profile's period must be at least 1 day.

Decay math is whole-day and linear:

```
remaining_fraction = max(0, 1 - floor(age_in_days) / period)
contribution = weight * remaining_fraction
```

A 14-day "Fast" profile reaches 0 contribution once the activity is 14 or more days old. Persistent always contributes at full weight (`remaining_fraction = 1`), no matter how old the activity is. Editing or deleting a decay profile triggers a rescore for every rule using it.

## How company scores are calculated

A company's score is the sum of two parts:

* **Persons total** — the live scores of every person linked to that company, summed.
* **Direct total** — the contribution of any company-scoped custom activities (Applies To: Company) logged directly against the company.

Contact-level activity is never scored twice against the company separately — it reaches the company score only through the linked person's own score. There's no independent "company weight" for standard activities, since none of the standard activity types are company-scoped; only custom activities can be.

<Warning>
  Logging a company-scoped custom activity doesn't trigger an immediate rescore the way a contact-scoped one does — there's no equivalent queue for companies, only for persons. It's picked up the next time that company's score is fully recomputed: whenever any scoring rule or decay profile is edited (which forces a full client-wide recompute), or when you look at the company through an explicit [Scoring period](#where-scores-show-up) window covering the activity's date, since windowed snapshots always re-derive direct company activity from scratch. Outside of those triggers, don't expect a company-scoped activity to move the live score the moment you log it.
</Warning>

## Where scores show up

* **People and Companies lists** — a sortable **Score** column, sorted by score descending by default. Hovering a score opens a breakdown popover showing each rule's contribution. The Filters panel has a **Scoring period** control that computes a windowed snapshot (a background job, not instant) using only activity inside the selected date range, with decay applied relative to the window's end — as opposed to the default live, all-time score. See [People → Scoring](/user-guide/people#scoring) for the full behavior of that control, including how missing-vs-zero scores render inside a window.
* **Person detail page** — a collapsible **Score History** chart (last 30/60/90/180/365 days, or a custom range) showing the score trend, with a hover popover breaking down each day's score by rule.

Both of these are consumption surfaces for the rules configured on this page — this page is where you decide *how* activity turns into points; the People/Companies pages are where you *read* the resulting scores.

## Troubleshooting

* **A rule shows "No Score Set Up" and I can't enable it.** You need to set a weight first (open Edit Scoring Rule) — the Enable/Disable action is unavailable until a weight exists, even a weight of 0.
* **I enabled a rule with weight 0 and scores didn't change.** That's expected — zero-weight rules are excluded from scoring regardless of their enabled state. Set a non-zero weight if you want the activity to count.
* **"Add a source" is grayed out.** It's only available for the five public-API standard types (Email, LinkedIn, Call, SMS, WhatsApp) and custom activities your team created. Form submissions and Close CRM's per-disposition call/meeting rules can't take a custom source.
* **A row shows "Mixed" for weight, decay, or status.** The rules grouped under that activity name (one per source) currently disagree. Open Edit Scoring Rule and save — it applies the same weight/decay/enabled to every source in the group at once.
* **I can't delete a decay profile.** Only profiles you created can be deleted. The four built-in profiles (Fast, Medium, Long, Persistent) always reject deletion, even though Fast/Medium/Long let you edit the period.
* **Sending a `source` value returns a 422.** The source either isn't registered yet, or isn't bound to that specific activity type. Register it (or add it) from the row's **Add a source** action first — see [The `source` field](/api-reference/activities#the-source-field).
* **Scores don't look like they've updated yet.** Rule and decay-profile changes trigger a background rescore job rather than an instant recalculation — give it a moment, especially on clients with a large contact base.
