{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/beatra-ai/json-schema/beatra-ai-image-edit-request-schema.json",
  "title": "ImageEditRequest",
  "description": "Edit a base image with optional ordered references and normalized regions.",
  "x-generated": "2026-11-02",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/beatra-ai-api-openapi.json#/components/schemas/ImageEditRequest",
  "properties": {
    "metadata": {
      "anyOf": [
        {
          "additionalProperties": {
            "type": "string"
          },
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "title": "Metadata",
      "description": "Caller-supplied metadata; ≤16 keys, key ≤64 chars, value ≤512 chars"
    },
    "callback_url": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 2048,
          "pattern": "^https://"
        },
        {
          "type": "null"
        }
      ],
      "title": "Callback Url",
      "description": "HTTPS URL beatra will POST the final Task envelope to when the Task reaches a terminal state"
    },
    "callback_signing_key_id": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 64,
          "minLength": 1,
          "pattern": "^whkey_[A-Za-z0-9]+$"
        },
        {
          "type": "null"
        }
      ],
      "title": "Callback Signing Key Id",
      "description": "Optional standalone callback signing key. Omit for unsigned callback delivery; requires callback_url when provided."
    },
    "model": {
      "type": "string",
      "enum": [
        "auto",
        "gpt-image-2.5-flare",
        "gpt-image-2.5-sunburst",
        "gpt-image-2",
        "image-01-live",
        "wan2.7-image-pro",
        "wan2.7-image",
        "qwen-image-3.0-pro",
        "qwen-image-3.0",
        "qwen-image-2.0-pro",
        "qwen-image-2.0"
      ],
      "title": "Model",
      "description": "Use auto for compatibility-based selection from the configured live candidates. A concrete model is evaluated exactly as requested and is never substituted.",
      "default": "auto"
    },
    "prompt": {
      "type": "string",
      "minLength": 1,
      "pattern": "\\S",
      "title": "Prompt",
      "description": "Required prompt containing at least one non-whitespace character."
    },
    "count": {
      "type": "integer",
      "maximum": 4.0,
      "minimum": 1.0,
      "title": "Count",
      "description": "Requested output image count. The public range is one through four, and the selected model must support the exact count; Beatra does not split the request.",
      "default": 1
    },
    "canvas": {
      "oneOf": [
        {
          "$ref": "#/$defs/ImageEditPresetCanvas"
        },
        {
          "$ref": "#/$defs/ImageTargetCanvas"
        }
      ],
      "title": "Canvas",
      "description": "Desired output canvas. The default is a 2K tier derived from the first base image's ratio; actual output dimensions remain authoritative.",
      "default": {
        "type": "preset",
        "tier": "2K",
        "aspect": "source"
      }
    },
    "seed": {
      "anyOf": [
        {
          "type": "integer",
          "maximum": 2147483647.0,
          "minimum": 0.0
        },
        {
          "type": "null"
        }
      ],
      "title": "Seed",
      "description": "Optional random seed. Supplying it constrains model eligibility; omit it for model-managed randomness."
    },
    "negative_prompt": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Negative Prompt",
      "description": "Optional content or qualities to avoid. Supplying it constrains model eligibility and is rejected when no compatible model is available."
    },
    "enhance_prompt": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ],
      "title": "Enhance Prompt",
      "description": "Ask the model to rewrite the prompt before generation. Omit or use null to keep the prompt exactly as written; an explicit boolean constrains model eligibility."
    },
    "palette": {
      "anyOf": [
        {
          "items": {
            "$ref": "#/$defs/ImagePaletteColor"
          },
          "type": "array",
          "maxItems": 10,
          "minItems": 3
        },
        {
          "type": "null"
        }
      ],
      "title": "Palette",
      "description": "Three to ten weighted RGB colors. Runtime validation requires the weights to sum exactly to 1.0000.",
      "x-beatra-runtime-relations": [
        {
          "expression": "sum(palette[*].weight) == 1.0000",
          "id": "palette-weight-sum"
        }
      ]
    },
    "images": {
      "items": {
        "oneOf": [
          {
            "$ref": "#/$defs/ImageMediaInputUrl"
          },
          {
            "$ref": "#/$defs/ImageMediaInputArtifact"
          },
          {
            "$ref": "#/$defs/ImageMediaInputDataUri"
          }
        ]
      },
      "type": "array",
      "maxItems": 4,
      "minItems": 1,
      "title": "Images",
      "description": "Ordered inputs; images[0] is the base and later entries are references."
    },
    "edit_regions": {
      "anyOf": [
        {
          "items": {
            "$ref": "#/$defs/ImageEditRegion"
          },
          "type": "array",
          "maxItems": 8,
          "minItems": 1
        },
        {
          "type": "null"
        }
      ],
      "title": "Edit Regions",
      "description": "Flat normalized rectangles keyed by an input image_index. Runtime validation enforces cross-coordinate and collection relations.",
      "x-beatra-runtime-relations": [
        {
          "expression": "x + width <= 1 and y + height <= 1",
          "id": "region-within-canvas"
        },
        {
          "expression": "0 <= image_index < len(images)",
          "id": "region-image-index"
        },
        {
          "expression": "count(edit_regions where image_index == i) <= 2 for each i",
          "id": "region-per-image-limit"
        },
        {
          "expression": "unique(image_index, x, y, width, height)",
          "id": "region-unique-geometry"
        }
      ]
    }
  },
  "additionalProperties": false,
  "type": "object",
  "required": [
    "prompt",
    "images"
  ],
  "$defs": {
    "ImageEditPresetCanvas": {
      "properties": {
        "type": {
          "type": "string",
          "const": "preset",
          "title": "Type"
        },
        "tier": {
          "$ref": "#/$defs/ImageResolution"
        },
        "aspect": {
          "anyOf": [
            {
              "type": "string",
              "pattern": "^(?:source|[1-9][0-9]{0,5}:[1-9][0-9]{0,5})(?![\\s\\S])"
            },
            {
              "type": "null"
            }
          ],
          "title": "Aspect",
          "description": "Positive width:height ratio with integer components from 1 to 999999, or `source` to inherit the first input image's ratio. Positive ratios are normalized by greatest common divisor.",
          "default": "source",
          "x-beatra-runtime-normalization": {
            "appliesTo": "concrete-positive-width:height",
            "id": "aspect-ratio-gcd",
            "operation": "divide-width-and-height-by-greatest-common-divisor",
            "result": "reduced-width:height",
            "sourceBehavior": "pass-through"
          }
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "type",
        "tier"
      ],
      "title": "ImageEditPresetCanvas",
      "description": "Edit canvas whose ratio may be inherited from the first input image."
    },
    "ImageEditRegion": {
      "properties": {
        "image_index": {
          "type": "integer",
          "minimum": 0.0,
          "title": "Image Index"
        },
        "x": {
          "type": "number",
          "exclusiveMaximum": 1.0,
          "minimum": 0.0,
          "title": "X",
          "x-beatra-runtime-constraints": [
            {
              "expression": "decode(encode(value)) == value",
              "id": "exact-json-number-round-trip"
            }
          ]
        },
        "y": {
          "type": "number",
          "exclusiveMaximum": 1.0,
          "minimum": 0.0,
          "title": "Y",
          "x-beatra-runtime-constraints": [
            {
              "expression": "decode(encode(value)) == value",
              "id": "exact-json-number-round-trip"
            }
          ]
        },
        "width": {
          "type": "number",
          "maximum": 1.0,
          "exclusiveMinimum": 0.0,
          "title": "Width",
          "x-beatra-runtime-constraints": [
            {
              "expression": "decode(encode(value)) == value",
              "id": "exact-json-number-round-trip"
            }
          ]
        },
        "height": {
          "type": "number",
          "maximum": 1.0,
          "exclusiveMinimum": 0.0,
          "title": "Height",
          "x-beatra-runtime-constraints": [
            {
              "expression": "decode(encode(value)) == value",
              "id": "exact-json-number-round-trip"
            }
          ]
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "image_index",
        "x",
        "y",
        "width",
        "height"
      ],
      "title": "ImageEditRegion",
      "description": "Normalized rectangle associated with one ordered input image."
    },
    "ImageMediaInputArtifact": {
      "properties": {
        "type": {
          "type": "string",
          "const": "artifact",
          "title": "Type"
        },
        "artifact_id": {
          "type": "string",
          "title": "Artifact Id"
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "type",
        "artifact_id"
      ],
      "title": "ImageMediaInputArtifact",
      "description": "Closed reference to a Beatra artifact."
    },
    "ImageMediaInputDataUri": {
      "properties": {
        "type": {
          "type": "string",
          "const": "data_uri",
          "title": "Type"
        },
        "data": {
          "type": "string",
          "maxLength": 262144,
          "title": "Data",
          "description": "Data URI with a 256 KiB encoded inline transport cap. This is not the model image-byte limit; use an artifact or public HTTPS URL for larger inputs."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "type",
        "data"
      ],
      "title": "ImageMediaInputDataUri",
      "description": "Closed inline image reference accepted by Beatra."
    },
    "ImageMediaInputUrl": {
      "properties": {
        "type": {
          "type": "string",
          "const": "url",
          "title": "Type"
        },
        "url": {
          "type": "string",
          "pattern": "^[Hh][Tt][Tt][Pp][Ss]://(?:(?=[A-Za-z0-9.-]{1,253}\\.?(?=[:/?#]|$))(?=[A-Za-z0-9.-]*[A-Za-z])[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*\\.?|(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])|\\[(?:(?:[0-9A-Fa-f]{1,4}:){6}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]))|::(?:[0-9A-Fa-f]{1,4}:){5}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]))|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]))|(?:(?:[0-9A-Fa-f]{1,4}:){0,1}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]))|(?:(?:[0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]))|(?:(?:[0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]))|(?:(?:[0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]))|(?:(?:[0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(?:(?:[0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})?::)\\])(?::0*(?:[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]))?(?:[/?#][^\\s]*)?(?![\\s\\S])",
          "title": "Url",
          "description": "Public HTTPS image URL with a non-empty host."
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "type",
        "url"
      ],
      "title": "ImageMediaInputUrl",
      "description": "Closed HTTPS image reference accepted by Beatra."
    },
    "ImagePaletteColor": {
      "properties": {
        "color": {
          "type": "string",
          "pattern": "^#[0-9A-Fa-f]{6}(?![\\s\\S])",
          "title": "Color"
        },
        "weight": {
          "anyOf": [
            {
              "type": "number",
              "maximum": 1.0,
              "exclusiveMinimum": 0.0
            },
            {
              "type": "string",
              "pattern": "^\\+?(?:0*\\.(?=[0-9]{0,3}[1-9])[0-9]{1,4}|0*1(?:\\.0{0,4})?)(?![\\s\\S])"
            }
          ],
          "title": "Weight",
          "description": "Exact decimal weight greater than 0 and at most 1, with no more than 4 fractional digits. Decimal strings avoid binary-float ambiguity.",
          "x-beatra-decimal-precision": {
            "maximumFractionalDigits": 4,
            "numberEnforcement": "runtime",
            "stringEnforcement": "schema-and-runtime"
          },
          "x-beatra-maximum-fractional-digits": 4
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "color",
        "weight"
      ],
      "title": "ImagePaletteColor",
      "description": "One exact weighted RGB color in a requested palette."
    },
    "ImageResolution": {
      "type": "string",
      "enum": [
        "1K",
        "2K",
        "4K"
      ],
      "title": "ImageResolution",
      "description": "Named quality tier, not a promise of exact encoded dimensions."
    },
    "ImageTargetCanvas": {
      "properties": {
        "type": {
          "type": "string",
          "const": "target",
          "title": "Type"
        },
        "width": {
          "type": "integer",
          "maximum": 999999.0,
          "exclusiveMinimum": 0.0,
          "title": "Width",
          "description": "Desired output width in pixels"
        },
        "height": {
          "type": "integer",
          "maximum": 999999.0,
          "exclusiveMinimum": 0.0,
          "title": "Height",
          "description": "Desired output height in pixels"
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "type",
        "width",
        "height"
      ],
      "title": "ImageTargetCanvas",
      "description": "Desired pixel target; the selected implementation may normalize actual output."
    }
  }
}