PinePods Database API Documentation
🎯 Overview
The PinePods Database API is a comprehensive Rust-based Axum application that manages all podcast data, user authentication, settings, and media operations. This API serves as the backbone for the PinePods application ecosystem.
✨ Key Features
- User Management: Authentication, profiles, preferences, and MFA
- Podcast Management: Subscriptions, episodes, playback tracking, and metadata
- Media Operations: Downloading, streaming, queueing, and playlist management
- Sync Integration: GPodder, Nextcloud, and OIDC providers
- Administrative Functions: Server management, backups, and system configuration
- Real-time Features: WebSocket support and task progress tracking
🔑 Authentication Overview
All API endpoints require authentication via API key in the Api-Key header, except where noted. API keys are obtained through user credentials and carry the permissions of the associated user account.
Authentication Types
- 🔓 Open Endpoints: No authentication required
- 🔐 User API Key: Standard user authentication required
- 👑 Admin API Key: Administrative privileges required
🔓 OPEN ENDPOINTS (No Authentication Required)
Health & System Checks
GET /api/pinepods_check
Description: Simple health check to validate service connectivity and confirm PinePods instance
Authentication: 🔓 Open
Parameters: None
Request Example:
curl -X GET http://localhost:8000/api/pinepods_check
Response Example:
{
"status_code": 200,
"pinepods_instance": true
}
Error Responses:
500: Internal Server Error - Service unavailable
Notes:
- Used for basic service health monitoring
- Returns quickly with minimal processing
- Confirms this is a PinePods API instance
GET /api/health
Description: Comprehensive health check including database connectivity, Redis status, and system metrics
Authentication: 🔓 Open
Parameters: None
Request Example:
curl -X GET http://localhost:8000/api/health
Response Example:
{
"status": "healthy",
"timestamp": "2024-01-15T14:30:00Z",
"version": "1.0.0",
"database": "connected",
"redis": "connected",
"uptime": "2d 14h 32m"
}
Error Responses:
503: Service Unavailable - One or more components are unhealthy
Notes:
- More comprehensive than
/api/pinepods_check - Includes dependency status checks
- Useful for monitoring and alerting systems
Authentication & Initial Setup
GET /api/data/get_key
Description: Retrieve API key using HTTP Basic Authentication (username:password). Creates new API key if none exists for the user.
Authentication: 🔓 Open (requires Basic Auth)
Request Headers:
Authorization: Basic <base64_encoded_username:password>
Parameters: None
Request Example:
curl -X GET \
-H "Authorization: Basic $(echo -n 'username:password' | base64)" \
http://localhost:8000/api/data/get_key
Response Example (No MFA):
{
"status": "success",
"retrieved_key": "pk_1234567890abcdef1234567890abcdef",
"mfa_required": false,
"user_id": 123,
"mfa_session_token": null
}
Response Example (MFA Required):
{
"status": "mfa_required",
"retrieved_key": null,
"mfa_required": true,
"user_id": 123,
"mfa_session_token": "secure_session_token_12345"
}
Error Responses:
401: Unauthorized - Invalid username/password or missing Authorization header500: Internal Server Error - Database error
Notes:
- Uses HTTP Basic Authentication (RFC 7617)
- If MFA is enabled, returns session token for MFA verification step
- If MFA is disabled, returns API key directly
- Session tokens expire after 5 minutes
- API key permissions match user account level (admin/standard)
POST /api/data/verify_mfa_and_get_key
Description: Complete MFA authentication and receive API key using session token from get_key endpoint
Authentication: 🔓 Open (requires MFA session token)
Request Headers:
-H "Content-Type: application/json"
Request Body:
{
"mfa_session_token": "secure_session_token_12345",
"mfa_code": "123456"
}
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| mfa_session_token | string | Yes | Session token from get_key endpoint when MFA required |
| mfa_code | string | Yes | 6-digit TOTP code from authenticator app |
Request Example:
curl -X POST \
-H "Content-Type: application/json" \
-d '{"mfa_session_token":"secure_session_token_12345","mfa_code":"123456"}' \
http://localhost:8000/api/data/verify_mfa_and_get_key
Response Example (Success):
{
"status": "success",
"retrieved_key": "pk_1234567890abcdef1234567890abcdef",
"verified": true
}
Response Example (Invalid Code):
{
"status": "invalid_code",
"retrieved_key": null,
"verified": false
}
Response Example (Session Expired):
{
"status": "session_expired",
"retrieved_key": null,
"verified": false
}
Error Responses:
400: Bad Request - Missing required fields500: Internal Server Error - Database error
Notes:
- Second step of two-factor authentication flow
- Must use mfa_session_token received from get_key endpoint
- Session tokens expire after 5 minutes
- MFA codes are 6-digit TOTP tokens (30-second window)
- Session token is consumed on successful verification (prevents replay)
GET /api/data/public_oidc_providers
Description: List all publicly available OIDC authentication providers configured on the server
Authentication: 🔓 Open
Parameters: None
Request Example:
curl -X GET http://localhost:8000/api/data/public_oidc_providers
Response Example:
{
"providers": [
{
"id": "google",
"name": "Google",
"icon_url": "https://accounts.google.com/favicon.ico",
"login_url": "/api/auth/google/login"
},
{
"id": "github",
"name": "GitHub",
"icon_url": "https://github.com/favicon.ico",
"login_url": "/api/auth/github/login"
}
]
}
Error Responses:
500: Internal Server Error - Configuration error
Notes:
- Used by login pages to show available SSO options
- Only returns enabled and publicly visible providers
- Icon URLs may be external or proxied through the API
POST /api/data/create_first
Description: Create the first admin user during initial setup. Only works if no admin users exist.
Authentication: 🔓 Open (first-time setup only)
Request Headers:
Content-Type: application/json
Request Body:
{
"fullname": "string",
"username": "string",
"email": "string",
"password": "string"
}
Request Example:
curl -X POST \
-H "Content-Type: application/json" \
-d '{
"fullname":"Admin User",
"username":"admin",
"email":"admin@example.com",
"password":"securepassword123"
}' \
http://localhost:8000/api/data/create_first
Response Example:
{
"status": "success",
"message": "First admin user created successfully",
"user_id": 1
}
Error Responses:
409: Conflict - Admin user already exists400: Bad Request - Invalid input data500: Internal Server Error - Database error
Notes:
- Only available during initial server setup
- Automatically grants admin privileges
- Endpoint becomes unavailable after first admin is created
- Password is automatically hashed and salted
GET /api/data/self_service_status
Description: Check if self-service user registration is enabled on the server
Authentication: 🔓 Open
Parameters: None
Request Example:
curl -X GET http://localhost:8000/api/data/self_service_status
Response Example:
{
"self_service_enabled": true
}
Error Responses:
500: Internal Server Error - Configuration retrieval error
Notes:
- Used by registration pages to show/hide signup forms
- Configuration controlled by admin settings
- When disabled, only admins can create new accounts
POST /api/auth/store_state
Description: Store OIDC authentication state for secure OAuth flow validation
Authentication: 🔓 Open
Request Headers:
Content-Type: application/json
Request Body:
{
"state": "string",
"provider": "string",
"redirect_url": "string"
}
Request Example:
curl -X POST \
-H "Content-Type: application/json" \
-d '{
"state":"random_state_string_123",
"provider":"google",
"redirect_url":"http://localhost:3000/auth/callback"
}' \
http://localhost:8000/api/auth/store_state
Response Example:
{
"status": "success",
"expires_in": 300
}
Error Responses:
400: Bad Request - Invalid state or provider500: Internal Server Error - Storage error
Notes:
- Part of secure OIDC authentication flow
- State expires after 5 minutes for security
- Used to prevent CSRF attacks in OAuth flow
GET /api/auth/callback
Description: Handle OIDC authentication callback and complete user authentication
Authentication: 🔓 Open
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| code | string | Yes | Authorization code from OIDC provider |
| state | string | Yes | State parameter for CSRF protection |
Request Example:
curl -X GET 'http://localhost:8000/api/auth/callback?code=auth_code_123&state=random_state_string_123'
Response Example:
{
"status": "success",
"api_key": "pk_1234567890abcdef1234567890abcdef",
"user_id": 123,
"redirect_url": "http://localhost:3000/dashboard"
}
Error Responses:
400: Bad Request - Invalid or expired state401: Unauthorized - OIDC authentication failed500: Internal Server Error - Token exchange error
Notes:
- Completes OIDC authentication flow
- Creates user account if first-time login
- Returns API key for subsequent requests
- Handles automatic account linking
Public Configuration
GET /api/data/config
Description: Retrieve public API configuration information required by clients
Authentication: 🔓 Open
Parameters: None
Request Example:
curl -X GET http://localhost:8000/api/data/config
Response Example:
{
"api_url": "http://localhost:8000/api",
"search_api_url": "http://localhost:5000/api/search",
"proxy_url": "http://localhost:8000/api/proxy",
"websocket_url": "ws://localhost:8000/ws",
"version": "1.0.0",
"features": {
"downloads_enabled": true,
"guest_access": false,
"self_service": true,
"rss_feeds": true
}
}
Error Responses:
500: Internal Server Error - Configuration error
Notes:
- Used by clients to discover API endpoints
- Feature flags help clients adapt to server configuration
- URLs may include reverse proxy configuration
- Version information helps with client compatibility
🔐 USER API KEY ENDPOINTS (Standard User Authentication)
User Profile & Settings
GET /api/data/verify_key
Description: Verify the validity of an API key
Authentication: 🔐 User API Key
Request Headers:
-H "Api-Key: YOUR_API_KEY"
Parameters: None
Request Example:
curl -X GET \
-H "Api-Key: pk_1234567890abcdef1234567890abcdef" \
http://localhost:8000/api/data/verify_key
Response Example:
{
"status": "success"
}
Error Responses:
401: Unauthorized - Invalid API key500: Internal Server Error - Database error
Notes:
- Simple API key validation endpoint
- Returns success if key is valid, error if invalid
- Used for testing API key validity
GET /api/data/get_user
Description: Get user ID associated with the provided API key
Authentication: 🔐 User API Key
Request Headers:
-H "Api-Key: YOUR_API_KEY"
Parameters: None
Request Example:
curl -X GET \
-H "Api-Key: pk_1234567890abcdef1234567890abcdef" \
http://localhost:8000/api/data/get_user
Response Example:
{
"status": "success",
"retrieved_id": 123
}
Error Responses:
401: Unauthorized - Invalid API key500: Internal Server Error - Database error
Notes:
- Simple endpoint to get user ID from API key
- Commonly used by clients to identify current user
- More lightweight than
/verify_key
GET /api/data/user_details_id/user_id
Description: Get detailed user information by user ID. Users can only access their own details unless they are admin.
Authentication: 🔐 User API Key
Request Headers:
-H "Api-Key: YOUR_API_KEY"
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| user_id | integer | Yes | User ID to retrieve details for |
Request Example:
curl -X GET \
-H "Api-Key: pk_1234567890abcdef1234567890abcdef" \
http://localhost:8000/api/data/user_details_id/123
Response Example:
{
"UserID": 123,
"Fullname": "John Doe",
"Username": "johndoe",
"Email": "john@example.com",
"Hashed_PW": null,
"Salt": null
}
Error Responses:
401: Unauthorized - Invalid API key403: Forbidden - Access denied to user details (non-admin accessing other users)500: Internal Server Error - Database error
Notes:
- Standard users can only access their own details
- Admin users can access any user's details
- Contains full user profile information
GET /api/data/get_theme/user_id
Description: Get the current theme settings for a user. Users can only get their own theme settings.
Authentication: 🔐 User API Key
Request Headers:
-H "Api-Key: YOUR_API_KEY"
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| user_id | integer | Yes | User ID to get theme for |
Request Example:
curl -X GET \
-H "Api-Key: pk_1234567890abcdef1234567890abcdef" \
http://localhost:8000/api/data/get_theme/123
Response Example:
{
"theme": "dark"
}
Error Responses:
401: Unauthorized - Invalid API key403: Forbidden - Cannot access other user's theme settings404: Not Found - User does not exist500: Internal Server Error - Database error
Notes:
- Available themes: "light", "dark", "auto"
- Users can only access their own theme settings
- Theme setting affects UI appearance across all clients
PUT /api/data/user/set_theme
Description: Update the theme preference for a user. Users can only update their own theme.
Authentication: 🔐 User API Key
Request Headers:
-H "Api-Key: YOUR_API_KEY"
-H "Content-Type: application/json"
Request Body:
{
"user_id": 123,
"new_theme": "dark"
}
Request Example:
curl -X PUT \
-H "Api-Key: pk_1234567890abcdef1234567890abcdef" \
-H "Content-Type: application/json" \
-d '{"user_id":123,"new_theme":"dark"}' \
http://localhost:8000/api/data/user/set_theme
Response Example:
{
"message": "Theme updated successfully"
}
Error Responses:
401: Unauthorized - Invalid API key403: Forbidden - Cannot update other user's theme400: Bad Request - Invalid theme value500: Internal Server Error - Database error
Notes:
- Valid themes: "light", "dark", "auto"
- Changes are applied immediately
- Theme preference is synchronized across all user sessions
GET /api/data/first_login_done/user_id
Description: Check if a user has completed their first login setup process
Authentication: 🔐 User API Key
Request Headers:
-H "Api-Key: YOUR_API_KEY"
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| user_id | integer | Yes | User ID to check first login status |
Request Example:
curl -X GET \
-H "Api-Key: pk_1234567890abcdef1234567890abcdef" \
http://localhost:8000/api/data/first_login_done/123
Response Example:
{
"FirstLogin": false
}
Error Responses:
401: Unauthorized - Invalid API key403: Forbidden - Cannot check other user's login status404: Not Found - User does not exist500: Internal Server Error - Database error
Notes:
trueindicates user needs to complete first-time setupfalseindicates user has completed setup- Used to trigger onboarding flows in clients
GET /api/data/my_user_info/user_id
Description: Get comprehensive user information for the authenticated user. More detailed than user_details_id.
Authentication: 🔐 User API Key
Request Headers:
-H "Api-Key: YOUR_API_KEY"
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| user_id | integer | Yes | User ID (must match authenticated user) |
Request Example:
curl -X GET \
-H "Api-Key: pk_1234567890abcdef1234567890abcdef" \
http://localhost:8000/api/data/my_user_info/123
Response Example:
{
"userid": 123,
"fullname": "John Doe",
"username": "johndoe",
"email": "john@example.com",
"isadmin": 0
}
Error Responses:
401: Unauthorized - Invalid API key403: Forbidden - User ID does not match authenticated user404: Not Found - User does not exist500: Internal Server Error - Database error
Notes:
- Only accessible by the user themselves
- Contains all user preferences and settings
- Includes playback preferences and notification settings
POST /api/data/add_login_user
Description: Create a new user account via self-service registration (when self-service is enabled). No authentication required.
Authentication: 🔓 Open (No API Key Required)
Request Headers:
-H "Content-Type: application/json"
Request Body:
{
"fullname": "John Doe",
"username": "johndoe",
"email": "john@example.com",
"hash_pw": "$2b$12$abcdef1234567890abcdef1234567890abcdef1234567890"
}
Request Example:
curl -X POST \
-H "Content-Type: application/json" \
-d '{
"fullname":"John Doe",
"username":"johndoe",
"email":"john@example.com",
"hash_pw":"$2b$12$abcdef1234567890abcdef1234567890abcdef1234567890"
}' \
http://localhost:8000/api/data/add_login_user
Response Example:
{
"detail": "User added successfully",
"user_id": 124
}
Error Responses:
403: Forbidden - Self-service registration is disabled409: Conflict - Username or email already exists400: Bad Request - Invalid input data500: Internal Server Error - Database error
Notes:
- Only available when self-service registration is enabled
hash_pwfield must contain pre-hashed password (bcrypt recommended)- New users start with standard privileges (isadmin = false)
- Username and email must be unique
- Username is automatically converted to lowercase