{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/clipform-io/json-schema/clipform-io-form-with-nodes-schema.json",
  "title": "FormWithNodes",
  "x-generated": "2026-11-04",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/clipform-io-openapi.yml#/components/schemas/FormWithNodes",
  "type": "object",
  "properties": {
    "form_id": {
      "type": "string",
      "format": "uuid",
      "maxLength": 36
    },
    "title": {
      "type": "string",
      "maxLength": 2000
    },
    "is_live": {
      "type": "boolean",
      "description": "Whether the form is online for respondents (separate from publish state)."
    },
    "has_unpublished_changes": {
      "type": "boolean",
      "description": "True when the live working copy has drifted from the published snapshot respondents currently see. Cleared by publishing (sending `is_live: true`, which re-freezes the snapshot)."
    },
    "published_version_id": {
      "type": [
        "string",
        "null"
      ],
      "format": "uuid",
      "description": "The currently published form_version, or null if never published.",
      "maxLength": 36
    },
    "nodes": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/Node"
      },
      "maxItems": 500
    },
    "variables": {
      "type": "array",
      "description": "The form's stable variable registry (#4173) - category/custom scoring variables a conditional branch can route on by id. Built-ins (score, max_score) are reserved keys, not rows here. Present only with `include=logic`.",
      "items": {
        "$ref": "#/$defs/FormVariable"
      },
      "maxItems": 200
    },
    "urls": {
      "type": "object",
      "description": "Dashboard/viewer deeplinks for this form (#3405). An anonymous caller gets only `viewer` (a live link, or a scoped preview link for a draft); a non-anonymous caller gets every dashboard tab plus `viewer` when the form is live.",
      "properties": {
        "viewer": {
          "type": "string",
          "format": "uri",
          "description": "Live respondent link, or a scoped preview link for an anonymous caller's draft.",
          "maxLength": 2048
        },
        "builder": {
          "type": "string",
          "format": "uri",
          "description": "Build tab - the node/canvas editor.",
          "maxLength": 2048
        },
        "summary": {
          "type": "string",
          "format": "uri",
          "description": "Summary tab - form overview and key stats.",
          "maxLength": 2048
        },
        "responses": {
          "type": "string",
          "format": "uri",
          "description": "Responses tab - individual submissions.",
          "maxLength": 2048
        },
        "analytics": {
          "type": "string",
          "format": "uri",
          "description": "Analytics tab - views, starts, completion rate, drop-off per node.",
          "maxLength": 2048
        },
        "share": {
          "type": "string",
          "format": "uri",
          "description": "Share tab - link, QR, social.",
          "maxLength": 2048
        },
        "embed": {
          "type": "string",
          "format": "uri",
          "description": "Embed setup for websites.",
          "maxLength": 2048
        },
        "dynamic_link": {
          "type": "string",
          "format": "uri",
          "description": "Dynamic/personalized link setup.",
          "maxLength": 2048
        }
      }
    }
  },
  "$defs": {
    "FormVariable": {
      "type": "object",
      "description": "One row of a form's stable variable registry (#4173) - a category or custom scoring variable a conditional branch can route on by its stable id instead of a mutable name. Built-in variables (score, max_score) are reserved keys resolved specially and never appear here.",
      "properties": {
        "id": {
          "type": "string",
          "format": "uuid",
          "maxLength": 36
        },
        "key": {
          "type": "string",
          "description": "Immutable internal identifier, frozen at creation. Never rewritten - a rename only edits `label`.",
          "maxLength": 200
        },
        "label": {
          "type": "string",
          "description": "Editable display name.",
          "maxLength": 200
        },
        "type": {
          "type": "string",
          "enum": [
            "number",
            "text"
          ]
        },
        "kind": {
          "type": "string",
          "enum": [
            "builtin",
            "category",
            "custom"
          ]
        }
      }
    },
    "Node": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "format": "uuid",
          "maxLength": 36
        },
        "type": {
          "$ref": "#/$defs/NodeType"
        },
        "prompt": {
          "type": "string",
          "maxLength": 2000
        },
        "label": {
          "type": "string",
          "maxLength": 2000
        },
        "required": {
          "type": "boolean"
        },
        "config": {
          "type": "object"
        },
        "options": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid",
                "maxLength": 36
              },
              "content": {
                "type": "string",
                "maxLength": 2000
              },
              "order": {
                "type": "integer",
                "format": "int32",
                "minimum": 0,
                "maximum": 2147483647
              },
              "score": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Single-category point value (simple quiz scoring)",
                "format": "int32",
                "minimum": 0,
                "maximum": 2147483647
              },
              "scores": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": {
                  "type": "integer",
                  "format": "int32",
                  "minimum": 0,
                  "maximum": 2147483647
                },
                "description": "Per-category scoring map (multi-outcome quizzes)"
              }
            }
          },
          "maxItems": 500
        },
        "media_id": {
          "type": [
            "string",
            "null"
          ],
          "format": "uuid",
          "description": "Linked node_media row id (returned in builder views - include=canvas/logic/media)",
          "maxLength": 36
        }
      }
    },
    "NodeType": {
      "type": "string",
      "enum": [
        "choice",
        "open",
        "button",
        "details",
        "draw",
        "camera",
        "payment",
        "file_download",
        "redirect",
        "end_screen"
      ]
    }
  }
}