Skip to content
StudyFetch API

API References

Scenarios

Overview

The Scenarios component creates interactive learning experiences through case studies, role-playing exercises, and problem-solving scenarios. Learners talk with AI-played characters, use the tools you define, and are graded against your criteria. These immersive experiences help students apply theoretical knowledge in practical contexts.

You only need to describe the scenario. At create time, the AI fills in anything you leave blank: context, goal, greetingMessage, characters, criteria, and, when requiresFinalAnswer is true, finalAnswerPrompt. tools and format are never generated.

Creating a Scenarios Component

JavaScript

import StudyfetchSDK from '@studyfetch/sdk';

const client = new StudyfetchSDK({
  apiKey: 'your-api-key',
  baseURL: 'https://studyfetchapi.com',
});

const scenarioComponent = await client.v1.components.create({
  name: 'Medical Emergency Room Scenario',
  description: 'Assess and diagnose a patient presenting with chest pain',
  type: 'scenarios',
  // TypeScript: the SDK's config type doesn't include scenarios yet, so cast this object (`as any`).
  config: {
    context: 'You are a medical resident in a busy emergency room. A patient has just arrived with chest pain.',
    goal: 'Properly assess the patient, order appropriate tests, and make a diagnosis',
    format: 'Interactive dialogue with patient and medical staff',
    greetingMessage: 'Welcome Dr. [Student Name]. Your patient, Mr. Johnson, has just arrived in room 3 complaining of chest pain.',
    greetingCharacterId: 'nurse-jane',
    requiresFinalAnswer: true,
    finalAnswerPrompt: 'Based on your assessment, what is your diagnosis and treatment plan?',
    criteria: [
      { id: 'history-taking', description: 'Structured history and focused questions', weight: 7 },
      { id: 'clinical-reasoning', description: 'Sound differential and next steps', weight: 8 },
    ],
    characters: [
      {
        id: 'patient-johnson',
        name: 'Mr. Johnson',
        role: 'Patient',
        description: '58-year-old male with chest pain',
      },
      {
        id: 'nurse-jane',
        name: 'Nurse Jane',
        role: 'Emergency Room Nurse',
        description: 'Experienced ER nurse who assists with procedures',
      },
    ],
    tools: [
      {
        id: 'ekg-machine',
        name: 'EKG Machine',
        description: 'Performs 12-lead electrocardiogram',
        type: 'diagnostic',
        dataFormat: 'EKG readings with intervals and interpretation',
      },
      {
        id: 'lab-results',
        name: 'Lab Results System',
        description: 'Provides blood test results',
        type: 'diagnostic',
        dataFormat: 'Complete blood count, cardiac enzymes, etc.',
      },
    ],
  },
});

console.log('Scenario component created:', scenarioComponent._id, scenarioComponent.componentId);

Python

from studyfetch_sdk import StudyfetchSDK

client = StudyfetchSDK(
    api_key="your-api-key",
    base_url="https://studyfetchapi.com",
)

# The SDK's config type doesn't include scenarios yet, so snake_case keys are not
# converted. Use the API's camelCase keys as shown.
scenario_component = client.v1.components.create(
    name="Medical Emergency Room Scenario",
    description="Assess and diagnose a patient presenting with chest pain",
    type="scenarios",
    config={
        "context": "You are a medical resident in a busy emergency room. A patient has just arrived with chest pain.",
        "goal": "Properly assess the patient, order appropriate tests, and make a diagnosis",
        "format": "Interactive dialogue with patient and medical staff",
        "greetingMessage": "Welcome Dr. [Student Name]. Your patient, Mr. Johnson, has just arrived in room 3 complaining of chest pain.",
        "greetingCharacterId": "nurse-jane",
        "requiresFinalAnswer": True,
        "finalAnswerPrompt": "Based on your assessment, what is your diagnosis and treatment plan?",
        "criteria": [
            {"id": "history-taking", "description": "Structured history and focused questions", "weight": 7},
            {"id": "clinical-reasoning", "description": "Sound differential and next steps", "weight": 8},
        ],
        "characters": [
            {
                "id": "patient-johnson",
                "name": "Mr. Johnson",
                "role": "Patient",
                "description": "58-year-old male with chest pain",
            },
            {
                "id": "nurse-jane",
                "name": "Nurse Jane",
                "role": "Emergency Room Nurse",
                "description": "Experienced ER nurse who assists with procedures",
            },
        ],
        "tools": [
            {
                "id": "ekg-machine",
                "name": "EKG Machine",
                "description": "Performs 12-lead electrocardiogram",
                "type": "diagnostic",
                "dataFormat": "EKG readings with intervals and interpretation",
            },
            {
                "id": "lab-results",
                "name": "Lab Results System",
                "description": "Provides blood test results",
                "type": "diagnostic",
                "dataFormat": "Complete blood count, cardiac enzymes, etc.",
            },
        ],
    },
)

print(f"Scenario component created: {scenario_component.api_id} {scenario_component.component_id}")

Java

import com.studyfetch.javasdk.client.StudyfetchSdkClient;
import com.studyfetch.javasdk.client.okhttp.StudyfetchSdkOkHttpClient;
import com.studyfetch.javasdk.models.v1.components.ComponentResponse;
import com.studyfetch.javasdk.models.v1.components.ComponentCreateParams;

import java.util.List;

public class CreateScenariosComponent {
    public static void main(String[] args) {
        StudyfetchSdkClient client = StudyfetchSdkOkHttpClient.builder()
                .fromEnv()
                .baseUrl("https://studyfetchapi.com")
                .build();

        ComponentCreateParams params = ComponentCreateParams.builder()
                .name("Medical Emergency Room Scenario")
                .description("Assess and diagnose a patient presenting with chest pain")
                .type(ComponentCreateParams.Type.SCENARIOS)
                .config(ComponentCreateParams.Config.ScenariosConfigDto.builder()
                        .context("You are a medical resident in a busy emergency room. A patient has just arrived with chest pain.")
                        .goal("Properly assess the patient, order appropriate tests, and make a diagnosis")
                        .format("Interactive dialogue with patient and medical staff")
                        .greetingMessage("Welcome Dr. [Student Name]. Your patient, Mr. Johnson, has just arrived in room 3 complaining of chest pain.")
                        .greetingCharacterId("nurse-jane")
                        .requiresFinalAnswer(true)
                        .finalAnswerPrompt("Based on your assessment, what is your diagnosis and treatment plan?")
                        .criteria(List.of(
                                ComponentCreateParams.Config.ScenariosConfigDto.Criterion.builder()
                                        .id("history-taking")
                                        .description("Structured history and focused questions")
                                        .weight(7.0)
                                        .build(),
                                ComponentCreateParams.Config.ScenariosConfigDto.Criterion.builder()
                                        .id("clinical-reasoning")
                                        .description("Sound differential and next steps")
                                        .weight(8.0)
                                        .build()
                        ))
                        .characters(List.of(
                                ComponentCreateParams.Config.ScenariosConfigDto.Character.builder()
                                        .id("patient-johnson")
                                        .name("Mr. Johnson")
                                        .role("Patient")
                                        .description("58-year-old male with chest pain")
                                        .build(),
                                ComponentCreateParams.Config.ScenariosConfigDto.Character.builder()
                                        .id("nurse-jane")
                                        .name("Nurse Jane")
                                        .role("Emergency Room Nurse")
                                        .description("Experienced ER nurse who assists with procedures")
                                        .build()
                        ))
                        .tools(List.of(
                                ComponentCreateParams.Config.ScenariosConfigDto.Tool.builder()
                                        .id("ekg-machine")
                                        .name("EKG Machine")
                                        .description("Performs 12-lead electrocardiogram")
                                        .type("diagnostic")
                                        .dataFormat("EKG readings with intervals and interpretation")
                                        .build(),
                                ComponentCreateParams.Config.ScenariosConfigDto.Tool.builder()
                                        .id("lab-results")
                                        .name("Lab Results System")
                                        .description("Provides blood test results")
                                        .type("diagnostic")
                                        .dataFormat("Complete blood count, cardiac enzymes, etc.")
                                        .build()
                        ))
                        .build())
                .build();

        ComponentResponse component = client.v1().components().create(params);
        System.out.println("Scenario component created: " + component._id());
    }
}

cURL

# The C# SDK can't create scenarios components yet (its scenario config type is disabled).
# Use the REST API directly from C#, or this request.
curl -X POST "https://studyfetchapi.com/api/v1/components" \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Medical Emergency Room Scenario",
    "description": "Assess and diagnose a patient presenting with chest pain",
    "type": "scenarios",
    "config": {
      "context": "You are a medical resident in a busy emergency room. A patient has just arrived with chest pain.",
      "goal": "Properly assess the patient, order appropriate tests, and make a diagnosis",
      "greetingCharacterId": "nurse-jane",
      "characters": [
        { "id": "patient-johnson", "name": "Mr. Johnson", "role": "Patient" },
        { "id": "nurse-jane", "name": "Nurse Jane", "role": "Emergency Room Nurse" }
      ],
      "tools": [
        { "id": "ekg-machine", "name": "EKG Machine", "description": "Performs 12-lead electrocardiogram", "type": "diagnostic" }
      ],
      "criteria": []
    }
  }'

Configuration Parameters

name

string · required

Name of the scenarios component

description

string · required

Short description of the scenario. Required for scenarios, even though other component types treat it as optional.

type

string · required

Must be "scenarios"

config

object · required

Scenarios configuration object. Unknown keys are rejected with 400.

Configuration Properties

These properties go inside config.

context

string

Overall context and setting of the scenario. Generated if blank.

goal

string

Primary goal or learning objective of the interaction. Generated if blank.

format

string

Interaction format and step-by-step instructions. Never generated; when empty, the scenario runs as a general conversation.

greetingMessage

string

Initial greeting message displayed to users. Generated if blank.

greetingCharacterId

string

ID of the character who delivers the greeting. If blank or not one of the characters, the first character is used.

requiresFinalAnswer

boolean · default: false

Whether the learner must submit a final answer to finish the scenario

finalAnswerPrompt

string

Prompt shown when asking for the final answer. Generated if blank and requiresFinalAnswer is true.

criteria

array

Evaluation criteria for grading. Each entry needs a stable id, a human-readable description, and a weight from 1–10 (relative importance). Generated if omitted or empty at create time.

Criterion object

These properties go inside criteria.

id

string · required

Stable identifier for this criterion

description

string · required

What this criterion measures

weight

number · required

Importance weight from 1 to 10

characters

array

Characters in the scenario. Generated if omitted or empty at create time.

Character Properties

These properties go inside characters.

id

string · required

Unique identifier for the character

name

string · required

Character's name

role

string · required

Character's role in the scenario

description

string

Character's description and personality

tools

array

Tools available in the scenario. Never generated.

Tool Properties

These properties go inside tools.

id

string · required

Unique identifier for the tool

name

string · required

Tool's name

description

string · required

What the tool does or shows

type

string · required

Type of tool (e.g., "Database", "Document", "diagnostic")

dataFormat

string

Format of data the tool provides

model

string · default: gpt-4o-mini-2024-07-18

Model that plays the characters and grades the learner. Generating blank fields at create time uses a fixed model.

materials

array

Accepted and stored, but not currently used by scenarios

folders

array

Accepted and stored, but not currently used by scenarios

enableHistory

boolean

Stored on the component. The embed reads this setting from the embed token; use features.enableHistory.

enableVoice

boolean

Stored on the component. Use features.enableVoice to control the embed.

placeholderText

string

Stored on the component. Use features.placeholderText to control the embed.

Response

{
  "_id": "6650f1c2a9b3e4d5f6a7b8c9",
  "componentId": "scenarios_V1StGXR8_Z",
  "name": "Medical Emergency Room Scenario",
  "description": "Assess and diagnose a patient presenting with chest pain",
  "type": "scenarios",
  "status": "active",
  "origin": "api",
  "organization": "64f0a1b2c3d4e5f6a7b8c9d0",
  "config": {
    "context": "You are a medical resident in a busy emergency room. A patient has just arrived with chest pain.",
    "goal": "Properly assess the patient, order appropriate tests, and make a diagnosis",
    "format": "Interactive dialogue with patient and medical staff",
    "greetingMessage": "Welcome Dr. [Student Name]. Your patient, Mr. Johnson, has just arrived in room 3 complaining of chest pain.",
    "greetingCharacterId": "nurse-jane",
    "requiresFinalAnswer": true,
    "finalAnswerPrompt": "Based on your assessment, what is your diagnosis and treatment plan?",
    "criteria": [
      { "id": "history-taking", "description": "Structured history and focused questions", "weight": 7 },
      { "id": "clinical-reasoning", "description": "Sound differential and next steps", "weight": 8 }
    ],
    "characters": [
      {
        "id": "patient-johnson",
        "name": "Mr. Johnson",
        "role": "Patient",
        "description": "58-year-old male with chest pain"
      },
      {
        "id": "nurse-jane",
        "name": "Nurse Jane",
        "role": "Emergency Room Nurse",
        "description": "Experienced ER nurse who assists with procedures"
      }
    ],
    "tools": [
      {
        "id": "ekg-machine",
        "name": "EKG Machine",
        "description": "Performs 12-lead electrocardiogram",
        "type": "diagnostic",
        "dataFormat": "EKG readings with intervals and interpretation"
      },
      {
        "id": "lab-results",
        "name": "Lab Results System",
        "description": "Provides blood test results",
        "type": "diagnostic",
        "dataFormat": "Complete blood count, cardiac enzymes, etc."
      }
    ]
  },
  "usageCount": 0,
  "createdAt": "2026-10-06T10:00:00.000Z",
  "updatedAt": "2026-10-06T10:00:00.000Z"
}

The response config includes any values the AI generated, and the greetingCharacterId the server chose.

Updating a Scenario

Update a scenario with PATCH /api/v1/components/{id}, where {id} is the component's _id. Include "type": "scenarios" whenever you send config; without it the request is rejected with 400.

The server merges your changes with the existing scenario. Partial updates (just criteria, just tools, and so on) are fine; the existing values fill in. The update fails with 400 if the merged result would leave any of these empty:

  • name and description
  • context, goal, greetingMessage
  • finalAnswerPrompt, when requiresFinalAnswer is true

Updates are not auto-filled, so any characters, tools, or criteria you send must be complete. format can be empty.

The SDKs' update methods only change a component's status for now, so update scenario content with cURL or an HTTP client:

curl -X PATCH "https://studyfetchapi.com/api/v1/components/6650f1c2a9b3e4d5f6a7b8c9" \
  -H "x-api-key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "scenarios",
    "config": {
      "criteria": [
        { "id": "history-taking", "description": "Structured history and focused questions", "weight": 6 },
        { "id": "clinical-reasoning", "description": "Sound differential and next steps", "weight": 9 }
      ]
    }
  }'

Embedding This Component

Once you've created a Scenarios component, you can embed it on your website using the embedding API. The component must be active.

Generate Embed URL

JavaScript

const embedResponse = await client.v1.components.generateEmbed(scenarioComponent._id, {
  // User tracking
  userId: 'user-456',
  studentName: 'Jane Smith',  // Student name for display
  groupIds: ['class-101', 'class-102'],
  sessionId: 'session-789',

  // Scenarios-specific features
  features: {
    enableBadWordsFilter: true,  // Required by the SDK type; no effect on Scenarios
    enableHistory: true,
    enableVoice: true,
    placeholderText: 'Type your message...',
  },

  // Dimensions
  width: '100%',
  height: '600px',
});

console.log(embedResponse.embedUrl);

Python

embed_response = client.v1.components.generate_embed(
    scenario_component.api_id,
    user_id="user-456",
    student_name="Jane Smith",  # Student name for display
    group_ids=["class-101", "class-102"],
    session_id="session-789",
    features={
        "enable_bad_words_filter": True,  # Required by the SDK type; no effect on Scenarios
        "enable_history": True,
        "enable_voice": True,
        "placeholder_text": "Type your message...",
    },
    width="100%",
    height="600px",
)

print(embed_response.embed_url)

Java

import com.studyfetch.javasdk.models.v1.components.ComponentGenerateEmbedParams;
import com.studyfetch.javasdk.models.v1.components.ComponentGenerateEmbedResponse;

ComponentGenerateEmbedParams params = ComponentGenerateEmbedParams.builder()
    .id(scenarioComponent._id())
    // User tracking
    .userId("user-456")
    .studentName("Jane Smith")  // Student name for display
    .groupIds(List.of("class-101", "class-102"))
    .sessionId("session-789")

    // Scenarios-specific features
    .features(ComponentGenerateEmbedParams.Features.builder()
        .enableBadWordsFilter(true)  // Required: build() throws without it
        .enableHistory(true)
        .enableVoice(true)
        .placeholderText("Type your message...")
        .build())

    // Dimensions
    .width("100%")
    .height("600px")
    .build();

ComponentGenerateEmbedResponse embedResponse = client.v1().components()
    .generateEmbed(params);

System.out.println(embedResponse.embedUrl());

C#

using StudyfetchSDK;
using StudyfetchSDK.Models.V1.Components;
using StudyfetchSDK.Models.V1.Components.ComponentGenerateEmbedParamsProperties;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

public class GenerateScenariosEmbed
{
    public static async Task GenerateEmbed(string scenarioComponentId)
    {
        var client = new StudyfetchSDKClient()
        {
            APIKey = Environment.GetEnvironmentVariable("STUDYFETCH_API_KEY"),
            BaseUrl = new Uri("https://studyfetchapi.com")
        };

        var embedResponse = await client.V1.Components.GenerateEmbed(new()
        {
            ID = scenarioComponentId,
            UserID = "user-456",
            StudentName = "Jane Smith",  // Student name for display
            GroupIDs = new List<string> { "class-101", "class-102" },
            SessionID = "session-789",
            Features = new Features(enableBadWordsFilter: true)
            {
                EnableHistory = true,
                EnableVoice = true,
                PlaceholderText = "Type your message..."
            },
            Width = "100%",
            Height = "600px"
        });

        Console.WriteLine($"Embed URL: {embedResponse.EmbedURL}");
        Console.WriteLine($"Token: {embedResponse.Token}");
    }
}

The response contains embedUrl, token, expiresAt, componentId (the component's _id), componentType, and options (width and height, defaulting to 100% and 600px).

Scenarios-Specific Embedding Features

features.enableHistory

boolean · default: true

Save scenario progress and allow users to resume where they left off

features.enableVoice

boolean · default: true

Enable voice input. Your iframe needs allow="microphone".

features.placeholderText

string · default: Type your message...

Placeholder text for the message input

Embed in Your HTML

Use the embedUrl from the response as the iframe source. The host can differ per organization, so don't build the URL yourself.

<iframe
  src="EMBED_URL_FROM_RESPONSE"
  width="100%"
  height="600px"
  frameborder="0"
  allow="microphone"
  style="border: 1px solid #e5e5e5; border-radius: 8px;">
</iframe>

React Native

The React Native SDK (@studyfetch/react-native-sdk) renders Scenarios natively with embed tokens instead of an iframe. Import it from @studyfetch/react-native-sdk/scenarios and wrap your app in EmbedTokenProvider with a getToken function that asks your backend to mint an embed token for a component.

import { EmbedTokenProvider } from '@studyfetch/react-native-sdk';
import { StudyFetchScenario, useScenario } from '@studyfetch/react-native-sdk/scenarios';

// Full scenario UI: character dialogue, tools, grading
<EmbedTokenProvider getToken={fetchToken}>
  <StudyFetchScenario componentId="scenarios_V1StGXR8_Z" userId="user-456" />
</EmbedTokenProvider>

// Headless: build your own UI
const {
  scenario, messages, activeCharacterName,
  submission, sendMessage, submit, evaluate, restart,
} = useScenario({ componentId: 'scenarios_V1StGXR8_Z', userId: 'user-456' });
  • Replies stream by default, and a single reply can include several characters speaking.
  • submit(finalAnswer) grades and completes the session and populates submission. evaluate(draft) returns a preview grade without saving.
  • Pass stream={false} to receive each reply in one response on networks where streaming is unreliable.