{
  "openapi": "3.1.0",
  "info": {
    "title": "Pattalium Music API",
    "version": "1.0.0",
    "description": "Public listening and embed API, first-party private projects, and consented Synthoverse publishing. Tokens stay on the server."
  },
  "servers": [
    {
      "url": "/"
    }
  ],
  "paths": {
    "/api/v1/session": {
      "get": {
        "summary": "Current member, CSRF token, connection scopes and expiry",
        "security": [],
        "responses": {
          "200": {
            "description": "JSON result; see the endpoint contract and examples in /api/docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "summary": "Sign out and revoke this Music session",
        "security": [
          {
            "musicSession": []
          }
        ],
        "parameters": [
          {
            "in": "header",
            "name": "X-CSRF-Token",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "From GET /api/v1/session. Origin must match the Music origin."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON result; see the endpoint contract and examples in /api/docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/projects": {
      "get": {
        "summary": "List up to 50 private projects",
        "security": [
          {
            "musicSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "JSON result; see the endpoint contract and examples in /api/docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "post": {
        "summary": "Create a private project; JSON {data: Project}",
        "security": [
          {
            "musicSession": []
          }
        ],
        "parameters": [
          {
            "in": "header",
            "name": "X-CSRF-Token",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "From GET /api/v1/session. Origin must match the Music origin."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "JSON result; see the endpoint contract and examples in /api/docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/projects/{id}": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "summary": "Read your project and published version",
        "security": [
          {
            "musicSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "JSON result; see the endpoint contract and examples in /api/docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "patch": {
        "summary": "Save {data: Project, revision: integer}; stale revisions return 409",
        "security": [
          {
            "musicSession": []
          }
        ],
        "parameters": [
          {
            "in": "header",
            "name": "X-CSRF-Token",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "From GET /api/v1/session. Origin must match the Music origin."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON result; see the endpoint contract and examples in /api/docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "summary": "Delete a project and its listening link",
        "security": [
          {
            "musicSession": []
          }
        ],
        "parameters": [
          {
            "in": "header",
            "name": "X-CSRF-Token",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "From GET /api/v1/session. Origin must match the Music origin."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON result; see the endpoint contract and examples in /api/docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/projects/{id}/audio": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "put": {
        "summary": "Attach rendered PCM WAV to the current saved revision",
        "security": [
          {
            "musicSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "JSON result; see the endpoint contract and examples in /api/docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "revision",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "in": "header",
            "name": "X-CSRF-Token",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "audio/wav": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          }
        }
      }
    },
    "/api/v1/projects/{id}/publish": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "post": {
        "summary": "Publish {revision, visibility: public|unlisted, remix: boolean}",
        "security": [
          {
            "musicSession": []
          }
        ],
        "parameters": [
          {
            "in": "header",
            "name": "X-CSRF-Token",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "From GET /api/v1/session. Origin must match the Music origin."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON result; see the endpoint contract and examples in /api/docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      },
      "delete": {
        "summary": "Unpublish the listening link and public source",
        "security": [
          {
            "musicSession": []
          }
        ],
        "parameters": [
          {
            "in": "header",
            "name": "X-CSRF-Token",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "From GET /api/v1/session. Origin must match the Music origin."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON result; see the endpoint contract and examples in /api/docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/projects/{id}/social": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "post": {
        "summary": "Explicit Synthoverse post: {revision, caption, audience, request_id: UUID}",
        "security": [
          {
            "musicSession": []
          }
        ],
        "parameters": [
          {
            "in": "header",
            "name": "X-CSRF-Token",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "From GET /api/v1/session. Origin must match the Music origin."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "JSON result; see the endpoint contract and examples in /api/docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/shares/{id}": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "summary": "Read your durable Synthoverse publishing receipt",
        "security": [
          {
            "musicSession": []
          }
        ],
        "responses": {
          "200": {
            "description": "JSON result; see the endpoint contract and examples in /api/docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/tracks": {
      "get": {
        "summary": "Browse public releases; unlisted and private projects excluded",
        "security": [],
        "responses": {
          "200": {
            "description": "JSON result; see the endpoint contract and examples in /api/docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            },
            "description": "The previous next_cursor. Up to 24 tracks per page."
          }
        ]
      }
    },
    "/api/v1/tracks/{slug}": {
      "parameters": [
        {
          "in": "path",
          "name": "slug",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{22}$"
          }
        }
      ],
      "get": {
        "summary": "Published track metadata; no private project data",
        "security": [],
        "responses": {
          "200": {
            "description": "JSON result; see the endpoint contract and examples in /api/docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/tracks/{slug}/source": {
      "parameters": [
        {
          "in": "path",
          "name": "slug",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "summary": "Editable score only if creator opted into remixing",
        "security": [],
        "responses": {
          "200": {
            "description": "JSON result; see the endpoint contract and examples in /api/docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/tracks/{slug}/audio": {
      "parameters": [
        {
          "in": "path",
          "name": "slug",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "summary": "Published PCM WAV with single byte-range support",
        "security": [],
        "responses": {
          "200": {
            "description": "WAV audio",
            "content": {
              "audio/wav": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "206": {
            "description": "Partial WAV audio"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "416": {
            "description": "Invalid byte range"
          }
        }
      }
    },
    "/api/oembed": {
      "get": {
        "summary": "Embeddable player metadata",
        "security": [],
        "responses": {
          "200": {
            "description": "JSON result; see the endpoint contract and examples in /api/docs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/Error"
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "url",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uri"
            },
            "description": "A listening URL on this Music origin."
          },
          {
            "in": "query",
            "name": "maxwidth",
            "schema": {
              "type": "integer",
              "minimum": 240,
              "maximum": 800
            }
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "musicSession": {
        "type": "apiKey",
        "in": "cookie",
        "name": "__Host-music_session"
      }
    },
    "responses": {
      "Error": {
        "description": "A bounded error without credentials or internals.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "error"
              ],
              "properties": {
                "error": {
                  "type": "object",
                  "required": [
                    "code",
                    "message"
                  ],
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
