Create a new user account.
Request Body:
{
"email": "user@example.com",
"username": "artistname",
"password": "securepassword",
"role": "fan" | "artist" | "admin"
}Response:
{
"token": "jwt-token-here",
"user": {
"id": "user-id",
"email": "user@example.com",
"username": "artistname",
"role": "fan"
}
}Authenticate an existing user.
Request Body:
{
"email": "user@example.com",
"password": "securepassword"
}Response:
{
"token": "jwt-token-here",
"user": {
"id": "user-id",
"email": "user@example.com",
"username": "artistname",
"role": "artist"
}
}Verify current session.
Headers:
Authorization: Bearer <token>
Response:
{
"authenticated": true,
"user": {
"id": "user-id",
"email": "user@example.com",
"username": "artistname",
"role": "artist"
}
}Create an artist profile.
Request Body:
{
"stageName": "The Midnight Strummer",
"slug": "midnight-strummer",
"bio": "Jazz guitarist from Brooklyn",
"genres": ["jazz", "blues", "soul"],
"walletAddress": "GXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}Response:
{
"id": "profile-id",
"userId": "user-id",
"stageName": "The Midnight Strummer",
"slug": "midnight-strummer",
"bio": "Jazz guitarist from Brooklyn",
"genres": ["jazz", "blues", "soul"],
"walletAddress": "GXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"createdAt": "2026-04-13T10:00:00Z"
}Update an existing profile.
Request Body:
{
"bio": "Updated bio text",
"genres": ["jazz", "blues"]
}Response:
{
"id": "profile-id",
"stageName": "The Midnight Strummer",
"slug": "midnight-strummer",
"bio": "Updated bio text",
"genres": ["jazz", "blues"],
"updatedAt": "2026-04-13T11:00:00Z"
}Get public profile by slug.
Response:
{
"id": "profile-id",
"stageName": "The Midnight Strummer",
"slug": "midnight-strummer",
"bio": "Jazz guitarist from Brooklyn",
"genres": ["jazz", "blues", "soul"],
"sessionCount": 42,
"totalTips": 1250.50
}Create a new session draft.
Request Body:
{
"title": "Evening Jazz Session",
"description": "Smooth jazz for your evening",
"scheduledFor": "2026-04-13T20:00:00Z"
}Response:
{
"id": "session-id",
"artistId": "profile-id",
"title": "Evening Jazz Session",
"description": "Smooth jazz for your evening",
"status": "draft",
"scheduledFor": "2026-04-13T20:00:00Z",
"createdAt": "2026-04-13T10:00:00Z"
}Update session details.
Request Body:
{
"title": "Updated Title",
"description": "Updated description"
}Response:
{
"id": "session-id",
"title": "Updated Title",
"description": "Updated description",
"updatedAt": "2026-04-13T11:00:00Z"
}Start a live session.
Response:
{
"id": "session-id",
"status": "live",
"startedAt": "2026-04-13T20:00:00Z",
"streamUrl": "https://stream.example.com/session-id"
}End a live session.
Response:
{
"id": "session-id",
"status": "ended",
"endedAt": "2026-04-13T21:30:00Z",
"duration": 5400,
"viewerCount": 127,
"tipCount": 15,
"totalTips": 85.50
}List all live sessions.
Query Parameters:
genre(optional): Filter by genrelimit(optional): Number of results (default: 20)offset(optional): Pagination offset
Response:
{
"sessions": [
{
"id": "session-id",
"artist": {
"stageName": "The Midnight Strummer",
"slug": "midnight-strummer"
},
"title": "Evening Jazz Session",
"status": "live",
"viewerCount": 127,
"startedAt": "2026-04-13T20:00:00Z"
}
],
"total": 1,
"limit": 20,
"offset": 0
}Prepare a tip transaction.
Request Body:
{
"sessionId": "session-id",
"amount": "10.00",
"asset": "XLM",
"destination": "GXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"note": "Great performance!"
}Response:
{
"id": "tip-intent-id",
"network": "stellar",
"asset": "XLM",
"amount": "10.00",
"destination": "GXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"memo": "session-id",
"submitMode": "manual",
"expiresAt": "2026-04-13T11:00:00Z"
}Confirm a completed transaction.
Request Body:
{
"tipIntentId": "tip-intent-id",
"transactionHash": "abc123..."
}Response:
{
"id": "tip-id",
"status": "confirmed",
"amount": "10.00",
"asset": "XLM",
"confirmedAt": "2026-04-13T10:30:00Z"
}Query audit events (admin only).
Query Parameters:
actor(optional): Filter by user IDaction(optional): Filter by action typestartDate(optional): Filter by date rangeendDate(optional): Filter by date rangelimit(optional): Number of results (default: 50)offset(optional): Pagination offset
Headers:
Authorization: Bearer <admin-token>
Response:
{
"items": [
{
"id": "audit-id",
"actor": "user-id",
"action": "profile.update",
"path": "/profile/profile-id",
"method": "PATCH",
"metadata": {
"changes": ["bio", "genres"]
},
"createdAt": "2026-04-13T10:00:00Z"
}
],
"total": 1,
"limit": 50,
"offset": 0
}All endpoints may return error responses in the following format:
{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {}
}
}UNAUTHORIZED(401): Missing or invalid authenticationFORBIDDEN(403): Insufficient permissionsNOT_FOUND(404): Resource not foundVALIDATION_ERROR(400): Invalid request dataCONFLICT(409): Resource conflict (e.g., duplicate slug)INTERNAL_ERROR(500): Server error