{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://tutorflow.io/resources/integrations/source-json.schema.json",
  "title": "TutorFlow Content API source JSON",
  "description": "The `payload` of POST /v1/content/integrations/expansions. The canonical shape is { language, category, level: { lessons } }. The `categories[].levels[]` and flat `lessons` variants are also accepted. One level is expanded per job: the first level that has at least one lesson. Extra fields are allowed and stored with the job. See https://tutorflow.io/resources/integrations/source-json-payload",
  "type": "object",
  "properties": {
    "language": {
      "type": "string",
      "description": "Language of the generated content, for example \"en\" or \"ko\". Defaults to \"en\". Only this top-level field is read; `locale` is not."
    },
    "category": {
      "description": "The category the level belongs to. Its title is read from `title`, then `name`, then `id`. A plain string is used as the title. Defaults to \"Imported content\".",
      "oneOf": [
        {
          "type": "string",
          "minLength": 1
        },
        {
          "$ref": "#/$defs/titled"
        }
      ]
    },
    "level": {
      "$ref": "#/$defs/level"
    },
    "categories": {
      "type": "array",
      "description": "Nested variant. The first level, in array order, that has at least one lesson is expanded; every other level is ignored.",
      "items": {
        "allOf": [
          {
            "$ref": "#/$defs/titled"
          },
          {
            "type": "object",
            "properties": {
              "levels": {
                "type": "array",
                "description": "Levels without lessons are skipped.",
                "items": {
                  "allOf": [
                    {
                      "$ref": "#/$defs/titled"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "lessons": {
                          "type": "array",
                          "items": {
                            "$ref": "#/$defs/lesson"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            },
            "required": [
              "levels"
            ]
          }
        ]
      }
    },
    "title": {
      "type": "string",
      "description": "Flat variant only: the level title when `lessons` sits at the top level."
    },
    "lessons": {
      "type": "array",
      "description": "Flat variant: the payload itself is the level.",
      "minItems": 1,
      "items": {
        "$ref": "#/$defs/lesson"
      }
    }
  },
  "anyOf": [
    {
      "required": [
        "level"
      ]
    },
    {
      "required": [
        "categories"
      ]
    },
    {
      "required": [
        "lessons"
      ]
    }
  ],
  "additionalProperties": true,
  "$defs": {
    "titled": {
      "type": "object",
      "description": "An object whose display title is read from `title`, then `name`, then `id`.",
      "properties": {
        "id": {
          "type": "string",
          "description": "Your stable id. Stored with the job for traceability."
        },
        "title": {
          "type": "string"
        },
        "name": {
          "type": "string"
        }
      },
      "additionalProperties": true
    },
    "level": {
      "allOf": [
        {
          "$ref": "#/$defs/titled"
        },
        {
          "type": "object",
          "properties": {
            "lessons": {
              "type": "array",
              "minItems": 1,
              "description": "Ordered lessons. At least one is required.",
              "items": {
                "$ref": "#/$defs/lesson"
              }
            }
          },
          "required": [
            "lessons"
          ]
        }
      ]
    },
    "lesson": {
      "description": "A lesson object. TutorFlow reads `title` (or `name`), `type`, and the first 6 other fields in key order; the values of those fields are included as JSON text. A non-object lesson is included as text.",
      "oneOf": [
        {
          "type": "object",
          "properties": {
            "id": {
              "type": "string",
              "description": "Your stable lesson id. Not used for generation."
            },
            "title": {
              "type": "string"
            },
            "name": {
              "type": "string",
              "description": "Used when `title` is absent."
            },
            "type": {
              "type": "string",
              "description": "Your lesson type, for example vocabulary, example, dialogue, quiz, or review. Any value is accepted and used as a label. Defaults to \"content\"."
            }
          },
          "additionalProperties": true
        },
        {
          "type": "string"
        }
      ]
    }
  }
}
