{
  "openapi": "3.1.0",
  "info": {
    "title": "Nech.PL Audio Intelligence API",
    "description": "Stem-aware audio analysis \u2014 emotion, features, sample role, loop grading, onsets/tempo, waveform & spectrogram, loudness, naming. The `audio` API of the Nech.PL APIs platform, served at /audio/v1/...; the gateway does central auth + metering (Bearer token).",
    "version": "0.1.0"
  },
  "paths": {
    "/healthz": {
      "get": {
        "summary": "Healthz",
        "operationId": "healthz_healthz_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/me": {
      "get": {
        "summary": "Whoami",
        "description": "Echo the caller's gateway-resolved identity \u2014 handy for onboarding smoke tests.",
        "operationId": "whoami_me_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/analyze/emotion": {
      "post": {
        "summary": "Analyze Emotion",
        "description": "Upload a short audio clip \u2192 valence/arousal + top emotions. Cached (#26):\nthe same audio returns instantly on a repeat instead of recomputing.",
        "operationId": "analyze_emotion_analyze_emotion_post",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_analyze_emotion_analyze_emotion_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/features": {
      "post": {
        "summary": "Features",
        "description": "Upload a clip \u2192 the ~35-dim audio feature stack (spectral moments, MFCCs,\nchroma/key, envelope, + rhythm when `rhythm=true`). Torch-free, cached.",
        "operationId": "features_features_post",
        "parameters": [
          {
            "name": "rhythm",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true,
              "title": "Rhythm"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_features_features_post"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/analyze/samples": {
      "post": {
        "summary": "Analyze Samples",
        "description": "Upload a one-shot/loop \u2192 per-sample EDA + MEASURED role (percs|bass|melodic|\ntops|atmos) from the spectrum, never the name. Optional `name` only\ndisambiguates breaks/drums. Torch-free, cached.",
        "operationId": "analyze_samples_analyze_samples_post",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "",
              "title": "Name"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_analyze_samples_analyze_samples_post"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/onsets": {
      "post": {
        "summary": "Onsets",
        "description": "Upload audio \u2192 onset hit times (s) + tempo + onset rate. The cheapest tier\n(no model): rhythmic hits for visual sync / slicing. Torch-free, cached.",
        "operationId": "onsets_onsets_post",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_onsets_onsets_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/waveform": {
      "post": {
        "summary": "Waveform",
        "description": "Upload audio \u2192 render-ready waveform: per-bin [min,max] + a 0..1 RMS energy\nenvelope (`?bins=`, \u22644000). For audio-reactive visuals. Torch-free, cached.",
        "operationId": "waveform_waveform_post",
        "parameters": [
          {
            "name": "bins",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 800,
              "title": "Bins"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_waveform_waveform_post"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/analyze": {
      "post": {
        "summary": "Analyze All",
        "description": "One call \u2192 emotion + features + sample role for a clip (fewer round-trips\nfor hexa). Each is the same engine the dedicated routes use. Cached as a unit.",
        "operationId": "analyze_all_analyze_post",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_analyze_all_analyze_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/grade": {
      "post": {
        "summary": "Grade",
        "description": "Upload a loop/one-shot \u2192 the Foundry's MECHANICAL quality grade: composite\n0..1 + S/A/B/C/D tier, per-rule sub-scores (seam click, zero-crossing\ncleanliness, DC, bar self-consistency, level, bass mono-compat) + flags.\n`role` ('bass'|'drums'|\u2026) is a hint. WAV/FLAC preferred. Torch-free, cached.",
        "operationId": "grade_grade_post",
        "parameters": [
          {
            "name": "role",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "",
              "title": "Role"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_grade_grade_post"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/loudness": {
      "post": {
        "summary": "Loudness",
        "description": "Upload audio \u2192 BS.1770 integrated LUFS + sample/true peak + crest + the\ngain (dB) to hit each delivery target (-14 streaming, -9 club). Torch-free, cached.",
        "operationId": "loudness_loudness_post",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_loudness_loudness_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/spectrum": {
      "post": {
        "summary": "Spectrum",
        "description": "FFT-as-a-service: a downsampled, render-ready spectrogram (`bands`\u00d7`frames`,\n0..1). `mel=` perceptual vs log-linear; `frames=1` \u2192 a single averaged FFT\nspectrum. Bounded payload \u2192 caches cheaply. Torch-free.",
        "operationId": "spectrum_spectrum_post",
        "parameters": [
          {
            "name": "bands",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 64,
              "title": "Bands"
            }
          },
          {
            "name": "frames",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Frames"
            }
          },
          {
            "name": "mel",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true,
              "title": "Mel"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_spectrum_spectrum_post"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/naming": {
      "post": {
        "summary": "Naming",
        "description": "Upload a sample \u2192 a convention-compliant name (NN_role_character) derived\nfrom the MEASURED role + character, not the file name. Torch-free, cached.",
        "operationId": "naming_naming_post",
        "parameters": [
          {
            "name": "index",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1,
              "title": "Index"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_naming_naming_post"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/separate": {
      "post": {
        "summary": "Separate",
        "description": "Stem separation (demucs/roformer). erable has no GPU and no CPU-viable path,\nso this is a deliberate 503 until a GPU-runner backend is wired (env-selected,\nsame response shape). The route exists now so hexa can code against it and get\na clean, documented \"compute pending\" rather than a 404.",
        "operationId": "separate_separate_post",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Body_analyze_all_analyze_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File"
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_analyze_all_analyze_post"
      },
      "Body_analyze_emotion_analyze_emotion_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File"
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_analyze_emotion_analyze_emotion_post"
      },
      "Body_analyze_samples_analyze_samples_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File"
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_analyze_samples_analyze_samples_post"
      },
      "Body_features_features_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File"
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_features_features_post"
      },
      "Body_grade_grade_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File"
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_grade_grade_post"
      },
      "Body_loudness_loudness_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File"
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_loudness_loudness_post"
      },
      "Body_naming_naming_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File"
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_naming_naming_post"
      },
      "Body_onsets_onsets_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File"
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_onsets_onsets_post"
      },
      "Body_spectrum_spectrum_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File"
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_spectrum_spectrum_post"
      },
      "Body_waveform_waveform_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File"
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_waveform_waveform_post"
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          },
          "input": {
            "title": "Input"
          },
          "ctx": {
            "type": "object",
            "title": "Context"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      }
    }
  },
  "servers": [
    {
      "url": "https://api.nech.pl/audio/v1",
      "description": "Nech.PL APIs gateway (public)"
    }
  ]
}