{
 "openapi": "3.1.0",
 "info": {
  "title": "MixMedia API",
  "version": "1.0.0",
  "summary": "AI image and video generation API (pay per run, USD/RUB).",
  "description": "One REST API for AI image and video models (Nano Banana, Nano Banana 2, Nano Banana Pro, Seedream Pro, Seedream Flash, GPT Image 2.5, Wan 3.0, Higgsfield Genjutsu, Wan 2.7, Seedance 2.5, Seedance 2.0, Seedance 2.0 Fast, Seedance 2.0 Mini, Seedance 1.5 Pro, Grok Imagine 1.5, Grok Imagine). Create a task, then poll its status or receive a callback. The price is charged on creation and refunded if the task fails.\n\nPrices: https://mixmedia.tech/prices.json · exact calculator: https://api.mixmedia.tech/v1/pricing/calculate · MCP: https://api.mixmedia.tech/mcp · docs: https://docs.mixmedia.tech/",
  "contact": {
   "name": "MixMedia support",
   "url": "https://mixmedia.tech/support"
  }
 },
 "externalDocs": {
  "description": "Documentation",
  "url": "https://docs.mixmedia.tech/en/"
 },
 "servers": [
  {
   "url": "https://mixmedia.tech/api/v1",
   "description": "Production"
  }
 ],
 "security": [
  {
   "bearerAuth": []
  }
 ],
 "tags": [
  {
   "name": "Generation"
  },
  {
   "name": "Account"
  },
  {
   "name": "Catalog"
  },
  {
   "name": "Pricing"
  }
 ],
 "paths": {
  "/jobs/createTask": {
   "post": {
    "tags": [
     "Generation"
    ],
    "operationId": "createTask",
    "summary": "Create a generation task",
    "description": "Starts an image or video generation and returns `taskId` immediately. The list price is charged now and refunded automatically if the task fails. Parameters for each model: GET /models or prices.json.",
    "parameters": [
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "maxLength": 128
      },
      "description": "Retry safely: the same key + body returns the same task without a second charge."
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CreateTaskRequest"
       },
       "examples": {
        "image": {
         "summary": "Image",
         "value": {
          "model": "nano-banana-2",
          "input": {
           "prompt": "A cat astronaut in a neon city",
           "resolution": "1K",
           "aspect_ratio": "16:9"
          }
         }
        },
        "video": {
         "summary": "Video",
         "value": {
          "model": "seedance-2.0",
          "input": {
           "prompt": "A drone flies over an autumn forest at sunrise, fog, cinematic",
           "resolution": "720p",
           "duration": "5"
          }
         }
        },
        "edit": {
         "summary": "Photo edit",
         "value": {
          "model": "nano-banana-2",
          "input": {
           "prompt": "Make the background a neon city at night",
           "image_input": [
            "https://example.com/photo.jpg"
           ]
          }
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Task created",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "code": {
           "type": "integer",
           "example": 200
          },
          "msg": {
           "type": "string",
           "example": "success"
          },
          "data": {
           "$ref": "#/components/schemas/TaskCreated"
          }
         }
        },
        "example": {
         "code": 200,
         "msg": "success",
         "data": {
          "taskId": "task_nano-banana-2_1790621023886ca4e4d",
          "task_id": "task_nano-banana-2_1790621023886ca4e4d",
          "status": "submitted"
         }
        }
       }
      }
     },
     "400": {
      "description": "Invalid request",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "Missing or invalid API key",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "402": {
      "description": "Insufficient balance (top up at /cabinet/billing)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "Rate limit",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "505": {
      "description": "Model temporarily disabled",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/jobs/recordInfo": {
   "get": {
    "tags": [
     "Generation"
    ],
    "operationId": "getTask",
    "summary": "Get task status and result",
    "description": "Poll every 3–5 s until `state` is `success` or `fail`. On success `resultJson` is a JSON string with `resultUrls` (files are kept for 24 h).",
    "parameters": [
     {
      "name": "taskId",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Task",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "code": {
           "type": "integer",
           "example": 200
          },
          "msg": {
           "type": "string",
           "example": "success"
          },
          "data": {
           "$ref": "#/components/schemas/Task"
          }
         }
        },
        "example": {
         "code": 200,
         "msg": "success",
         "data": {
          "taskId": "task_nano-banana-2_1790621023886ca4e4d",
          "model": "nano-banana-2",
          "state": "success",
          "resultJson": "{\"resultUrls\":[\"https://mixmedia.tech/files/7496aef5292507f51b84cb2cb258d001.png\"]}",
          "failCode": "",
          "failMsg": "",
          "costUsd": "0.0250",
          "refunded": false
         }
        }
       }
      }
     },
     "401": {
      "description": "Missing or invalid API key",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "Task not found",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/jobs/list": {
   "get": {
    "tags": [
     "Generation"
    ],
    "operationId": "listTasks",
    "summary": "Recent tasks of the account",
    "parameters": [
     {
      "name": "limit",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 100,
       "default": 20
      }
     },
     {
      "name": "state",
      "in": "query",
      "schema": {
       "type": "string",
       "enum": [
        "waiting",
        "queuing",
        "generating",
        "success",
        "fail"
       ]
      }
     },
     {
      "name": "before",
      "in": "query",
      "schema": {
       "type": "integer"
      },
      "description": "Pass data.nextBefore for the next page"
     }
    ],
    "responses": {
     "200": {
      "description": "Tasks",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "code": {
           "type": "integer",
           "example": 200
          },
          "msg": {
           "type": "string",
           "example": "success"
          },
          "data": {
           "type": "object",
           "properties": {
            "items": {
             "type": "array",
             "items": {
              "$ref": "#/components/schemas/Task"
             }
            },
            "nextBefore": {
             "type": [
              "integer",
              "null"
             ]
            }
           }
          }
         }
        }
       }
      }
     },
     "401": {
      "description": "Missing or invalid API key",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/files/upload": {
   "post": {
    "tags": [
     "Generation"
    ],
    "operationId": "uploadFile",
    "summary": "Upload a reference photo, video or audio",
    "description": "Returns a URL to pass in the model input (image_urls, video_urls, audio_urls…). Files are kept for 24 h. Reference videos/audio must be uploaded here (their length sets the price).",
    "requestBody": {
     "required": true,
     "content": {
      "multipart/form-data": {
       "schema": {
        "type": "object",
        "required": [
         "file"
        ],
        "properties": {
         "file": {
          "type": "string",
          "format": "binary"
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Uploaded",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "code": {
           "type": "integer",
           "example": 200
          },
          "msg": {
           "type": "string",
           "example": "success"
          },
          "data": {
           "type": "object",
           "properties": {
            "url": {
             "type": "string",
             "format": "uri"
            },
            "kind": {
             "type": "string",
             "enum": [
              "image",
              "video",
              "audio"
             ]
            },
            "duration": {
             "type": "number"
            },
            "seconds": {
             "type": "integer"
            }
           }
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Invalid request",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "Missing or invalid API key",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/user/balance": {
   "get": {
    "tags": [
     "Account"
    ],
    "operationId": "getBalance",
    "summary": "Account balance",
    "responses": {
     "200": {
      "description": "Balance",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "code": {
           "type": "integer",
           "example": 200
          },
          "msg": {
           "type": "string",
           "example": "success"
          },
          "data": {
           "type": "object",
           "properties": {
            "balance": {
             "type": "string",
             "example": "12.3400"
            },
            "currency": {
             "type": "string",
             "example": "USD"
            },
            "balanceRub": {
             "type": "number"
            }
           }
          }
         }
        }
       }
      }
     },
     "401": {
      "description": "Missing or invalid API key",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/models": {
   "get": {
    "tags": [
     "Catalog"
    ],
    "operationId": "listModels",
    "summary": "Model catalog (no key)",
    "security": [],
    "responses": {
     "200": {
      "description": "Models with ids, parameters and prices",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "code": {
           "type": "integer",
           "example": 200
          },
          "msg": {
           "type": "string",
           "example": "success"
          },
          "data": {
           "type": "array",
           "items": {
            "type": "object"
           }
          }
         }
        }
       }
      }
     }
    }
   }
  },
  "/v1/pricing": {
   "servers": [
    {
     "url": "https://api.mixmedia.tech"
    }
   ],
   "get": {
    "tags": [
     "Pricing"
    ],
    "operationId": "getPricing",
    "summary": "All models with prices and price rules (same as prices.json, no key)",
    "security": [],
    "responses": {
     "200": {
      "description": "Prices",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     }
    }
   }
  },
  "/v1/pricing/calculate": {
   "servers": [
    {
     "url": "https://api.mixmedia.tech"
    }
   ],
   "get": {
    "tags": [
     "Pricing"
    ],
    "operationId": "calculatePrice",
    "summary": "Exact price for a model and parameters (no key)",
    "security": [],
    "parameters": [
     {
      "name": "model",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "enum": [
        "google/nano-banana",
        "google/nano-banana-edit",
        "nano-banana-2",
        "nano-banana-pro",
        "seedream-pro",
        "seedream-flash",
        "gpt-image-2.5-text-to-image",
        "gpt-image-2.5-image-to-image",
        "wan-3.0",
        "higgsfield-genjutsu",
        "wan-2.7",
        "seedance-2.5",
        "seedance-2.0",
        "seedance-2.0-fast",
        "seedance-2.0-mini",
        "seedance-1.5-pro",
        "grok-imagine-1.5",
        "grok-imagine"
       ]
      }
     },
     {
      "name": "resolution",
      "in": "query",
      "schema": {
       "type": "string"
      },
      "example": "720p"
     },
     {
      "name": "quality",
      "in": "query",
      "schema": {
       "type": "string",
       "enum": [
        "auto",
        "low",
        "medium",
        "high"
       ]
      }
     },
     {
      "name": "duration",
      "in": "query",
      "schema": {
       "type": "string"
      },
      "description": "Video length in seconds, or \"auto\"",
      "example": "5"
     },
     {
      "name": "generate_audio",
      "in": "query",
      "schema": {
       "type": "boolean"
      }
     },
     {
      "name": "reference_images",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     },
     {
      "name": "reference_video_seconds",
      "in": "query",
      "schema": {
       "type": "number",
       "minimum": 0
      },
      "description": "Total length of reference/source videos"
     }
    ],
    "responses": {
     "200": {
      "description": "Price",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Price"
        },
        "example": {
         "ok": true,
         "model": "seedance-2.0",
         "unit": "second",
         "params": {
          "resolution": "720p",
          "duration": "5"
         },
         "billable_seconds": 5,
         "price_usd": 1.2,
         "price_rub": 110.7,
         "price_display": "$1.2 (~111 ₽)"
        }
       }
      }
     },
     "400": {
      "description": "Invalid parameters",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "Unknown model",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   },
   "post": {
    "tags": [
     "Pricing"
    ],
    "operationId": "calculatePricePost",
    "summary": "Exact price (JSON body)",
    "security": [],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "model"
        ],
        "properties": {
         "model": {
          "type": "string",
          "enum": [
           "google/nano-banana",
           "google/nano-banana-edit",
           "nano-banana-2",
           "nano-banana-pro",
           "seedream-pro",
           "seedream-flash",
           "gpt-image-2.5-text-to-image",
           "gpt-image-2.5-image-to-image",
           "wan-3.0",
           "higgsfield-genjutsu",
           "wan-2.7",
           "seedance-2.5",
           "seedance-2.0",
           "seedance-2.0-fast",
           "seedance-2.0-mini",
           "seedance-1.5-pro",
           "grok-imagine-1.5",
           "grok-imagine"
          ]
         },
         "params": {
          "type": "object",
          "additionalProperties": true
         }
        }
       },
       "example": {
        "model": "gpt-image-2.5-text-to-image",
        "params": {
         "quality": "high",
         "resolution": "2K"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Price",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Price"
        }
       }
      }
     },
     "400": {
      "description": "Invalid parameters",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "Unknown model",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  }
 },
 "components": {
  "securitySchemes": {
   "bearerAuth": {
    "type": "http",
    "scheme": "bearer",
    "description": "API key from https://mixmedia.tech/cabinet/keys (sk-aim-…)"
   }
  },
  "schemas": {
   "Error": {
    "type": "object",
    "properties": {
     "code": {
      "type": "integer"
     },
     "msg": {
      "type": "string"
     },
     "data": {},
     "error": {
      "type": "string",
      "example": "invalid_request_error"
     }
    }
   },
   "CreateTaskRequest": {
    "type": "object",
    "required": [
     "model",
     "input"
    ],
    "properties": {
     "model": {
      "type": "string",
      "enum": [
       "google/nano-banana",
       "google/nano-banana-edit",
       "nano-banana-2",
       "nano-banana-pro",
       "seedream-pro",
       "seedream-flash",
       "gpt-image-2.5-text-to-image",
       "gpt-image-2.5-image-to-image",
       "wan-3.0",
       "higgsfield-genjutsu",
       "wan-2.7",
       "seedance-2.5",
       "seedance-2.0",
       "seedance-2.0-fast",
       "seedance-2.0-mini",
       "seedance-1.5-pro",
       "grok-imagine-1.5",
       "grok-imagine"
      ],
      "description": "Model id (see GET /models)"
     },
     "input": {
      "type": "object",
      "additionalProperties": true,
      "description": "Model parameters: prompt plus model-specific fields (resolution, aspect_ratio, duration, image_urls…).",
      "properties": {
       "prompt": {
        "type": "string"
       }
      }
     },
     "callBackUrl": {
      "type": "string",
      "format": "uri",
      "description": "Optional: we POST the final task JSON here (header X-Signature = HMAC-SHA256 of the raw body)."
     }
    }
   },
   "TaskCreated": {
    "type": "object",
    "properties": {
     "taskId": {
      "type": "string"
     },
     "task_id": {
      "type": "string"
     },
     "status": {
      "type": "string",
      "example": "submitted"
     },
     "idempotentReplay": {
      "type": "boolean"
     }
    }
   },
   "Task": {
    "type": "object",
    "properties": {
     "taskId": {
      "type": "string"
     },
     "model": {
      "type": "string"
     },
     "state": {
      "type": "string",
      "enum": [
       "waiting",
       "queuing",
       "generating",
       "success",
       "fail"
      ]
     },
     "resultJson": {
      "type": "string",
      "description": "JSON string {\"resultUrls\": [...]} on success"
     },
     "failCode": {
      "type": "string"
     },
     "failMsg": {
      "type": "string"
     },
     "costUsd": {
      "type": "string"
     },
     "costRub": {
      "type": "number"
     },
     "refunded": {
      "type": "boolean"
     },
     "createTime": {
      "type": "integer"
     },
     "completeTime": {
      "type": "integer"
     }
    }
   },
   "Price": {
    "type": "object",
    "properties": {
     "ok": {
      "type": "boolean"
     },
     "model": {
      "type": "string"
     },
     "unit": {
      "type": "string",
      "enum": [
       "image",
       "second"
      ]
     },
     "params": {
      "type": "object"
     },
     "billable_seconds": {
      "type": "integer"
     },
     "usd_per_second": {
      "type": "number"
     },
     "price_usd": {
      "type": "number"
     },
     "price_rub": {
      "type": "number"
     },
     "price_display": {
      "type": "string"
     },
     "breakdown": {
      "type": "string"
     }
    }
   }
  }
 }
}