veza/veza-backend-api/docs/swagger.json
senke b8eed72f96 feat(webrtc): coturn ICE config endpoint + frontend wiring + ops template (v1.0.9 item 1.2)
Closes FUNCTIONAL_AUDIT.md §4 #1: WebRTC 1:1 calls had working
signaling but no NAT traversal, so calls between two peers behind
symmetric NAT (corporate firewalls, mobile carrier CGNAT, Incus
container default networking) failed silently after the SDP exchange.

Backend:
  - GET /api/v1/config/webrtc (public) returns {iceServers: [...]}
    built from WEBRTC_STUN_URLS / WEBRTC_TURN_URLS / *_USERNAME /
    *_CREDENTIAL env vars. Half-config (URLs without creds, or vice
    versa) deliberately omits the TURN block — a half-configured TURN
    surfaces auth errors at call time instead of falling back cleanly
    to STUN-only.
  - 4 handler tests cover the matrix.

Frontend:
  - services/api/webrtcConfig.ts caches the config for the page
    lifetime and falls back to the historical hardcoded Google STUN
    if the fetch fails.
  - useWebRTC fetches at mount, hands iceServers synchronously to
    every RTCPeerConnection, exposes a {hasTurn, loaded} hint.
  - CallButton tooltip warns up-front when TURN isn't configured
    instead of letting calls time out silently.

Ops:
  - infra/coturn/turnserver.conf — annotated template with the SSRF-
    safe denied-peer-ip ranges, prometheus exporter, TLS for TURNS,
    static lt-cred-mech (REST-secret rotation deferred to v1.1).
  - infra/coturn/README.md — Incus deploy walkthrough, smoke test
    via turnutils_uclient, capacity rules of thumb.
  - docs/ENV_VARIABLES.md gains a 13bis. WebRTC ICE servers section.

Coturn deployment itself is a separate ops action — this commit lands
the plumbing so the deploy can light up the path with zero code
changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 23:38:42 +02:00

10485 lines
No EOL
395 KiB
JSON

{
"swagger": "2.0",
"info": {
"description": "Backend API for Veza platform.",
"title": "Veza Backend API",
"termsOfService": "http://swagger.io/terms/",
"contact": {
"name": "API Support",
"url": "http://www.veza.app/support",
"email": "support@veza.app"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
},
"version": "1.2.0"
},
"host": "localhost:18080",
"basePath": "/api/v1",
"paths": {
"/api/v1/dashboard": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get aggregated dashboard data including stats, recent activity, and library preview",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Dashboard"
],
"summary": "Get Dashboard Data",
"parameters": [
{
"type": "integer",
"description": "Number of recent activity items (default: 10)",
"name": "activity_limit",
"in": "query"
},
{
"type": "integer",
"description": "Number of library items (default: 5)",
"name": "library_limit",
"in": "query"
},
{
"type": "string",
"description": "Time period for statistics: 7d, 30d, 90d, all (default: 30d)",
"name": "stats_period",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/internal_handlers.DashboardResponse"
}
}
}
]
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/api/v1/logs/frontend": {
"post": {
"description": "Receive and store a log entry from the frontend application",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Logging"
],
"summary": "Receive frontend log",
"parameters": [
{
"description": "Frontend log entry",
"name": "log",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.FrontendLogRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"received": {
"type": "boolean"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid log entry",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/api/v1/marketplace/download/{product_id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get a secure download URL for a purchased product",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Marketplace"
],
"summary": "Get download URL",
"parameters": [
{
"type": "string",
"description": "Product ID",
"name": "product_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
"403": {
"description": "No license",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
}
},
"/api/v1/marketplace/orders": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get all orders for the authenticated user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Marketplace"
],
"summary": "List user orders",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_core_marketplace.Order"
}
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Purchase products",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Marketplace"
],
"summary": "Create a new order",
"parameters": [
{
"description": "Order items",
"name": "order",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.CreateOrderRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_core_marketplace.Order"
}
},
"400": {
"description": "Validation Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
}
},
"/api/v1/marketplace/orders/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get details of a specific order (only order owner can access)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Marketplace"
],
"summary": "Get order details",
"parameters": [
{
"type": "string",
"description": "Order ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_core_marketplace.Order"
}
},
"400": {
"description": "Validation Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"403": {
"description": "Forbidden - Not order owner",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"404": {
"description": "Order not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
}
},
"/api/v1/marketplace/products": {
"get": {
"description": "List marketplace products with filters",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Marketplace"
],
"summary": "List products",
"parameters": [
{
"type": "string",
"description": "Product status",
"name": "status",
"in": "query"
},
{
"type": "string",
"description": "Seller ID",
"name": "seller_id",
"in": "query"
},
{
"type": "string",
"description": "Search query",
"name": "q",
"in": "query"
},
{
"type": "string",
"description": "Product type (track, pack, service)",
"name": "type",
"in": "query"
},
{
"type": "number",
"description": "Minimum price",
"name": "min_price",
"in": "query"
},
{
"type": "number",
"description": "Maximum price",
"name": "max_price",
"in": "query"
},
{
"type": "integer",
"description": "Page number",
"name": "page",
"in": "query"
},
{
"type": "integer",
"description": "Items per page",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_core_marketplace.Product"
}
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Create a product (Track, Pack, Service) for sale",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Marketplace"
],
"summary": "Create a new product",
"parameters": [
{
"description": "Product info",
"name": "product",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.CreateProductRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_core_marketplace.Product"
}
},
"400": {
"description": "Validation Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
}
},
"/api/v1/marketplace/products/{id}": {
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Update product details (only seller can update)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Marketplace"
],
"summary": "Update a product",
"parameters": [
{
"type": "string",
"description": "Product ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Product updates",
"name": "product",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.UpdateProductRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_core_marketplace.Product"
}
},
"400": {
"description": "Validation Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"403": {
"description": "Forbidden - Not product owner",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"404": {
"description": "Product not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
}
},
"/audit/activity": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get recent activity logs for the current user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Audit"
],
"summary": "Get user activity",
"parameters": [
{
"type": "integer",
"default": 50,
"description": "Number of activities to return",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"activities": {
"type": "array"
}
}
}
}
}
]
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/audit/logs": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Search and filter audit logs with pagination support. Supports filtering by action, resource, date range, IP address, and user agent.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Audit"
],
"summary": "Search audit logs",
"parameters": [
{
"type": "string",
"description": "Filter by action type",
"name": "action",
"in": "query"
},
{
"type": "string",
"description": "Filter by resource type",
"name": "resource",
"in": "query"
},
{
"type": "string",
"description": "Filter by resource ID (UUID)",
"name": "resource_id",
"in": "query"
},
{
"type": "string",
"description": "Filter by IP address",
"name": "ip_address",
"in": "query"
},
{
"type": "string",
"description": "Filter by user agent",
"name": "user_agent",
"in": "query"
},
{
"type": "string",
"description": "Start date filter (YYYY-MM-DD)",
"name": "start_date",
"in": "query"
},
{
"type": "string",
"description": "End date filter (YYYY-MM-DD)",
"name": "end_date",
"in": "query"
},
{
"type": "integer",
"default": 1,
"description": "Page number",
"name": "page",
"in": "query"
},
{
"type": "integer",
"default": 20,
"description": "Items per page",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Offset for pagination",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"logs": {
"type": "array"
},
"pagination": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/audit/stats": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get audit statistics for the current user, optionally filtered by date range",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Audit"
],
"summary": "Get audit statistics",
"parameters": [
{
"type": "string",
"description": "Start date (YYYY-MM-DD)",
"name": "start_date",
"in": "query"
},
{
"type": "string",
"description": "End date (YYYY-MM-DD)",
"name": "end_date",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"stats": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/auth/2fa/disable": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Disable 2FA for user (requires password confirmation)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Auth"
],
"summary": "Disable 2FA",
"parameters": [
{
"description": "Password Confirmation",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.DisableTwoFactorRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid password or 2FA not enabled",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/auth/2fa/setup": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Generate 2FA secret and QR code for setup",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Auth"
],
"summary": "Setup 2FA",
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/internal_handlers.SetupTwoFactorResponse"
}
}
}
]
}
},
"400": {
"description": "2FA already enabled",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/auth/2fa/status": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get 2FA enabled status for authenticated user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Auth"
],
"summary": "Get 2FA Status",
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
}
}
}
}
}
]
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/auth/2fa/verify": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Verify 2FA code and enable 2FA for user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Auth"
],
"summary": "Verify and Enable 2FA",
"parameters": [
{
"description": "2FA Code",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.VerifyTwoFactorRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid code",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/auth/check-username": {
"get": {
"description": "Check if a username is already taken",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Auth"
],
"summary": "Check Username Availability",
"parameters": [
{
"type": "string",
"description": "Username to check",
"name": "username",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"available": {
"type": "boolean"
},
"username": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Missing Username",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/auth/login": {
"post": {
"description": "Authenticate user and return access token. Refresh token is set in httpOnly cookie.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Auth"
],
"summary": "User Login",
"parameters": [
{
"description": "Login Credentials",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_dto.LoginRequest"
}
}
],
"responses": {
"200": {
"description": "Access token returned in body, refresh token in httpOnly cookie",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_dto.LoginResponse"
}
},
"400": {
"description": "Validation or Bad Request",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Invalid credentials",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/auth/logout": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Revoke refresh token and current session",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Auth"
],
"summary": "Logout",
"parameters": [
{
"description": "Refresh Token to revoke",
"name": "request",
"in": "body",
"required": true,
"schema": {
"type": "object",
"properties": {
"refresh_token": {
"type": "string"
}
}
}
}
],
"responses": {
"200": {
"description": "Success message",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"400": {
"description": "Validation Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/auth/me": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get profile information of the currently logged-in user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Auth"
],
"summary": "Get Current User",
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object"
}
}
}
]
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "User not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/auth/password/reset": {
"post": {
"description": "Completes a password reset using a valid token previously emailed to the user. Invalidates all the user's existing sessions on success.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Auth"
],
"summary": "Reset password with token",
"parameters": [
{
"description": "Reset token + new password",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.ResetPasswordRequest"
}
}
],
"responses": {
"200": {
"description": "Password reset successfully",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid or expired token, or password validation failed",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Failed to update password",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/auth/password/reset-request": {
"post": {
"description": "Sends a password reset link to the user's email if the address exists. Always returns 200 with a generic message to prevent email enumeration.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Auth"
],
"summary": "Request password reset",
"parameters": [
{
"description": "Email of the account to reset",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.RequestPasswordResetRequest"
}
}
],
"responses": {
"200": {
"description": "If the email exists, a reset link has been sent",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Token generation/storage failed (or SMTP failure in production)",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/auth/refresh": {
"post": {
"description": "Get a new access token using a refresh token",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Auth"
],
"summary": "Refresh Token",
"parameters": [
{
"description": "Refresh Token",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_dto.RefreshRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_dto.TokenResponse"
}
},
"400": {
"description": "Validation Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Invalid/Expired Refresh Token",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/auth/register": {
"post": {
"description": "Register a new user account",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Auth"
],
"summary": "User Registration",
"parameters": [
{
"description": "Registration Data",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_dto.RegisterRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_dto.RegisterResponse"
}
},
"400": {
"description": "Validation Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"409": {
"description": "User already exists",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/auth/resend-verification": {
"post": {
"description": "Resend the email verification link",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Auth"
],
"summary": "Resend Verification Email",
"parameters": [
{
"description": "Email",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_dto.ResendVerificationRequest"
}
}
],
"responses": {
"200": {
"description": "Success message",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"400": {
"description": "Validation Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/auth/stream-token": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Returns a 5-minute JWT for HLS and WebSocket authentication (httpOnly cookies prevent direct token access)",
"tags": [
"Auth"
],
"summary": "Get ephemeral stream token",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/internal_handlers.StreamTokenResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/auth/verify-email": {
"post": {
"description": "Verify user email address using a token. v1.0.9 item 1.3:\nthe token is read from the X-Verify-Token header (anti-leak\nvia Referer / proxy access logs). The query-param form\nremains accepted for backward compatibility with emails sent\nbefore v1.0.9 — both paths log a deprecation warning when\nthe query path is used.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Auth"
],
"summary": "Verify Email",
"parameters": [
{
"type": "string",
"description": "Verification Token (preferred)",
"name": "X-Verify-Token",
"in": "header",
"required": true
},
{
"type": "string",
"description": "Verification Token (deprecated, accepted for backward compat)",
"name": "token",
"in": "query"
}
],
"responses": {
"200": {
"description": "Success message",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"400": {
"description": "Invalid Token",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/chat/token": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Generate a short-lived token for chat authentication",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Chat"
],
"summary": "Get Chat Token",
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"token": {
"type": "string"
}
}
}
}
}
]
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/comments/{id}": {
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Update a comment (only by owner)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Comment"
],
"summary": "Update comment",
"parameters": [
{
"type": "string",
"description": "Comment ID (UUID)",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Updated comment content",
"name": "comment",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.UpdateCommentRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"comment": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"403": {
"description": "Forbidden - can only edit own comments",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Comment not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/comments/{id}/replies": {
"get": {
"description": "Get paginated list of replies to a comment",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Comment"
],
"summary": "Get comment replies",
"parameters": [
{
"type": "string",
"description": "Parent Comment ID (UUID)",
"name": "id",
"in": "path",
"required": true
},
{
"minimum": 1,
"type": "integer",
"default": 1,
"description": "Page number",
"name": "page",
"in": "query"
},
{
"maximum": 100,
"minimum": 1,
"type": "integer",
"default": 20,
"description": "Items per page",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"pagination": {
"type": "object"
},
"replies": {
"type": "array"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Parent comment not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/config/webrtc": {
"get": {
"description": "Public — returns the ICE-server set the SPA feeds to RTCPeerConnection. STUN-only when no TURN is configured. TURN credentials are always emitted as static (REST shared-secret rotation deferred to v1.1).",
"produces": [
"application/json"
],
"tags": [
"Config"
],
"summary": "WebRTC ICE configuration",
"responses": {
"200": {
"description": "ICE servers",
"schema": {
"$ref": "#/definitions/internal_handlers.WebRTCConfigResponse"
}
}
}
}
},
"/internal/tracks/{id}/stream-ready": {
"post": {
"description": "Internal endpoint called by the Rust stream server when HLS transcoding completes or fails. Updates the track's stream_status and stream_manifest_url. Requires internal API key (not user-facing).",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Stream server callback",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Callback payload",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_core_track.StreamCallbackRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
},
"400": {
"description": "Validation / invalid id",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
}
},
"/playlists": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get a paginated list of playlists",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Get Playlists",
"parameters": [
{
"type": "integer",
"default": 1,
"description": "Page number",
"name": "page",
"in": "query"
},
{
"type": "integer",
"default": 20,
"description": "Items per page",
"name": "limit",
"in": "query"
},
{
"type": "string",
"description": "Filter by User ID",
"name": "user_id",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"pagination": {
"type": "object"
},
"playlists": {
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_models.Playlist"
}
}
}
}
}
}
]
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Create a new playlist",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Create Playlist",
"parameters": [
{
"description": "Playlist Metadata",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.CreatePlaylistRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"playlist": {
"$ref": "#/definitions/veza-backend-api_internal_models.Playlist"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/playlists/favoris": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Returns the authenticated user's \"Favoris\" playlist. Auto-created on first call. Used by the like-as-save pattern.",
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Get Favoris playlist",
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"playlist": {
"$ref": "#/definitions/veza-backend-api_internal_models.Playlist"
}
}
}
}
}
]
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/playlists/import": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Create a playlist from a JSON payload (title, description, is_public, ordered track IDs). Useful for bulk seed / migration.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Import playlist",
"parameters": [
{
"description": "Playlist + tracks",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.ImportPlaylistRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"playlist": {
"$ref": "#/definitions/veza-backend-api_internal_models.Playlist"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/playlists/recommendations": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Suggested playlists for the authenticated user. Chronological / declarative discovery — no behavioural ranking (CLAUDE.md rule 7).",
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Get playlist recommendations",
"parameters": [
{
"type": "integer",
"default": 20,
"description": "Max items (max 100)",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"playlists": {
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_models.Playlist"
}
}
}
}
}
}
]
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/playlists/search": {
"get": {
"description": "Full-text search on public playlists (title + description). Paginated.",
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Search playlists",
"parameters": [
{
"type": "string",
"description": "Full-text query",
"name": "q",
"in": "query"
},
{
"type": "integer",
"default": 1,
"description": "Page number",
"name": "page",
"in": "query"
},
{
"type": "integer",
"default": 20,
"description": "Items per page (max 100)",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"pagination": {
"type": "object"
},
"playlists": {
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_models.Playlist"
}
}
}
}
}
}
]
}
},
"400": {
"description": "Validation",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/playlists/shared/{token}": {
"get": {
"description": "Public endpoint resolving a share token. Allows unauthenticated access to the playlist snapshot + tracks.",
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Get playlist by share token",
"parameters": [
{
"type": "string",
"description": "Share token",
"name": "token",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"playlist": {
"$ref": "#/definitions/veza-backend-api_internal_models.Playlist"
}
}
}
}
}
]
}
},
"400": {
"description": "Missing token",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"403": {
"description": "Share expired",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Share or playlist not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/playlists/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get detailed information about a playlist",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Get Playlist by ID",
"parameters": [
{
"type": "string",
"description": "Playlist ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"playlist": {
"$ref": "#/definitions/veza-backend-api_internal_models.Playlist"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid ID",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Playlist not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
},
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Update playlist metadata",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Update Playlist",
"parameters": [
{
"type": "string",
"description": "Playlist ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Playlist Metadata",
"name": "playlist",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.UpdatePlaylistRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"playlist": {
"$ref": "#/definitions/veza-backend-api_internal_models.Playlist"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Playlist not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Permanently delete a playlist",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Delete Playlist",
"parameters": [
{
"type": "string",
"description": "Playlist ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Playlist not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/playlists/{id}/analytics": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Returns aggregated stats for a playlist (plays, follows, tracks count, etc.). Visible to the owner, collaborators and admins.",
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Get playlist statistics",
"parameters": [
{
"type": "string",
"description": "Playlist UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"stats": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid id",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Playlist not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/playlists/{id}/collaborators": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Returns the collaborators of a playlist with their permission level.",
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "List playlist collaborators",
"parameters": [
{
"type": "string",
"description": "Playlist UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"collaborators": {
"type": "array",
"items": {
"type": "object"
}
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid id",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Playlist not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Invite a user as collaborator. Only the owner (or admin) can add.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Add playlist collaborator",
"parameters": [
{
"type": "string",
"description": "Playlist UUID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Collaborator + permission",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.AddCollaboratorRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"collaborator": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"403": {
"description": "Not owner",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Playlist not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/playlists/{id}/collaborators/{userId}": {
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Change a collaborator's permission level (read / write / admin). Only the owner can update.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Update collaborator permission",
"parameters": [
{
"type": "string",
"description": "Playlist UUID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Collaborator user UUID",
"name": "userId",
"in": "path",
"required": true
},
{
"description": "New permission",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.UpdateCollaboratorPermissionRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"collaborator": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"403": {
"description": "Not owner",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Playlist or collaborator not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Revoke a collaborator's access. Only the owner (or admin) can remove.",
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Remove playlist collaborator",
"parameters": [
{
"type": "string",
"description": "Playlist UUID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Collaborator user UUID",
"name": "userId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"403": {
"description": "Not owner",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Playlist or collaborator not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/playlists/{id}/duplicate": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Copy a playlist's track list into a new playlist owned by the authenticated user. Cover/description copied; original unchanged.",
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Duplicate playlist",
"parameters": [
{
"type": "string",
"description": "Source playlist UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"playlist": {
"$ref": "#/definitions/veza-backend-api_internal_models.Playlist"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid id",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"403": {
"description": "Source not visible",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Source playlist not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/playlists/{id}/share": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Generate a tokenised link to share a playlist (read-only). Only owner / admin can issue. No body required.",
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Create playlist share link",
"parameters": [
{
"type": "string",
"description": "Playlist UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"share": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"403": {
"description": "Not owner",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Playlist not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/playlists/{id}/tracks": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Add a track to the playlist",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Add Track to Playlist",
"parameters": [
{
"type": "string",
"description": "Playlist ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Track ID (in body)",
"name": "trackId",
"in": "body",
"required": true,
"schema": {
"type": "object",
"properties": {
"track_id": {
"type": "string"
}
}
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Track already present or invalid ID",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Playlist or Track not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/playlists/{id}/tracks/reorder": {
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Reorder tracks in the playlist",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Reorder Tracks",
"parameters": [
{
"type": "string",
"description": "Playlist ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "New Track Order",
"name": "order",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.ReorderTracksRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/playlists/{id}/tracks/{trackId}": {
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Remove a track from the playlist",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Playlist"
],
"summary": "Remove Track from Playlist",
"parameters": [
{
"type": "string",
"description": "Playlist ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Track ID",
"name": "trackId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"404": {
"description": "Playlist or Track not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/queue": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Returns the authenticated user's persistent playback queue with all items in position order",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Queue"
],
"summary": "Get user playback queue",
"responses": {
"200": {
"description": "Queue + items",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object"
}
},
"queue": {
"type": "object"
}
}
}
}
}
]
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
},
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Updates the authenticated user's queue state (current track / position / playback flags / item order)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Queue"
],
"summary": "Update user playback queue",
"parameters": [
{
"description": "Queue update payload",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_services.UpdateQueueRequest"
}
}
],
"responses": {
"200": {
"description": "Updated queue",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object"
}
},
"queue": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Removes every item from the authenticated user's playback queue",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Queue"
],
"summary": "Clear queue",
"responses": {
"200": {
"description": "Queue cleared",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/queue/items": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Appends a track to the authenticated user's playback queue",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Queue"
],
"summary": "Add track to queue",
"parameters": [
{
"description": "Track to enqueue",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.AddQueueItemRequest"
}
}
],
"responses": {
"201": {
"description": "Created queue item",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"item": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/queue/items/{id}": {
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Removes a single item from the authenticated user's playback queue by item ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Queue"
],
"summary": "Remove queue item",
"parameters": [
{
"type": "string",
"description": "Queue item ID (UUID)",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Item removed",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid item ID",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Queue item not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/queue/session": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Creates a shared queue session and returns its share token + URL. The session creator is recorded as host.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Queue"
],
"summary": "Create collaborative queue session",
"responses": {
"201": {
"description": "Created session",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"session": {
"type": "object"
},
"share_token": {
"type": "string"
},
"share_url": {
"type": "string"
}
}
}
}
}
]
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/queue/session/{token}": {
"get": {
"description": "Returns the session metadata + items for a given share token. No auth required (public — anyone with the link can join).",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Queue"
],
"summary": "Get queue session by share token",
"parameters": [
{
"type": "string",
"description": "Session share token",
"name": "token",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Session and queue items",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object"
}
},
"session": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Token required",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Session not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Deletes a collaborative queue session. Only the original session creator can delete.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Queue"
],
"summary": "Delete queue session",
"parameters": [
{
"type": "string",
"description": "Session share token",
"name": "token",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Session deleted",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Token required",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"403": {
"description": "Only the creator can delete this session",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Session not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/queue/session/{token}/items": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Adds a track to a collaborative queue session. Anyone with the share token can add.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Queue"
],
"summary": "Add track to queue session",
"parameters": [
{
"type": "string",
"description": "Session share token",
"name": "token",
"in": "path",
"required": true
},
{
"description": "Track to enqueue",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.AddToSessionRequest"
}
}
],
"responses": {
"201": {
"description": "Updated session and items",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object"
}
},
"session": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Session not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/queue/session/{token}/items/{id}": {
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Removes an item from a collaborative queue session by item ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Queue"
],
"summary": "Remove item from queue session",
"parameters": [
{
"type": "string",
"description": "Session share token",
"name": "token",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Queue item ID (UUID)",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Item removed",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Session or item not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/search": {
"get": {
"description": "Postgres FTS-backed search across tracks, users, and playlists. Optional `type` filter accepts repeated values (e.g., ?type=track\u0026type=user). v1.0.9 item 1.6 — annotation added so orval can generate a typed client.",
"produces": [
"application/json"
],
"tags": [
"Search"
],
"summary": "Unified search",
"parameters": [
{
"type": "string",
"description": "Search query",
"name": "q",
"in": "query",
"required": true
},
{
"type": "array",
"items": {
"type": "string"
},
"collectionFormat": "multi",
"description": "Restrict to one or more entity types: track, user, playlist",
"name": "type",
"in": "query"
},
{
"type": "string",
"description": "Opaque pagination cursor",
"name": "cursor",
"in": "query"
},
{
"type": "integer",
"description": "Page size (max 50)",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "Search results",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"400": {
"description": "Validation error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Search failed",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/search/suggestions": {
"get": {
"description": "Lightweight autocomplete used by the search bar. Returns a small SearchResult subset (typically tracks + users + playlists), capped at `limit` (1..20, default 5). v1.0.9 item 1.6 — annotation added so orval can generate a typed client.",
"produces": [
"application/json"
],
"tags": [
"Search"
],
"summary": "Search suggestions",
"parameters": [
{
"type": "string",
"description": "Partial query (min 1 char)",
"name": "q",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Max number of suggestions (1..20, default 5)",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "Suggestions",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"400": {
"description": "Validation error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Suggestions failed",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/social/trending": {
"get": {
"description": "Returns the top hashtags surfacing in posts published recently. Counts are aggregated, not user-personalised — discovery is by declarative tags, not behavioural ranking (cf. CLAUDE.md rule 7). v1.0.9 item 1.6 — annotation added so orval can generate a typed client.",
"produces": [
"application/json"
],
"tags": [
"Social"
],
"summary": "Trending hashtags",
"parameters": [
{
"type": "integer",
"description": "Max tags to return (1..50, default 10)",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "Trending tags",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Failed to compute trending",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/tracks": {
"get": {
"description": "List tracks with pagination, filters, sort. Cursor-based when ?cursor provided, otherwise page/limit offset.",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "List tracks",
"parameters": [
{
"type": "string",
"description": "Opaque pagination cursor (overrides page)",
"name": "cursor",
"in": "query"
},
{
"type": "integer",
"default": 1,
"description": "Page number, 1-based (ignored if cursor set)",
"name": "page",
"in": "query"
},
{
"type": "integer",
"default": 20,
"description": "Items per page (max 100)",
"name": "limit",
"in": "query"
},
{
"type": "string",
"description": "Filter by creator UUID",
"name": "user_id",
"in": "query"
},
{
"type": "string",
"description": "Filter by genre",
"name": "genre",
"in": "query"
},
{
"type": "string",
"description": "Filter by audio format (mp3, flac, wav, ogg, m4a, aac)",
"name": "format",
"in": "query"
},
{
"type": "string",
"default": "created_at",
"description": "Sort column (created_at, play_count, title)",
"name": "sort_by",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"pagination": {
"type": "object"
},
"tracks": {
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_models.Track"
}
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid query params",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Upload a new track (audio file)",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Upload Track",
"parameters": [
{
"type": "file",
"description": "Audio File (MP3, WAV, FLAC, OGG)",
"name": "file",
"in": "formData",
"required": true
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"track": {
"$ref": "#/definitions/veza-backend-api_internal_models.Track"
}
}
}
}
}
]
}
},
"400": {
"description": "No file or validation error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"403": {
"description": "Quota exceeded",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
}
},
"/tracks/batch/delete": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Soft-delete up to N tracks in one request. Per-track ownership checked (admin can delete others).",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Batch delete tracks",
"parameters": [
{
"description": "List of track UUIDs",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_core_track.BatchDeleteRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"deleted": {
"type": "array",
"items": {
"type": "string"
}
},
"failed": {
"type": "array",
"items": {
"type": "object"
}
}
}
}
}
}
]
}
},
"400": {
"description": "Validation / batch size exceeded",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
}
},
"/tracks/batch/update": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Apply a partial metadata update to up to N tracks in one request. Per-track ownership checked.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Batch update tracks",
"parameters": [
{
"description": "Track UUIDs + shared updates map",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_core_track.BatchUpdateRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"failed": {
"type": "array",
"items": {
"type": "object"
}
},
"updated": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
]
}
},
"400": {
"description": "Validation / batch size exceeded",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
}
},
"/tracks/chunk": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Upload a single chunk of a file",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Upload Chunk",
"parameters": [
{
"type": "file",
"description": "Chunk Data",
"name": "chunk",
"in": "formData",
"required": true
},
{
"type": "string",
"description": "Upload ID",
"name": "upload_id",
"in": "formData",
"required": true
},
{
"type": "integer",
"description": "Chunk Number",
"name": "chunk_number",
"in": "formData",
"required": true
},
{
"type": "integer",
"description": "Total Chunks",
"name": "total_chunks",
"in": "formData",
"required": true
},
{
"type": "integer",
"format": "int64",
"description": "Total Size",
"name": "total_size",
"in": "formData",
"required": true
},
{
"type": "string",
"description": "Filename",
"name": "filename",
"in": "formData",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
},
"progress": {
"type": "number",
"format": "float64"
},
"received_chunks": {
"type": "integer"
},
"upload_id": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
}
},
"/tracks/complete": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Finish upload session and assemble file",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Complete Chunked Upload",
"parameters": [
{
"description": "Upload ID",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_core_track.CompleteChunkedUploadRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"md5": {
"type": "string"
},
"message": {
"type": "string"
},
"track": {
"$ref": "#/definitions/veza-backend-api_internal_models.Track"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation or Assemblage Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
}
},
"/tracks/initiate": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Start a new chunked upload session",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Initiate Chunked Upload",
"parameters": [
{
"description": "Upload Metadata",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_core_track.InitiateChunkedUploadRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
},
"upload_id": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
}
},
"/tracks/quota/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get remaining upload quota for the user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Get Upload Quota",
"parameters": [
{
"type": "string",
"description": "User ID or 'me' for current user",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"quota": {
"type": "object"
}
}
}
}
}
]
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
}
},
"/tracks/recommendations": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Personalized tracks for D2 autoplay. If seed_track_id is given, returns tracks similar to that seed. Otherwise, uses the caller's history (chronological, no behavioural ranking — CLAUDE.md rule 7).",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Get track recommendations",
"parameters": [
{
"type": "integer",
"default": 20,
"description": "Max items (max 100)",
"name": "limit",
"in": "query"
},
{
"type": "string",
"description": "Start from this track's similarity neighbours",
"name": "seed_track_id",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"tracks": {
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_models.Track"
}
}
}
}
}
}
]
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
}
},
"/tracks/resume/{uploadId}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get state of an interrupted upload",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Resume Upload",
"parameters": [
{
"type": "string",
"description": "Upload ID",
"name": "uploadId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"chunks_received": {
"type": "integer"
},
"upload_id": {
"type": "string"
}
}
}
}
}
]
}
},
"404": {
"description": "Upload session not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
}
},
"/tracks/search": {
"get": {
"description": "Full-text + faceted search on tracks (genre, BPM, duration, tags, musical key, dates). Sort-by and order configurable.",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Advanced track search",
"parameters": [
{
"type": "string",
"description": "Full-text query (title/artist/album)",
"name": "q",
"in": "query"
},
{
"type": "string",
"description": "Comma-separated tag list",
"name": "tags",
"in": "query"
},
{
"type": "string",
"default": "OR",
"description": "Tag combinator (OR / AND)",
"name": "tag_mode",
"in": "query"
},
{
"type": "integer",
"description": "Minimum duration (seconds)",
"name": "min_duration",
"in": "query"
},
{
"type": "integer",
"description": "Maximum duration (seconds)",
"name": "max_duration",
"in": "query"
},
{
"type": "integer",
"description": "Minimum BPM",
"name": "min_bpm",
"in": "query"
},
{
"type": "integer",
"description": "Maximum BPM",
"name": "max_bpm",
"in": "query"
},
{
"type": "string",
"description": "Genre filter",
"name": "genre",
"in": "query"
},
{
"type": "string",
"description": "Audio format filter",
"name": "format",
"in": "query"
},
{
"type": "string",
"description": "Musical key filter",
"name": "musical_key",
"in": "query"
},
{
"type": "string",
"description": "Created-after (RFC3339)",
"name": "min_date",
"in": "query"
},
{
"type": "string",
"description": "Created-before (RFC3339)",
"name": "max_date",
"in": "query"
},
{
"type": "integer",
"default": 1,
"description": "Page (1-based)",
"name": "page",
"in": "query"
},
{
"type": "integer",
"default": 20,
"description": "Items per page (max 100)",
"name": "limit",
"in": "query"
},
{
"type": "string",
"default": "created_at",
"description": "Sort column",
"name": "sort_by",
"in": "query"
},
{
"type": "string",
"default": "desc",
"description": "asc / desc",
"name": "sort_order",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"pagination": {
"type": "object"
},
"tracks": {
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_models.Track"
}
}
}
}
}
}
]
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
}
},
"/tracks/share/{id}": {
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Permanently disable a share token. Only the share issuer (or admin) can revoke.",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Revoke share link",
"parameters": [
{
"type": "string",
"description": "Share UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"403": {
"description": "Not issuer",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"404": {
"description": "Share not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
}
},
"/tracks/shared/{token}": {
"get": {
"description": "Public endpoint that resolves a share token and returns the track + share metadata. No auth required; the token IS the auth.",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Get track by share token",
"parameters": [
{
"type": "string",
"description": "Opaque share token issued by CreateShare",
"name": "token",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"share": {
"type": "object"
},
"track": {
"$ref": "#/definitions/veza-backend-api_internal_models.Track"
}
}
}
}
}
]
}
},
"400": {
"description": "Missing token",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"403": {
"description": "Share link expired",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"404": {
"description": "Share or track not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
}
},
"/tracks/suggested-tags": {
"get": {
"description": "Returns a static tag suggestion list for a genre — useful for upload autocomplete and filter chips.",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Get suggested tags",
"parameters": [
{
"type": "string",
"default": "default",
"description": "Genre slug (pop, rock, electronic, hip-hop, jazz, classical, ambient, default)",
"name": "genre",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
]
}
}
}
}
},
"/tracks/{id}": {
"get": {
"description": "Retrieve a single track. Private play_count / like_count are omitted for non-owners (v0.10.3 F202).",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Get track by ID",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"track": {
"$ref": "#/definitions/veza-backend-api_internal_models.Track"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid track id",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"404": {
"description": "Track not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
},
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Update the metadata of an existing track. Caller must own the track or be admin.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Update track metadata",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Updated metadata",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_core_track.UpdateTrackRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"track": {
"$ref": "#/definitions/veza-backend-api_internal_models.Track"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation / invalid id",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"403": {
"description": "Not owner / no admin",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"404": {
"description": "Track not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Soft-delete a track (sets deleted_at). Caller must own the track or be admin.",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Delete track",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid track id",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"403": {
"description": "Not owner / no admin",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"404": {
"description": "Track not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
}
},
"/tracks/{id}/comments": {
"get": {
"description": "Get paginated list of comments for a track",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Comment"
],
"summary": "Get track comments",
"parameters": [
{
"type": "string",
"description": "Track ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "integer",
"default": 1,
"description": "Page number",
"name": "page",
"in": "query"
},
{
"type": "integer",
"default": 20,
"description": "Items per page",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"comments": {
"type": "array"
},
"pagination": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Track not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Create a new comment on a track. Can be a top-level comment or a reply to another comment (using parent_id).",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Comment"
],
"summary": "Create comment",
"parameters": [
{
"type": "string",
"description": "Track ID (UUID)",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Comment data",
"name": "comment",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.CreateCommentRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"comment": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Track not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/tracks/{id}/comments/{comment_id}": {
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Delete a comment (only by owner or admin)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Comment"
],
"summary": "Delete comment",
"parameters": [
{
"type": "string",
"description": "Track ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Comment ID",
"name": "comment_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"403": {
"description": "Forbidden - not comment owner",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Comment not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/tracks/{id}/download": {
"get": {
"description": "Serve the original audio file. For S3-backed tracks returns a 302 redirect to a signed URL (TTL 30min). For local-backed tracks streams the file with Range support. Public tracks or share_token access; paid tracks require a license.",
"produces": [
"application/octet-stream"
],
"tags": [
"Track"
],
"summary": "Download a track",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Grants access without authentication for a limited time",
"name": "share_token",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "file"
}
},
"302": {
"description": "Location header points to signed S3 URL (s3-backed tracks)",
"schema": {
"type": "string"
}
},
"400": {
"description": "Invalid track id",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"403": {
"description": "No permission / license required",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"404": {
"description": "Track or file not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
}
},
"/tracks/{id}/history": {
"get": {
"description": "Paginated audit log of modifications (metadata updates, version changes) for a track.",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Get track history",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "integer",
"default": 50,
"description": "Items per page",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"history": {
"type": "array",
"items": {
"type": "object"
}
},
"limit": {
"type": "integer"
},
"offset": {
"type": "integer"
},
"total": {
"type": "integer"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid track id",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"404": {
"description": "Track not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
}
},
"/tracks/{id}/like": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Record a like from the authenticated user. Creates a grouped notification for the creator (F554).",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Like a track",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid track id",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"404": {
"description": "Track not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Remove the authenticated user's like on the track (idempotent).",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Unlike a track",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid track id",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
}
},
"/tracks/{id}/likes": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Returns whether the current user has liked the track. The total like count is returned ONLY to the creator or an admin (privacy per ORIGIN_UI_UX_SYSTEM §13).",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Get track like status",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "count is omitted for non-owners",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"count": {
"type": "integer"
},
"is_liked": {
"type": "boolean"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid track id",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"404": {
"description": "Track not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
}
},
"/tracks/{id}/lyrics": {
"get": {
"description": "Returns the current lyrics for a track, or null if no lyrics exist.",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Get track lyrics",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "lyrics may be null",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"lyrics": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid track id",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"404": {
"description": "Track not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
},
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Replace the lyrics of a track. Caller must own the track or be admin.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Create or update track lyrics",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Lyrics payload",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_core_track.UpdateLyricsRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"lyrics": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation / invalid id",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"403": {
"description": "Not owner / no admin",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"404": {
"description": "Track not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
}
},
"/tracks/{id}/play": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Persist a playback event with optional play_time so the creator's analytics dashboard tracks listening behaviour.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Record play event",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Playback metadata (optional)",
"name": "request",
"in": "body",
"schema": {
"$ref": "#/definitions/internal_core_track.RecordPlayRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid track id / body",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"404": {
"description": "Track not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
}
},
"/tracks/{id}/repost": {
"get": {
"description": "Returns whether the current user has reposted the track. Public (optional auth); unauthenticated callers get is_reposted=false.",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Get repost status",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"is_reposted": {
"type": "boolean"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid track id",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Add a track to the authenticated user's profile as a repost. Notifies the creator (F204) unless self-repost.",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Repost a track",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid track id",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"404": {
"description": "Track not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Remove the authenticated user's repost of the track (idempotent).",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Remove track repost",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid track id",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
}
},
"/tracks/{id}/share": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Generate a tokenized share link for a track with given permission level and optional expiry.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Create share link",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Share parameters",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_core_track.CreateShareRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"share": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"403": {
"description": "Not owner",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"404": {
"description": "Track not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
}
},
"/tracks/{id}/stats": {
"get": {
"description": "Aggregated track stats: views, likes, comments, play time, downloads, average duration.",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Get track statistics",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"stats": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid track id",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"404": {
"description": "Track not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
}
},
"/tracks/{id}/status": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get the processing status of an uploaded track",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Get Upload Status",
"parameters": [
{
"type": "string",
"description": "Track ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"progress": {
"type": "integer"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid ID",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
},
"404": {
"description": "Track not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_response.APIResponse"
}
}
}
}
},
"/tracks/{id}/stream": {
"get": {
"description": "Default playback path. S3-backed tracks return a 302 redirect to a signed URL (TTL 15min). Local-backed tracks are streamed via http.ServeContent with Range support. Always available, unlike /hls/* which is gated by HLSEnabled.",
"produces": [
"audio/*"
],
"tags": [
"Track"
],
"summary": "Stream a track (raw audio + Range)",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Grants access without authentication",
"name": "share_token",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "file"
}
},
"302": {
"description": "Location header points to signed S3 URL (s3-backed tracks)",
"schema": {
"type": "string"
}
},
"400": {
"description": "Invalid track id",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"403": {
"description": "No permission",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"404": {
"description": "Track or file not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
}
},
"/tracks/{id}/versions/{versionId}/restore": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Rollback a track to a previous version. Only the track owner can restore.",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Restore track version",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Version UUID",
"name": "versionId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid id",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"403": {
"description": "Not owner",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"404": {
"description": "Track or version not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
}
},
"/tracks/{id}/waveform": {
"get": {
"description": "Returns a JSON peaks array used by the client to draw the audio waveform preview. 404 if waveform extraction is not complete yet.",
"produces": [
"application/json"
],
"tags": [
"Track"
],
"summary": "Get track waveform",
"parameters": [
{
"type": "string",
"description": "Track UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Waveform peaks JSON (tool-specific shape)",
"schema": {
"type": "object"
}
},
"400": {
"description": "Invalid track id",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"404": {
"description": "Waveform not generated / track not found",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
}
},
"/users": {
"get": {
"description": "Get a paginated list of users with optional filtering",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"User"
],
"summary": "List Users",
"parameters": [
{
"type": "integer",
"default": 1,
"description": "Page number",
"name": "page",
"in": "query"
},
{
"type": "integer",
"default": 20,
"description": "Items per page",
"name": "limit",
"in": "query"
},
{
"type": "string",
"description": "Filter by role",
"name": "role",
"in": "query"
},
{
"type": "boolean",
"description": "Filter by active status",
"name": "is_active",
"in": "query"
},
{
"type": "boolean",
"description": "Filter by verified status",
"name": "is_verified",
"in": "query"
},
{
"type": "string",
"description": "Search by username, email, first_name, last_name",
"name": "search",
"in": "query"
},
{
"type": "string",
"default": "created_at",
"description": "Sort field (created_at, username, email, last_login_at)",
"name": "sort_by",
"in": "query"
},
{
"type": "string",
"default": "desc",
"description": "Sort order (asc, desc)",
"name": "sort_order",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"pagination": {
"type": "object"
},
"users": {
"type": "array"
}
}
}
}
}
]
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/users/by-username/{username}": {
"get": {
"description": "Get public profile information for a user by username",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"User"
],
"summary": "Get Profile by Username",
"parameters": [
{
"type": "string",
"description": "Username",
"name": "username",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"profile": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Missing username",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "User not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/users/me": {
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Permanently delete user account with anonymization, session revocation, audit log",
"tags": [
"Users"
],
"summary": "Delete account",
"parameters": [
{
"description": "Password, reason, confirm_text (must be DELETE)",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.DeleteAccountRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/users/me/privacy/opt-out": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Saves the user's Do Not Sell preference (CCPA compliance)",
"tags": [
"Users"
],
"summary": "CCPA Do Not Sell opt-out",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "Unauthorized",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/users/search": {
"get": {
"description": "Full-text search on users (username, display_name). Paginated. Public.",
"produces": [
"application/json"
],
"tags": [
"User"
],
"summary": "Search users",
"parameters": [
{
"type": "string",
"description": "Full-text query",
"name": "q",
"in": "query"
},
{
"type": "integer",
"default": 1,
"description": "Page",
"name": "page",
"in": "query"
},
{
"type": "integer",
"default": 20,
"description": "Items per page (max 100)",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"pagination": {
"type": "object"
},
"users": {
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_models.User"
}
}
}
}
}
}
]
}
},
"400": {
"description": "Validation (bounds)",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/users/suggestions": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Returns suggested users to follow for the authenticated user. Declarative discovery — no behavioural scoring (CLAUDE.md rule 7).",
"produces": [
"application/json"
],
"tags": [
"User"
],
"summary": "Get follow suggestions",
"parameters": [
{
"type": "integer",
"default": 10,
"description": "Max items (max 50)",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"users": {
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_models.User"
}
}
}
}
}
}
]
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/users/{id}": {
"get": {
"description": "Get public profile information for a user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"User"
],
"summary": "Get Profile by ID",
"parameters": [
{
"type": "string",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"profile": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid ID",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "User not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
},
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "Update user profile details",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"User"
],
"summary": "Update Profile",
"parameters": [
{
"type": "string",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Profile Data",
"name": "profile",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.UpdateProfileRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"profile": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Soft delete a user (only user owner or admin can delete)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"User"
],
"summary": "Delete user",
"parameters": [
{
"type": "string",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "User deleted successfully",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"400": {
"description": "Invalid ID",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"403": {
"description": "Forbidden - Not user owner or admin",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "User not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/users/{id}/block": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Authenticated user blocks target user (hides their content, prevents follows). Cannot self-block.",
"produces": [
"application/json"
],
"tags": [
"User"
],
"summary": "Block user",
"parameters": [
{
"type": "string",
"description": "Target user UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation / self-block",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Authenticated user unblocks target user (idempotent).",
"produces": [
"application/json"
],
"tags": [
"User"
],
"summary": "Unblock user",
"parameters": [
{
"type": "string",
"description": "Target user UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid id",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/users/{id}/completion": {
"get": {
"description": "Get profile completion percentage and missing fields",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"User"
],
"summary": "Get Profile Completion",
"parameters": [
{
"type": "string",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object"
}
}
}
]
}
},
"400": {
"description": "Invalid ID",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/users/{id}/follow": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Authenticated user follows target user. Creates a notification (F554 grouped) for the target.",
"produces": [
"application/json"
],
"tags": [
"User"
],
"summary": "Follow user",
"parameters": [
{
"type": "string",
"description": "Target user UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid id",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "User not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Authenticated user stops following target user (idempotent).",
"produces": [
"application/json"
],
"tags": [
"User"
],
"summary": "Unfollow user",
"parameters": [
{
"type": "string",
"description": "Target user UUID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid id",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/users/{id}/likes": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Returns paginated tracks the given user has liked. Used for profile \"Likes\" tab.",
"produces": [
"application/json"
],
"tags": [
"User"
],
"summary": "List tracks liked by a user",
"parameters": [
{
"type": "string",
"description": "User UUID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "integer",
"default": 20,
"description": "Items per page (max 100)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset for pagination",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"limit": {
"type": "integer"
},
"offset": {
"type": "integer"
},
"total": {
"type": "integer"
},
"tracks": {
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_models.Track"
}
}
}
}
}
}
]
}
},
"400": {
"description": "Validation",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
}
},
"/users/{id}/reposts": {
"get": {
"description": "Returns paginated tracks the user has reposted. Used for profile \"Reposts\" tab.",
"produces": [
"application/json"
],
"tags": [
"User"
],
"summary": "List tracks reposted by a user",
"parameters": [
{
"type": "string",
"description": "User UUID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "integer",
"default": 20,
"description": "Items per page (max 100)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset for pagination",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"limit": {
"type": "integer"
},
"offset": {
"type": "integer"
},
"total": {
"type": "integer"
},
"tracks": {
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_models.Track"
}
}
}
}
}
}
]
}
},
"400": {
"description": "Validation",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal Error",
"schema": {
"$ref": "#/definitions/veza-backend-api_internal_handlers.APIResponse"
}
}
}
}
},
"/validate": {
"post": {
"description": "Validates request data against known DTO types without executing the actual operation",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Validation"
],
"summary": "Validate request body",
"parameters": [
{
"description": "Validation request with type and data",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/internal_handlers.ValidateRequest"
}
}
],
"responses": {
"200": {
"description": "Validation result",
"schema": {
"$ref": "#/definitions/internal_handlers.ValidateResponse"
}
},
"400": {
"description": "Invalid request format",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/webhooks": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get a list of all webhooks registered by the current user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Webhook"
],
"summary": "List webhooks",
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"webhooks": {
"type": "array"
}
}
}
}
}
]
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Register a new webhook for receiving events",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Webhook"
],
"summary": "Register webhook",
"parameters": [
{
"description": "Webhook registration data",
"name": "webhook",
"in": "body",
"required": true,
"schema": {
"type": "object"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"webhook": {
"type": "object"
}
}
}
}
}
]
}
},
"400": {
"description": "Validation error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/webhooks/stats": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get statistics for webhook delivery and performance",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Webhook"
],
"summary": "Get webhook statistics",
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"stats": {
"type": "object"
}
}
}
}
}
]
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/webhooks/{id}": {
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Delete a webhook by ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Webhook"
],
"summary": "Delete webhook",
"parameters": [
{
"type": "string",
"description": "Webhook ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid webhook ID",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Webhook not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/webhooks/{id}/regenerate-key": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Generate a new API key for a webhook (invalidates the old one)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Webhook"
],
"summary": "Regenerate webhook API key",
"parameters": [
{
"type": "string",
"description": "Webhook ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"api_key": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid webhook ID",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Webhook not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
},
"/webhooks/{id}/test": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "Send a test event to a webhook to verify it's working",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Webhook"
],
"summary": "Test webhook",
"parameters": [
{
"type": "string",
"description": "Webhook ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/internal_handlers.APIResponse"
},
{
"type": "object",
"properties": {
"data": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
]
}
},
"400": {
"description": "Invalid webhook ID",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
},
"404": {
"description": "Webhook not found",
"schema": {
"$ref": "#/definitions/internal_handlers.APIResponse"
}
}
}
}
}
},
"definitions": {
"internal_core_track.BatchDeleteRequest": {
"type": "object",
"required": [
"track_ids"
],
"properties": {
"track_ids": {
"type": "array",
"minItems": 1,
"items": {
"type": "string"
}
}
}
},
"internal_core_track.BatchUpdateRequest": {
"type": "object",
"required": [
"track_ids",
"updates"
],
"properties": {
"track_ids": {
"type": "array",
"minItems": 1,
"items": {
"type": "string"
}
},
"updates": {
"type": "object",
"additionalProperties": true
}
}
},
"internal_core_track.CompleteChunkedUploadRequest": {
"type": "object",
"required": [
"upload_id"
],
"properties": {
"upload_id": {
"type": "string"
}
}
},
"internal_core_track.CreateShareRequest": {
"type": "object",
"required": [
"permissions"
],
"properties": {
"expires_at": {
"type": "string"
},
"permissions": {
"type": "string",
"enum": [
"read",
"write",
"admin"
]
}
}
},
"internal_core_track.InitiateChunkedUploadRequest": {
"type": "object",
"required": [
"filename",
"total_chunks",
"total_size"
],
"properties": {
"filename": {
"type": "string"
},
"total_chunks": {
"type": "integer",
"minimum": 1
},
"total_size": {
"type": "integer",
"minimum": 1
}
}
},
"internal_core_track.RecordPlayRequest": {
"type": "object",
"properties": {
"play_time": {
"type": "integer",
"minimum": 0
}
}
},
"internal_core_track.StreamCallbackRequest": {
"type": "object",
"required": [
"status"
],
"properties": {
"error": {
"type": "string"
},
"manifest_url": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"completed",
"failed",
"processing"
]
}
}
},
"internal_core_track.UpdateLyricsRequest": {
"type": "object",
"properties": {
"content": {
"type": "string"
}
}
},
"internal_core_track.UpdateTrackRequest": {
"type": "object",
"properties": {
"album": {
"type": "string",
"maxLength": 255
},
"artist": {
"type": "string",
"maxLength": 255
},
"bpm": {
"type": "integer",
"maximum": 300,
"minimum": 0
},
"genre": {
"description": "legacy, single",
"type": "string",
"maxLength": 100
},
"genres": {
"description": "v0.10.1: max 3, taxonomy slugs",
"type": "array",
"items": {
"type": "string"
}
},
"is_public": {
"type": "boolean"
},
"musical_key": {
"type": "string",
"maxLength": 10
},
"tags": {
"description": "v0.10.1: max 10, 30 chars each",
"type": "array",
"items": {
"type": "string"
}
},
"title": {
"type": "string",
"maxLength": 255,
"minLength": 1
},
"year": {
"type": "integer",
"maximum": 2100,
"minimum": 1900
}
}
},
"internal_handlers.APIResponse": {
"type": "object",
"properties": {
"data": {},
"error": {},
"success": {
"type": "boolean"
}
}
},
"internal_handlers.AddCollaboratorRequest": {
"type": "object",
"required": [
"permission",
"user_id"
],
"properties": {
"permission": {
"type": "string",
"enum": [
"read",
"write",
"admin"
]
},
"user_id": {
"type": "string"
}
}
},
"internal_handlers.AddQueueItemRequest": {
"type": "object",
"required": [
"track_id"
],
"properties": {
"track_id": {
"type": "string"
}
}
},
"internal_handlers.AddToSessionRequest": {
"type": "object",
"required": [
"track_id"
],
"properties": {
"track_id": {
"type": "string"
}
}
},
"internal_handlers.CreateCommentRequest": {
"type": "object",
"required": [
"content"
],
"properties": {
"content": {
"type": "string",
"maxLength": 5000,
"minLength": 1
},
"parent_id": {
"type": "string"
},
"timestamp": {
"description": "Position in seconds (0 = top-level, no specific time)",
"type": "number"
}
}
},
"internal_handlers.CreateOrderRequest": {
"type": "object",
"required": [
"items"
],
"properties": {
"items": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": [
"product_id"
],
"properties": {
"product_id": {
"type": "string"
}
}
}
},
"promo_code": {
"type": "string",
"maxLength": 50
}
}
},
"internal_handlers.CreatePlaylistRequest": {
"type": "object",
"required": [
"title"
],
"properties": {
"description": {
"type": "string",
"maxLength": 1000
},
"is_public": {
"type": "boolean"
},
"title": {
"type": "string",
"maxLength": 200,
"minLength": 1
}
}
},
"internal_handlers.CreateProductRequest": {
"type": "object",
"required": [
"price",
"product_type",
"title"
],
"properties": {
"bpm": {
"description": "v0.401 M1",
"type": "integer",
"maximum": 300,
"minimum": 1
},
"category": {
"type": "string",
"enum": [
"sample",
"beat",
"preset",
"pack"
]
},
"description": {
"type": "string",
"maxLength": 2000
},
"license_type": {
"type": "string",
"enum": [
"standard",
"exclusive",
"commercial"
]
},
"licenses": {
"description": "v0.401 M2: Product licenses (streaming, personal, commercial, exclusive)",
"type": "array",
"items": {
"type": "object",
"required": [
"license_type",
"price_cents"
],
"properties": {
"license_type": {
"type": "string",
"enum": [
"streaming",
"personal",
"commercial",
"exclusive"
]
},
"price_cents": {
"type": "integer",
"minimum": 0
},
"terms_text": {
"type": "string"
}
}
}
},
"musical_key": {
"type": "string",
"maxLength": 10
},
"price": {
"type": "number",
"minimum": 0
},
"product_type": {
"type": "string",
"enum": [
"track",
"pack",
"service"
]
},
"title": {
"type": "string",
"maxLength": 200,
"minLength": 3
},
"track_id": {
"description": "UUID string",
"type": "string"
}
}
},
"internal_handlers.DashboardResponse": {
"type": "object",
"properties": {
"library_preview": {
"$ref": "#/definitions/internal_handlers.LibraryPreview"
},
"recent_activity": {
"type": "array",
"items": {
"$ref": "#/definitions/internal_handlers.RecentActivity"
}
},
"stats": {
"$ref": "#/definitions/internal_handlers.DashboardStats"
}
}
},
"internal_handlers.DashboardStats": {
"type": "object",
"properties": {
"active_friends": {
"type": "integer"
},
"active_friends_change": {
"type": "string"
},
"favorites": {
"type": "integer"
},
"favorites_change": {
"type": "string"
},
"messages_sent": {
"type": "integer"
},
"messages_sent_change": {
"type": "string"
},
"period": {
"type": "string"
},
"tracks_played": {
"type": "integer"
},
"tracks_played_change": {
"type": "string"
}
}
},
"internal_handlers.DeleteAccountRequest": {
"type": "object",
"required": [
"confirm_text",
"password"
],
"properties": {
"confirm_text": {
"type": "string"
},
"keep_public_tracks": {
"description": "If true, public tracks remain (attributed to deleted account)",
"type": "boolean"
},
"password": {
"type": "string"
},
"reason": {
"type": "string"
}
}
},
"internal_handlers.DisableTwoFactorRequest": {
"type": "object",
"required": [
"password"
],
"properties": {
"password": {
"type": "string"
}
}
},
"internal_handlers.FrontendLogRequest": {
"type": "object",
"properties": {
"context": {
"type": "object",
"additionalProperties": true
},
"data": {},
"level": {
"type": "string"
},
"message": {
"type": "string"
},
"timestamp": {
"type": "string"
}
}
},
"internal_handlers.IceServer": {
"type": "object",
"properties": {
"credential": {
"type": "string"
},
"urls": {
"type": "array",
"items": {
"type": "string"
}
},
"username": {
"type": "string"
}
}
},
"internal_handlers.ImportPlaylistRequest": {
"type": "object",
"properties": {
"playlist": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"is_public": {
"type": "boolean"
},
"title": {
"type": "string"
}
}
},
"tracks": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
}
}
}
}
}
},
"internal_handlers.LibraryPreview": {
"type": "object",
"properties": {
"has_more": {
"type": "boolean"
},
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/internal_handlers.TrackPreview"
}
},
"total_count": {
"type": "integer"
}
}
},
"internal_handlers.RecentActivity": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"icon": {
"type": "string"
},
"id": {
"type": "string"
},
"metadata": {
"type": "object",
"additionalProperties": true
},
"timestamp": {
"type": "string"
},
"title": {
"type": "string"
},
"type": {
"type": "string"
}
}
},
"internal_handlers.ReorderTracksRequest": {
"type": "object",
"required": [
"track_ids"
],
"properties": {
"track_ids": {
"description": "Changed to []uuid.UUID",
"type": "array",
"minItems": 1,
"items": {
"type": "string"
}
}
}
},
"internal_handlers.RequestPasswordResetRequest": {
"type": "object",
"required": [
"email"
],
"properties": {
"email": {
"type": "string"
}
}
},
"internal_handlers.ResetPasswordRequest": {
"type": "object",
"required": [
"new_password",
"token"
],
"properties": {
"new_password": {
"type": "string",
"minLength": 12
},
"token": {
"type": "string"
}
}
},
"internal_handlers.SetupTwoFactorResponse": {
"type": "object",
"properties": {
"qr_code_url": {
"type": "string"
},
"recovery_codes": {
"type": "array",
"items": {
"type": "string"
}
},
"secret": {
"type": "string"
}
}
},
"internal_handlers.StreamTokenResponse": {
"type": "object",
"properties": {
"expires_in": {
"description": "seconds",
"type": "integer"
},
"token": {
"type": "string"
}
}
},
"internal_handlers.TrackPreview": {
"type": "object",
"properties": {
"artist": {
"type": "string"
},
"cover_art_path": {
"type": "string"
},
"created_at": {
"type": "string"
},
"duration": {
"type": "integer"
},
"id": {
"type": "string"
},
"like_count": {
"type": "integer"
},
"play_count": {
"type": "integer"
},
"title": {
"type": "string"
}
}
},
"internal_handlers.UpdateCollaboratorPermissionRequest": {
"type": "object",
"required": [
"permission"
],
"properties": {
"permission": {
"type": "string",
"enum": [
"read",
"write",
"admin"
]
}
}
},
"internal_handlers.UpdateCommentRequest": {
"type": "object",
"required": [
"content"
],
"properties": {
"content": {
"type": "string",
"maxLength": 5000,
"minLength": 1
}
}
},
"internal_handlers.UpdatePlaylistRequest": {
"type": "object",
"properties": {
"description": {
"type": "string",
"maxLength": 1000
},
"is_public": {
"type": "boolean"
},
"title": {
"type": "string",
"maxLength": 200,
"minLength": 1
}
}
},
"internal_handlers.UpdateProductRequest": {
"type": "object",
"properties": {
"bpm": {
"type": "integer",
"maximum": 300,
"minimum": 1
},
"category": {
"type": "string",
"enum": [
"sample",
"beat",
"preset",
"pack"
]
},
"description": {
"type": "string",
"maxLength": 2000
},
"licenses": {
"description": "v0.401 M2: Product licenses",
"type": "array",
"items": {
"type": "object",
"required": [
"license_type",
"price_cents"
],
"properties": {
"license_type": {
"type": "string",
"enum": [
"streaming",
"personal",
"commercial",
"exclusive"
]
},
"price_cents": {
"type": "integer",
"minimum": 0
},
"terms_text": {
"type": "string"
}
}
}
},
"musical_key": {
"type": "string",
"maxLength": 10
},
"price": {
"type": "number",
"minimum": 0
},
"status": {
"type": "string",
"enum": [
"draft",
"active",
"archived"
]
},
"title": {
"type": "string",
"maxLength": 200,
"minLength": 3
}
}
},
"internal_handlers.UpdateProfileRequest": {
"type": "object",
"properties": {
"banner_url": {
"type": "string",
"maxLength": 2048
},
"bio": {
"type": "string",
"maxLength": 500
},
"birthdate": {
"type": "string"
},
"first_name": {
"type": "string",
"maxLength": 100
},
"gender": {
"type": "string",
"enum": [
"Male",
"Female",
"Other",
"Prefer not to say"
]
},
"is_public": {
"type": "boolean"
},
"last_name": {
"type": "string",
"maxLength": 100
},
"location": {
"type": "string",
"maxLength": 100
},
"social_links": {
"type": "object",
"additionalProperties": true
},
"username": {
"type": "string",
"maxLength": 30,
"minLength": 3
}
}
},
"internal_handlers.ValidateRequest": {
"type": "object",
"required": [
"data",
"type"
],
"properties": {
"data": {
"description": "The data to validate",
"type": "array",
"items": {
"type": "integer"
}
},
"type": {
"description": "e.g., \"RegisterRequest\", \"LoginRequest\"",
"type": "string"
}
}
},
"internal_handlers.ValidateResponse": {
"type": "object",
"properties": {
"errors": {
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_dto.ValidationError"
}
},
"message": {
"type": "string"
},
"valid": {
"type": "boolean"
}
}
},
"internal_handlers.VerifyTwoFactorRequest": {
"type": "object",
"required": [
"code",
"secret"
],
"properties": {
"code": {
"description": "TOTP code to verify",
"type": "string"
},
"secret": {
"description": "Secret from setup step",
"type": "string"
}
}
},
"internal_handlers.WebRTCConfigResponse": {
"type": "object",
"properties": {
"iceServers": {
"type": "array",
"items": {
"$ref": "#/definitions/internal_handlers.IceServer"
}
}
}
},
"veza-backend-api_internal_core_marketplace.LicenseType": {
"type": "string",
"enum": [
"basic",
"premium",
"exclusive"
],
"x-enum-varnames": [
"LicenseBasic",
"LicensePremium",
"LicenseExclusive"
]
},
"veza-backend-api_internal_core_marketplace.Order": {
"type": "object",
"properties": {
"buyer_id": {
"type": "string"
},
"created_at": {
"type": "string"
},
"currency": {
"type": "string"
},
"discount_amount_cents": {
"type": "integer"
},
"hyperswitch_payment_id": {
"type": "string"
},
"id": {
"type": "string"
},
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_core_marketplace.OrderItem"
}
},
"payment_intent": {
"description": "Legacy / Stripe PaymentIntent ID",
"type": "string"
},
"payment_status": {
"description": "Hyperswitch payment status",
"type": "string"
},
"promo_code_id": {
"type": "string"
},
"refund_deadline": {
"description": "v0.12.0: 14-day refund deadline",
"type": "string"
},
"status": {
"description": "pending, completed, failed, refunded",
"type": "string"
},
"total_amount": {
"type": "number"
},
"updated_at": {
"type": "string"
}
}
},
"veza-backend-api_internal_core_marketplace.OrderItem": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"order_id": {
"type": "string"
},
"price": {
"type": "number"
},
"product_id": {
"type": "string"
}
}
},
"veza-backend-api_internal_core_marketplace.Product": {
"type": "object",
"properties": {
"avg_rating": {
"description": "v0.403 R1: Computed from product_reviews (not stored in DB)",
"type": "number"
},
"bpm": {
"description": "v0.401 M1: Métadonnées musicales et catégorie",
"type": "integer"
},
"category": {
"description": "sample, beat, preset, pack",
"type": "string"
},
"created_at": {
"type": "string"
},
"currency": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "string"
},
"images": {
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_core_marketplace.ProductImage"
}
},
"license_type": {
"$ref": "#/definitions/veza-backend-api_internal_core_marketplace.LicenseType"
},
"licenses": {
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_core_marketplace.ProductLicense"
}
},
"musical_key": {
"type": "string"
},
"previews": {
"description": "Relations",
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_core_marketplace.ProductPreview"
}
},
"price": {
"type": "number"
},
"product_type": {
"description": "\"track\", \"pack\", \"service\"",
"type": "string"
},
"review_count": {
"type": "integer"
},
"seller_id": {
"type": "string"
},
"status": {
"$ref": "#/definitions/veza-backend-api_internal_core_marketplace.ProductStatus"
},
"title": {
"type": "string"
},
"track_id": {
"description": "Liaison optionnelle avec un Track (si ProductType == \"track\")",
"type": "string"
},
"updated_at": {
"type": "string"
}
}
},
"veza-backend-api_internal_core_marketplace.ProductImage": {
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"id": {
"type": "string"
},
"product_id": {
"type": "string"
},
"sort_order": {
"type": "integer"
},
"url": {
"type": "string"
}
}
},
"veza-backend-api_internal_core_marketplace.ProductLicense": {
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"id": {
"type": "string"
},
"license_type": {
"description": "streaming, personal, commercial, exclusive",
"type": "string"
},
"price_cents": {
"type": "integer"
},
"product_id": {
"type": "string"
},
"terms_text": {
"type": "string"
}
}
},
"veza-backend-api_internal_core_marketplace.ProductPreview": {
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"duration_sec": {
"type": "integer"
},
"file_path": {
"type": "string"
},
"id": {
"type": "string"
},
"product_id": {
"type": "string"
}
}
},
"veza-backend-api_internal_core_marketplace.ProductStatus": {
"type": "string",
"enum": [
"draft",
"active",
"archived"
],
"x-enum-varnames": [
"ProductStatusDraft",
"ProductStatusActive",
"ProductStatusArchived"
]
},
"veza-backend-api_internal_dto.LoginRequest": {
"type": "object",
"required": [
"email",
"password"
],
"properties": {
"email": {
"type": "string"
},
"password": {
"type": "string"
},
"remember_me": {
"type": "boolean"
}
}
},
"veza-backend-api_internal_dto.LoginResponse": {
"type": "object",
"properties": {
"requires_2fa": {
"description": "BE-API-001: Flag indicating 2FA is required",
"type": "boolean"
},
"token": {
"$ref": "#/definitions/veza-backend-api_internal_dto.TokenResponse"
},
"user": {
"$ref": "#/definitions/veza-backend-api_internal_dto.UserResponse"
}
}
},
"veza-backend-api_internal_dto.RefreshRequest": {
"type": "object",
"required": [
"refresh_token"
],
"properties": {
"refresh_token": {
"type": "string"
}
}
},
"veza-backend-api_internal_dto.RegisterRequest": {
"type": "object",
"required": [
"email",
"password",
"password_confirmation"
],
"properties": {
"email": {
"type": "string"
},
"password": {
"type": "string",
"minLength": 12
},
"password_confirmation": {
"type": "string"
},
"username": {
"type": "string",
"maxLength": 50,
"minLength": 3
}
}
},
"veza-backend-api_internal_dto.RegisterResponse": {
"type": "object",
"properties": {
"message": {
"type": "string"
},
"user": {
"$ref": "#/definitions/veza-backend-api_internal_dto.UserResponse"
},
"verification_required": {
"type": "boolean"
}
}
},
"veza-backend-api_internal_dto.ResendVerificationRequest": {
"type": "object",
"required": [
"email"
],
"properties": {
"email": {
"type": "string"
}
}
},
"veza-backend-api_internal_dto.TokenResponse": {
"type": "object",
"properties": {
"access_token": {
"type": "string"
},
"expires_in": {
"type": "integer"
},
"refresh_token": {
"type": "string"
}
}
},
"veza-backend-api_internal_dto.UserResponse": {
"type": "object",
"properties": {
"email": {
"type": "string"
},
"id": {
"type": "string"
},
"username": {
"type": "string"
}
}
},
"veza-backend-api_internal_dto.ValidationError": {
"type": "object",
"properties": {
"field": {
"type": "string"
},
"message": {
"type": "string"
},
"value": {
"type": "string"
}
}
},
"veza-backend-api_internal_handlers.APIResponse": {
"type": "object",
"properties": {
"data": {},
"error": {},
"success": {
"type": "boolean"
}
}
},
"veza-backend-api_internal_models.Playlist": {
"type": "object",
"properties": {
"collaborators": {
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_models.PlaylistCollaborator"
}
},
"cover_url": {
"type": "string"
},
"created_at": {
"type": "string"
},
"description": {
"type": "string"
},
"follower_count": {
"type": "integer"
},
"id": {
"type": "string"
},
"is_default_favorites": {
"description": "v0.10.4 F136",
"type": "boolean"
},
"is_editorial": {
"description": "v0.10.4 F141",
"type": "boolean"
},
"is_public": {
"type": "boolean"
},
"title": {
"type": "string"
},
"track_count": {
"type": "integer"
},
"tracks": {
"type": "array",
"items": {
"$ref": "#/definitions/veza-backend-api_internal_models.PlaylistTrack"
}
},
"updated_at": {
"type": "string"
},
"user_id": {
"type": "string"
}
}
},
"veza-backend-api_internal_models.PlaylistCollaborator": {
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"id": {
"type": "string"
},
"permission": {
"$ref": "#/definitions/veza-backend-api_internal_models.PlaylistPermission"
},
"playlist_id": {
"type": "string"
},
"updated_at": {
"type": "string"
},
"user": {
"$ref": "#/definitions/veza-backend-api_internal_models.User"
},
"user_id": {
"type": "string"
}
}
},
"veza-backend-api_internal_models.PlaylistPermission": {
"type": "string",
"enum": [
"read",
"write",
"admin"
],
"x-enum-varnames": [
"PlaylistPermissionRead",
"PlaylistPermissionWrite",
"PlaylistPermissionAdmin"
]
},
"veza-backend-api_internal_models.PlaylistTrack": {
"type": "object",
"properties": {
"added_at": {
"type": "string"
},
"added_by": {
"type": "string"
},
"id": {
"type": "string"
},
"playlist_id": {
"type": "string"
},
"position": {
"type": "integer"
},
"track": {
"$ref": "#/definitions/veza-backend-api_internal_models.Track"
},
"track_id": {
"type": "string"
}
}
},
"veza-backend-api_internal_models.Track": {
"type": "object",
"properties": {
"album": {
"type": "string"
},
"artist": {
"type": "string"
},
"bitrate": {
"description": "kbps",
"type": "integer"
},
"bpm": {
"type": "integer"
},
"cover_art_path": {
"type": "string"
},
"created_at": {
"type": "string"
},
"creator_id": {
"type": "string"
},
"duration": {
"description": "seconds",
"type": "integer"
},
"file_id": {
"description": "NULL temporairement avant création fichier",
"type": "string"
},
"file_path": {
"type": "string"
},
"file_size": {
"description": "bytes",
"type": "integer"
},
"format": {
"description": "mp3, flac, wav, etc.",
"type": "string"
},
"genre": {
"type": "string"
},
"id": {
"type": "string"
},
"is_public": {
"type": "boolean"
},
"musical_key": {
"type": "string"
},
"sample_rate": {
"description": "Hz",
"type": "integer"
},
"status": {
"$ref": "#/definitions/veza-backend-api_internal_models.TrackStatus"
},
"status_message": {
"type": "string"
},
"stream_manifest_url": {
"type": "string"
},
"stream_status": {
"description": "pending, processing, ready, error",
"type": "string"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"title": {
"type": "string"
},
"updated_at": {
"type": "string"
},
"waveform_path": {
"type": "string"
},
"waveform_url": {
"type": "string"
},
"year": {
"type": "integer"
}
}
},
"veza-backend-api_internal_models.TrackStatus": {
"type": "string",
"enum": [
"uploading",
"processing",
"completed",
"failed"
],
"x-enum-varnames": [
"TrackStatusUploading",
"TrackStatusProcessing",
"TrackStatusCompleted",
"TrackStatusFailed"
]
},
"veza-backend-api_internal_models.User": {
"type": "object",
"properties": {
"avatar": {
"type": "string"
},
"banner_url": {
"type": "string"
},
"bio": {
"type": "string"
},
"birthdate": {
"type": "string"
},
"created_at": {
"type": "string"
},
"email": {
"type": "string"
},
"first_name": {
"type": "string"
},
"gender": {
"type": "string"
},
"id": {
"type": "string"
},
"is_active": {
"type": "boolean"
},
"is_admin": {
"type": "boolean"
},
"is_banned": {
"type": "boolean"
},
"is_public": {
"type": "boolean"
},
"is_verified": {
"type": "boolean"
},
"last_login_at": {
"type": "string"
},
"last_name": {
"type": "string"
},
"location": {
"type": "string"
},
"login_count": {
"type": "integer"
},
"password": {
"description": "Virtual field for input",
"type": "string"
},
"password_changed_at": {
"description": "F016: Password expiration tracking",
"type": "string"
},
"promoted_to_creator_at": {
"description": "v1.0.6: set the first time a user self-promotes to `role='creator'`\nvia POST /api/v1/users/me/upgrade-creator. NULL for users who never\ntook that path (still 'user', or promoted by an admin out-of-band).",
"type": "string"
},
"role": {
"type": "string"
},
"slug": {
"type": "string"
},
"social_links": {
"type": "string"
},
"token_version": {
"type": "integer"
},
"updated_at": {
"type": "string"
},
"username": {
"type": "string"
},
"username_changed_at": {
"type": "string"
}
}
},
"veza-backend-api_internal_response.APIResponse": {
"type": "object",
"properties": {
"data": {},
"error": {},
"success": {
"type": "boolean"
}
}
},
"veza-backend-api_internal_services.UpdateQueueRequest": {
"type": "object",
"properties": {
"current_position": {
"type": "integer"
},
"current_track_id": {
"type": "string"
},
"is_playing": {
"type": "boolean"
},
"item_order": {
"type": "array",
"items": {
"type": "string"
}
},
"repeat_mode": {
"type": "string"
},
"shuffle": {
"type": "boolean"
},
"volume": {
"type": "integer"
}
}
}
},
"securityDefinitions": {
"ApiKeyAuth": {
"description": "Developer API key (obtain from Developer Portal). Format: vza_xxxxx",
"type": "apiKey",
"name": "X-API-Key",
"in": "header"
},
"BearerAuth": {
"type": "apiKey",
"name": "Authorization",
"in": "header"
}
}
}