Ditto Platform Help
Ditto (askditto.io) is a self-serve synthetic market research platform: recruit a
demographically filtered panel from 300,000+ census-calibrated AI personas (across 15+
countries), run a study, ask questions, and get an AI analysis — in minutes instead of the
weeks/thousands a traditional focus group costs. Its edge in the synthetic-research cluster is a
real REST API with a free-tier key plus official Claude Code skills, so an agent can drive
the whole recruit → study → analysis flow. EY-validated at a 92% overlap with focus groups (a
vendor-cited figure).
Its signal is directional, not demand: personas model existing/census/training data, so they
skew agreeable, generic, and Western-biased and can't surface a genuinely new unmet need.
Treat any synthetic result as a hypothesis to disconfirm with real behavior, never a green light.
Step 1 — Gather context
If references/learnings.md exists, read it first for accumulated platform knowledge.
Ask only what you can't infer:
- What do you want from Ditto?
- A) Recruit a research group (demographic panel) — filter by country/state/age
- B) Run a study — launch, ask questions, get the AI analysis + share link
- C) Automate it — drive the recruit → study → questions → analysis flow via the API/Claude Code
- D) Get access — a free-tier (
rk_free_) key vs a paid (rk_live_) key with real filtering
- E) Interpret a study/analysis you already ran, or decide whether to trust it
- What's the research question and who's the audience? A sharp objective + panel yields usable
answers; a vague one yields generic filler.
Skip-ahead: if the user wants to compare synthetic-research/persona/idea tools across the market,
or the validate-before-building method, that's a /sales-idea-validation question — route in Step 2.
Step 2 — Route or answer directly
| If the user's question is about… | Route to |
|---|
| Comparing synthetic-research/persona/idea tools, or the validate-before-building method | /sales-idea-validation {question} |
| Running a real demand test (smoke-test page, waitlist, pre-sale) after synthetic signal | /sales-idea-validation or /sales-funnel {question} |
| Analyzing real-customer NPS/CSAT/VoC feedback (post-launch) | /sales-customer-feedback {question} |
| The pure-play interview-study API peer, or a reusable persona with memory | /sales-syntheticusers or /sales-imario {question} |
When routing, give the exact command: "This is a {domain} question — run: /sales-idea-validation {original question}"
Otherwise, answer Ditto-specific questions using Step 3.
Step 3 — Ditto platform reference
Read references/platform-guide.md for the full reference — the module/automation-surface table
(what's API-accessible vs UI-only), best-effort pricing and the free-vs-paid key gates, the
Group → Study → Question → Analysis data model (JSON shapes), and quick-start recipes.
For raw endpoints, auth, JSON schemas, and the end-to-end Python script, read
references/ditto-api-reference.md.
Answer using only the relevant section — don't dump the full reference.
Step 4 — Actionable guidance
- A synthetic "yes" is not demand — say so every time. Whatever the user asks, make explicit that
Ditto's personas model census/existing/training data, so they run agreeable, generic, and
Western-biased and can be confidently wrong. Frame every result as a hypothesis to
disconfirm with a real behavior test (smoke-test click, reply, pre-sale) — keep the objections,
segments, and language it surfaces (its real value), take the go/no-go from real strangers, and
route the real test to
/sales-idea-validation.
- Present the EY "92% overlap" and all pricing as best-effort — cite the source, don't assert it.
The 92%-overlap-with-focus-groups figure is EY-validated but vendor-cited; paid pricing is
not publicly listed (third-party sources cite an enterprise ~$50–75K/yr range). Say figures are
best-effort and point the user to askditto.io to confirm before relying on them.
- Start on the free tier, name its limits. A
rk_free_ key (free-tier-auth.sh) gives ~12
shared US personas with no custom filters — enough to build/debug the flow and read directional
patterns. Custom demographic filtering (country/state/age) needs a paid rk_live_ key. Tell
the user to prototype on free, then upgrade only when they need real filtering — the request shapes
are identical.
- For automation, give the real endpoints and the hard limits. Base
https://app.askditto.io,
auth Authorization: Bearer <key>. Core flow: POST /v1/research-groups/recruit → POST /v1/research-studies (set shareable:true, pass the group uuid not the numeric id) → POST /v1/research-studies/{id}/questions → poll every job_id via GET /v1/jobs/{id} to finished
→ repeat per question → POST .../complete → POST .../share. Enforce the limits: questions are
sequential (poll all jobs before the next — no concurrency), max 20 personas per recruit call
(use /append), group_size not size, 2-letter state codes, , and
(job polling only). Pull a concrete cURL/Python snippet from the references.
If you discover a gotcha or tip not in references/learnings.md, append it there with today's date.
Gotchas
Best-effort from research (2026-07) — pricing, the EY figure, persona counts/countries, and the API
surface move; verify at askditto.io and app.askditto.io/docs.
- Sycophancy / agreeableness bias. Personas skew favorable — they can approve a concept or
price real buyers would reject. Never read a positive synthetic reaction as validation.
- Census-calibrated ≠ real behavior. "Population-true" personas match demographic distributions,
not the messy, unpredictable choices of a real person — and they can't surface a new unmet need.
- Western/English and identity-flattening bias. Outputs skew Western/majority and can flatten
identity groups — be cautious generalizing across markets or narrow segments.
- Free tier is deliberately thin.
rk_free_ = ~12 shared personas, no custom filters —
demographic filtering requires a paid rk_live_ key. Don't promise country/state/age targeting on free.
- Sequential questions + job polling. The API rejects concurrent questions; each question fans out
to one async job per persona. Poll all job_ids to
finished (30–90s typical) before the next.
- Field/format traps.
group_size (not size); use the group uuid (not id) for studies;
2-letter state codes; no income filter; response_text may contain HTML to strip.
Related skills
/sales-idea-validation — The tool-agnostic validate-before-building method + the full synthetic-research/persona/validator tool landscape (use this to actually decide build-or-not; a synthetic "yes" is not demand)
/sales-syntheticusers — Synthetic Users platform help (the pure-play interview-study peer with a documented public REST API [Python/TS SDKs, SSE streaming]; Ditto's edge is census-calibrated demographic panels + a free-tier key + official Claude Code skills)
/sales-imario — iMario platform help (the reusable-persona canvas — a Synthetic Individual with cross-session memory run across six jobs; Ditto runs one-shot demographic studies but ships the real free-tier API)
/sales-societies — Artificial Societies platform help (the self-serve network simulator that predicts how a post/message spreads; Ditto asks isolated personas, Societies models influence between them)
/sales-customer-feedback — Real-customer NPS/CSAT/VoC strategy across tools (use once you have live customers; synthetic research is pre-launch only)
/sales-funnel — Build the smoke-test / fake-door landing page that turns a synthetic hypothesis into a real demand test
/sales-do — Not sure which skill to use? The router matches any sales objective to the right skill. Install: npx skills add sales-skills/sales --skill sales-do -a claude-code
Examples
Example 1: "Ditto's personas loved my pricing — should I ship it?"
User says: "I ran a Ditto study and 9 of 10 personas said $29/mo is fair. Green light?"
Skill does: Explains Ditto's personas model census/training data and skew agreeable, so a
near-unanimous "yes" is a directional signal, not demand — census-calibration matches
distributions, not real purchase behavior. Tells the user to mine the answers for objections and
price language (the real value) and take the go/no-go from a real behavior test — a pre-sale or
a "buy at $29" click — routed via /sales-idea-validation. Flags the EY 92% overlap claim as
vendor-cited.
Result: The founder keeps the pricing objections, runs a real pre-sale before committing.
Example 2: Free vs paid — can I filter by demographics? (references/platform-guide.md)
User says: "I want US women 25–34 in Texas. Does the free Ditto key do that?"
Skill does: Says no — a rk_free_ key is ~12 shared US personas with no custom filters;
country/state/age filtering needs a paid rk_live_ key. Explains how to get the free key
(free-tier-auth.sh) to build the flow, then upgrade; notes the recruit constraints (country
required, 2-letter state like "TX", no income filter, max 20 per call) and that pricing is
best-effort/enterprise — confirm on askditto.io.
Result: The user prototypes on free, understands filtering is a paid gate, and budgets accordingly.
Example 3: Automate a study end-to-end from Claude Code (developer/automation)
User says: "How do I recruit a panel, ask 3 questions, and export the analysis via the API?"
Skill does: Gives the flow — auth Authorization: Bearer <key>, base https://app.askditto.io;
POST /v1/research-groups/recruit → POST /v1/research-studies (shareable:true, group uuid) →
POST /v1/research-studies/{id}/questions one at a time, polling every job_id via
GET /v1/jobs/{id} to finished before the next → POST .../complete → POST .../share. Stresses
no webhooks (job polling only), max 20 personas/recruit (use /append), and points to the
Python script in references/ditto-api-reference.md; mentions the official Ask-Ditto Claude Code skills.
Result: The user wires the recruit → study → analyze → export flow with sequential polling, no webhooks.
Troubleshooting
"The personas agreed with everything — is that real signal?"
Symptom: Study answers are uniformly positive and agreeable.
Cause: LLM-based personas exhibit sycophancy and model plausible agreement — census
calibration fixes who they are, not the agreeableness bias.
Solution: Discard the "verdict," keep the objections and language surfaced, and validate with
real behavior (smoke test, pre-sale). Sharpen the objective and panel (over-recruit-and-curate) to
cut generic agreement. Cross-check via /sales-idea-validation.
"My recruit call keeps 400-ing / the filter isn't applied"
Symptom: POST /research-groups/recruit returns 400/422, or the free key ignores your filters.
Cause: Wrong field name or format (size instead of group_size, "Texas" instead of "TX", an
income filter), missing required country, or a free rk_free_ key (no custom filters — shared
personas only).
Solution: Use group_size, include country, use 2-letter state codes, drop income, and
cap at 20 personas (use /append for more). For real demographic filtering, use a paid rk_live_
key. See references/ditto-api-reference.md.
"My study never 'finishes' — how do I know the answers are in?"
Symptom: After POST .../questions the responses aren't there and nothing calls back.
Cause: Responses are async (one job per persona) and there are no webhooks.
Solution: Poll GET /v1/jobs/{job_id} for every returned job_id until each shows
finished (30–90s typical, poll every 10–15s) before asking the next question, then GET /v1/research-studies/{id}/questions to read answers and POST .../complete for the AI analysis.