veza/veza-backend-api/openapi.yaml
senke ef386e0ae3 fix(backend): commit swagger annotation pass + missing handler methods
routes_users.go (already on main) calls settingsHandler.GetPreferences /
UpdatePreferences and gdprExportHandler.ExportJSON, but the methods only
existed in the working tree — main wouldn't compile, so deploy.yml's
build-backend job was stuck on the same compile error every run.

Bundles the WIP swagger annotation sweep across chat / marketplace /
role / settings / gdpr / etc. handlers with the regenerated swagger.json,
swagger.yaml, docs.go and openapi.yaml.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 10:16:57 +02:00

9750 lines
264 KiB
YAML

basePath: /api/v1
definitions:
internal_core_track.BatchDeleteRequest:
properties:
track_ids:
items:
type: string
minItems: 1
type: array
required:
- track_ids
type: object
internal_core_track.BatchUpdateRequest:
properties:
track_ids:
items:
type: string
minItems: 1
type: array
updates:
additionalProperties: true
type: object
required:
- track_ids
- updates
type: object
internal_core_track.CompleteChunkedUploadRequest:
properties:
upload_id:
type: string
required:
- upload_id
type: object
internal_core_track.CreateShareRequest:
properties:
expires_at:
type: string
permissions:
enum:
- read
- write
- admin
type: string
required:
- permissions
type: object
internal_core_track.InitiateChunkedUploadRequest:
properties:
filename:
type: string
total_chunks:
minimum: 1
type: integer
total_size:
minimum: 1
type: integer
required:
- filename
- total_chunks
- total_size
type: object
internal_core_track.RecordPlayRequest:
properties:
play_time:
minimum: 0
type: integer
type: object
internal_core_track.StreamCallbackRequest:
properties:
error:
type: string
manifest_url:
type: string
status:
enum:
- completed
- failed
- processing
type: string
required:
- status
type: object
internal_core_track.UpdateLyricsRequest:
properties:
content:
type: string
type: object
internal_core_track.UpdateTrackRequest:
properties:
album:
maxLength: 255
type: string
artist:
maxLength: 255
type: string
bpm:
maximum: 300
minimum: 0
type: integer
genre:
description: legacy, single
maxLength: 100
type: string
genres:
description: 'v0.10.1: max 3, taxonomy slugs'
items:
type: string
type: array
is_public:
type: boolean
musical_key:
maxLength: 10
type: string
tags:
description: 'v0.10.1: max 10, 30 chars each'
items:
type: string
type: array
title:
maxLength: 255
minLength: 1
type: string
year:
maximum: 2100
minimum: 1900
type: integer
type: object
internal_handlers.APIResponse:
properties:
data: {}
error: {}
success:
type: boolean
type: object
internal_handlers.AddCollaboratorRequest:
properties:
permission:
enum:
- read
- write
- admin
type: string
user_id:
type: string
required:
- permission
- user_id
type: object
internal_handlers.AddQueueItemRequest:
properties:
track_id:
type: string
required:
- track_id
type: object
internal_handlers.AddReactionRequest:
properties:
emoji:
maxLength: 50
type: string
required:
- emoji
type: object
internal_handlers.AddToCartRequest:
properties:
product_id:
type: string
quantity:
type: integer
required:
- product_id
type: object
internal_handlers.AddToSessionRequest:
properties:
track_id:
type: string
required:
- track_id
type: object
internal_handlers.AddToWishlistRequest:
properties:
product_id:
type: string
required:
- product_id
type: object
internal_handlers.AdminActionRequest:
properties:
note:
maxLength: 2000
type: string
type: object
internal_handlers.CheckoutRequest:
properties:
promo_code:
maxLength: 50
type: string
type: object
internal_handlers.ConnectOnboardRequest:
properties:
refresh_url:
type: string
return_url:
type: string
type: object
internal_handlers.ContentSettings:
properties:
autoplay:
type: boolean
explicit_content:
type: boolean
type: object
internal_handlers.CreateCommentRequest:
properties:
content:
maxLength: 5000
minLength: 1
type: string
parent_id:
type: string
timestamp:
description: Position in seconds (0 = top-level, no specific time)
type: number
required:
- content
type: object
internal_handlers.CreateOrderRequest:
properties:
items:
items:
properties:
product_id:
type: string
required:
- product_id
type: object
minItems: 1
type: array
promo_code:
maxLength: 50
type: string
required:
- items
type: object
internal_handlers.CreatePlaylistRequest:
properties:
description:
maxLength: 1000
type: string
is_public:
type: boolean
title:
maxLength: 200
minLength: 1
type: string
required:
- title
type: object
internal_handlers.CreateProductRequest:
properties:
bpm:
description: v0.401 M1
maximum: 300
minimum: 1
type: integer
category:
enum:
- sample
- beat
- preset
- pack
type: string
description:
maxLength: 2000
type: string
license_type:
enum:
- standard
- exclusive
- commercial
type: string
licenses:
description: 'v0.401 M2: Product licenses (streaming, personal, commercial,
exclusive)'
items:
properties:
license_type:
enum:
- streaming
- personal
- commercial
- exclusive
type: string
price_cents:
minimum: 0
type: integer
terms_text:
type: string
required:
- license_type
- price_cents
type: object
type: array
musical_key:
maxLength: 10
type: string
price:
minimum: 0
type: number
product_type:
enum:
- track
- pack
- service
type: string
title:
maxLength: 200
minLength: 3
type: string
track_id:
description: UUID string
type: string
required:
- price
- product_type
- title
type: object
internal_handlers.CreateReviewRequest:
properties:
comment:
maxLength: 2000
type: string
rating:
maximum: 5
minimum: 1
type: integer
required:
- rating
type: object
internal_handlers.CreateVerificationRequest:
properties:
return_url:
type: string
type: object
internal_handlers.DashboardResponse:
properties:
library_preview:
$ref: '#/definitions/internal_handlers.LibraryPreview'
recent_activity:
items:
$ref: '#/definitions/internal_handlers.RecentActivity'
type: array
stats:
$ref: '#/definitions/internal_handlers.DashboardStats'
type: object
internal_handlers.DashboardStats:
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
type: object
internal_handlers.DeleteAccountRequest:
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
required:
- confirm_text
- password
type: object
internal_handlers.DisableTwoFactorRequest:
properties:
password:
type: string
required:
- password
type: object
internal_handlers.FrontendLogRequest:
properties:
context:
additionalProperties: true
type: object
data: {}
level:
type: string
message:
type: string
timestamp:
type: string
type: object
internal_handlers.IceServer:
properties:
credential:
type: string
urls:
items:
type: string
type: array
username:
type: string
type: object
internal_handlers.ImportPlaylistRequest:
properties:
playlist:
properties:
description:
type: string
is_public:
type: boolean
title:
type: string
type: object
tracks:
items:
properties:
id:
type: string
type: object
type: array
type: object
internal_handlers.LibraryPreview:
properties:
has_more:
type: boolean
items:
items:
$ref: '#/definitions/internal_handlers.TrackPreview'
type: array
total_count:
type: integer
type: object
internal_handlers.NotificationSettings:
properties:
browser_notifications:
type: boolean
email_marketing:
type: boolean
email_notifications:
type: boolean
email_on_comment:
type: boolean
email_on_follow:
type: boolean
email_on_like:
type: boolean
email_on_mention:
type: boolean
email_on_message:
type: boolean
push_notifications:
type: boolean
type: object
internal_handlers.PreferenceSettings:
properties:
language:
description: ISO 639-1
type: string
theme:
description: light, dark, auto
type: string
timezone:
type: string
type: object
internal_handlers.PrivacySettings:
properties:
allow_search_indexing:
type: boolean
show_activity:
type: boolean
type: object
internal_handlers.RecentActivity:
properties:
description:
type: string
icon:
type: string
id:
type: string
metadata:
additionalProperties: true
type: object
timestamp:
type: string
title:
type: string
type:
type: string
type: object
internal_handlers.RefundOrderRequest:
properties:
details:
maxLength: 2000
type: string
reason:
maxLength: 500
type: string
type: object
internal_handlers.ReorderTracksRequest:
properties:
track_ids:
description: Changed to []uuid.UUID
items:
type: string
minItems: 1
type: array
required:
- track_ids
type: object
internal_handlers.RequestPasswordResetRequest:
properties:
email:
type: string
required:
- email
type: object
internal_handlers.ResetPasswordRequest:
properties:
new_password:
minLength: 12
type: string
token:
type: string
required:
- new_password
- token
type: object
internal_handlers.SetupTwoFactorResponse:
properties:
qr_code_url:
type: string
recovery_codes:
items:
type: string
type: array
secret:
type: string
type: object
internal_handlers.StreamTokenResponse:
properties:
expires_in:
description: seconds
type: integer
token:
type: string
type: object
internal_handlers.SubmitNoticeRequest:
properties:
claimant_address:
maxLength: 2000
minLength: 5
type: string
claimant_email:
maxLength: 255
type: string
claimant_name:
maxLength: 255
minLength: 2
type: string
infringing_track_id:
type: string
sworn_statement:
description: |-
SwornStatement MUST be true — it's the "under penalty of perjury"
acknowledgement (DMCA § 512(c)(3)(A)(vi)). No checkbox = no notice.
type: boolean
work_description:
maxLength: 5000
minLength: 10
type: string
required:
- claimant_address
- claimant_email
- claimant_name
- sworn_statement
- work_description
type: object
internal_handlers.SubmitTicketRequest:
properties:
category:
type: string
email:
type: string
message:
maxLength: 5000
minLength: 10
type: string
subject:
maxLength: 500
minLength: 3
type: string
required:
- email
- message
- subject
type: object
internal_handlers.TrackPreview:
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
type: object
internal_handlers.UpdateCollaboratorPermissionRequest:
properties:
permission:
enum:
- read
- write
- admin
type: string
required:
- permission
type: object
internal_handlers.UpdateCommentRequest:
properties:
content:
maxLength: 5000
minLength: 1
type: string
required:
- content
type: object
internal_handlers.UpdatePlaylistRequest:
properties:
description:
maxLength: 1000
type: string
is_public:
type: boolean
title:
maxLength: 200
minLength: 1
type: string
type: object
internal_handlers.UpdateProductImagesRequest:
properties:
images:
items:
properties:
sort_order:
type: integer
url:
maxLength: 512
type: string
required:
- url
type: object
type: array
required:
- images
type: object
internal_handlers.UpdateProductRequest:
properties:
bpm:
maximum: 300
minimum: 1
type: integer
category:
enum:
- sample
- beat
- preset
- pack
type: string
description:
maxLength: 2000
type: string
licenses:
description: 'v0.401 M2: Product licenses'
items:
properties:
license_type:
enum:
- streaming
- personal
- commercial
- exclusive
type: string
price_cents:
minimum: 0
type: integer
terms_text:
type: string
required:
- license_type
- price_cents
type: object
type: array
musical_key:
maxLength: 10
type: string
price:
minimum: 0
type: number
status:
enum:
- draft
- active
- archived
type: string
title:
maxLength: 200
minLength: 3
type: string
type: object
internal_handlers.UpdateProfileRequest:
properties:
banner_url:
maxLength: 2048
type: string
bio:
maxLength: 500
type: string
birthdate:
type: string
first_name:
maxLength: 100
type: string
gender:
enum:
- Male
- Female
- Other
- Prefer not to say
type: string
is_public:
type: boolean
last_name:
maxLength: 100
type: string
location:
maxLength: 100
type: string
social_links:
additionalProperties: true
type: object
username:
maxLength: 30
minLength: 3
type: string
type: object
internal_handlers.UserSettingsResponse:
properties:
content:
$ref: '#/definitions/internal_handlers.ContentSettings'
notifications:
$ref: '#/definitions/internal_handlers.NotificationSettings'
preferences:
$ref: '#/definitions/internal_handlers.PreferenceSettings'
privacy:
$ref: '#/definitions/internal_handlers.PrivacySettings'
type: object
internal_handlers.ValidateRequest:
properties:
data:
description: The data to validate
items:
type: integer
type: array
type:
description: e.g., "RegisterRequest", "LoginRequest"
type: string
required:
- data
- type
type: object
internal_handlers.ValidateResponse:
properties:
errors:
items:
$ref: '#/definitions/veza-backend-api_internal_dto.ValidationError'
type: array
message:
type: string
valid:
type: boolean
type: object
internal_handlers.VerifyTwoFactorRequest:
properties:
code:
description: TOTP code to verify
type: string
secret:
description: Secret from setup step
type: string
required:
- code
- secret
type: object
internal_handlers.WebRTCConfigResponse:
properties:
iceServers:
items:
$ref: '#/definitions/internal_handlers.IceServer'
type: array
type: object
veza-backend-api_internal_core_marketplace.CartItem:
properties:
created_at:
type: string
id:
type: string
product:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.Product'
product_id:
type: string
quantity:
type: integer
updated_at:
type: string
user_id:
type: string
type: object
veza-backend-api_internal_core_marketplace.LicenseType:
enum:
- basic
- premium
- exclusive
type: string
x-enum-varnames:
- LicenseBasic
- LicensePremium
- LicenseExclusive
veza-backend-api_internal_core_marketplace.Order:
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:
items:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.OrderItem'
type: array
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
type: object
veza-backend-api_internal_core_marketplace.OrderItem:
properties:
id:
type: string
order_id:
type: string
price:
type: number
product_id:
type: string
type: object
veza-backend-api_internal_core_marketplace.Product:
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:
items:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.ProductImage'
type: array
license_type:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.LicenseType'
licenses:
items:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.ProductLicense'
type: array
musical_key:
type: string
preview_enabled:
description: |-
v1.0.9 W4 Day 17 — creator-opt-in 30s pre-listen for marketplace
products. When true, anonymous /api/v1/marketplace/products/:id/preview
returns a streaming URL capped to ~30s. Trust model is documented
in the handler — client-side cutoff is sufficient for the
"tease-to-buy" use case ; not anti-rip.
type: boolean
previews:
description: Relations
items:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.ProductPreview'
type: array
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
type: object
veza-backend-api_internal_core_marketplace.ProductImage:
properties:
created_at:
type: string
id:
type: string
product_id:
type: string
sort_order:
type: integer
url:
type: string
type: object
veza-backend-api_internal_core_marketplace.ProductLicense:
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
type: object
veza-backend-api_internal_core_marketplace.ProductPreview:
properties:
created_at:
type: string
duration_sec:
type: integer
file_path:
type: string
id:
type: string
product_id:
type: string
type: object
veza-backend-api_internal_core_marketplace.ProductReview:
properties:
buyer_id:
type: string
comment:
type: string
created_at:
type: string
id:
type: string
order_id:
type: string
product_id:
type: string
rating:
description: 1-5
type: integer
type: object
veza-backend-api_internal_core_marketplace.ProductStatus:
enum:
- draft
- active
- archived
type: string
x-enum-varnames:
- ProductStatusDraft
- ProductStatusActive
- ProductStatusArchived
veza-backend-api_internal_core_marketplace.SellerPayout:
properties:
amount_cents:
type: integer
created_at:
type: string
currency:
type: string
error_message:
type: string
external_payout_id:
type: string
id:
type: string
payout_method:
type: string
processed_at:
type: string
scheduled_at:
type: string
seller_id:
type: string
status:
description: pending, processing, completed, failed
type: string
type: object
veza-backend-api_internal_core_marketplace.SellerTransfer:
properties:
amount_cents:
type: integer
commission_rate:
description: v0.12.0
type: number
created_at:
type: string
currency:
type: string
error_message:
type: string
id:
type: string
next_retry_at:
type: string
order_id:
type: string
platform_fee_cents:
type: integer
retry_count:
type: integer
seller_id:
type: string
status:
type: string
stripe_reversal_id:
description: |-
StripeReversalID is populated by the v1.0.7 item B reversal worker
when a refund triggers a reverse-charge against the transfer.
Empty for transfers that never got reversed. Unique when non-empty
(partial UNIQUE index in migration 981).
type: string
stripe_transfer_id:
type: string
updated_at:
type: string
type: object
veza-backend-api_internal_core_marketplace.WishlistItem:
properties:
created_at:
type: string
id:
type: string
product:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.Product'
product_id:
type: string
user_id:
type: string
type: object
veza-backend-api_internal_dto.LoginRequest:
properties:
email:
type: string
password:
type: string
remember_me:
type: boolean
required:
- email
- password
type: object
veza-backend-api_internal_dto.LoginResponse:
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'
type: object
veza-backend-api_internal_dto.RefreshRequest:
properties:
refresh_token:
type: string
required:
- refresh_token
type: object
veza-backend-api_internal_dto.RegisterRequest:
properties:
email:
type: string
password:
minLength: 12
type: string
password_confirmation:
type: string
username:
maxLength: 50
minLength: 3
type: string
required:
- email
- password
- password_confirmation
type: object
veza-backend-api_internal_dto.RegisterResponse:
properties:
message:
type: string
user:
$ref: '#/definitions/veza-backend-api_internal_dto.UserResponse'
verification_required:
type: boolean
type: object
veza-backend-api_internal_dto.ResendVerificationRequest:
properties:
email:
type: string
required:
- email
type: object
veza-backend-api_internal_dto.TokenResponse:
properties:
access_token:
type: string
expires_in:
type: integer
refresh_token:
type: string
type: object
veza-backend-api_internal_dto.UserResponse:
properties:
email:
type: string
id:
type: string
username:
type: string
type: object
veza-backend-api_internal_dto.ValidationError:
properties:
field:
type: string
message:
type: string
value:
type: string
type: object
veza-backend-api_internal_handlers.APIResponse:
properties:
data: {}
error: {}
success:
type: boolean
type: object
veza-backend-api_internal_models.Announcement:
properties:
content:
type: string
created_at:
type: string
created_by:
type: string
ends_at:
type: string
id:
type: string
is_active:
type: boolean
starts_at:
type: string
title:
type: string
type:
type: string
type: object
veza-backend-api_internal_models.FeatureFlag:
properties:
description:
type: string
enabled:
type: boolean
name:
type: string
updated_at:
type: string
type: object
veza-backend-api_internal_models.Playlist:
properties:
collaborators:
items:
$ref: '#/definitions/veza-backend-api_internal_models.PlaylistCollaborator'
type: array
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:
items:
$ref: '#/definitions/veza-backend-api_internal_models.PlaylistTrack'
type: array
updated_at:
type: string
user_id:
type: string
type: object
veza-backend-api_internal_models.PlaylistCollaborator:
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
type: object
veza-backend-api_internal_models.PlaylistPermission:
enum:
- read
- write
- admin
type: string
x-enum-varnames:
- PlaylistPermissionRead
- PlaylistPermissionWrite
- PlaylistPermissionAdmin
veza-backend-api_internal_models.PlaylistTrack:
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
type: object
veza-backend-api_internal_models.Role:
properties:
created_at:
type: string
description:
type: string
display_name:
type: string
id:
type: string
is_active:
type: boolean
is_system:
type: boolean
name:
type: string
updated_at:
type: string
type: object
veza-backend-api_internal_models.Track:
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:
items:
type: string
type: array
title:
type: string
updated_at:
type: string
waveform_path:
type: string
waveform_url:
type: string
year:
type: integer
type: object
veza-backend-api_internal_models.TrackStatus:
enum:
- uploading
- processing
- completed
- failed
type: string
x-enum-varnames:
- TrackStatusUploading
- TrackStatusProcessing
- TrackStatusCompleted
- TrackStatusFailed
veza-backend-api_internal_models.User:
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'`
via POST /api/v1/users/me/upgrade-creator. NULL for users who never
took 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
type: object
veza-backend-api_internal_response.APIResponse:
properties:
data: {}
error: {}
success:
type: boolean
type: object
veza-backend-api_internal_services.CreateAnnouncementRequest:
properties:
content:
type: string
ends_at:
type: string
is_active:
type: boolean
starts_at:
type: string
title:
type: string
type:
description: info, warning, error
type: string
required:
- content
- title
type: object
veza-backend-api_internal_services.UpdateQueueRequest:
properties:
current_position:
type: integer
current_track_id:
type: string
is_playing:
type: boolean
item_order:
items:
type: string
type: array
repeat_mode:
type: string
shuffle:
type: boolean
volume:
type: integer
type: object
veza-backend-api_internal_types.ContentSettings:
properties:
explicit_content:
type: boolean
type: object
veza-backend-api_internal_types.NotificationSettings:
properties:
comments:
type: boolean
email:
type: boolean
followers:
type: boolean
in_app:
type: boolean
likes:
type: boolean
mentions:
type: boolean
playlist:
type: boolean
push:
type: boolean
type: object
veza-backend-api_internal_types.PreferenceSettings:
properties:
accentHue:
description: 'v0.801: 0-360'
type: integer
contrast:
description: 'v0.801: normal, high'
type: string
date_format:
description: 'v0.10.8: Format de date (e.g. YYYY-MM-DD)'
type: string
density:
description: 'v0.801: comfortable, compact'
type: string
fontSize:
description: 'v0.801: in px (e.g. 16)'
type: integer
language:
description: ISO 639-1
type: string
theme:
description: 'v0.801: light, dark, auto'
type: string
timezone:
description: IANA Timezone
type: string
type: object
veza-backend-api_internal_types.PrivacySettings:
properties:
playlists_public:
type: boolean
profile_visibility:
type: string
type: object
veza-backend-api_internal_types.UpdateSettingsRequest:
properties:
content:
$ref: '#/definitions/veza-backend-api_internal_types.ContentSettings'
notifications:
$ref: '#/definitions/veza-backend-api_internal_types.NotificationSettings'
preferences:
$ref: '#/definitions/veza-backend-api_internal_types.PreferenceSettings'
privacy:
$ref: '#/definitions/veza-backend-api_internal_types.PrivacySettings'
type: object
veza-backend-api_internal_upload.BatchUploadResponse:
properties:
errors:
description: General errors (if any)
items:
type: string
type: array
failed:
description: Number of failed uploads
type: integer
results:
description: Individual file results
items:
$ref: '#/definitions/veza-backend-api_internal_upload.BatchUploadResult'
type: array
successful:
description: Number of successful uploads
type: integer
total_files:
description: Total files in batch
type: integer
type: object
veza-backend-api_internal_upload.BatchUploadResult:
properties:
error:
description: Error message (if failed)
type: string
file_name:
description: Original filename
type: string
file_size:
description: File size in bytes
type: integer
file_type:
description: File type
type: string
index:
description: File index (1-based)
type: integer
status:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_upload.UploadStatus'
description: Upload status
upload_id:
description: Upload ID (if successful)
type: string
type: object
veza-backend-api_internal_upload.StandardUploadResponse:
properties:
bytes_uploaded:
description: Bytes uploaded so far
type: integer
checksum:
description: File checksum (SHA-256)
type: string
created_at:
description: Timestamps
type: string
expires_at:
description: Expiration time (if applicable)
type: string
file_name:
description: File information
type: string
file_size:
description: File size in bytes
type: integer
file_type:
description: 'File type: "audio", "image", "video"'
type: string
id:
description: Upload identification
type: string
is_processed:
description: Processing information
type: boolean
mime_type:
description: MIME type
type: string
processed_at:
description: Processing completion time
type: string
processing_error:
description: Processing error (if any)
type: string
progress:
description: Progress percentage (0-100)
type: integer
status:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_upload.UploadStatus'
description: Upload status
storage_path:
description: Storage path
type: string
storage_provider:
description: 'Storage provider: "s3", "local", etc.'
type: string
thumbnail_url:
description: Thumbnail URL (if applicable)
type: string
track_id:
description: Track ID (if applicable)
type: string
updated_at:
description: Last update time (ISO 8601)
type: string
url:
description: Storage information
type: string
virus_scan_result:
description: 'Scan result: "clean", "infected", "error"'
type: string
virus_scanned:
description: Security information
type: boolean
virus_scanned_at:
description: Scan timestamp
type: string
type: object
veza-backend-api_internal_upload.UploadLimits:
properties:
allowed_extensions:
description: Allowed file extensions
items:
type: string
type: array
allowed_types:
description: Allowed MIME types
items:
type: string
type: array
max_size:
description: Human-readable max size (e.g., "100MB")
type: string
max_size_bytes:
description: Max size in bytes
type: integer
type: object
veza-backend-api_internal_upload.UploadLimitsResponse:
properties:
audio:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_upload.UploadLimits'
description: Audio file limits
image:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_upload.UploadLimits'
description: Image file limits
video:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_upload.UploadLimits'
description: Video file limits
type: object
veza-backend-api_internal_upload.UploadProgressResponse:
properties:
bytes_uploaded:
description: Bytes uploaded
type: integer
estimated_time_remaining:
description: Seconds remaining (if available)
type: integer
id:
description: Upload ID
type: string
message:
description: Status message
type: string
progress:
description: Progress percentage (0-100)
type: integer
status:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_upload.UploadStatus'
description: Current status
total_bytes:
description: Total bytes
type: integer
updated_at:
description: Last update time (ISO 8601)
type: string
type: object
veza-backend-api_internal_upload.UploadStatus:
enum:
- pending
- uploading
- processing
- completed
- failed
- cancelled
type: string
x-enum-varnames:
- UploadStatusPending
- UploadStatusUploading
- UploadStatusProcessing
- UploadStatusCompleted
- UploadStatusFailed
- UploadStatusCancelled
host: localhost:18080
info:
contact:
email: support@veza.fr
name: API Support
url: https://veza.fr/support
description: Backend API for Veza platform.
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
termsOfService: http://swagger.io/terms/
title: Veza Backend API
version: 1.2.0
paths:
/admin/dmca/notices:
get:
parameters:
- description: Page number (1-based, default 1)
in: query
name: page
type: integer
- description: Page size (max 100, default 20)
in: query
name: limit
type: integer
produces:
- application/json
responses:
"200":
description: Paginated pending queue
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"403":
description: Forbidden (admin required)
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: List pending DMCA notices (admin queue)
tags:
- DMCA-Admin
/admin/dmca/notices/{id}/dismiss:
post:
consumes:
- application/json
parameters:
- description: Notice UUID
in: path
name: id
required: true
type: string
- description: Optional note
in: body
name: request
schema:
$ref: '#/definitions/internal_handlers.AdminActionRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"404":
description: Notice not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"409":
description: Notice not in pending state
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Reject a DMCA notice (admin)
tags:
- DMCA-Admin
/admin/dmca/notices/{id}/takedown:
post:
consumes:
- application/json
description: Atomically transitions notice to status=takedown, sets takedown_at,
and flips the referenced track to is_public=false + dmca_blocked=true.
parameters:
- description: Notice UUID
in: path
name: id
required: true
type: string
- description: Optional note
in: body
name: request
schema:
$ref: '#/definitions/internal_handlers.AdminActionRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"404":
description: Notice not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"409":
description: Notice not in pending state
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"410":
description: Track no longer exists
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Honor a DMCA notice (admin)
tags:
- DMCA-Admin
/api/v1/admin/feature-flags:
get:
consumes:
- application/json
description: Get a list of all feature flags and their current status. Admin
only.
produces:
- application/json
responses:
"200":
description: OK
schema:
properties:
feature_flags:
type: array
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: List all feature flags
tags:
- Admin
/api/v1/admin/feature-flags/{name}/toggle:
put:
consumes:
- application/json
description: Enable or disable a specific feature flag. Admin only.
parameters:
- description: Flag name
in: path
name: name
required: true
type: string
- description: Toggle data
in: body
name: data
required: true
schema:
properties:
enabled:
type: boolean
type: object
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/veza-backend-api_internal_models.FeatureFlag'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Toggle feature flag
tags:
- Admin
/api/v1/announcements:
get:
consumes:
- application/json
description: Get a list of all announcements, including expired ones. Admin
only.
produces:
- application/json
responses:
"200":
description: OK
schema:
properties:
announcements:
type: array
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: List all announcements
tags:
- Admin
post:
consumes:
- application/json
description: Create a new platform announcement. Admin only.
parameters:
- description: Announcement data
in: body
name: announcement
required: true
schema:
$ref: '#/definitions/veza-backend-api_internal_services.CreateAnnouncementRequest'
produces:
- application/json
responses:
"201":
description: Created
schema:
$ref: '#/definitions/veza-backend-api_internal_models.Announcement'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Create announcement
tags:
- Admin
/api/v1/announcements/{id}:
delete:
consumes:
- application/json
description: Permanently delete an announcement. Admin only.
parameters:
- description: Announcement ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
properties:
message:
type: string
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Delete announcement
tags:
- Admin
/api/v1/announcements/active:
get:
consumes:
- application/json
description: Get a list of currently active announcements. Public access.
produces:
- application/json
responses:
"200":
description: OK
schema:
properties:
announcements:
type: array
type: object
summary: Get active announcements
tags:
- Admin
/api/v1/chat/rooms/{roomId}/attachments:
post:
consumes:
- multipart/form-data
description: Upload a file (audio, image, PDF) as a chat attachment. Max 50MB.
parameters:
- description: Room ID
in: path
name: roomId
required: true
type: string
- description: Attachment file
in: formData
name: file
required: true
type: file
produces:
- application/json
responses:
"201":
description: Created
schema:
properties:
file_id:
type: string
file_name:
type: string
file_size:
type: integer
file_type:
type: string
url:
type: string
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'
security:
- BearerAuth: []
summary: Upload chat attachment
tags:
- Chat
/api/v1/chat/rooms/{roomId}/messages/{messageId}/reactions:
delete:
consumes:
- application/json
description: Remove an emoji reaction from a specific chat message.
parameters:
- description: Room ID
in: path
name: roomId
required: true
type: string
- description: Message ID
in: path
name: messageId
required: true
type: string
- description: Specific emoji to remove
in: query
name: emoji
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
properties:
success:
type: boolean
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"403":
description: Forbidden
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Remove reaction
tags:
- Chat
post:
consumes:
- application/json
description: Add an emoji reaction to a specific chat message.
parameters:
- description: Room ID
in: path
name: roomId
required: true
type: string
- description: Message ID
in: path
name: messageId
required: true
type: string
- description: Reaction emoji
in: body
name: reaction
required: true
schema:
$ref: '#/definitions/internal_handlers.AddReactionRequest'
produces:
- application/json
responses:
"201":
description: Created
schema:
properties:
reaction:
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"403":
description: Forbidden
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Add reaction
tags:
- Chat
/api/v1/chat/rooms/{roomId}/messages/search:
get:
consumes:
- application/json
description: Search for text content within a specific chat room.
parameters:
- description: Room ID
in: path
name: roomId
required: true
type: string
- description: Search query
in: query
name: q
required: true
type: string
- default: 20
description: Limit
in: query
name: limit
type: integer
- default: 0
description: Offset
in: query
name: offset
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
properties:
messages:
type: array
total:
type: integer
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"403":
description: Forbidden
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Search messages
tags:
- Chat
/api/v1/commerce/cart:
get:
consumes:
- application/json
description: Get the authenticated user's active shopping cart.
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
items:
type: array
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get cart
tags:
- Marketplace
/api/v1/commerce/cart/checkout:
post:
consumes:
- application/json
description: Convert the current shopping cart into a final order.
parameters:
- description: Checkout options
in: body
name: checkout
required: true
schema:
$ref: '#/definitions/internal_handlers.CheckoutRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
order_id:
type: string
type: object
type: object
"400":
description: Validation Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Checkout
tags:
- Marketplace
/api/v1/commerce/cart/items:
post:
consumes:
- application/json
description: Add a product to the user's shopping cart.
parameters:
- description: Cart item data
in: body
name: item
required: true
schema:
$ref: '#/definitions/internal_handlers.AddToCartRequest'
produces:
- application/json
responses:
"201":
description: Created
schema:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.CartItem'
"400":
description: Validation Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Add to cart
tags:
- Marketplace
/api/v1/commerce/cart/items/{id}:
delete:
consumes:
- application/json
description: Remove an item from the user's active shopping cart.
parameters:
- description: Cart Item ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: Removed from cart
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"400":
description: Invalid ID
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Remove from cart
tags:
- Marketplace
/api/v1/commerce/promo/{code}:
get:
consumes:
- application/json
description: Check if a promo code is valid and return the discount details.
parameters:
- description: Promo Code
in: path
name: code
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
type: object
type: object
"404":
description: Invalid or expired code
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Validate promo code
tags:
- Marketplace
/api/v1/dashboard:
get:
consumes:
- application/json
description: Get aggregated dashboard data including stats, recent activity,
and library preview
parameters:
- description: 'Number of recent activity items (default: 10)'
in: query
name: activity_limit
type: integer
- description: 'Number of library items (default: 5)'
in: query
name: library_limit
type: integer
- description: 'Time period for statistics: 7d, 30d, 90d, all (default: 30d)'
in: query
name: stats_period
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
$ref: '#/definitions/internal_handlers.DashboardResponse'
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal server error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get Dashboard Data
tags:
- Dashboard
/api/v1/logs/frontend:
post:
consumes:
- application/json
description: Receive and store a log entry from the frontend application
parameters:
- description: Frontend log entry
in: body
name: log
required: true
schema:
$ref: '#/definitions/internal_handlers.FrontendLogRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
received:
type: boolean
type: object
type: object
"400":
description: Invalid log entry
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal server error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Receive frontend log
tags:
- Logging
/api/v1/marketplace/download/{product_id}:
get:
consumes:
- application/json
description: Get a secure download URL for a purchased product
parameters:
- description: Product ID
in: path
name: product_id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
additionalProperties:
type: string
type: object
"403":
description: No license
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"404":
description: Not Found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get download URL
tags:
- Marketplace
/api/v1/marketplace/licenses/mine:
get:
consumes:
- application/json
description: Get a list of all product licenses purchased by the authenticated
user.
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.ProductLicense'
type: array
security:
- BearerAuth: []
summary: Get my licenses
tags:
- Marketplace
/api/v1/marketplace/orders:
get:
consumes:
- application/json
description: Get all orders for the authenticated user
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.Order'
type: array
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: List user orders
tags:
- Marketplace
post:
consumes:
- application/json
description: Purchase products
parameters:
- description: Order items
in: body
name: order
required: true
schema:
$ref: '#/definitions/internal_handlers.CreateOrderRequest'
produces:
- application/json
responses:
"201":
description: Created
schema:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.Order'
"400":
description: Validation Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Create a new order
tags:
- Marketplace
/api/v1/marketplace/orders/{id}:
get:
consumes:
- application/json
description: Get details of a specific order (only order owner can access)
parameters:
- description: Order ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.Order'
"400":
description: Validation Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"403":
description: Forbidden - Not order owner
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"404":
description: Order not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get order details
tags:
- Marketplace
/api/v1/marketplace/orders/{id}/invoice:
get:
description: Generate and download a PDF invoice for a specific order.
parameters:
- description: Order ID
in: path
name: id
required: true
type: string
produces:
- application/pdf
responses:
"200":
description: PDF Invoice
schema:
type: file
"403":
description: Forbidden
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"404":
description: Order not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get order invoice
tags:
- Marketplace
/api/v1/marketplace/orders/{id}/refund:
post:
consumes:
- application/json
description: Initiate a refund for a completed order. Allowed for buyer, seller,
or admin.
parameters:
- description: Order ID
in: path
name: id
required: true
type: string
- description: Refund data
in: body
name: refund
required: true
schema:
$ref: '#/definitions/internal_handlers.RefundOrderRequest'
produces:
- application/json
responses:
"200":
description: Refund initiated
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"400":
description: Validation Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"403":
description: Forbidden
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Refund an order
tags:
- Marketplace
/api/v1/marketplace/products:
get:
consumes:
- application/json
description: List marketplace products with filters
parameters:
- description: Product status
in: query
name: status
type: string
- description: Seller ID
in: query
name: seller_id
type: string
- description: Search query
in: query
name: q
type: string
- description: Product type (track, pack, service)
in: query
name: type
type: string
- description: Minimum price
in: query
name: min_price
type: number
- description: Maximum price
in: query
name: max_price
type: number
- description: Page number
in: query
name: page
type: integer
- description: Items per page
in: query
name: limit
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.Product'
type: array
summary: List products
tags:
- Marketplace
post:
consumes:
- application/json
description: Create a product (Track, Pack, Service) for sale
parameters:
- description: Product info
in: body
name: product
required: true
schema:
$ref: '#/definitions/internal_handlers.CreateProductRequest'
produces:
- application/json
responses:
"201":
description: Created
schema:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.Product'
"400":
description: Validation Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Create a new product
tags:
- Marketplace
/api/v1/marketplace/products/{id}:
get:
consumes:
- application/json
description: Get detailed information about a product, including previews, images,
and licenses.
parameters:
- description: Product ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.Product'
"400":
description: Invalid ID
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"404":
description: Product not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Get product by ID
tags:
- Marketplace
put:
consumes:
- application/json
description: Update product details (only seller can update)
parameters:
- description: Product ID
in: path
name: id
required: true
type: string
- description: Product updates
in: body
name: product
required: true
schema:
$ref: '#/definitions/internal_handlers.UpdateProductRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.Product'
"400":
description: Validation Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"403":
description: Forbidden - Not product owner
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"404":
description: Product not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Update a product
tags:
- Marketplace
/api/v1/marketplace/products/{id}/images:
put:
consumes:
- application/json
description: Update the list of images for a product. Must be the seller.
parameters:
- description: Product ID
in: path
name: id
required: true
type: string
- description: Images data
in: body
name: images
required: true
schema:
$ref: '#/definitions/internal_handlers.UpdateProductImagesRequest'
produces:
- application/json
responses:
"200":
description: Images updated
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"400":
description: Validation Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"403":
description: Forbidden
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Update product images
tags:
- Marketplace
/api/v1/marketplace/products/{id}/preview:
get:
consumes:
- application/json
description: Stream the audio preview for a product. Supports Range requests.
parameters:
- description: Product ID
in: path
name: id
required: true
type: string
produces:
- audio/mpeg
- ' audio/wav'
responses:
"200":
description: Audio stream
schema:
type: file
"206":
description: Partial audio stream
schema:
type: file
"404":
description: Preview not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Stream product preview
tags:
- Marketplace
post:
consumes:
- multipart/form-data
description: Upload an audio preview file for a product. Must be the seller.
parameters:
- description: Product ID
in: path
name: id
required: true
type: string
- description: Audio file
in: formData
name: file
required: true
type: file
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.ProductPreview'
"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'
security:
- BearerAuth: []
summary: Upload product preview
tags:
- Marketplace
/api/v1/marketplace/products/{id}/reviews:
get:
consumes:
- application/json
description: Get a paginated list of reviews for a specific product.
parameters:
- description: Product ID
in: path
name: id
required: true
type: string
- default: 20
description: Limit
in: query
name: limit
type: integer
- default: 0
description: Offset
in: query
name: offset
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.ProductReview'
type: array
summary: List product reviews
tags:
- Marketplace
post:
consumes:
- application/json
description: Create a review with rating and comment for a product. Buyer must
have purchased the product.
parameters:
- description: Product ID
in: path
name: id
required: true
type: string
- description: Review data
in: body
name: review
required: true
schema:
$ref: '#/definitions/internal_handlers.CreateReviewRequest'
produces:
- application/json
responses:
"201":
description: Created
schema:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.ProductReview'
"400":
description: Validation Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"403":
description: Not purchased or already reviewed
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Create product review
tags:
- Marketplace
/api/v1/marketplace/wishlist:
get:
consumes:
- application/json
description: Get all products in the authenticated user's wishlist.
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
items:
type: array
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get wishlist
tags:
- Marketplace
post:
consumes:
- application/json
description: Add a product to the authenticated user's wishlist.
parameters:
- description: Product to add
in: body
name: item
required: true
schema:
$ref: '#/definitions/internal_handlers.AddToWishlistRequest'
produces:
- application/json
responses:
"201":
description: Created
schema:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.WishlistItem'
"400":
description: Validation Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"404":
description: Product not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Add to wishlist
tags:
- Marketplace
/api/v1/marketplace/wishlist/{productId}:
delete:
consumes:
- application/json
description: Remove a product from the authenticated user's wishlist.
parameters:
- description: Product ID
in: path
name: productId
required: true
type: string
produces:
- application/json
responses:
"200":
description: Removed from wishlist
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"400":
description: Invalid ID
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Remove from wishlist
tags:
- Marketplace
/api/v1/roles:
get:
consumes:
- application/json
description: Get a list of all available roles in the system.
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/veza-backend-api_internal_models.Role'
type: array
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: List all roles
tags:
- Admin
post:
consumes:
- application/json
description: Create a new custom role.
parameters:
- description: Role data
in: body
name: role
required: true
schema:
$ref: '#/definitions/veza-backend-api_internal_models.Role'
produces:
- application/json
responses:
"201":
description: Created
schema:
properties:
role:
$ref: '#/definitions/veza-backend-api_internal_models.Role'
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Create role
tags:
- Admin
/api/v1/roles/{id}:
delete:
consumes:
- application/json
description: Permanently delete a role. System roles cannot be deleted.
parameters:
- description: Role ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
properties:
message:
type: string
type: object
"400":
description: Cannot delete system role
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Delete role
tags:
- Admin
get:
consumes:
- application/json
description: Get detailed information about a specific role.
parameters:
- description: Role ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/veza-backend-api_internal_models.Role'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"404":
description: Role not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get role by ID
tags:
- Admin
put:
consumes:
- application/json
description: Update an existing role's information.
parameters:
- description: Role ID
in: path
name: id
required: true
type: string
- description: Role updates
in: body
name: role
required: true
schema:
$ref: '#/definitions/veza-backend-api_internal_models.Role'
produces:
- application/json
responses:
"200":
description: OK
schema:
properties:
message:
type: string
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"404":
description: Role not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Update role
tags:
- Admin
/api/v1/sell/balance:
get:
consumes:
- application/json
description: Get the current Stripe Connect balance (connected, available, pending)
for the seller.
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get seller balance
tags:
- Sell
/api/v1/sell/connect/callback:
get:
consumes:
- application/json
description: Callback endpoint to sync Stripe account status after redirection.
produces:
- application/json
responses:
"200":
description: Account synced
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Sync Stripe account
tags:
- Sell
/api/v1/sell/connect/onboard:
post:
consumes:
- application/json
description: Initiate the Stripe Connect onboarding process and get a redirection
link.
parameters:
- description: Return and Refresh URLs
in: body
name: data
required: true
schema:
$ref: '#/definitions/internal_handlers.ConnectOnboardRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
onboarding_url:
type: string
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Start Stripe Connect onboarding
tags:
- Sell
/api/v1/sell/kyc/start:
post:
consumes:
- application/json
description: Initiate a Stripe Identity verification session for the seller.
parameters:
- description: Return URL
in: body
name: data
required: true
schema:
$ref: '#/definitions/internal_handlers.CreateVerificationRequest'
produces:
- application/json
responses:
"201":
description: Created
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Start KYC verification
tags:
- Sell
/api/v1/sell/kyc/status:
get:
consumes:
- application/json
description: Get the current identity verification status for the authenticated
seller.
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
status:
type: string
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get KYC status
tags:
- Sell
/api/v1/sell/marketplace-balance:
get:
consumes:
- application/json
description: Get current available and pending balance from marketplace sales.
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get seller marketplace balance
tags:
- Sell
/api/v1/sell/payouts:
get:
consumes:
- application/json
description: Get a list of past payout requests and their status.
parameters:
- default: 20
description: Limit
in: query
name: limit
type: integer
- default: 0
description: Offset
in: query
name: offset
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
payouts:
type: array
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get payout history
tags:
- Sell
/api/v1/sell/payouts/request:
post:
consumes:
- application/json
description: Initiate a manual payout request for the available balance.
produces:
- application/json
responses:
"201":
description: Created
schema:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.SellerPayout'
"400":
description: Validation Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Request payout
tags:
- Sell
/api/v1/sell/sales:
get:
consumes:
- application/json
description: Get a list of recent sales for the authenticated seller.
parameters:
- default: 10
description: Limit
in: query
name: limit
type: integer
- default: 0
description: Offset
in: query
name: offset
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get recent sales
tags:
- Marketplace
/api/v1/sell/stats:
get:
consumes:
- application/json
description: Get total revenue and sales count for the authenticated seller.
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get seller stats
tags:
- Marketplace
/api/v1/sell/stats/evolution:
get:
consumes:
- application/json
description: Get revenue and sales evolution over time for the authenticated
seller.
parameters:
- default: day
description: Evolution period (day, week, month)
in: query
name: period
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get sales evolution
tags:
- Marketplace
/api/v1/sell/stats/top-products:
get:
consumes:
- application/json
description: Get the top selling products by revenue for the authenticated seller.
parameters:
- default: 5
description: Limit
in: query
name: limit
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get top selling products
tags:
- Marketplace
/api/v1/sell/transfers:
get:
consumes:
- application/json
description: Get a list of all Stripe transfers for the authenticated seller.
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/veza-backend-api_internal_core_marketplace.SellerTransfer'
type: array
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get transfer history
tags:
- Sell
/api/v1/support/tickets:
post:
consumes:
- application/json
description: Create a new support or contact request. Optional authentication.
parameters:
- description: Ticket data
in: body
name: ticket
required: true
schema:
$ref: '#/definitions/internal_handlers.SubmitTicketRequest'
produces:
- application/json
responses:
"201":
description: Created
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
ticket_id:
type: string
type: object
type: object
"400":
description: Validation Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Submit support ticket
tags:
- Marketplace
/api/v1/tracks/{id}/hls/{bitrate}/{segment}:
get:
description: Serve a specific video/audio segment (.ts) for a track and quality.
parameters:
- description: Track ID
in: path
name: id
required: true
type: string
- description: Bitrate
in: path
name: bitrate
required: true
type: string
- description: Segment name
in: path
name: segment
required: true
type: string
produces:
- video/mp2t
responses:
"200":
description: MPEG-TS segment
schema:
type: file
"404":
description: Segment not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Get HLS segment
tags:
- Streaming
/api/v1/tracks/{id}/hls/{bitrate}/index.m3u8:
get:
description: Serve a specific quality M3U8 playlist for a track.
parameters:
- description: Track ID
in: path
name: id
required: true
type: string
- description: Bitrate (e.g. 128k)
in: path
name: bitrate
required: true
type: string
produces:
- application/vnd.apple.mpegurl
responses:
"200":
description: '#EXTM3U...'
schema:
type: string
"404":
description: Playlist not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Get HLS quality playlist
tags:
- Streaming
/api/v1/tracks/{id}/hls/info:
get:
consumes:
- application/json
description: Get metadata about the HLS stream (bitrates, codecs).
parameters:
- description: Track ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
type: object
"404":
description: Stream not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Get HLS stream info
tags:
- Streaming
/api/v1/tracks/{id}/hls/master.m3u8:
get:
description: Serve the master M3U8 playlist for a track, containing all available
qualities.
parameters:
- description: Track ID
in: path
name: id
required: true
type: string
produces:
- application/vnd.apple.mpegurl
responses:
"200":
description: '#EXTM3U...'
schema:
type: string
"404":
description: Playlist not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Get HLS master playlist
tags:
- Streaming
/api/v1/tracks/{id}/hls/status:
get:
consumes:
- application/json
description: Get current transcoding status (pending, processing, ready).
parameters:
- description: Track ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
type: object
"404":
description: Stream not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Get HLS stream status
tags:
- Streaming
/api/v1/tracks/{id}/hls/transcode:
post:
consumes:
- application/json
description: Manually start or restart the HLS transcoding process for a track.
parameters:
- description: Track ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"202":
description: Accepted
schema:
properties:
job_id:
type: string
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"403":
description: Forbidden
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Trigger HLS transcode
tags:
- Streaming
/api/v1/uploads:
post:
consumes:
- multipart/form-data
description: Upload a file (audio, image, or video) to the platform. Supports
backpressure and virus scanning.
parameters:
- description: The file to upload
in: formData
name: file
required: true
type: file
- description: Track ID (UUID)
in: formData
name: track_id
required: true
type: string
- description: File type (audio, image, video)
in: formData
name: file_type
required: true
type: string
- description: Title
in: formData
name: title
required: true
type: string
- description: Artist
in: formData
name: artist
required: true
type: string
produces:
- application/json
responses:
"201":
description: Created
schema:
$ref: '#/definitions/veza-backend-api_internal_upload.StandardUploadResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"422":
description: Virus detected
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"503":
description: Too many concurrent uploads or virus scanner down
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Upload a file
tags:
- Upload
/api/v1/uploads/{id}:
delete:
consumes:
- application/json
description: Delete a specific upload and its associated files.
parameters:
- description: Upload ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
properties:
message:
type: string
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Delete upload
tags:
- Upload
/api/v1/uploads/{id}/progress:
get:
consumes:
- application/json
description: Get detailed progress information (bytes uploaded, ETA) for a specific
upload.
parameters:
- description: Upload ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/veza-backend-api_internal_upload.UploadProgressResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get upload progress
tags:
- Upload
/api/v1/uploads/{id}/status:
get:
consumes:
- application/json
description: Get the current status and progress of a specific upload.
parameters:
- description: Upload ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
properties:
id:
type: string
progress:
type: integer
status:
type: string
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"404":
description: Upload not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get upload status
tags:
- Upload
/api/v1/uploads/batch:
post:
consumes:
- multipart/form-data
description: Upload multiple files in a single request. Max 10 files.
parameters:
- description: Files to upload
in: formData
name: files
required: true
type: file
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/veza-backend-api_internal_upload.BatchUploadResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Batch upload files
tags:
- Upload
/api/v1/uploads/limits:
get:
consumes:
- application/json
description: Get current file size limits and allowed MIME types for each category.
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/veza-backend-api_internal_upload.UploadLimitsResponse'
summary: Get upload limits
tags:
- Upload
/api/v1/uploads/stats:
get:
consumes:
- application/json
description: Get upload statistics for the authenticated user (quota, total
uploads).
produces:
- application/json
responses:
"200":
description: OK
schema:
properties:
stats:
type: object
user_id:
type: string
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get upload stats
tags:
- Upload
/api/v1/uploads/validate-type:
get:
consumes:
- application/json
description: Check if a file type (audio, image, video) is supported by the
platform.
parameters:
- description: File type to validate
in: query
name: type
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
properties:
supported:
type: boolean
supported_types:
type: array
type:
type: string
type: object
"400":
description: Unsupported file type
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Validate file type
tags:
- Upload
/api/v1/users/{id}/roles:
get:
consumes:
- application/json
description: Get all roles currently assigned to a specific user.
parameters:
- description: User ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
properties:
roles:
type: array
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: List user roles
tags:
- Admin
/api/v1/users/{userId}/roles:
post:
consumes:
- application/json
description: Assign a specific role to a user, optionally with an expiration
date.
parameters:
- description: User ID
in: path
name: userId
required: true
type: string
- description: Role assignment data
in: body
name: assignment
required: true
schema:
properties:
expires_at:
type: string
role_id:
type: string
type: object
produces:
- application/json
responses:
"200":
description: OK
schema:
properties:
message:
type: string
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Assign role to user
tags:
- Admin
/api/v1/users/{userId}/roles/{roleId}:
delete:
consumes:
- application/json
description: Remove a specific role assignment from a user.
parameters:
- description: User ID
in: path
name: userId
required: true
type: string
- description: Role ID
in: path
name: roleId
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
properties:
message:
type: string
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"404":
description: Role assignment not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Revoke role from user
tags:
- Admin
/audit/activity:
get:
consumes:
- application/json
description: Get recent activity logs for the current user
parameters:
- default: 50
description: Number of activities to return
in: query
name: limit
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
activities:
type: array
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal server error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get user activity
tags:
- Audit
/audit/logs:
get:
consumes:
- application/json
description: Search and filter audit logs with pagination support. Supports
filtering by action, resource, date range, IP address, and user agent.
parameters:
- description: Filter by action type
in: query
name: action
type: string
- description: Filter by resource type
in: query
name: resource
type: string
- description: Filter by resource ID (UUID)
in: query
name: resource_id
type: string
- description: Filter by IP address
in: query
name: ip_address
type: string
- description: Filter by user agent
in: query
name: user_agent
type: string
- description: Start date filter (YYYY-MM-DD)
in: query
name: start_date
type: string
- description: End date filter (YYYY-MM-DD)
in: query
name: end_date
type: string
- default: 1
description: Page number
in: query
name: page
type: integer
- default: 20
description: Items per page
in: query
name: limit
type: integer
- description: Offset for pagination
in: query
name: offset
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
logs:
type: array
pagination:
type: object
type: object
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'
security:
- BearerAuth: []
summary: Search audit logs
tags:
- Audit
/audit/stats:
get:
consumes:
- application/json
description: Get audit statistics for the current user, optionally filtered
by date range
parameters:
- description: Start date (YYYY-MM-DD)
in: query
name: start_date
type: string
- description: End date (YYYY-MM-DD)
in: query
name: end_date
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
stats:
type: object
type: object
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'
security:
- BearerAuth: []
summary: Get audit statistics
tags:
- Audit
/auth/2fa/disable:
post:
consumes:
- application/json
description: Disable 2FA for user (requires password confirmation)
parameters:
- description: Password Confirmation
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_handlers.DisableTwoFactorRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Disable 2FA
tags:
- Auth
/auth/2fa/setup:
post:
consumes:
- application/json
description: Generate 2FA secret and QR code for setup
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
$ref: '#/definitions/internal_handlers.SetupTwoFactorResponse'
type: object
"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'
security:
- BearerAuth: []
summary: Setup 2FA
tags:
- Auth
/auth/2fa/status:
get:
consumes:
- application/json
description: Get 2FA enabled status for authenticated user
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
enabled:
type: boolean
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get 2FA Status
tags:
- Auth
/auth/2fa/verify:
post:
consumes:
- application/json
description: Verify 2FA code and enable 2FA for user
parameters:
- description: 2FA Code
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_handlers.VerifyTwoFactorRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Verify and Enable 2FA
tags:
- Auth
/auth/check-username:
get:
consumes:
- application/json
description: Check if a username is already taken
parameters:
- description: Username to check
in: query
name: username
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
available:
type: boolean
username:
type: string
type: object
type: object
"400":
description: Missing Username
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Check Username Availability
tags:
- Auth
/auth/login:
post:
consumes:
- application/json
description: Authenticate user and return access token. Refresh token is set
in httpOnly cookie.
parameters:
- description: Login Credentials
in: body
name: request
required: true
schema:
$ref: '#/definitions/veza-backend-api_internal_dto.LoginRequest'
produces:
- application/json
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'
summary: User Login
tags:
- Auth
/auth/logout:
post:
consumes:
- application/json
description: Revoke refresh token and current session
parameters:
- description: Refresh Token to revoke
in: body
name: request
required: true
schema:
properties:
refresh_token:
type: string
type: object
produces:
- application/json
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'
security:
- BearerAuth: []
summary: Logout
tags:
- Auth
/auth/me:
get:
consumes:
- application/json
description: Get profile information of the currently logged-in user
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"404":
description: User not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get Current User
tags:
- Auth
/auth/password/reset:
post:
consumes:
- application/json
description: Completes a password reset using a valid token previously emailed
to the user. Invalidates all the user's existing sessions on success.
parameters:
- description: Reset token + new password
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_handlers.ResetPasswordRequest'
produces:
- application/json
responses:
"200":
description: Password reset successfully
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
summary: Reset password with token
tags:
- Auth
/auth/password/reset-request:
post:
consumes:
- application/json
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.
parameters:
- description: Email of the account to reset
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_handlers.RequestPasswordResetRequest'
produces:
- application/json
responses:
"200":
description: If the email exists, a reset link has been sent
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
summary: Request password reset
tags:
- Auth
/auth/refresh:
post:
consumes:
- application/json
description: Get a new access token using a refresh token
parameters:
- description: Refresh Token
in: body
name: request
required: true
schema:
$ref: '#/definitions/veza-backend-api_internal_dto.RefreshRequest'
produces:
- application/json
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'
summary: Refresh Token
tags:
- Auth
/auth/register:
post:
consumes:
- application/json
description: Register a new user account
parameters:
- description: Registration Data
in: body
name: request
required: true
schema:
$ref: '#/definitions/veza-backend-api_internal_dto.RegisterRequest'
produces:
- application/json
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'
summary: User Registration
tags:
- Auth
/auth/resend-verification:
post:
consumes:
- application/json
description: Resend the email verification link
parameters:
- description: Email
in: body
name: request
required: true
schema:
$ref: '#/definitions/veza-backend-api_internal_dto.ResendVerificationRequest'
produces:
- application/json
responses:
"200":
description: Success message
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"400":
description: Validation Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Resend Verification Email
tags:
- Auth
/auth/stream-token:
post:
description: Returns a 5-minute JWT for HLS and WebSocket authentication (httpOnly
cookies prevent direct token access)
responses:
"200":
description: OK
schema:
$ref: '#/definitions/internal_handlers.StreamTokenResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get ephemeral stream token
tags:
- Auth
/auth/verify-email:
post:
consumes:
- application/json
description: |-
Verify user email address using a token. v1.0.9 item 1.3:
the token is read from the X-Verify-Token header (anti-leak
via Referer / proxy access logs). The query-param form
remains accepted for backward compatibility with emails sent
before v1.0.9 — both paths log a deprecation warning when
the query path is used.
parameters:
- description: Verification Token (preferred)
in: header
name: X-Verify-Token
required: true
type: string
- description: Verification Token (deprecated, accepted for backward compat)
in: query
name: token
type: string
produces:
- application/json
responses:
"200":
description: Success message
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"400":
description: Invalid Token
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Verify Email
tags:
- Auth
/chat/token:
get:
consumes:
- application/json
description: Generate a short-lived token for chat authentication
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
token:
type: string
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get Chat Token
tags:
- Chat
/comments/{id}:
put:
consumes:
- application/json
description: Update a comment (only by owner)
parameters:
- description: Comment ID (UUID)
in: path
name: id
required: true
type: string
- description: Updated comment content
in: body
name: comment
required: true
schema:
$ref: '#/definitions/internal_handlers.UpdateCommentRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
comment:
type: object
type: object
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'
security:
- BearerAuth: []
summary: Update comment
tags:
- Comment
/comments/{id}/replies:
get:
consumes:
- application/json
description: Get paginated list of replies to a comment
parameters:
- description: Parent Comment ID (UUID)
in: path
name: id
required: true
type: string
- default: 1
description: Page number
in: query
minimum: 1
name: page
type: integer
- default: 20
description: Items per page
in: query
maximum: 100
minimum: 1
name: limit
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
pagination:
type: object
replies:
type: array
type: object
type: object
"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'
summary: Get comment replies
tags:
- Comment
/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
responses:
"200":
description: ICE servers
schema:
$ref: '#/definitions/internal_handlers.WebRTCConfigResponse'
summary: WebRTC ICE configuration
tags:
- Config
/dmca/notice:
post:
consumes:
- application/json
description: Public endpoint. Rate-limited per IP. Records a "pending" notice
for admin review. The sworn_statement field MUST be true (DMCA § 512(c)(3)(A)(vi)).
parameters:
- description: DMCA notice payload
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_handlers.SubmitNoticeRequest'
produces:
- application/json
responses:
"201":
description: Notice accepted
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"400":
description: Validation error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"429":
description: Rate-limited
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Submit a DMCA takedown notice
tags:
- DMCA
/embed/track/{id}:
get:
description: Standalone HTML widget (audio player + minimal styling) for embedding
via iframe. Public, no auth. Twitter/Facebook scrapers ingest the OG tags
inside.
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
produces:
- text/html
responses:
"200":
description: HTML embed page
schema:
type: string
"404":
description: Track not found or not public
schema:
type: string
"451":
description: DMCA takedown in force
schema:
type: string
summary: Embed widget for a track
tags:
- Embed
/internal/tracks/{id}/stream-ready:
post:
consumes:
- application/json
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).
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
- description: Callback payload
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_core_track.StreamCallbackRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
properties:
message:
type: string
type: object
"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'
summary: Stream server callback
tags:
- Track
/oembed:
get:
description: Returns oEmbed JSON for a Veza track URL. Used by Twitter, Slack,
Discord etc. for in-line previews. format=xml is not supported.
parameters:
- description: Veza track URL (must point at /tracks/:id)
in: query
name: url
required: true
type: string
- description: Must be 'json' (default)
in: query
name: format
type: string
- description: Optional max iframe width
in: query
name: maxwidth
type: integer
produces:
- application/json
responses:
"200":
description: oEmbed envelope
schema:
additionalProperties: true
type: object
"400":
description: Bad URL or unsupported format
schema:
type: string
"404":
description: Track not found
schema:
type: string
summary: oEmbed endpoint
tags:
- Embed
/playlists:
get:
consumes:
- application/json
description: Get a paginated list of playlists
parameters:
- default: 1
description: Page number
in: query
name: page
type: integer
- default: 20
description: Items per page
in: query
name: limit
type: integer
- description: Filter by User ID
in: query
name: user_id
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
pagination:
type: object
playlists:
items:
$ref: '#/definitions/veza-backend-api_internal_models.Playlist'
type: array
type: object
type: object
"500":
description: Internal Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get Playlists
tags:
- Playlist
post:
consumes:
- application/json
description: Create a new playlist
parameters:
- description: Playlist Metadata
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_handlers.CreatePlaylistRequest'
produces:
- application/json
responses:
"201":
description: Created
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
playlist:
$ref: '#/definitions/veza-backend-api_internal_models.Playlist'
type: object
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'
security:
- BearerAuth: []
summary: Create Playlist
tags:
- Playlist
/playlists/{id}:
delete:
consumes:
- application/json
description: Permanently delete a playlist
parameters:
- description: Playlist ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Delete Playlist
tags:
- Playlist
get:
consumes:
- application/json
description: Get detailed information about a playlist
parameters:
- description: Playlist ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
playlist:
$ref: '#/definitions/veza-backend-api_internal_models.Playlist'
type: object
type: object
"400":
description: Invalid ID
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"404":
description: Playlist not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get Playlist by ID
tags:
- Playlist
put:
consumes:
- application/json
description: Update playlist metadata
parameters:
- description: Playlist ID
in: path
name: id
required: true
type: string
- description: Playlist Metadata
in: body
name: playlist
required: true
schema:
$ref: '#/definitions/internal_handlers.UpdatePlaylistRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
playlist:
$ref: '#/definitions/veza-backend-api_internal_models.Playlist'
type: object
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'
"404":
description: Playlist not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Update Playlist
tags:
- Playlist
/playlists/{id}/analytics:
get:
description: Returns aggregated stats for a playlist (plays, follows, tracks
count, etc.). Visible to the owner, collaborators and admins.
parameters:
- description: Playlist UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
stats:
type: object
type: object
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'
security:
- BearerAuth: []
summary: Get playlist statistics
tags:
- Playlist
/playlists/{id}/collaborators:
get:
description: Returns the collaborators of a playlist with their permission level.
parameters:
- description: Playlist UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
collaborators:
items:
type: object
type: array
type: object
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'
security:
- BearerAuth: []
summary: List playlist collaborators
tags:
- Playlist
post:
consumes:
- application/json
description: Invite a user as collaborator. Only the owner (or admin) can add.
parameters:
- description: Playlist UUID
in: path
name: id
required: true
type: string
- description: Collaborator + permission
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_handlers.AddCollaboratorRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
collaborator:
type: object
type: object
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'
security:
- BearerAuth: []
summary: Add playlist collaborator
tags:
- Playlist
/playlists/{id}/collaborators/{userId}:
delete:
description: Revoke a collaborator's access. Only the owner (or admin) can remove.
parameters:
- description: Playlist UUID
in: path
name: id
required: true
type: string
- description: Collaborator user UUID
in: path
name: userId
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
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'
security:
- BearerAuth: []
summary: Remove playlist collaborator
tags:
- Playlist
put:
consumes:
- application/json
description: Change a collaborator's permission level (read / write / admin).
Only the owner can update.
parameters:
- description: Playlist UUID
in: path
name: id
required: true
type: string
- description: Collaborator user UUID
in: path
name: userId
required: true
type: string
- description: New permission
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_handlers.UpdateCollaboratorPermissionRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
collaborator:
type: object
type: object
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'
security:
- BearerAuth: []
summary: Update collaborator permission
tags:
- Playlist
/playlists/{id}/duplicate:
post:
description: Copy a playlist's track list into a new playlist owned by the authenticated
user. Cover/description copied; original unchanged.
parameters:
- description: Source playlist UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"201":
description: Created
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
playlist:
$ref: '#/definitions/veza-backend-api_internal_models.Playlist'
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Duplicate playlist
tags:
- Playlist
/playlists/{id}/share:
post:
description: Generate a tokenised link to share a playlist (read-only). Only
owner / admin can issue. No body required.
parameters:
- description: Playlist UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
share:
type: object
type: object
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'
security:
- BearerAuth: []
summary: Create playlist share link
tags:
- Playlist
/playlists/{id}/tracks:
post:
consumes:
- application/json
description: Add a track to the playlist
parameters:
- description: Playlist ID
in: path
name: id
required: true
type: string
- description: Track ID (in body)
in: body
name: trackId
required: true
schema:
properties:
track_id:
type: string
type: object
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Add Track to Playlist
tags:
- Playlist
/playlists/{id}/tracks/{trackId}:
delete:
consumes:
- application/json
description: Remove a track from the playlist
parameters:
- description: Playlist ID
in: path
name: id
required: true
type: string
- description: Track ID
in: path
name: trackId
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"404":
description: Playlist or Track not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Remove Track from Playlist
tags:
- Playlist
/playlists/{id}/tracks/reorder:
put:
consumes:
- application/json
description: Reorder tracks in the playlist
parameters:
- description: Playlist ID
in: path
name: id
required: true
type: string
- description: New Track Order
in: body
name: order
required: true
schema:
$ref: '#/definitions/internal_handlers.ReorderTracksRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"400":
description: Validation Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Reorder Tracks
tags:
- Playlist
/playlists/favoris:
get:
description: Returns the authenticated user's "Favoris" playlist. Auto-created
on first call. Used by the like-as-save pattern.
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
playlist:
$ref: '#/definitions/veza-backend-api_internal_models.Playlist'
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get Favoris playlist
tags:
- Playlist
/playlists/import:
post:
consumes:
- application/json
description: Create a playlist from a JSON payload (title, description, is_public,
ordered track IDs). Useful for bulk seed / migration.
parameters:
- description: Playlist + tracks
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_handlers.ImportPlaylistRequest'
produces:
- application/json
responses:
"201":
description: Created
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
playlist:
$ref: '#/definitions/veza-backend-api_internal_models.Playlist'
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Import playlist
tags:
- Playlist
/playlists/recommendations:
get:
description: Suggested playlists for the authenticated user. Chronological /
declarative discovery — no behavioural ranking (CLAUDE.md rule 7).
parameters:
- default: 20
description: Max items (max 100)
in: query
name: limit
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
playlists:
items:
$ref: '#/definitions/veza-backend-api_internal_models.Playlist'
type: array
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get playlist recommendations
tags:
- Playlist
/playlists/search:
get:
description: Full-text search on public playlists (title + description). Paginated.
parameters:
- description: Full-text query
in: query
name: q
type: string
- default: 1
description: Page number
in: query
name: page
type: integer
- default: 20
description: Items per page (max 100)
in: query
name: limit
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
pagination:
type: object
playlists:
items:
$ref: '#/definitions/veza-backend-api_internal_models.Playlist'
type: array
type: object
type: object
"400":
description: Validation
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Search playlists
tags:
- Playlist
/playlists/shared/{token}:
get:
description: Public endpoint resolving a share token. Allows unauthenticated
access to the playlist snapshot + tracks.
parameters:
- description: Share token
in: path
name: token
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
playlist:
$ref: '#/definitions/veza-backend-api_internal_models.Playlist'
type: object
type: object
"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'
summary: Get playlist by share token
tags:
- Playlist
/queue:
delete:
consumes:
- application/json
description: Removes every item from the authenticated user's playback queue
produces:
- application/json
responses:
"200":
description: Queue cleared
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Clear queue
tags:
- Queue
get:
consumes:
- application/json
description: Returns the authenticated user's persistent playback queue with
all items in position order
produces:
- application/json
responses:
"200":
description: Queue + items
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
items:
items:
type: object
type: array
queue:
type: object
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get user playback queue
tags:
- Queue
put:
consumes:
- application/json
description: Updates the authenticated user's queue state (current track / position
/ playback flags / item order)
parameters:
- description: Queue update payload
in: body
name: request
required: true
schema:
$ref: '#/definitions/veza-backend-api_internal_services.UpdateQueueRequest'
produces:
- application/json
responses:
"200":
description: Updated queue
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
items:
items:
type: object
type: array
queue:
type: object
type: object
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'
security:
- BearerAuth: []
summary: Update user playback queue
tags:
- Queue
/queue/items:
post:
consumes:
- application/json
description: Appends a track to the authenticated user's playback queue
parameters:
- description: Track to enqueue
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_handlers.AddQueueItemRequest'
produces:
- application/json
responses:
"201":
description: Created queue item
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
item:
type: object
type: object
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'
security:
- BearerAuth: []
summary: Add track to queue
tags:
- Queue
/queue/items/{id}:
delete:
consumes:
- application/json
description: Removes a single item from the authenticated user's playback queue
by item ID
parameters:
- description: Queue item ID (UUID)
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: Item removed
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Remove queue item
tags:
- Queue
/queue/session:
post:
consumes:
- application/json
description: Creates a shared queue session and returns its share token + URL.
The session creator is recorded as host.
produces:
- application/json
responses:
"201":
description: Created session
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
session:
type: object
share_token:
type: string
share_url:
type: string
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Create collaborative queue session
tags:
- Queue
/queue/session/{token}:
delete:
consumes:
- application/json
description: Deletes a collaborative queue session. Only the original session
creator can delete.
parameters:
- description: Session share token
in: path
name: token
required: true
type: string
produces:
- application/json
responses:
"200":
description: Session deleted
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Delete queue session
tags:
- Queue
get:
consumes:
- application/json
description: Returns the session metadata + items for a given share token. No
auth required (public — anyone with the link can join).
parameters:
- description: Session share token
in: path
name: token
required: true
type: string
produces:
- application/json
responses:
"200":
description: Session and queue items
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
items:
items:
type: object
type: array
session:
type: object
type: object
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'
summary: Get queue session by share token
tags:
- Queue
/queue/session/{token}/items:
post:
consumes:
- application/json
description: Adds a track to a collaborative queue session. Anyone with the
share token can add.
parameters:
- description: Session share token
in: path
name: token
required: true
type: string
- description: Track to enqueue
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_handlers.AddToSessionRequest'
produces:
- application/json
responses:
"201":
description: Updated session and items
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
items:
items:
type: object
type: array
session:
type: object
type: object
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'
security:
- BearerAuth: []
summary: Add track to queue session
tags:
- Queue
/queue/session/{token}/items/{id}:
delete:
consumes:
- application/json
description: Removes an item from a collaborative queue session by item ID
parameters:
- description: Session share token
in: path
name: token
required: true
type: string
- description: Queue item ID (UUID)
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: Item removed
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Remove item from queue session
tags:
- Queue
/search:
get:
description: 'Postgres FTS-backed search across tracks, users, and playlists.
Optional `type` filter accepts repeated values (e.g., ?type=track&type=user).
v1.0.9 W4 Day 18 adds faceted filters on tracks: genre, musical_key, bpm_min,
bpm_max, year_from, year_to (all optional ; ignored on user/playlist results).'
parameters:
- description: Search query
in: query
name: q
required: true
type: string
- collectionFormat: multi
description: 'Restrict to one or more entity types: track, user, playlist'
in: query
items:
type: string
name: type
type: array
- description: Filter tracks by genre (exact match)
in: query
name: genre
type: string
- description: Filter tracks by musical key (e.g. C, Am)
in: query
name: musical_key
type: string
- description: Minimum BPM (1..999)
in: query
name: bpm_min
type: integer
- description: Maximum BPM (1..999)
in: query
name: bpm_max
type: integer
- description: Minimum release year (1900..2100)
in: query
name: year_from
type: integer
- description: Maximum release year (1900..2100)
in: query
name: year_to
type: integer
- description: Opaque pagination cursor
in: query
name: cursor
type: string
- description: Page size (max 50)
in: query
name: limit
type: integer
produces:
- application/json
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'
summary: Unified search
tags:
- Search
/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.
parameters:
- description: Partial query (min 1 char)
in: query
name: q
required: true
type: string
- description: Max number of suggestions (1..20, default 5)
in: query
name: limit
type: integer
produces:
- application/json
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'
summary: Search suggestions
tags:
- Search
/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.
parameters:
- description: Max tags to return (1..50, default 10)
in: query
name: limit
type: integer
produces:
- application/json
responses:
"200":
description: Trending tags
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Failed to compute trending
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Trending hashtags
tags:
- Social
/tracks:
get:
description: List tracks with pagination, filters, sort. Cursor-based when ?cursor
provided, otherwise page/limit offset.
parameters:
- description: Opaque pagination cursor (overrides page)
in: query
name: cursor
type: string
- default: 1
description: Page number, 1-based (ignored if cursor set)
in: query
name: page
type: integer
- default: 20
description: Items per page (max 100)
in: query
name: limit
type: integer
- description: Filter by creator UUID
in: query
name: user_id
type: string
- description: Filter by genre
in: query
name: genre
type: string
- description: Filter by audio format (mp3, flac, wav, ogg, m4a, aac)
in: query
name: format
type: string
- default: created_at
description: Sort column (created_at, play_count, title)
in: query
name: sort_by
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
- properties:
data:
properties:
pagination:
type: object
tracks:
items:
$ref: '#/definitions/veza-backend-api_internal_models.Track'
type: array
type: object
type: object
"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'
summary: List tracks
tags:
- Track
post:
consumes:
- multipart/form-data
description: Upload a new track (audio file)
parameters:
- description: Audio File (MP3, WAV, FLAC, OGG)
in: formData
name: file
required: true
type: file
produces:
- application/json
responses:
"201":
description: Created
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
- properties:
data:
properties:
track:
$ref: '#/definitions/veza-backend-api_internal_models.Track'
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Upload Track
tags:
- Track
/tracks/{id}:
delete:
description: Soft-delete a track (sets deleted_at). Caller must own the track
or be admin.
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Delete track
tags:
- Track
get:
description: Retrieve a single track. Private play_count / like_count are omitted
for non-owners (v0.10.3 F202).
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
- properties:
data:
properties:
track:
$ref: '#/definitions/veza-backend-api_internal_models.Track'
type: object
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'
summary: Get track by ID
tags:
- Track
put:
consumes:
- application/json
description: Update the metadata of an existing track. Caller must own the track
or be admin.
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
- description: Updated metadata
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_core_track.UpdateTrackRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
- properties:
data:
properties:
track:
$ref: '#/definitions/veza-backend-api_internal_models.Track'
type: object
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'
security:
- BearerAuth: []
summary: Update track metadata
tags:
- Track
/tracks/{id}/comments:
get:
consumes:
- application/json
description: Get paginated list of comments for a track
parameters:
- description: Track ID
in: path
name: id
required: true
type: string
- default: 1
description: Page number
in: query
name: page
type: integer
- default: 20
description: Items per page
in: query
name: limit
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
comments:
type: array
pagination:
type: object
type: object
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'
summary: Get track comments
tags:
- Comment
post:
consumes:
- application/json
description: Create a new comment on a track. Can be a top-level comment or
a reply to another comment (using parent_id).
parameters:
- description: Track ID (UUID)
in: path
name: id
required: true
type: string
- description: Comment data
in: body
name: comment
required: true
schema:
$ref: '#/definitions/internal_handlers.CreateCommentRequest'
produces:
- application/json
responses:
"201":
description: Created
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
comment:
type: object
type: object
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'
security:
- BearerAuth: []
summary: Create comment
tags:
- Comment
/tracks/{id}/comments/{comment_id}:
delete:
consumes:
- application/json
description: Delete a comment (only by owner or admin)
parameters:
- description: Track ID
in: path
name: id
required: true
type: string
- description: Comment ID
in: path
name: comment_id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Delete comment
tags:
- Comment
/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.
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
- description: Grants access without authentication for a limited time
in: query
name: share_token
type: string
produces:
- application/octet-stream
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'
summary: Download a track
tags:
- Track
/tracks/{id}/history:
get:
description: Paginated audit log of modifications (metadata updates, version
changes) for a track.
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
- default: 50
description: Items per page
in: query
name: limit
type: integer
- default: 0
description: Offset
in: query
name: offset
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_handlers.APIResponse'
- properties:
data:
properties:
history:
items:
type: object
type: array
limit:
type: integer
offset:
type: integer
total:
type: integer
type: object
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'
summary: Get track history
tags:
- Track
/tracks/{id}/like:
delete:
description: Remove the authenticated user's like on the track (idempotent).
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Unlike a track
tags:
- Track
post:
description: Record a like from the authenticated user. Creates a grouped notification
for the creator (F554).
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Like a track
tags:
- Track
/tracks/{id}/likes:
get:
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).
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: count is omitted for non-owners
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_handlers.APIResponse'
- properties:
data:
properties:
count:
type: integer
is_liked:
type: boolean
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Get track like status
tags:
- Track
/tracks/{id}/lyrics:
get:
description: Returns the current lyrics for a track, or null if no lyrics exist.
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: lyrics may be null
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
- properties:
data:
properties:
lyrics:
type: object
type: object
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'
summary: Get track lyrics
tags:
- Track
put:
consumes:
- application/json
description: Replace the lyrics of a track. Caller must own the track or be
admin.
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
- description: Lyrics payload
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_core_track.UpdateLyricsRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
- properties:
data:
properties:
lyrics:
type: object
type: object
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'
security:
- BearerAuth: []
summary: Create or update track lyrics
tags:
- Track
/tracks/{id}/play:
post:
consumes:
- application/json
description: Persist a playback event with optional play_time so the creator's
analytics dashboard tracks listening behaviour.
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
- description: Playback metadata (optional)
in: body
name: request
schema:
$ref: '#/definitions/internal_core_track.RecordPlayRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_handlers.APIResponse'
- properties:
data:
properties:
id:
type: string
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Record play event
tags:
- Track
/tracks/{id}/repost:
delete:
description: Remove the authenticated user's repost of the track (idempotent).
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Remove track repost
tags:
- Track
get:
description: Returns whether the current user has reposted the track. Public
(optional auth); unauthenticated callers get is_reposted=false.
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_handlers.APIResponse'
- properties:
data:
properties:
is_reposted:
type: boolean
type: object
type: object
"400":
description: Invalid track id
schema:
$ref: '#/definitions/veza-backend-api_internal_handlers.APIResponse'
summary: Get repost status
tags:
- Track
post:
description: Add a track to the authenticated user's profile as a repost. Notifies
the creator (F204) unless self-repost.
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Repost a track
tags:
- Track
/tracks/{id}/share:
post:
consumes:
- application/json
description: Generate a tokenized share link for a track with given permission
level and optional expiry.
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
- description: Share parameters
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_core_track.CreateShareRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_handlers.APIResponse'
- properties:
data:
properties:
share:
type: object
type: object
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'
security:
- BearerAuth: []
summary: Create share link
tags:
- Track
/tracks/{id}/stats:
get:
description: 'Aggregated track stats: views, likes, comments, play time, downloads,
average duration.'
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_handlers.APIResponse'
- properties:
data:
properties:
stats:
type: object
type: object
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'
summary: Get track statistics
tags:
- Track
/tracks/{id}/status:
get:
consumes:
- application/json
description: Get the processing status of an uploaded track
parameters:
- description: Track ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
- properties:
data:
properties:
progress:
type: integer
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Get Upload Status
tags:
- Track
/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.
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
- description: Grants access without authentication
in: query
name: share_token
type: string
produces:
- audio/*
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'
summary: Stream a track (raw audio + Range)
tags:
- Track
/tracks/{id}/versions/{versionId}/restore:
post:
description: Rollback a track to a previous version. Only the track owner can
restore.
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
- description: Version UUID
in: path
name: versionId
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Restore track version
tags:
- Track
/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.
parameters:
- description: Track UUID
in: path
name: id
required: true
type: string
produces:
- application/json
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'
summary: Get track waveform
tags:
- Track
/tracks/batch/delete:
post:
consumes:
- application/json
description: Soft-delete up to N tracks in one request. Per-track ownership
checked (admin can delete others).
parameters:
- description: List of track UUIDs
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_core_track.BatchDeleteRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
- properties:
data:
properties:
deleted:
items:
type: string
type: array
failed:
items:
type: object
type: array
type: object
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'
security:
- BearerAuth: []
summary: Batch delete tracks
tags:
- Track
/tracks/batch/update:
post:
consumes:
- application/json
description: Apply a partial metadata update to up to N tracks in one request.
Per-track ownership checked.
parameters:
- description: Track UUIDs + shared updates map
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_core_track.BatchUpdateRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
- properties:
data:
properties:
failed:
items:
type: object
type: array
updated:
items:
type: string
type: array
type: object
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'
security:
- BearerAuth: []
summary: Batch update tracks
tags:
- Track
/tracks/chunk:
post:
consumes:
- multipart/form-data
description: Upload a single chunk of a file
parameters:
- description: Chunk Data
in: formData
name: chunk
required: true
type: file
- description: Upload ID
in: formData
name: upload_id
required: true
type: string
- description: Chunk Number
in: formData
name: chunk_number
required: true
type: integer
- description: Total Chunks
in: formData
name: total_chunks
required: true
type: integer
- description: Total Size
format: int64
in: formData
name: total_size
required: true
type: integer
- description: Filename
in: formData
name: filename
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
- properties:
data:
properties:
message:
type: string
progress:
format: float64
type: number
received_chunks:
type: integer
upload_id:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Upload Chunk
tags:
- Track
/tracks/complete:
post:
consumes:
- application/json
description: Finish upload session and assemble file
parameters:
- description: Upload ID
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_core_track.CompleteChunkedUploadRequest'
produces:
- application/json
responses:
"201":
description: Created
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
- properties:
data:
properties:
md5:
type: string
message:
type: string
track:
$ref: '#/definitions/veza-backend-api_internal_models.Track'
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Complete Chunked Upload
tags:
- Track
/tracks/initiate:
post:
consumes:
- application/json
description: Start a new chunked upload session
parameters:
- description: Upload Metadata
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_core_track.InitiateChunkedUploadRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
- properties:
data:
properties:
message:
type: string
upload_id:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Initiate Chunked Upload
tags:
- Track
/tracks/quota/{id}:
get:
consumes:
- application/json
description: Get remaining upload quota for the user
parameters:
- description: User ID or 'me' for current user
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
- properties:
data:
properties:
quota:
type: object
type: object
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'
security:
- BearerAuth: []
summary: Get Upload Quota
tags:
- Track
/tracks/recommendations:
get:
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).
parameters:
- default: 20
description: Max items (max 100)
in: query
name: limit
type: integer
- description: Start from this track's similarity neighbours
in: query
name: seed_track_id
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
- properties:
data:
properties:
tracks:
items:
$ref: '#/definitions/veza-backend-api_internal_models.Track'
type: array
type: object
type: object
"500":
description: Internal Error
schema:
$ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
security:
- BearerAuth: []
summary: Get track recommendations
tags:
- Track
/tracks/resume/{uploadId}:
get:
consumes:
- application/json
description: Get state of an interrupted upload
parameters:
- description: Upload ID
in: path
name: uploadId
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
- properties:
data:
properties:
chunks_received:
type: integer
upload_id:
type: string
type: object
type: object
"404":
description: Upload session not found
schema:
$ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
security:
- BearerAuth: []
summary: Resume Upload
tags:
- Track
/tracks/search:
get:
description: Full-text + faceted search on tracks (genre, BPM, duration, tags,
musical key, dates). Sort-by and order configurable.
parameters:
- description: Full-text query (title/artist/album)
in: query
name: q
type: string
- description: Comma-separated tag list
in: query
name: tags
type: string
- default: OR
description: Tag combinator (OR / AND)
in: query
name: tag_mode
type: string
- description: Minimum duration (seconds)
in: query
name: min_duration
type: integer
- description: Maximum duration (seconds)
in: query
name: max_duration
type: integer
- description: Minimum BPM
in: query
name: min_bpm
type: integer
- description: Maximum BPM
in: query
name: max_bpm
type: integer
- description: Genre filter
in: query
name: genre
type: string
- description: Audio format filter
in: query
name: format
type: string
- description: Musical key filter
in: query
name: musical_key
type: string
- description: Created-after (RFC3339)
in: query
name: min_date
type: string
- description: Created-before (RFC3339)
in: query
name: max_date
type: string
- default: 1
description: Page (1-based)
in: query
name: page
type: integer
- default: 20
description: Items per page (max 100)
in: query
name: limit
type: integer
- default: created_at
description: Sort column
in: query
name: sort_by
type: string
- default: desc
description: asc / desc
in: query
name: sort_order
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
- properties:
data:
properties:
pagination:
type: object
tracks:
items:
$ref: '#/definitions/veza-backend-api_internal_models.Track'
type: array
type: object
type: object
"500":
description: Internal Error
schema:
$ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
summary: Advanced track search
tags:
- Track
/tracks/share/{id}:
delete:
description: Permanently disable a share token. Only the share issuer (or admin)
can revoke.
parameters:
- description: Share UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
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 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'
security:
- BearerAuth: []
summary: Revoke share link
tags:
- Track
/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.
parameters:
- description: Opaque share token issued by CreateShare
in: path
name: token
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_handlers.APIResponse'
- properties:
data:
properties:
share:
type: object
track:
$ref: '#/definitions/veza-backend-api_internal_models.Track'
type: object
type: object
"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'
summary: Get track by share token
tags:
- Track
/tracks/suggested-tags:
get:
description: Returns a static tag suggestion list for a genre — useful for upload
autocomplete and filter chips.
parameters:
- default: default
description: Genre slug (pop, rock, electronic, hip-hop, jazz, classical,
ambient, default)
in: query
name: genre
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_response.APIResponse'
- properties:
data:
properties:
tags:
items:
type: string
type: array
type: object
type: object
summary: Get suggested tags
tags:
- Track
/users:
get:
consumes:
- application/json
description: Get a paginated list of users with optional filtering
parameters:
- default: 1
description: Page number
in: query
name: page
type: integer
- default: 20
description: Items per page
in: query
name: limit
type: integer
- description: Filter by role
in: query
name: role
type: string
- description: Filter by active status
in: query
name: is_active
type: boolean
- description: Filter by verified status
in: query
name: is_verified
type: boolean
- description: Search by username, email, first_name, last_name
in: query
name: search
type: string
- default: created_at
description: Sort field (created_at, username, email, last_login_at)
in: query
name: sort_by
type: string
- default: desc
description: Sort order (asc, desc)
in: query
name: sort_order
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
pagination:
type: object
users:
type: array
type: object
type: object
"500":
description: Internal Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: List Users
tags:
- User
/users/{id}:
delete:
consumes:
- application/json
description: Soft delete a user (only user owner or admin can delete)
parameters:
- description: User ID
in: path
name: id
required: true
type: string
produces:
- application/json
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'
security:
- BearerAuth: []
summary: Delete user
tags:
- User
get:
consumes:
- application/json
description: Get public profile information for a user
parameters:
- description: User ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
profile:
type: object
type: object
type: object
"400":
description: Invalid ID
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"404":
description: User not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Get Profile by ID
tags:
- User
put:
consumes:
- application/json
description: Update user profile details
parameters:
- description: User ID
in: path
name: id
required: true
type: string
- description: Profile Data
in: body
name: profile
required: true
schema:
$ref: '#/definitions/internal_handlers.UpdateProfileRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
profile:
type: object
type: object
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'
security:
- BearerAuth: []
summary: Update Profile
tags:
- User
/users/{id}/block:
delete:
description: Authenticated user unblocks target user (idempotent).
parameters:
- description: Target user UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Unblock user
tags:
- User
post:
description: Authenticated user blocks target user (hides their content, prevents
follows). Cannot self-block.
parameters:
- description: Target user UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Block user
tags:
- User
/users/{id}/completion:
get:
consumes:
- application/json
description: Get profile completion percentage and missing fields
parameters:
- description: User ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
type: object
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'
summary: Get Profile Completion
tags:
- User
/users/{id}/follow:
delete:
description: Authenticated user stops following target user (idempotent).
parameters:
- description: Target user UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Unfollow user
tags:
- User
post:
description: Authenticated user follows target user. Creates a notification
(F554 grouped) for the target.
parameters:
- description: Target user UUID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Follow user
tags:
- User
/users/{id}/likes:
get:
description: Returns paginated tracks the given user has liked. Used for profile
"Likes" tab.
parameters:
- description: User UUID
in: path
name: id
required: true
type: string
- default: 20
description: Items per page (max 100)
in: query
name: limit
type: integer
- default: 0
description: Offset for pagination
in: query
name: offset
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_handlers.APIResponse'
- properties:
data:
properties:
limit:
type: integer
offset:
type: integer
total:
type: integer
tracks:
items:
$ref: '#/definitions/veza-backend-api_internal_models.Track'
type: array
type: object
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'
"500":
description: Internal Error
schema:
$ref: '#/definitions/veza-backend-api_internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: List tracks liked by a user
tags:
- User
/users/{id}/reposts:
get:
description: Returns paginated tracks the user has reposted. Used for profile
"Reposts" tab.
parameters:
- description: User UUID
in: path
name: id
required: true
type: string
- default: 20
description: Items per page (max 100)
in: query
name: limit
type: integer
- default: 0
description: Offset for pagination
in: query
name: offset
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/veza-backend-api_internal_handlers.APIResponse'
- properties:
data:
properties:
limit:
type: integer
offset:
type: integer
total:
type: integer
tracks:
items:
$ref: '#/definitions/veza-backend-api_internal_models.Track'
type: array
type: object
type: object
"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'
summary: List tracks reposted by a user
tags:
- User
/users/by-username/{username}:
get:
consumes:
- application/json
description: Get public profile information for a user by username
parameters:
- description: Username
in: path
name: username
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
profile:
type: object
type: object
type: object
"400":
description: Missing username
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"404":
description: User not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Get Profile by Username
tags:
- User
/users/me:
delete:
description: Permanently delete user account with anonymization, session revocation,
audit log
parameters:
- description: Password, reason, confirm_text (must be DELETE)
in: body
name: body
required: true
schema:
$ref: '#/definitions/internal_handlers.DeleteAccountRequest'
responses:
"200":
description: OK
schema:
additionalProperties: true
type: object
"400":
description: Bad Request
schema:
additionalProperties: true
type: object
"401":
description: Unauthorized
schema:
additionalProperties: true
type: object
"500":
description: Internal Server Error
schema:
additionalProperties: true
type: object
security:
- BearerAuth: []
summary: Delete account
tags:
- Users
/users/me/export:
get:
consumes:
- application/json
description: Synchronously export all user data in JSON format.
produces:
- application/json
responses:
"200":
description: JSON Data Export
schema:
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Export User Data (JSON)
tags:
- User
post:
consumes:
- application/json
description: Start an asynchronous export of all user data. User will receive
an email when ready.
produces:
- application/json
responses:
"202":
description: Accepted
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
export_id:
type: string
status:
type: string
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"429":
description: Too Many Requests
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Request GDPR Export
tags:
- User
/users/me/exports:
get:
consumes:
- application/json
description: Get a list of recent GDPR data exports for the authenticated user
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
exports:
type: array
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: List GDPR Exports
tags:
- User
/users/me/exports/{id}:
get:
consumes:
- application/json
description: Get the status and download URL of a specific GDPR export
parameters:
- description: Export ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"404":
description: Export not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Get GDPR Export Status
tags:
- User
/users/me/exports/{id}/download:
get:
consumes:
- application/json
description: Redirect to a temporary download URL for a completed GDPR export
parameters:
- description: Export ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"302":
description: Redirect to S3
schema:
type: string
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"404":
description: Export not found
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"410":
description: Export expired
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Download GDPR Export
tags:
- User
/users/me/preferences:
get:
consumes:
- application/json
description: Get UI/Appearance preferences for the authenticated user
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
$ref: '#/definitions/veza-backend-api_internal_types.PreferenceSettings'
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Get User Preferences
tags:
- User
put:
consumes:
- application/json
description: Update UI/Appearance preferences (theme, contrast, etc.)
parameters:
- description: Preferences Data
in: body
name: preferences
required: true
schema:
$ref: '#/definitions/veza-backend-api_internal_types.PreferenceSettings'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
$ref: '#/definitions/veza-backend-api_internal_types.PreferenceSettings'
type: object
"400":
description: Validation Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Update User Preferences
tags:
- User
/users/me/privacy/opt-out:
post:
description: Saves the user's Do Not Sell preference (CCPA compliance)
responses:
"200":
description: OK
schema:
additionalProperties: true
type: object
"401":
description: Unauthorized
schema:
additionalProperties: true
type: object
"500":
description: Internal Server Error
schema:
additionalProperties: true
type: object
security:
- BearerAuth: []
summary: CCPA Do Not Sell opt-out
tags:
- Users
/users/search:
get:
description: Full-text search on users (username, display_name). Paginated.
Public.
parameters:
- description: Full-text query
in: query
name: q
type: string
- default: 1
description: Page
in: query
name: page
type: integer
- default: 20
description: Items per page (max 100)
in: query
name: limit
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
pagination:
type: object
users:
items:
$ref: '#/definitions/veza-backend-api_internal_models.User'
type: array
type: object
type: object
"400":
description: Validation (bounds)
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Search users
tags:
- User
/users/settings:
get:
consumes:
- application/json
description: Get settings for the authenticated user
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
$ref: '#/definitions/internal_handlers.UserSettingsResponse'
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Get User Settings
tags:
- User
put:
consumes:
- application/json
description: Update settings for the authenticated user
parameters:
- description: Settings Data
in: body
name: settings
required: true
schema:
$ref: '#/definitions/veza-backend-api_internal_types.UpdateSettingsRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
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'
summary: Update User Settings
tags:
- User
/users/suggestions:
get:
description: Returns suggested users to follow for the authenticated user. Declarative
discovery — no behavioural scoring (CLAUDE.md rule 7).
parameters:
- default: 10
description: Max items (max 50)
in: query
name: limit
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
users:
items:
$ref: '#/definitions/veza-backend-api_internal_models.User'
type: array
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal Error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get follow suggestions
tags:
- User
/validate:
post:
consumes:
- application/json
description: Validates request data against known DTO types without executing
the actual operation
parameters:
- description: Validation request with type and data
in: body
name: request
required: true
schema:
$ref: '#/definitions/internal_handlers.ValidateRequest'
produces:
- application/json
responses:
"200":
description: Validation result
schema:
$ref: '#/definitions/internal_handlers.ValidateResponse'
"400":
description: Invalid request format
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
summary: Validate request body
tags:
- Validation
/webhooks:
get:
consumes:
- application/json
description: Get a list of all webhooks registered by the current user
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
webhooks:
type: array
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal server error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: List webhooks
tags:
- Webhook
post:
consumes:
- application/json
description: Register a new webhook for receiving events
parameters:
- description: Webhook registration data
in: body
name: webhook
required: true
schema:
type: object
produces:
- application/json
responses:
"201":
description: Created
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
webhook:
type: object
type: object
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'
security:
- BearerAuth: []
summary: Register webhook
tags:
- Webhook
/webhooks/{id}:
delete:
consumes:
- application/json
description: Delete a webhook by ID
parameters:
- description: Webhook ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Delete webhook
tags:
- Webhook
/webhooks/{id}/regenerate-key:
post:
consumes:
- application/json
description: Generate a new API key for a webhook (invalidates the old one)
parameters:
- description: Webhook ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
api_key:
type: string
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Regenerate webhook API key
tags:
- Webhook
/webhooks/{id}/test:
post:
consumes:
- application/json
description: Send a test event to a webhook to verify it's working
parameters:
- description: Webhook ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
message:
type: string
type: object
type: object
"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'
security:
- BearerAuth: []
summary: Test webhook
tags:
- Webhook
/webhooks/stats:
get:
consumes:
- application/json
description: Get statistics for webhook delivery and performance
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/internal_handlers.APIResponse'
- properties:
data:
properties:
stats:
type: object
type: object
type: object
"401":
description: Unauthorized
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
"500":
description: Internal server error
schema:
$ref: '#/definitions/internal_handlers.APIResponse'
security:
- BearerAuth: []
summary: Get webhook statistics
tags:
- Webhook
securityDefinitions:
ApiKeyAuth:
description: 'Developer API key (obtain from Developer Portal). Format: vza_xxxxx'
in: header
name: X-API-Key
type: apiKey
BearerAuth:
in: header
name: Authorization
type: apiKey
swagger: "2.0"