{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Pulse Program Export",
  "description": "The JSON format Pulse imports as a training program (Programs → Import program). Give this schema to an AI assistant along with your training topic and ask it to produce a single JSON file matching it exactly — see https://usepulse.training/docs/creating-programs-with-ai for example prompts.",
  "type": "object",
  "required": ["title", "steps"],
  "additionalProperties": false,
  "properties": {
    "pulseProgramExport": {
      "type": "integer",
      "const": 1,
      "description": "Optional format version marker. Include it as 1 if present at all; omitting it is also fine."
    },
    "title": {
      "type": "string",
      "minLength": 1,
      "description": "The program's title, shown in the program library."
    },
    "description": {
      "type": "string",
      "default": "",
      "description": "A one- or two-sentence summary shown in the program library."
    },
    "category": {
      "type": ["string", "null"],
      "description": "Optional free-text grouping label (e.g. \"Onboarding\", \"Security\"). Omit or use null if you don't need one."
    },
    "steps": {
      "type": "array",
      "minItems": 1,
      "description": "The ordered sequence of steps a session runs through, top to bottom. A step's position in this array is its order — there is no separate order field.",
      "items": { "$ref": "#/definitions/step" }
    }
  },
  "definitions": {
    "step": {
      "type": "object",
      "required": ["type", "title"],
      "additionalProperties": false,
      "properties": {
        "type": {
          "type": "string",
          "enum": ["INFO", "POLL", "SCENARIO", "DISCUSSION", "WORDCLOUD", "REVEAL"],
          "description": "INFO = a markdown slide with no interaction. POLL = a quick multiple-choice question, aggregated live. SCENARIO = a multiple-choice question with a correct/best answer, for knowledge checks. DISCUSSION = an open-ended free-text prompt with no right answer. WORDCLOUD = participants each submit one or more short words/phrases, aggregated into a live word cloud. REVEAL = shows a live chart of the group's answers to an earlier POLL/SCENARIO/DISCUSSION/WORDCLOUD step — always place it after the step it reveals."
        },
        "title": {
          "type": "string",
          "minLength": 1,
          "description": "The step's heading, shown to participants."
        },
        "body": {
          "type": "string",
          "default": "",
          "description": "Markdown body text. This is the main content for an INFO step; for other step types it's optional supporting context shown above the question/prompt."
        },
        "media": {
          "type": "array",
          "default": [],
          "description": "Optional images/videos attached to this step, shown below the body.",
          "items": {
            "type": "object",
            "required": ["type", "url"],
            "additionalProperties": false,
            "properties": {
              "type": { "type": "string", "enum": ["image", "video"] },
              "url": { "type": "string", "description": "A publicly reachable URL — Pulse does not host files uploaded via this JSON format." },
              "caption": { "type": "string" }
            }
          }
        },
        "config": {
          "type": "object",
          "default": {},
          "description": "Shape depends on `type`. INFO: {} — no config needed. POLL: { \"options\": string[] (2 or more choices), \"resultsVisibility\": \"PRIVATE\" | \"PUBLIC\" }. SCENARIO: { \"options\": string[], \"bestOptionIndex\": number (optional, 0-based index of the correct/best choice), \"resultsVisibility\": \"PRIVATE\" | \"PUBLIC\" }. DISCUSSION: { \"placeholder\": string (optional input placeholder text) }. WORDCLOUD: { \"maxEntries\": number or null (optional cap on words per participant), \"placeholder\": string (optional) }. REVEAL: { \"sourceStepOrder\": number } — the 0-based index, in this same top-level steps array, of the POLL/SCENARIO/DISCUSSION/WORDCLOUD step whose results this reveal shows. \"PRIVATE\" visibility means only the host sees who answered what; \"PUBLIC\" shows named results to everyone in the session."
        }
      }
    }
  }
}
