{
  "openapi": "3.1.0",
  "info": {
    "title": "Imagegex API",
    "version": "0.2.0",
    "description": "Generate images, or transparent print-ready T-shirt artwork, with the Z-Image Turbo model. Jobs are asynchronous: POST /v1/images returns a job id, poll GET /v1/jobs/{job_id} every 2-3 seconds until status is succeeded or failed, then download GET /v1/jobs/{job_id}/image. A standard image usually finishes in under 10 s and a print file in about 20 s after it starts running. Every image endpoint needs the header 'Authorization: Bearer igx_...'. Each succeeded job uses one image from the monthly allowance; failed jobs are free."
  },
  "servers": [
    { "url": "https://img.richemoji.com", "description": "Production" }
  ],
  "security": [
    { "ClientKey": [] }
  ],
  "components": {
    "securitySchemes": {
      "ClientKey": { "type": "http", "scheme": "bearer", "description": "The client's igx_ API key." }
    },
    "schemas": {
      "PrintOptions": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "size": { "type": "string", "enum": ["12x16", "10x10", "4x4"], "default": "12x16", "description": "Canvas in inches at 300 DPI: 12x16 = 3600x4800 px full front, 10x10 = 3000x3000 px, 4x4 = 1200x1200 px pocket/left chest." },
          "align": { "type": "string", "enum": ["center", "top"], "default": "center", "description": "Vertical placement of the art on the canvas. 'top' puts it at the top margin, as most print providers expect for full-front prints." },
          "prompt_assist": { "type": "boolean", "default": true, "description": "Rewrite the prompt so the model draws standalone artwork on a flat background (removes garment/mockup words). Leave on unless you write that framing yourself." }
        }
      },
      "ImageRequest": {
        "type": "object",
        "required": ["prompt"],
        "additionalProperties": false,
        "properties": {
          "prompt": { "type": "string", "minLength": 1, "maxLength": 2000, "description": "What to draw. Describe the subject, style and colors. Lettering is attempted but spelling is not guaranteed; check the result." },
          "output": { "type": "string", "enum": ["standard", "print"], "default": "standard", "description": "'standard' returns the generated image. 'print' returns a transparent RGBA PNG at 300 DPI with the background removed, upscaled and placed on a print canvas." },
          "print": { "$ref": "#/components/schemas/PrintOptions", "description": "Only allowed with output 'print'." },
          "model": { "type": "string", "const": "z-image-turbo", "default": "z-image-turbo" },
          "width": { "type": "integer", "enum": [512, 576, 640, 704, 768, 832, 896, 960, 1024], "description": "Generation width. Default 1024, or 768 for a 12x16 print and 1024 for square prints." },
          "height": { "type": "integer", "enum": [512, 576, 640, 704, 768, 832, 896, 960, 1024], "description": "Generation height. Default 1024." },
          "seed": { "type": "integer", "minimum": 0, "maximum": 4294967295, "description": "Fix for reproducible results; omit for a random seed. Retry a failed or unwanted result with a different seed." },
          "reference_image_base64": { "type": "string", "contentEncoding": "base64", "description": "Optional PNG or JPEG (max 10 MB, 4 megapixels) to make a variation of. Not a precise editor." },
          "denoise": { "type": "number", "minimum": 0.05, "maximum": 0.8, "default": 0.35, "description": "How far a variation may move from the reference image. Ignored without reference_image_base64." }
        }
      },
      "PrintInfo": {
        "type": "object",
        "properties": {
          "size": { "type": "string" },
          "align": { "type": "string" },
          "canvas_px": { "type": "array", "items": { "type": "integer" } },
          "dpi": { "type": "integer", "const": 300 },
          "art_px": { "type": "array", "items": { "type": "integer" }, "description": "Size of the artwork on the canvas." },
          "art_inches": { "type": "array", "items": { "type": "number" } },
          "generated_px": { "type": "array", "items": { "type": "integer" }, "description": "Size of the artwork as the model drew it." },
          "upscale_factor": { "type": "number" },
          "coverage": { "type": "number", "description": "Fraction of the generated image covered by the design." },
          "background_rgb": { "type": "array", "items": { "type": "integer" } },
          "warnings": { "type": "array", "items": { "type": "string" }, "description": "Quality notes, e.g. the design touched the edge. Show these to the user." }
        }
      },
      "Job": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "model": { "type": "string" },
          "mode": { "type": "string", "enum": ["text", "edit"] },
          "output": { "type": "string", "enum": ["standard", "print"] },
          "status": { "type": "string", "enum": ["pending", "running", "succeeded", "failed"] },
          "seed": { "type": "integer" },
          "width": { "type": "integer" },
          "height": { "type": "integer" },
          "created_at": { "type": "string", "format": "date-time" },
          "started_at": { "type": ["string", "null"], "format": "date-time" },
          "finished_at": { "type": ["string", "null"], "format": "date-time" },
          "processing_seconds": { "type": ["number", "null"] },
          "error": { "type": ["string", "null"], "description": "Why the job failed. Print jobs fail with a readable reason when no separable design was produced; retry with another seed." },
          "image_url": { "type": ["string", "null"], "description": "Relative URL of the PNG once succeeded. For print jobs this is the print file." },
          "raw_image_url": { "type": ["string", "null"], "description": "Print jobs only: the original generation before background removal." },
          "print_options": { "$ref": "#/components/schemas/PrintOptions" },
          "print": { "oneOf": [{ "$ref": "#/components/schemas/PrintInfo" }, { "type": "null" }] }
        }
      },
      "Usage": {
        "type": "object",
        "properties": {
          "client_id": { "type": "string" },
          "month_utc": { "type": "string", "description": "YYYY-MM. Allowances reset at 00:00 UTC on the 1st." },
          "plan": { "type": ["string", "null"] },
          "billing_status": { "type": "string" },
          "monthly_quota": { "type": "integer" },
          "completed_images": { "type": "integer" },
          "reserved_images": { "type": "integer", "description": "Queued or running jobs, which hold a slot." },
          "failed_jobs": { "type": "integer" },
          "remaining_images": { "type": "integer" },
          "processing_seconds": { "type": "number" }
        }
      },
      "Error": {
        "type": "object",
        "properties": { "error": { "type": "string" } }
      }
    }
  },
  "paths": {
    "/v1/images": {
      "post": {
        "operationId": "createImageJob",
        "summary": "Queue an image or print-file job",
        "requestBody": {
          "required": true,
          "content": { "application/json": {
            "schema": { "$ref": "#/components/schemas/ImageRequest" },
            "examples": {
              "print": { "value": { "prompt": "Retro skull wearing headphones, hot pink and cyan, halftone shading", "output": "print", "print": { "size": "12x16", "align": "top" } } },
              "standard": { "value": { "prompt": "A watercolor fox in a snowy forest", "width": 1024, "height": 768 } }
            }
          } }
        },
        "responses": {
          "202": { "description": "Queued", "content": { "application/json": { "schema": { "type": "object", "properties": { "job_id": { "type": "string" }, "status": { "type": "string" }, "status_url": { "type": "string" } } } } } },
          "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "401": { "description": "Missing or invalid API key" },
          "403": { "description": "Subscription inactive or key revoked" },
          "429": { "description": "Queue full (max 5 active jobs per client) or monthly allowance used up" }
        }
      }
    },
    "/v1/jobs/{job_id}": {
      "get": {
        "operationId": "getImageJob",
        "summary": "Check a job's status",
        "parameters": [ { "name": "job_id", "in": "path", "required": true, "schema": { "type": "string" } } ],
        "responses": {
          "200": { "description": "Job", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Job" } } } },
          "404": { "description": "Job not found for this client" }
        }
      }
    },
    "/v1/jobs/{job_id}/image": {
      "get": {
        "operationId": "downloadImage",
        "summary": "Download a succeeded job's PNG",
        "parameters": [
          { "name": "job_id", "in": "path", "required": true, "schema": { "type": "string" } },
          { "name": "variant", "in": "query", "required": false, "schema": { "type": "string", "enum": ["final", "raw"], "default": "final" }, "description": "'raw' returns the original generation of a print job." }
        ],
        "responses": {
          "200": { "description": "PNG", "content": { "image/png": { "schema": { "type": "string", "format": "binary" } } } },
          "404": { "description": "Image not available" }
        }
      }
    },
    "/v1/jobs": {
      "get": {
        "operationId": "listJobs",
        "summary": "List this client's 100 most recent jobs",
        "responses": { "200": { "description": "Jobs", "content": { "application/json": { "schema": { "type": "object", "properties": { "jobs": { "type": "array", "items": { "$ref": "#/components/schemas/Job" } } } } } } } }
      }
    },
    "/v1/usage": {
      "get": {
        "operationId": "getUsage",
        "summary": "Monthly allowance and usage",
        "responses": { "200": { "description": "Usage", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Usage" } } } } }
      }
    },
    "/v1/models": {
      "get": {
        "operationId": "listModels",
        "summary": "List available models",
        "responses": { "200": { "description": "Models" } }
      }
    },
    "/v1/plans": {
      "get": {
        "operationId": "listPlans",
        "summary": "List subscription plans (no key needed)",
        "security": [],
        "responses": { "200": { "description": "Plans" } }
      }
    },
    "/health": {
      "get": {
        "operationId": "health",
        "summary": "Service status; comfyui_connected is false while the GPU is offline (jobs then wait in the queue)",
        "security": [],
        "responses": { "200": { "description": "Status" } }
      }
    }
  }
}
