資源
Simulations over the Content API

Simulations over the Content API

The simulation object, its brief, and the metadata keys that shape its plan. Create, list, and update classroom simulations from an external system.

本頁內容

A simulation is an interactive model with controls. Learners change the controls and watch the result, so there is no score, no winning, and no losing. If you want something with a score, build a game instead. Every route is under /v1/content/classrooms/{classroomId}/simulations and takes a tf_content_ key.

Planning, building, revising, restoring, and sharing work the same way for games and simulations, and are described once in Generation: Brief, Build, Revise. This page covers what is specific to simulations. The full route list is in the API Reference.

The simulation object

Create, read, update, and restore return the same shape. content appears only on GET /simulations/{simulationId}.

FieldNotes
idUse as {simulationId} on later calls.
classroomIdThe classroom the simulation belongs to.
title, descriptionDisplay text. description may be null. A generated brief replaces title with its own.
visibilityPRIVATE or PUBLIC. A public, built simulation opens at its play page (publicUrl) without an account.
subjectSet by the brief: computer-science, ai-ml, finance, business, math, science, or other. other until a brief exists. A brief you send with PATCH sets it from brief.subject.
representationSet by the brief: 2d-canvas for a plain canvas, or 3d-three when the third dimension is part of the lesson. New simulations start as 2d-canvas. It decides the build and revision price; see Pricing. A brief you send with PATCH sets it from brief.representation, which changes the price.
slugA short label TutorFlow assigns. It is not part of any link.
metadataAn object you own. The keys in Metadata that shapes the plan feed the brief; other keys are stored untouched, except that sending language also stores isLanguageChosen: true.
briefThe plan the build reads. null until a brief is generated or written. See The brief.
contentKeyStorage reference of the version being served. An opaque identifier, not a URL. null until the first build.
contentVersionThe version being served. 0 until the first build, then incremented by every build, revision, tuning, and restore.
buildHistoryOne entry per version: version, contentKey (opaque), createdAt, source (build, revision, restore, or tuning), note with the revision feedback when there was one, and restoredFromVersion on a restore.
thumbnailStorage reference of a capture of the opening frame, or null. An opaque identifier, not a URL.
contentThe built simulation as one complete HTML document, or null before the first build. Only on GET /simulations/{simulationId}.
createdAt, updatedAtTimestamps. Sort the list by updatedAt to find recent changes.
editorUrlThe simulation in the TutorFlow editor, for a person signed in to TutorFlow as an admin of the organization. null in the sandbox classroom.
publicUrlThe play page, https://tutorflow.io/simulations/play/{simulationId}, while the simulation is PUBLIC and built. null otherwise and in the sandbox classroom.

A tuning entry records a save from the visual editor in the TutorFlow app, with note: "Visual editor". The page was edited in place rather than regenerated, so it cost no credits. No Content API call creates one.

The brief

The brief is the quickest way to see what a simulation computes without reading its HTML, and the place to catch a wrong model before paying for a build. A generated brief has these fields. Write your own with PATCH /simulations/{simulationId} and a brief object to skip the priced brief call.

FieldNotes
title, pitch, eyebrowThe title, one sentence for the learner, and a two-to-four-word label shown above the title.
factsTwo to four label and value pairs about the model: its parts, its rule, its scale.
statusA short footer line naming what kind of model is running.
subjectOne of the subject values above.
representation2d-canvas or 3d-three. Copied to the simulation's representation, so it sets the price.
themestudio or exhibit, the look the plan chose.
modelWhat the simulation computes: the state it tracks and the rules that advance it.
controlsOne to five entries of label, kind (slider, toggle, choice, or number), range, effect, and section.
observationsOne to four things the learner watches to read the result.
inquiryTwo to four questions the learner answers by moving the controls.

Check model and controls before building. A simulation that computes the wrong thing is the failure this content type is most prone to, and the build checks do not verify the arithmetic.

Metadata that shapes the plan

All keys are optional. PATCH merges metadata: keys you send replace their old values, and keys you leave out stay.

KeyValuesNotes
topicFree textThe principle the learner should work out. Falls back to title.
audienceFree textWho the simulation is for.
objectiveFocusFree textWhat the learner should end up understanding.
themeauto, studio, or exhibitstudio is light, exhibit is a dark stage, auto lets the plan choose. A learner can switch it in the player without a rebuild.
languageLanguage name or codeLanguage of on-screen text. When unset, the plan infers it from topic, objectiveFocus, and referenceMarkdown; set it to be sure.
referenceMarkdownMarkdownYour own material to ground the plan. POST /brief can override it per call.

Create a simulation

title and visibility are required. Create it PRIVATE, and set it PUBLIC once the build has been checked (you read content, or a person opens editorUrl).

bash
curl -X POST "$TUTORFLOW_API_BASE_URL/v1/content/classrooms/$CLASSROOM_ID/simulations" \
  -H "Authorization: Bearer $TUTORFLOW_CONTENT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: simulation:compound-interest:v1" \
  -d '{
    "title": "Compound interest",
    "description": "See how rate and time change a balance.",
    "visibility": "PRIVATE",
    "metadata": {
      "topic": "Compound interest on a savings balance",
      "audience": "First-year finance",
      "objectiveFocus": "Why doubling the time matters more than doubling the rate",
      "theme": "auto",
      "language": "en",
      "externalId": "simulation:compound-interest"
    }
  }'

The response is 201 with the simulation object, contentVersion: 0, brief: null, subject: "other".

List simulations

HTTP
GET /v1/content/classrooms/{classroomId}/simulations?page=1&limit=20&field=updatedAt&order=DESC&subject=finance
Authorization: Bearer tf_content_...
ParameterDefaultNotes
page11-based.
limit20Values above 100 are clamped to 100. take is a deprecated alias.
fieldcreatedAttitle, createdAt, updatedAt, or subject. Anything else returns 422 with error.allowedValues.
orderDESCASC or DESC. Ties break on id.
searchCase-insensitive substring of title.
updatedSinceISO 8601 date-time. Only simulations updated at or after it.
subjectOnly simulations with this subject.

The response is the list envelope with simulation objects without content. The same parameters work on every resource list; see List pages.

Update a simulation

PATCH /simulations/{simulationId} is partial. It accepts title, description, visibility, brief, and metadata, and returns 200 with the updated simulation. subject and representation cannot be set directly, but a brief you send sets both from brief.subject and brief.representation. contentKey and contentVersion belong to the build pipeline and cannot be set.

Other routes

The rest of the simulation routes are listed in the API Reference: DELETE /simulations/{simulationId}, POST .../brief, POST .../build, POST .../revise, GET .../run, and POST .../versions/{version}/restore (takes Idempotency-Key). The brief, build, and revise steps are described in Generation. Single reads and PATCH carry an ETag; send If-Match on PATCH to avoid overwriting a change made elsewhere. See Concurrency.

這個頁面對你有幫助嗎?