{
  "openapi": "3.1.0",
  "info": {
    "title": "knot ai Image API",
    "version": "1.0.0",
    "description": "knot ai API for image generation, job status and credit balance."
  },
  "servers": [{ "url": "https://knot-ai.xyz" }],
  "security": [{ "bearerAuth": [] }],
  "paths": {
    "/api/v1/images/generations": {
      "post": {
        "summary": "Generate images",
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/GenerationRequest" }
            }
          }
        },
        "responses": {
          "201": { "description": "Generation completed" },
          "200": { "description": "Result of an earlier request with the same Idempotency-Key" },
          "402": { "description": "Not enough credits" },
          "409": { "description": "Idempotency-Key conflict" },
          "429": { "description": "Rate limit exceeded" }
        }
      }
    },
    "/api/v1/jobs/{job_id}": {
      "get": {
        "summary": "Get a generation job",
        "parameters": [{ "name": "job_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Job details" }, "404": { "description": "Job not found" } }
      }
    },
    "/api/v1/balance": {
      "get": {
        "summary": "Get plan and credit balance",
        "responses": { "200": { "description": "Balance details" } }
      }
    },
    "/api/images/{image_id}": {
      "get": {
        "summary": "Download a generated image from your account",
        "parameters": [
          { "name": "image_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "download", "in": "query", "schema": { "type": "string", "enum": ["1"] } }
        ],
        "responses": { "200": { "description": "Image binary" }, "404": { "description": "Image not found or not accessible" } }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "knot_live_*" }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "schema": { "type": "string", "minLength": 8, "maxLength": 128, "pattern": "^[A-Za-z0-9._:-]+$" }
      }
    },
    "schemas": {
      "GenerationRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["prompt", "model", "size", "n"],
        "properties": {
          "prompt": { "type": "string", "minLength": 1, "maxLength": 2048 },
          "model": { "type": "string", "enum": ["sdxl-lightning", "phoenix"] },
          "size": { "type": "string", "enum": ["square", "landscape", "portrait"] },
          "n": { "type": "integer", "minimum": 1, "maximum": 4 }
        }
      }
    }
  }
}
