Dynamic Sets
Dynamic sets are user-curated sets of comparison listings used to track competitive performance. Use these endpoints to build a set from scratch (search for candidate listings near a location, create a set from them, and upgrade it to paid), list a user's sets, inspect a set's definition and member listings, retrieve aggregated performance metrics, manage which of the user's own listings the set is associated with, and fetch a set's change history, time-series metrics, and metric distributions.
GET /sets returns both free and paid sets; the is_paid field on each set indicates which. Everything involved in building a set works on a free one — creating it, adding and removing its member listings, reviewing them, and managing which of your own listings it is associated with. What the paid plan buys is the set-level analytics computed across the set, including its price calendar. A paid-only endpoint returns 404 Not Found for a free set, which is indistinguishable from a set that does not exist, so check is_paid before calling one.
| Endpoint | Free sets | Paid sets |
|---|---|---|
GET /sets | ✅ | ✅ |
POST /sets | ✅ (creates a free set) | — |
GET /sets/candidates | ✅ (no set required) | ✅ |
GET /sets/{set_id} | ✅ | ✅ |
POST /sets/{set_id}/upgrade | ✅ (this is what upgrades it) | — |
POST /sets/{set_id}/share | ✅ | ✅ |
GET /sets/{set_id}/listings | ✅ | ✅ |
PUT /sets/{set_id}/listings | ✅ | ✅ |
DELETE /sets/{set_id}/listings | ✅ | ✅ |
GET /sets/{set_id}/associated_listings | ✅ | ✅ |
PUT /sets/{set_id}/associated_listings | ✅ | ✅ |
DELETE /sets/{set_id}/associated_listings | ✅ | ✅ |
GET /sets/{set_id}/aggregated_metrics | ❌ 404 | ✅ |
GET /sets/{set_id}/price_calendar | ❌ 404 | ✅ (up to 25 members) |
GET /sets/{set_id}/time_series | ❌ 404 | ✅ |
GET /sets/{set_id}/distribution | ❌ 404 | ✅ |
GET /sets/{set_id}/changelog | ❌ 404 | ✅ |
Upgrade a free set with POST /sets/{set_id}/upgrade, which purchases the paid plan and charges the billable user. Sets the user owns as well as sets shared with the user are included throughout; modifying a shared set requires editor or manager access to it.
List dynamic sets.
Returns all dynamic sets the authenticated user owns or has shared access to, including both free and paid sets. Use the `is_paid` field to tell them apart — only paid sets expose KPI data, and free sets can be upgraded via `POST /sets/{set_id}/upgrade`. Results are ordered by most recently updated first and paginated.
Create a dynamic set.
Creates a free dynamic set owned by the authenticated user. Add candidate listings (from `GET /sets/candidates`) by passing their internal `listing_id`s in `listing_ids`; they are added with the `active` status. The set is created on the free plan — upgrade it with `POST /sets/{set_id}/upgrade` to access its KPI endpoints.
Search candidate listings for a dynamic set.
Returns market listings near a location, with their trailing-year performance metrics, to choose from when building a dynamic set. Provide either a `lat`/`long`/`radius` (radius in meters) or one or more `market_ids`. Results are ordered nearest-first (each carries a `distance_meters` value) and paginated. Pass the returned `listing_id`s to `POST /sets` to add them as members. Not tied to a set, so no set plan applies.
Get a single dynamic set.
Returns detailed information about one dynamic set, including its definition (kind, filters, boundary) and member listing counts per status. **Works for free and paid sets.**
Upgrade a dynamic set to a paid set.
Purchases the paid Dynamic Sets plan for a free set so its KPI endpoints (aggregated_metrics, time_series, distribution, report) become available. **This creates a real paid subscription and charges the billable user's payment method.** Only the set's owner or a manager-level collaborator may upgrade a set (editors cannot), and the billable user must have a valid payment method on file. Returns the upgraded set.
Get aggregated metrics for a dynamic set.
Returns monthly performance metrics aggregated across the active member listings of the set. Monetary values are converted to the requested currency (defaults to the set's currency). **Paid sets only.** Returns `404 Not Found` for a free set — upgrade it first with `POST /sets/{set_id}/upgrade`.
List the listings in a dynamic set.
Returns the member listings of the set with their trailing-year performance metrics, grouped by membership status (`active`, `hidden`, `review`, `removed`). Monetary metrics are converted to the set's currency. Works for both free and paid sets, so a set can be reviewed before it is upgraded; the same per-listing metrics are also available ungated via `GET /sets/candidates`.
Add member listings to a dynamic set.
Adds the given listings to the set as members — the comparison listings the set is built from. Identify them by the internal `listing_id` values returned by `GET /sets/candidates`; only listings that are eligible comparison candidates can be added. Returns the set's member listings after the change, in the same shape as `GET /sets/{set_id}/listings`. Requires editor or manager access to the set when the set is shared. **Works for free and paid sets.** This is an upsert: a listing already in the set keeps its single membership and takes the requested `status`, so repeating an identical call leaves the set in the same state.
Remove member listings from a dynamic set.
Removes the given listings from the set's membership. Identify them by their internal `listing_id`. Returns the set's member listings after the change, in the same shape as `GET /sets/{set_id}/listings`. Requires editor or manager access to the set when the set is shared. **Works for free and paid sets.** Note that on a filter-based (non-static) set, membership is derived from the set's own filters, so removed members may be restored by the next sync — the same behaviour as the Wheelhouse app.
List the user listings associated with a dynamic set.
Returns the user's own listings that are associated with the set for comparison. Listings are returned in the standard RM API listing format; the `id` field is the channel listing ID used by the PUT and DELETE endpoints. For shared sets, associated listings the authenticated user does not have access to are omitted. Works for both free and paid sets: associating a listing is set configuration, not KPI data.
Associate user listings with a dynamic set.
Associates the given listings (the authenticated user's own listings, identified by their channel listing IDs) with the set for comparison. Listings that are already associated are left unchanged. Requires editor or manager access to the set when the set is shared. Works for both free and paid sets: associating a listing is set configuration, not KPI data.
Remove associated user listings from a dynamic set.
Removes the association between the given listings (identified by their channel listing IDs) and the set. Requires editor or manager access to the set when the set is shared. Works for both free and paid sets: associating a listing is set configuration, not KPI data.
Get the price calendar of a dynamic set's member listings.
Returns a night-by-night calendar for each **active member listing** of the set — the API equivalent of the set calendar in the Wheelhouse app. Each listing carries its own array of nights, with prices converted to a single currency so they are comparable across comps priced differently.
Get the changelog of a dynamic set.
Returns the history of changes made to the set (membership changes, edits), ordered oldest first and optionally restricted to a date range. **Paid sets only.** Returns `404 Not Found` for a free set — upgrade it first with `POST /sets/{set_id}/upgrade`.
Share a dynamic set with other users.
Grants specified access levels to other users for this dynamic set. Only the set's owner or a manager-level collaborator may share the set. Access levels are: **R** (viewer, read-only), **E** (restricted editor), **F** (editor, can modify set and associated listings), **M** (manager, can share and upgrade the set), and **N** (disabled, revokes access). Sharing with a user who already has access updates their level to the newly specified one. Returns the updated dynamic set. **Works for free and paid sets.**
Get time-series metrics for a dynamic set.
Returns daily time-series data for one or more metrics over a date range, aggregated across the active member listings of the set.
Get metric distributions for a dynamic set.
Returns histogram distributions for one or more metrics for a given calendar month, aggregated across the active member listings of the set.