RFM API
Compute RFM (Recency, Frequency, Monetary) scores for your contacts, retrieve analysis results, browse scored contacts, and create CRM segments from RFM cohorts. All endpoints require JWT authentication and the segments:read or segments:write permission.
For a user guide on RFM analysis in the dashboard, see RFM Analysis and RFM Segments.
Endpoints
| Method | Path | Description |
|---|---|---|
POST | /v1/rfm/analyze | Run or retrieve cached RFM analysis |
GET | /v1/rfm/analyses/{id} | Get a specific analysis by ID |
GET | /v1/rfm/analyses/{id}/contacts | List contacts with scores |
POST | /v1/rfm/analyses/{id}/segment | Create a CRM segment from an RFM cohort |
GET | /v1/rfm/events | List event names for config dropdowns |
GET | /v1/rfm/events/{event_name}/attributes | List numeric attributes for an event |
Authentication
All endpoints require a JWT bearer token:
| Operation | Required permission |
|---|---|
| Analyze, Get, List contacts, List events/attributes | segments:read |
| Create segment | segments:write |
Run Analysis
Run a new RFM analysis or return a cached result if one exists with matching parameters and has not expired (6-hour TTL).
Request Body
| Field | Type | Default | Description |
|---|---|---|---|
recency_event | string or null | null | Event name for recency (null = all events) |
frequency_event | string or null | null | Event name for frequency (null = same as recency) |
monetary_event | string or null | null | Event name for monetary value |
monetary_attribute | string or null | null | Numeric attribute within the event to sum |
date_range_days | integer | 30 | Lookback window in days (7--365) |
If monetary_event and monetary_attribute are both null, the engine uses an email engagement score: opens + (2 x clicks) from email_logs.
Response (200 OK)
Response Fields
| Field | Type | Description |
|---|---|---|
id | UUID | Analysis identifier |
total_contacts | integer | Total contacts scored |
segments | array | 10 segment results (see Segment Result below) |
heatmap | array | 25 cells (5x5 grid of R x F scores) |
score_boundaries | object | Quintile boundary values for each dimension |
date_from / date_to | datetime | The time window analyzed |
cached | boolean | Whether this is a cached result |
expires_at | datetime | When the cache expires |
Segment Result
| Field | Type | Description |
|---|---|---|
name | string | Machine-readable segment name (e.g., champions) |
display_name | string | Human-readable name (e.g., Champions) |
contact_count | integer | Contacts in this segment |
percentage | float | Percentage of total contacts |
avg_r_score / avg_f_score / avg_m_score | float | Average scores for the segment |
color | string | Hex color for visualization |
description | string | Behavior description |
suggested_action | string | Recommended marketing action |
Heatmap Cell
| Field | Type | Description |
|---|---|---|
r_score | integer | Recency score (1-5) |
f_score | integer | Frequency score (1-5) |
segment_name | string | Segment this cell belongs to |
display_name | string | Human-readable segment name |
contact_count | integer | Contacts with this (R, F) combination |
color | string | Hex color for visualization |
Get Analysis
Returns the same RFMAnalyzeResponse as the analyze endpoint, with cached: true.
List Contacts with Scores
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
segment | string | null | Filter by segment name (e.g., champions, at_risk) |
search | string | null | Search by email, first name, or last name |
limit | integer | 50 | Items per page (max 200) |
offset | integer | 0 | Pagination offset |
Response (200 OK)
Contact Score Fields
| Field | Type | Description |
|---|---|---|
contact_id | UUID | Contact identifier |
email | string or null | Contact email |
first_name / last_name | string or null | Contact name |
r_score / f_score / m_score | integer | Individual dimension scores (1-5) |
segment_name | string | Assigned segment |
recency_value | float or null | Days since last event |
frequency_value | float or null | Event count |
monetary_value | float or null | Summed monetary attribute or engagement score |
Results are ordered by composite RFM score (descending).
Create Segment from RFM Cohort
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
segment_name | string | Yes | RFM segment to create from (e.g., champions, at_risk, hibernating) |
custom_name | string | No | Custom segment name (defaults to "RFM: Display Name") |
Valid Segment Names
champions, loyal, potential_loyalist, new_contacts, promising, needs_attention, about_to_sleep, at_risk, cannot_lose, hibernating
Response (201 Created)
The created segment is dynamic and uses an rfm_segment filter operator that re-evaluates based on the original analysis parameters (events, attribute, date range).
List Event Names
Returns distinct event names in your workspace, used to populate configuration dropdowns.
Response (200 OK)
Limited to 200 event names, sorted alphabetically.
List Event Attributes
Returns numeric attributes from a specific event type, used to select the monetary attribute.
Response (200 OK)
The endpoint samples up to 100 events and returns attribute keys that have numeric values (integers, floats, or numeric strings). Sorted alphabetically.
Error Codes
| Status | Code | Description |
|---|---|---|
| 403 | Missing segments:read or segments:write permission | |
| 404 | Analysis not found | |
| 422 | Not enough contacts for analysis (minimum 5), invalid segment name, or validation error |