Sampling Strategy Tools — MCP Tool Reference¶
Sampling strategy tools define target demographic distributions for creating representative respondent samples. A strategy describes a population: its factors — demographic dimensions with target proportions — and how fit to them is graded (quality_metric, aggregation_method). Pool generation uses those factors to select respondents matching your sample design.
A strategy carries no draw settings
How many respondents to draw and how to pick them — requested_size, oversample_factor, selection_algorithm, require_email and exclude_respondent_ids — are inputs to each draw (generate_pool_from_strategy, preview_pool_generation) and are stored on the pool the draw produces. One strategy can therefore feed a 200-person pilot pool and a 1,000-person main-wave pool, and every pool drawn from it is graded the same way.
After fielding, a strategy can be advanced: cloned with appended outcome factors grounded in the actual responses, ready to serve as a Bundle's quality benchmark.
list_sampling_strategies¶
List all sampling strategies, optionally filtered by project or name.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
project_id |
string |
No | — | Filter by project ID |
name |
string |
No | — | Case-insensitive substring filter |
limit |
integer |
No | 100 |
Maximum results to return |
Returns: { data: [...], count, limit }. Each item carries id, name, description, project_id, factor_count, quality_metric, created_at.
get_sampling_strategy¶
Get a sampling strategy by ID, including the full factor definitions.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
strategy_id |
string |
Yes | — | Strategy UUID |
Returns: The full strategy object: id, name, description, project_id, factors, quality_metric, aggregation_method, is_default, created_at, modified_at, warnings.
create_sampling_strategy¶
Create a sampling strategy with demographic distribution factors.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
name |
string |
Yes | — | Strategy name |
project_id |
string |
No | — | Parent project ID |
factors |
object[] |
No | — | Distribution factor definitions (see below) |
quality_metric |
string |
No | "rmse" |
"rmse", "mae", "chi_square", or "max_deviation" |
description |
string |
No | — | Strategy description |
Returns: The full strategy object (as get_sampling_strategy), with warnings from the outcome-factor check.
Factor Schema¶
Each factor in the factors array defines a demographic dimension:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name |
string |
Yes | — | Display name (e.g., "Gender") |
attribute_path |
string |
Yes | — | Respondent attribute (e.g., "gender") or QML item ID for outcome factors |
target_distribution |
object |
Yes | — | Category → proportion mapping. Must sum to 1.0 (±0.01 tolerance) |
factor_type |
string |
No | "discrete" |
"discrete", "bucketed", or "geographic" |
source |
string |
No | "demographic" |
"demographic" (respondent property) or "outcome" (survey response column) |
bucket_ranges |
array |
No | — | For bucketed type: list of [min, max, label] tuples |
weight |
float |
No | 1.0 |
Importance weight for this factor |
Example:
{
"name": "Gender",
"attribute_path": "gender",
"target_distribution": {"male": 0.48, "female": 0.50, "other": 0.02},
"factor_type": "discrete",
"source": "demographic",
"weight": 1.0
}
create_default_strategy¶
Create a strategy with standard gender and age distribution factors.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
name |
string |
Yes | — | Strategy name |
project_id |
string |
No | — | Parent project ID |
Returns: The full strategy object (as get_sampling_strategy).
Default factors:
- Gender: male 48%, female 50%, other 2%
- Age Group: 18–24 (15%), 25–34 (20%), 35–44 (20%), 45–54 (18%), 55–64 (15%), 65+ (12%)
update_sampling_strategy¶
Update an existing sampling strategy (partial update — only provided fields change).
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
strategy_id |
string |
Yes | — | Strategy UUID |
name |
string |
No | — | New name |
description |
string |
No | — | New description |
factors |
object[] |
No | — | Replace all factors (not merged) |
quality_metric |
string |
No | — | New quality metric |
Returns: The full strategy object (as get_sampling_strategy), with warnings from the outcome-factor check.
Updating a strategy never changes a pool already drawn from it: each pool keeps the draw settings it was generated with, and a refresh redraws against the strategy's current factors at the pool's own stored size.
Factors Replacement
When factors is provided, it completely replaces the existing factor list — it does not merge.
advance_sampling_strategy¶
Advance a strategy with reality-grounded outcome factors: clone the strategy and append factors built from actual survey responses plus an external benchmark (e.g. a party-preference column benchmarked against election results). The original strategy is never edited — pools it generated keep their historical reference — and the clone can be assigned as a Bundle's current Strategy (see assign_bundle_strategy).
Requires manager permissions and an identified user (service-token-only callers are rejected).
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
strategy_id |
string |
Yes | — | Strategy to advance (clone source) |
factors |
object[] |
Yes | — | Outcome factors to append (at least one) |
name |
string |
No | "{source} (advanced)" |
Name for the clone |
Each factors entry:
| Field | Type | Required | Description |
|---|---|---|---|
attribute_path |
string |
Yes | Bronze response column the factor grades |
target_distribution |
object |
Yes | External benchmark proportions (must sum to 1.0) |
name |
string |
No | Display name (defaults to the column) |
factor_type |
string |
No | "discrete" (default) or "bucketed" for numeric columns |
bucket_ranges |
array |
No | [min, max, label] triples when factor_type is "bucketed" |
weight |
float |
No | Factor weight (default 1.0) |
Returns: { strategy_id, strategy_name, cloned_from, factor_count, warnings }. warnings names each outcome factor whose target keys could not be checked (see Outcome factor targets).
delete_sampling_strategy¶
Delete a sampling strategy. Protected if the strategy is the default or has linked pools.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
strategy_id |
string |
Yes | — | Strategy UUID |
Returns: { strategy_id, deleted }
Error Handling¶
Factor Validation¶
| Scenario | Response |
|---|---|
| Missing required field | {"error": "Each factor must have 'name', 'attribute_path', and 'target_distribution'"} |
| Distribution doesn't sum to 1.0 | {"error": "Factor '{name}' target_distribution must sum to 1.0 (got {sum:.3f})"} |
| Invalid source value | {"error": "Factor '{name}' source must be 'demographic' or 'outcome'"} |
Factor validation applies to both create_sampling_strategy and update_sampling_strategy.
Outcome factor targets¶
An outcome factor's target_distribution keys must name options its column offers, by option code ("1") or by option label ("Yes"). create_sampling_strategy, update_sampling_strategy and advance_sampling_strategy check this against every questionnaire in the strategy's project, and so does the Advance dialog in the Analysis app. A factor is accepted when one questionnaire that declares the column offers every one of its keys. Keys offered only by different questionnaires are refused, because a Bundle's data comes from one questionnaire.
Bucketed factors with bucket ranges are not checked: their keys are bucket names, not options.
| Scenario | Response |
|---|---|
| A key the questionnaire does not offer for that column | Refused: Factor 'Recommend' targets keys that are neither an option code nor an option label of 'q_cp07': 'Exit interview' offers no option ['Maybe'] and accepts, by code or label: 1 (Yes), 2 (No). |
| The column is not declared in any of the project's questionnaires, or a questionnaire declares it as an item whose labels do not name every value (free text, slider, multiple choice) | Written, with a warnings entry saying the keys were not checked |
| One of the project's questionnaires cannot be read (for example an unfinished draft) | Written, with a warnings entry, because the unreadable questionnaire might offer the key |
| The strategy belongs to no project | Written, with a warnings entry: there is no questionnaire to check against |
A strategy's warnings list is empty on every read; it is filled only by the write that produced it.
Default Strategy Protection¶
| Scenario | Response |
|---|---|
| Modify default strategy | {"error": "Cannot modify the default sampling strategy"} |
| Delete default strategy | {"error": "Cannot delete the default sampling strategy"} |
Linked Pool Protection¶
| Scenario | Response |
|---|---|
| Delete strategy with pools | {"error": "Cannot delete strategy: {count} pool(s) are linked to it"} |
Common Errors¶
| Scenario | Response |
|---|---|
| Strategy not found | {"error": "Strategy {id} not found"} |
| Not an owner of the strategy's project | {"error": "forbidden", "detail": "caller is not an owner of this project and lacks an admin role"} |