> ## 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

> Events logged against a contact or company, used for reporting and scoring.

An activity is a single event logged against a contact or a company: an email, a call, a LinkedIn message, an SMS, a WhatsApp message, or an occurrence of a custom activity type you define. Activities feed the [scoring engine](#scoring) and show up in the contact and company timelines in the UI.

There are two kinds of activity:

* **Standard activities**: call, email, linkedin\_message, sms, whatsapp. These have a fixed set of fields.
* **Custom activities**: activity types you define yourself (for example "Demo Booked" or "Trial Started"), each with its own schema of fields.

## Configuration

|                                 |                                                                                                                                 |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| Standard activity ingestion     | `POST /public/activities/standard/{type}/` where `type` is `call`, `email`, `linkedin_message`, `sms`, or `whatsapp`            |
| Custom activity type management | `GET`/`POST /public/activities/types/`                                                                                          |
| Custom activity ingestion       | `POST /public/activities/custom/` (also `PATCH`/`DELETE` to update or remove a type)                                            |
| MCP filter entity               | `activity` types are queryable through `query_entity`; each custom activity type gets its own entity id, `custom_activity_<id>` |
| UI                              | Settings > Scoring & Activities                                                                                                 |

## Common activity attributes

These fields exist on every activity, standard or custom, and are the ones exposed to the filter engine (`get_filter_schema` with `entity: "activity"` or a `custom_activity_<id>` entity).

| Attribute    | API field               | Type     | Writable?        | Notes                                                                                                                        |
| ------------ | ----------------------- | -------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| ID           | `id`                    | integer  | No               | Set by RevyOps on ingestion                                                                                                  |
| Origin       | `origin`                | string   | Set on ingestion | The [source](#custom-activity-types-and-sources) that sent the activity, e.g. `revyops`, `instantly`, or a custom source key |
| External ID  | `external_id`           | string   | No               | Set by RevyOps for activities synced from a connected CRM; null for activities logged through the public API                 |
| Created Date | `external_created_time` | datetime | Yes, on create   | When the activity happened. For standard activities this is `properties.timestamp`; for custom activities it is `occured_at` |

## Standard activity types

Each standard activity is logged by identifying the contact (`email`, `linkedin_url`, or `phone`, matched against the contact's own fields) and a `properties` object with the fields below. `source` is optional; omit it to use the implicit `revyops` source.

If a contact can't be matched from `email`/`linkedin_url`/`phone`, the request is rejected: a matching contact is required for standard activities.

### Call

`POST /public/activities/standard/call/`

| Attribute | API field              | Type     | Writable?     | Notes                                        |
| --------- | ---------------------- | -------- | ------------- | -------------------------------------------- |
| Direction | `properties.direction` | string   | **Required.** | `inbound` or `outbound`                      |
| Timestamp | `properties.timestamp` | datetime | Optional      | Defaults to the time the request is received |
| Duration  | `properties.duration`  | integer  | Optional      | Seconds, must be >= 0                        |
| Body      | `properties.body_text` | string   | Optional      | Call notes or transcript text                |

### Email

`POST /public/activities/standard/email/`

| Attribute  | API field               | Type     | Writable?     | Notes                                        |
| ---------- | ----------------------- | -------- | ------------- | -------------------------------------------- |
| Email type | `properties.email_type` | string   | **Required.** | `inbound`, `outbound`, or `bounced`          |
| Timestamp  | `properties.timestamp`  | datetime | Optional      | Defaults to the time the request is received |
| Opened at  | `properties.opened_at`  | datetime | Optional      |                                              |
| Interested | `properties.interested` | boolean  | Optional      |                                              |
| Subject    | `properties.subject`    | string   | Optional      |                                              |
| Body       | `properties.body_text`  | string   | Optional      |                                              |

This is a lighter-weight way to log an email event against a contact. For the full Email object (sends, replies, custom fields, and search) see [Emails](/data-model/emails).

### LinkedIn Message

`POST /public/activities/standard/linkedin_message/`

| Attribute    | API field                 | Type     | Writable?     | Notes                                                                                                                                         |
| ------------ | ------------------------- | -------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| Event type   | `properties.event_type`   | string   | **Required.** | `message_sent`, `message_reply_received`, `inmail_sent`, `inmail_reply_received`, `connection_request_sent`, or `connection_request_accepted` |
| Timestamp    | `properties.timestamp`    | datetime | Optional      | Defaults to the time the request is received                                                                                                  |
| Message text | `properties.message_text` | string   | Optional      |                                                                                                                                               |

### SMS

`POST /public/activities/standard/sms/`

| Attribute    | API field                 | Type     | Writable?     | Notes                                        |
| ------------ | ------------------------- | -------- | ------------- | -------------------------------------------- |
| Direction    | `properties.direction`    | string   | **Required.** | `inbound` or `outbound`                      |
| Timestamp    | `properties.timestamp`    | datetime | Optional      | Defaults to the time the request is received |
| Message text | `properties.message_text` | string   | Optional      |                                              |

### WhatsApp

`POST /public/activities/standard/whatsapp/`

Same fields as [SMS](#sms).

| Attribute    | API field                 | Type     | Writable?     | Notes                                        |
| ------------ | ------------------------- | -------- | ------------- | -------------------------------------------- |
| Direction    | `properties.direction`    | string   | **Required.** | `inbound` or `outbound`                      |
| Timestamp    | `properties.timestamp`    | datetime | Optional      | Defaults to the time the request is received |
| Message text | `properties.message_text` | string   | Optional      |                                              |

## Custom activity types and custom activities

A custom activity type is a definition you create once: a name, whether it applies to contacts or companies, and a field schema. Logging a custom activity is then a separate call that references the type and fills in its fields.

### Defining a type

`POST /public/activities/types/` (also available through the MCP `create_custom_activity_type` tool, which additionally sets up the type's scoring rule in one call).

| Attribute  | API field    | Type   | Writable?     | Notes                                                                                                                                                                                                 |
| ---------- | ------------ | ------ | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Name       | `name`       | string | **Required.** | Display name                                                                                                                                                                                          |
| Applies to | `applies_to` | string | Optional      | `contact` (default) or `company`                                                                                                                                                                      |
| Schema     | `schema`     | array  | Optional      | List of `{field_name, type, available_options}`. `type` is one of the [five custom field types](/data-model/custom-fields): `text`, `number`, `date`, `dropdown_singleselect`, `dropdown_multiselect` |

`PATCH /public/activities/custom/` updates a type's `name`, `schema`, or `applies_to` by `activity_key` (the type's id). `DELETE /public/activities/custom/` removes a type by `activity_key`; it fails if activities already exist for it.

### Logging an occurrence

`POST /public/activities/custom/`

| Attribute     | API field                        | Type     | Writable?     | Notes                                                                                                                                                                 |
| ------------- | -------------------------------- | -------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Activity type | `activity_key`                   | string   | **Required.** | The type's id, from `GET /public/activities/types/`                                                                                                                   |
| Occurred at   | `occured_at`                     | datetime | **Required.** |                                                                                                                                                                       |
| Contact match | `email`, `linkedin_url`, `phone` | string   | Optional      | Used to find the contact to link, same matching as standard activities                                                                                                |
| Company match | `domain`                         | string   | Optional      | Used to find the company to link, when the type applies to companies                                                                                                  |
| Source        | `source`                         | string   | Optional      | Defaults to `revyops`                                                                                                                                                 |
| Custom fields | `properties`                     | object   | Optional      | Keys must match the type's schema field names; values are validated against each field's type (dates as `YYYY-MM-DD`, dropdown values must be in `available_options`) |

### Custom activity sources

Sources (also called origins) are the keys a sender puts in `source` when logging an activity. Every client has the implicit `revyops` source; additional sources (for example a webhook integration) can be registered and scoped to the activity types they're allowed to send. See the MCP `list_sources`, `create_source`, `update_source`, and `delete_source` tools.

## Relationships

* **Contact**: a standard or contact-scoped custom activity links to one contact, matched by email, LinkedIn URL, or phone at ingestion time. A contact's activities are reachable through relations like `emails`, `calls`, `linkedin_messages`, `sms_messages`, `whatsapp_messages`, and the custom activity relations exposed by `get_filter_schema`.
* **Company**: a company-scoped custom activity links to one company, matched by domain.
* **Person**: a contact's activities also roll up to that contact's person record.

## Scoring

Every scored activity is tied to a scoring rule with a **weight** (-100 to 100) and, optionally, a **decay profile**. Each time the activity occurs, its weight is added to the person's or company's total score. As the activity ages, its contribution fades according to its decay profile:

```
current value = original weight × (1 − days elapsed ÷ decay length)
```

A decay profile with a period of `-1` is persistent: it never decays. The total score shown in the UI is the sum of every scored activity's current (post-decay) value.

A scoring rule can also carry a frequency cap, which limits how often an occurrence adds points to the same person: every time, once per time window, or once per distinct value of one of the activity's fields. See the MCP `list_scoring_rules` and `update_scoring_rule` tools, and `list_decay_profiles` for managing decay profiles.

## Related endpoints and MCP tools

**Public API**

* `POST /public/activities/standard/call/`, `.../email/`, `.../linkedin_message/`, `.../sms/`, `.../whatsapp/`
* `GET`/`POST /public/activities/types/`
* `POST`/`PATCH`/`DELETE /public/activities/custom/`

**MCP tools**

* `list_sources`, `create_source`, `update_source`, `delete_source`
* `set_activity_sources`
* `list_custom_activity_types`, `create_custom_activity_type`, `update_custom_activity_type`, `delete_custom_activity_type`
* `list_scoring_rules`, `update_scoring_rule`
* `list_decay_profiles`, `create_decay_profile`, `update_decay_profile`, `delete_decay_profile`
* `get_filter_schema`, `query_entity` (entity `activity`, or a specific `custom_activity_<id>`)
