Ditto for Political Polling & Voter Research
Run state-specific voter research, campaign messaging tests, and candidate perception studies using Ditto's 300,000+ synthetic personas — directly from the terminal.
Full documentation: https://askditto.io/claude-code-guide
What Ditto Does
Ditto maintains 300,000+ AI-powered synthetic personas calibrated to census data. You ask them open-ended questions and get qualitative responses with the specificity of real voter interviews.
- 92% overlap with traditional focus groups (EY Americas validation)
- 95% correlation with traditional research
- Harvard/Cambridge/Stanford/Oxford peer-reviewed methodology
- A 10-persona voter study completes in 10-12 minutes
- Traditional voter research: 2-4 weeks, $15,000-50,000
The Non-Negotiable Rule
Every political study MUST use a state-filtered research group.
- NEVER use generic groups like "American Voters" or "Suburban Voters"
- Group name format:
{StateCode} State Voters(e.g., "MI State Voters") - State filter: 2-letter codes ONLY (MI, TX, PA, OH, AZ)
- Full state names ("Michigan") return 0 agents
political_affiliationis NOT a supported filter
State-specific groups produce dramatically more relevant responses than generic national groups. This has been validated across 50+ studies.
Quick Start (Free Tier)
Get a free API key — no credit card, no sales call:
curl -sL https://app.askditto.io/scripts/free-tier-auth.sh | bash
Free keys (rk_free_): ~12 shared personas, no state filtering.
Paid keys (rk_live_): state-specific groups, demographic filtering, unlimited studies.
API Essentials
Base URL: https://app.askditto.io
Auth header: Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
The Voter Research Workflow (7 Steps)
Step 1: Research the Candidate
Before touching the API, research:
- Candidate background (career, previous offices, accomplishments)
- Party affiliation (Democrat/Republican/Independent)
- Key issues they are running on
- Opponent(s) — incumbent or challenger?
- Race dynamics (competitive? safe seat? toss-up?)
- Recent news (controversies, endorsements, polling numbers)
- Current campaign messaging and slogans
This research directly informs Q3 (candidate briefing) and Q6 (messaging test).
Step 2: Check for Existing State Group
Before creating a new group, check if one already exists:
curl -s "https://app.askditto.io/v1/research-groups?limit=50" \
-H "Authorization: Bearer $DITTO_API_KEY"
Look for groups named {StateCode} State Voters. Reuse existing
state groups for multiple races in the same state.
Step 3: Recruit State-Specific Panel
curl -s -X POST "https://app.askditto.io/v1/research-groups/recruit" \
-H "Authorization: Bearer $DITTO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "MI State Voters",
"group_size": 10,
"filters": {
"country": "USA",
"state": "MI",
"age_min": 18,
"age_max": 65
}
}'
Save the uuid. Use group_size (not size), group uuid (not id).
If recruitment returns 0 agents: wait 30 seconds and retry. If still 0, the study cannot proceed. NEVER fall back to a generic non-state group.
Step 4: Create Study
curl -s -X POST "https://app.askditto.io/v1/research-studies" \
-H "Authorization: Bearer $DITTO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "John Smith Voter Research - Michigan",
"objective": "Understand MI voter priorities and perception of John Smith in the congressional race",
"research_group_uuid": "UUID_FROM_STEP_3"
}'
Save the study id. Response nests under data.study — access via
response["study"]["id"], NOT response["id"].
Naming convention:
- Title:
[Candidate Name] Voter Research - [State] - Objective:
Understand [State] voter priorities and perception of [Candidate] in the [race type] race
Step 5: Ask Questions (One at a Time)
curl -s -X POST "https://app.askditto.io/v1/research-studies/STUDY_ID/questions" \
-H "Authorization: Bearer $DITTO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"question": "What are the top 2-3 issues that affect your daily life in Michigan? Walk me through what that looks like."}'
Returns job_ids. Poll until complete before asking the next question.
Step 6: Poll Until Complete
curl -s "https://app.askditto.io/v1/jobs/JOB_ID" \
-H "Authorization: Bearer $DITTO_API_KEY"
Polling strategy:
- Wait 45-50 seconds before first poll
- Then poll every 20 seconds
- Poll ONE job_id as proxy — all jobs finish together
- Status:
queued→started→finished(orfailed)
Step 7: Complete and Extract Insights
curl -s -X POST "https://app.askditto.io/v1/research-studies/STUDY_ID/complete" \
-H "Authorization: Bearer $DITTO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"force": false}'
Use "force": true to re-run analysis on an already-completed study (avoids 409).
Get share link:
curl -s -X POST "https://app.askditto.io/v1/research-studies/STUDY_ID/share" \
-H "Authorization: Bearer $DITTO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"enabled": true}'
Use share_link field (preferred over share_url).
The Political Question Framework (7 Questions)
These questions are designed to surface real voter dynamics, not predictable partisan responses. The candidate is introduced at Q3 — never Q1.
Q1 — Ground in Local Reality
"What are the top 2-3 issues that affect your daily life in [state/district]? Walk me through what that looks like."
Purpose: Establishes what voters actually care about before any candidate context.
Q2 — Decision Drivers
"When you're deciding who to vote for, what matters most? What's an instant dealbreaker for a candidate?"
Purpose: Reveals decision criteria and red lines.
Q3 — Candidate Briefing + Reaction
"Let me tell you about [Candidate]. [Background, party, key positions, endorsements, campaign focus — 6-8 concrete details]. What's your honest first reaction?"
Purpose: Tests candidate perception. Include 6-8 specific details: party affiliation, career background, key policy positions, endorsements, recent actions, campaign slogans. Generic briefings get generic responses.
ANCHORING RULE: Introduce the candidate at Q3, NOT Q1. Establishing voter priorities first (Q1-Q2) produces unbiased baseline data.
Q4 — Competitive Frame
"How does [Candidate] compare to [opponent(s)]? Who feels more trustworthy on the issues you care about?"
Purpose: Reveals competitive positioning and trust dynamics.
Q5 — Persuasion Levers
"What would [Candidate] need to say or do to earn your vote? Be specific."
Purpose: Identifies what persuades undecided or soft-opposition voters. This is the most actionable question for campaign strategists.
Q6 — Messaging Test
"Here's their main campaign message: '[quote/slogan]'. Does this resonate? What's missing?"
Purpose: Tests whether the campaign's actual messaging lands or falls flat. Use the real campaign slogan or tagline.
Q7 — Constituent Advice
"If [Candidate] sat down with you for 5 minutes, what would you tell them? Don't hold back."
Purpose: Surfaces unfiltered voter concerns, fears, and advice. Best source of quotable insights for reports and content.
Question Framework Variants
Mix these into the standard 7 questions or use standalone:
| Variant | Question Template | Measures |
|---|---|---|
| Name Recognition | "What's your gut reaction when you hear [Name]?" | Awareness + first impressions |
| Issue Ownership | "Who do you trust more on [issue]: [A] or [B]?" | Competitive positioning per issue |
| Messaging Test | "[Candidate] says '[message]'. Your reaction?" | Message effectiv |