{
  "openapi": "3.0.3",
  "info": {
    "title": "Nirai Flux Local API",
    "description": "Local HTTP API for Nirai Flux. Drive generation and playback from Stream Deck, OBS, chat bots, or scripts while the studio tab is open.\n\n**Base URL:** `http://127.0.0.1:8787` (localhost only \u2014 do not expose to the public internet)\n\n**Requirements**\n- Nirai Flux is running and the model is Ready\n- The studio is open in a browser tab at the base URL. If the tab is closed, commands queue and nothing plays\n",
    "version": "1.0.0",
    "contact": {
      "name": "Nirai Flux",
      "url": "https://github.com/amakann/nirai-flux"
    }
  },
  "servers": [
    {
      "url": "http://127.0.0.1:8787",
      "description": "Local studio (default)"
    }
  ],
  "tags": [
    {
      "name": "Control",
      "description": "Generate, stream, play, and stop"
    },
    {
      "name": "Library",
      "description": "Presets, songs, streams, and uploads"
    }
  ],
  "paths": {
    "/api/control": {
      "get": {
        "tags": [
          "Control"
        ],
        "summary": "Get last control command",
        "description": "Returns the last command sent to the studio (`seq` + `command`).",
        "operationId": "getControl",
        "responses": {
          "200": {
            "description": "Last command",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ControlStatus"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Control"
        ],
        "summary": "Send control command",
        "description": "Primary automation endpoint. Send JSON to generate, stream, play, or stop.\n\nFor `play`, provide exactly one of `generation_id`, `stream_id`, or `upload_id`.\n",
        "operationId": "postControl",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ControlCommand"
              },
              "examples": {
                "generatePreset": {
                  "summary": "Generate from preset",
                  "value": {
                    "action": "generate",
                    "preset": "Chill Pad",
                    "play_when": "now"
                  }
                },
                "stream": {
                  "summary": "Continuous stream",
                  "value": {
                    "action": "stream",
                    "preset": "Chill Pad",
                    "crossfade_seconds": 3,
                    "play_when": "now"
                  }
                },
                "playUpload": {
                  "summary": "Play uploaded intro",
                  "value": {
                    "action": "play",
                    "upload_id": "PASTE_ID_HERE",
                    "play_when": "now"
                  }
                },
                "stop": {
                  "summary": "Stop playback and stream",
                  "value": {
                    "action": "stop"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Command accepted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/api/favorites": {
      "get": {
        "tags": [
          "Library"
        ],
        "summary": "List presets",
        "description": "Saved presets from the Presets tab. Use `name` or `id` in control commands.",
        "operationId": "listFavorites",
        "responses": {
          "200": {
            "description": "Preset list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Preset"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/songs": {
      "get": {
        "tags": [
          "Library"
        ],
        "summary": "List generated songs",
        "operationId": "listSongs",
        "responses": {
          "200": {
            "description": "Song list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Song"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/streams": {
      "get": {
        "tags": [
          "Library"
        ],
        "summary": "List stream sessions",
        "operationId": "listStreams",
        "responses": {
          "200": {
            "description": "Stream session list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/StreamSession"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/uploads": {
      "get": {
        "tags": [
          "Library"
        ],
        "summary": "List uploaded files",
        "operationId": "listUploads",
        "responses": {
          "200": {
            "description": "Upload list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Upload"
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Library"
        ],
        "summary": "Upload audio file",
        "operationId": "uploadFile",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Upload created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Upload"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ControlCommand": {
        "type": "object",
        "required": [
          "action"
        ],
        "properties": {
          "action": {
            "type": "string",
            "enum": [
              "generate",
              "stream",
              "play",
              "stop"
            ]
          },
          "prompt": {
            "type": "string",
            "description": "Required for generate/stream unless `preset` is set"
          },
          "preset": {
            "type": "string",
            "description": "Preset name or id from `/api/favorites`"
          },
          "duration": {
            "type": "integer",
            "minimum": 60,
            "maximum": 380,
            "description": "Track length in seconds (capped by active model)"
          },
          "play_when": {
            "type": "string",
            "enum": [
              "now",
              "after_current"
            ],
            "default": "now",
            "description": "`now` starts ASAP (crossfade if playing); `after_current` waits for the current track"
          },
          "crossfade_seconds": {
            "type": "number",
            "minimum": 0,
            "maximum": 10
          },
          "crossfade_enabled": {
            "type": "boolean"
          },
          "negative_prompt": {
            "type": "string"
          },
          "output_format": {
            "type": "string",
            "enum": [
              "opus",
              "mp3",
              "aac",
              "wav"
            ]
          },
          "generation_id": {
            "type": "string",
            "description": "Song id from `/api/songs` (play only)"
          },
          "stream_id": {
            "type": "string",
            "description": "Stream session id from `/api/streams` (play only)"
          },
          "upload_id": {
            "type": "string",
            "description": "Upload id from `/api/uploads` (play only)"
          }
        }
      },
      "ControlStatus": {
        "type": "object",
        "properties": {
          "seq": {
            "type": "integer"
          },
          "command": {
            "$ref": "#/components/schemas/ControlCommand"
          }
        }
      },
      "Preset": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "Song": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "StreamSession": {
        "type": "object",
        "properties": {
          "stream_id": {
            "type": "string"
          }
        }
      },
      "Upload": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        }
      }
    }
  }
}