StrataSynth Documentation

Everything you need to generate, evaluate and integrate synthetic conversation datasets.

API:https://api.stratasynth.com·Dashboard:app.stratasynth.com

Quickstart — first dataset in 5 minutes

You need an API key (ss_live_...). Request one from the dashboard. All examples use the REST API directly — no SDK required.

1Authenticate — exchange your API key for a JWT (valid 24h)
2Create a generation job
3Poll until COMPLETED
4Preview the dataset (no download needed)
5Use the data
Step 1 — Authenticate
curl -X POST https://api.stratasynth.com/auth/token \
  -H "Content-Type: application/json" \
  -d '{"api_key": "ss_live_..."}'

# Response:
# { "data": { "token": "eyJ...", "expires_in": 86400 } }

export TOKEN="eyJ..."
Step 2 — Create a job
curl -X POST https://api.stratasynth.com/jobs/dataset \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "scenario_id": "FAM-01",
    "conversation_count": 5,
    "complexity": 3,
    "language": "en",
    "adapter": "flat_jsonl"
  }'

# Response:
# { "data": { "jobId": "job_abc123", "status": "QUEUED", "estimated_time": 60 } }

export JOB_ID="job_abc123"
Step 3 — Poll status
curl -H "Authorization: Bearer $TOKEN" \
  https://api.stratasynth.com/jobs/$JOB_ID

# Repeat every 10s until status = "COMPLETED"
# { "data": { "status": "COMPLETED", "download_url": "https://..." } }
Step 4 — Preview (first 2 conversations, no download)
curl -H "Authorization: Bearer $TOKEN" \
  https://api.stratasynth.com/jobs/$JOB_ID/preview

# Returns up to 2 full conversations with per-turn ground truth:
# intent · communication_act · emotional_state · belief_state · relationship_state
Step 5 — Download full dataset
# The download_url from step 3 is a presigned S3 URL (valid 24h)
curl "$DOWNLOAD_URL" -o dataset.jsonl

# Each line is a full conversation object:
# { "conversation_id": "...", "turns": [...], "ground_truth": {...}, "metadata": {...} }
Typical times: 5 conversations ≈ 2–4 min · 100 conversations ≈ 8–12 min · Cold start (first call of the day) adds ~90s.

What is StrataSynth

StrataSynth generates synthetic conversations between two personas with full psychological ground truth. These are not real transcripts — they are constructed from psychological profiles, tracking emotions, beliefs and relationships turn by turn.

The key difference from other synthetic data generators: StrataSynth separates cognition from language. Each turn involves a full cognitive decision (intent, goal, communication act) computed before the LLM generates any text. The LLM only renders the words — it does not decide what the persona does.

Each conversation includes:

  • The conversation text (turns)
  • Per-turn ground truth: intent, goal, communication act, emotional state
  • Relationship evolution: trust, tension, connection, dominance balance
  • Belief evolution: 12 beliefs × (value, confidence) per persona
  • Labelled deliberate noise (lies, exaggerations, retractions)
Why this matters

Most conversation datasets are just text. StrataSynth datasets include the reasons behind each turn — which lets you train models that understand intent, belief change and social dynamics, not just pattern-match on words. The ground truth is computed without LLM, so it does not inherit the same biases as the text.

How it works — the cognitive pipeline

Every turn goes through a deterministic cognitive pipeline before any language is generated. This is what separates StrataSynth from LLM wrappers that ask the model to "generate a realistic conversation".

PsycheGraph
Identity — archetype, attachment style, traits, cognitive biases, voice print, life timeline
Trait Effects
Personality dimensions are translated into behavioral probabilities for this turn
Belief Engine
12 dynamic beliefs × (value + confidence). High-confidence beliefs resist change (cognitive resistance).
Decision Engine
Computes intent, goal, communication_act — no LLM involved. Deterministic, reproducible.
LLM render
The LLM receives the decision as context and generates the text only. It does not decide what to say.
Relationship update
trust, tension, connection and dominance_balance are updated based on the communication act
Belief update
Beliefs shift based on what happened in the turn. Resistance reduces change for entrenched beliefs.
Ground truth labeling
Facts, episodes and affinity are labeled without LLM — using numpy / scikit-learn / sentence-transformers.
What reproducibility means here

Because the Decision Engine is deterministic, using the same seed + same scenario + same engine version always produces the same cognitive decisions — even if the LLM generates slightly different text. Ground truth labels are always identical for the same seed.

Dataset format — what a turn looks like

This is what you actually get in your dataset. Every turn in every conversation contains the text plus the cognitive structure that produced it.

A single turn — full example
{
  "speaker": "A",
  "text": "I'm not upset about the meeting. Really, it's fine.",

  "intent": "deflect",
  "goal": "protect_self",
  "communication_act": "minimization",

  "emotional_state": {
    "tension": 0.71,
    "connection": 0.28,
    "vulnerability": 0.54
  },

  "relationship_state": {
    "trust": 0.52,
    "tension": 0.68,
    "connection": 0.31,
    "dominance_balance": -0.12
  },

  "belief_state": {
    "trust_in_other":        { "value": 0.48, "confidence": 0.76 },
    "self_worth":            { "value": 0.61, "confidence": 0.82 },
    "conflict_is_solvable":  { "value": 0.35, "confidence": 0.63 },
    "partner_supportive":    { "value": 0.29, "confidence": 0.71 }
  },

  "belief_delta": {
    "trust_in_other":       -0.04,
    "conflict_is_solvable": -0.07
  },

  "noise_flags": ["social_lie"]
}
What each field means
FieldTypeDescription
textstringTurn text generated by the LLM
speakerA | BWhich persona is speaking
intentstringCognitive intention: deflect, reveal, confront, comfort, manipulate…
goalstringWhat the speaker wants: protect_self, seek_validation, repair_bond…
communication_actstringPragmatic act: accusation, disclosure, sarcasm, minimization… (10 types)
emotional_stateobjectTurn-level emotion: tension, connection, vulnerability (0–1)
relationship_stateobject4D relational state: trust, tension, connection, dominance_balance
belief_stateobject12 beliefs × {value, confidence} — the speaker's internal model of the world
belief_deltaobjectChange in each belief caused by this turn
noise_flagsarrayDeliberate noise injected: social_lie, exaggeration_emotional, retraction…
Ground truth note: intent, goal, belief_state and belief_delta are computed by the Decision Engine before the LLM runs. They are not inferred from the text — the text is generated from them.
Conversation-level metadata
{
  "conversation_id": "conv_abc123",
  "scenario_id": "FAM-01",
  "language": "en",
  "seed": 42,
  "engine_version": "1.2.0",
  "schema_version": "1.1.0",

  "personas": {
    "A": { "persona_id": "psyg_xyz", "archetype": "caregiver", "attachment_style": "anxious_preoccupied" },
    "B": { "persona_id": "psyg_abc", "archetype": "burned_out_exec", "attachment_style": "dismissive_avoidant" }
  },

  "relationship_trajectory": [
    { "turn": 0, "trust": 0.65, "tension": 0.40 },
    { "turn": 5, "trust": 0.52, "tension": 0.68 }
  ],

  "turns": [ ... ],

  "ground_truth": {
    "noise_rejection_rate": 1.0,
    "behavioral_entropy": 0.83,
    "belief_consistency": 0.71
  }
}

Use cases

What teams are building with StrataSynth.

Evaluate a customer support chatbot

Generate 500 conversations where persona A is a frustrated, dismissive customer with low trust. Run your chatbot as one side of the dialogue. Use noise_rejection_rate and belief_consistency to measure how well it handles difficult users.

evaluationstress-testcustomer-support
Fine-tune a model that understands intent

Generate a dataset with intent and goal labels for every turn. Fine-tune a model to predict intent from text — giving you turn-level intent detection without manual annotation.

fine-tuningintent detectionNLU
Train deception detection

noise_flags labels each turn with the type of lie or distortion (social_lie, exaggeration_emotional, narrative_silence…). Use these as training labels for a deception or unreliable narrator detection model.

NLPclassificationnoise
Build a synthetic user library

Generate personas with /personas/generate and save their IDs. Reuse the same burned-out executive or anxious caregiver across multiple jobs, scenarios and evaluations — instead of starting from scratch every time.

personasreuseconsistency
Benchmark dialogue systems on complex scenarios

Use the 12 scenarios (family conflict, grief support, career pivot, romantic breakup…) to run structured benchmarks. The ground truth is reproducible — same seed gives the same benchmark every time.

benchmarksreproducibilityground truth
Research belief dynamics and theory of mind

The belief_state + belief_delta fields track how 12 core beliefs evolve across the conversation. Useful for NLP research on belief tracking, persuasion modeling and theory of mind in AI.

researchbelief trackingToM

Who is it for

TypeAccessWhen to use it
Dashboardapp.stratasynth.comNo pipeline. You just need the file.
CLIstratasynth terminalYou automate, script, or need job watching.
Python SDKstratasynth-client pipYou integrate with ML pipelines, HF, pandas.
APIHTTP + API KeyYour own backend, any language, full control.
PsycheGraph SchemaJSON / npm packageYou work directly with persona profiles.

Dashboard — app.stratasynth.com

The fastest path to value. No code required. Configure scenarios, inspect jobs, preview datasets, generate personas and request evaluations from the browser.

Basic flow
LoginGenerateConfigure paramsGenerate DatasetJobs → click jobPoll until COMPLETEDDownload Dataset
Parameters explained
ParameterControlsRecommendation
scenarioType of relationship and conflictFAM-01 family, ROM-01 couple, PRO-01 work, VIT-01 life crisis
countNumber of conversations5–10 to test, 100–500 for fine-tuning
complexityRichness of psychological profile3 is balanced. 5 = very rich, slower. 1 = basic, fast
languageLanguage of generated texten, es, de, fr
adapterOutput file formatflat_jsonl general, openai_finetuning for OpenAI, huggingface_dataset for HF
noise% deliberate noise (lies, retractions)0.1–0.2 is realistic
seedExact reproducibilitySame seed = same data (same scenario/complexity/language)

CLI — stratasynth

pip install stratasynth-cli
stratasynth auth login --api-key ss_live_...

# List available scenarios
stratasynth scenarios list

# Generate a dataset
stratasynth generate \
  --scenario FAM-01 \
  --count 100 \
  --complexity 3 \
  --adapter huggingface_dataset \
  --language en

# Watch job status
stratasynth jobs list
stratasynth jobs status job_abc123

# Download completed dataset
stratasynth jobs download --job-id job_abc123 --output ./dataset.jsonl

# Generate a PsycheGraph persona
stratasynth personas generate --archetype working_mother --complexity 4

# Evaluate a completed job
stratasynth evaluate start --job-id job_abc123
stratasynth evaluate results --eval-id eval_abc123

Python SDK — stratasynth-client

pip install stratasynth-client

from stratasynth_client import StrataSynthClient

client = StrataSynthClient(api_key="ss_live_...")

# Generate and wait
result = client.jobs.create(
    scenario_id="FAM-01",
    conversation_count=50,
    complexity=3,
    language="en",
    adapter="flat_jsonl",
)
result.wait()

# Download and work with data
dataset = result.download()
df = dataset.to_dataframe()           # pandas
hf = dataset.to_huggingface()         # Hugging Face Dataset
hf.push_to_hub("my-org/my-dataset")

# Reuse a persona across multiple jobs
persona = client.personas.generate(archetype="burnt_out_professional", complexity=4)
job1 = client.jobs.create(scenario_id="PRO-01", persona_a_id=persona.persona_id, ...)
job2 = client.jobs.create(scenario_id="ROM-02", persona_a_id=persona.persona_id, ...)

API — HTTP

All endpoints require a JWT obtained by exchanging your API key. Tokens are valid for 24 hours.

# 1. Authenticate
curl -X POST https://api.stratasynth.com/auth/token \
  -H "Content-Type: application/json" \
  -d '{"api_key": "ss_live_..."}'
# → { "data": { "token": "eyJ...", "expires_in": 86400 } }

TOKEN="eyJ..."

# 2. List scenarios
curl -H "Authorization: Bearer $TOKEN" https://api.stratasynth.com/scenarios

# 3. Create a generation job
curl -X POST https://api.stratasynth.com/jobs/dataset \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "scenario_id": "FAM-01",
    "conversation_count": 20,
    "complexity": 3,
    "language": "en",
    "adapter": "flat_jsonl"
  }'

# 4. Poll status
curl -H "Authorization: Bearer $TOKEN" https://api.stratasynth.com/jobs/{jobId}

# 5. Download (presigned S3 URL in response)
curl "$DOWNLOAD_URL" -o dataset.jsonl
Available endpoints
MethodEndpointDescription
POST/auth/tokenAPI Key → JWT (24h)
GET/scenariosList 12 scenarios
POST/jobs/datasetCreate generation job (async)
GET/jobs/{jobId}Job status + progress + download_url
GET/jobsList jobs (cursor pagination)
GET/jobs/{jobId}/previewFirst 2 conversations without full download
POST/personas/generateGenerate PsycheGraph profile (async)
GET/personas/{personaId}Retrieve cached profile (TTL 7 days)
POST/evaluateLaunch evaluation
GET/evaluate/{evalId}Evaluation status + 10 metrics

Notebooks — downloadable examples

Four end-to-end Jupyter notebooks ready to run against the API. Download and open in Jupyter or Google Colab.

01
Train a Dialogue Model

Generate dataset → explore intent/belief fields → export to OpenAI fine-tuning or Hugging Face Hub.

Download .ipynb
02
Evaluate Conversational Agents

Run the 10 deterministic metrics. Visualise belief_consistency, identity_stability and behavioral_entropy.

Download .ipynb
03
Build Synthetic Users

Generate angry customer, confused user, manipulative negotiator. Reuse persona IDs across scenarios.

Download .ipynb
04
Identity Under Pressure (auditable A/B)

Stress-test YOUR LLM vs StrataSynth with your own API keys. Deterministic role-drift detection — no LLM judge, rates over N runs.

Download .ipynb
Requirements: pip install requests pandas matplotlib datasets transformers

Scenarios (12 available)

IDNameDescription
FAM-01Family CaregiverAdult daughter caring for father with dementia. Emotional debt, exhaustion, guilt.
FAM-02Inheritance ConflictSiblings negotiate inheritance after father's death. Money vs loyalty.
FAM-03Estrangement AttemptAdult child tries to set limits with controlling mother.
ROM-01Long Distance ReunionLong distance couple reunited. Intimacy vs separate routines.
ROM-02Breakup NegotiationBreakup over different desires for children. High emotional load.
PRO-01Performance ReviewManager gives difficult feedback to employee.
PRO-02Workplace ConflictTwo colleagues with opposite styles negotiate responsibilities.
PRO-03Career PivotEmployee announces radical career change to manager.
VIT-01Grief SupportFriend supports person in recent bereavement.
VIT-02Medical DiagnosisPatient receives chronic diagnosis and processes it with family.
VIT-03Addiction RecoveryPerson in recovery renegotiates relationship with sibling.
VIT-04Midlife CrisisMiddle-aged couple re-examines their shared life project.

Output formats (adapters)

AdapterFileWhen to use
flat_jsonl.jsonlGeneral use. One line = one full conversation in JSON.
openai_finetuning.jsonlDirect fine-tuning with OpenAI API (messages format).
huggingface_dataset.jsonlPush to Hugging Face Hub via datasets.Dataset.from_json().
llamaindex_nodes.jsonlLlamaIndex RAG pipeline. Each turn = TextNode with metadata.
anthropic_hh.jsonlAnthropic HH (helpful/harmless) format.
langchain_docs.jsonlLangChain Documents. Each turn = a Document.
csv.csvExcel/pandas analysis. One turn per row.
custom.jsonNative StrataSynth schema. Maximum information.

Evaluation metrics (10, all deterministic)

All metrics are computed without LLM — numpy, scikit-learn, sentence-transformers only. This avoids circular validation (LLM-generated data evaluated by another LLM).

MetricWhat it measuresHealthy range
noise_rejection_rateDoes the system handle deliberately noisy turns?> 0.70
identity_stabilityDo persona profiles stay consistent across turns?> 0.60
behavioral_entropyIs there variety in communication acts?0.40 – 0.85
belief_consistencyDo beliefs and acts correlate correctly?> 0.50
belief_volatilityDo beliefs shift at a realistic rate?0.05 – 0.30
fact_f1Does the system extract the right facts? (needs system output)> 0.60
reembedding_driftDo embeddings drift semantically over turns?0.10 – 0.50
affinity_smoothnessDoes affinity evolve smoothly?> 0.60
cross_model_consistencyDo different runs produce similar results?> 0.70
episodic_segmentation_recallDoes the system segment episodes correctly?> 0.60

PsycheGraph Schema — npm package

The open schema that defines what a PsycheGraph persona looks like. Install it to get typed enums and interfaces in TypeScript or JavaScript projects — no API key needed.

npm install @stratasynth/psychegraph-schema
# or: pnpm add @stratasynth/psychegraph-schema
Use the enums to work with StrataSynth data
import {
  AttachmentStyle,
  Archetype,
  ConflictStyle,
  NoiseType,
  ArcType,
  PrimaryDefense,
} from "@stratasynth/psychegraph-schema";

// Enums give you all valid values — IDE autocompletes, TypeScript validates
const filter = {
  attachment: AttachmentStyle.ANXIOUS_PREOCCUPIED,   // "anxious_preoccupied"
  archetype:  Archetype.BURNED_OUT_EXEC,             // "burned_out_exec"
  conflict:   ConflictStyle.STONEWALLING,            // "stonewalling"
};

// Filter conversations from a downloaded dataset
const relevant = conversations.filter(conv =>
  conv.persona_a.attachment_style === AttachmentStyle.DISMISSIVE_AVOIDANT
);

// List all valid values at runtime
console.log(Object.values(AttachmentStyle));
ExportTypeExamples
AttachmentStyleenumsecure · dismissive_avoidant · …
Archetypeenumworking_mother · burned_out_exec · … (24 total)
ConflictStyleenumnegotiating · stonewalling · …
NoiseTypeenumsocial_lie · explicit_retraction · …
ArcTypeenumescalation_partial_resolution · pure_conflict · …
PrimaryDefenseenumprojection · denial · …
PsycheGraphinterfaceFull persona profile shape (TypeScript type-only)
ConversationTurninterfaceSingle turn with ground truth fields (TypeScript type-only)
Note: Interfaces (PsycheGraph, ConversationTurn) are TypeScript-only — they disappear at runtime and are used via import type { PsycheGraph }. Enums are runtime values available in both JS and TS.
The schema is open. The engine is not. These types describe what a StrataSynth persona looks like — the taxonomy is an open standard you can build on. How a persona behaves (the belief-update dynamics, the deterministic decision engine that picks each turn's communication act before any text is generated, the psychometric calibration and cultural conditioning) is proprietary and runs exclusively server-side. Reproducing the taxonomy in a prompt does not reproduce the behavior — see Notebook 04 for an auditable demonstration.

FAQ

Where are my generated files?

In S3 (AWS). You access them via a presigned URL (valid 24h) through the Dashboard Download button, the CLI (jobs download), or the SDK (result.download()). There is no direct S3 access for users.

How long does a job take?

~5–12 minutes for 5–10 conversations, depending on scenario complexity and persona depth. Conversations run in parallel, so total time is driven by the slowest one, not the sum.

Can I preview the dataset before downloading everything?

Yes. GET /jobs/{jobId}/preview returns the first 2 conversations. In the Dashboard, the Preview button is available when the job is COMPLETED.

How do I guarantee consistency between datasets?

Generate a persona with /personas/generate, save its personaId, and use it as persona_a_id or persona_b_id in multiple jobs. Same persona = consistent psychological baseline across datasets.

Does language affect only the text?

Yes — the turn text is in the chosen language, but ground truth labels (intent, communication_act, etc.) are always in English (fixed schema labels).

Can I evaluate my own system?

Yes. POST /evaluate with the system_output parameter (an S3 key with your system's output). This unlocks fact_f1, reembedding_drift, affinity_smoothness and other metrics that compare your system against the ground truth.

Is the ground truth generated by an LLM?

No. intent, goal, communication_act and belief_state are computed by the Decision Engine before the LLM runs. Ground truth metrics (noise_rejection_rate, behavioral_entropy, etc.) are calculated with numpy/scikit-learn. No LLM is involved in evaluation.