- Add VideoProcessor service to PostHandler for frame-based video moderation - Implement multi-frame extraction and Azure OpenAI Vision analysis for video content - Enhance VideoStitchingService with filters, speed control, and text overlays - Add image upload dialogs for group avatar and banner in GroupCreationModal - Implement navigation placeholders for mentions, hashtags, and URLs in sojornRichText
1248 lines
22 KiB
Markdown
1248 lines
22 KiB
Markdown
# Sojorn API Reference
|
|
|
|
## 🚀 Complete REST API Documentation
|
|
|
|
**Version**: 3.0
|
|
**Status**: ✅ **PRODUCTION READY**
|
|
**Last Updated**: February 17, 2026
|
|
|
|
---
|
|
|
|
## 📋 Overview
|
|
|
|
The Sojorn API provides comprehensive REST endpoints for all platform features including authentication, posts, groups, beacons, E2EE chat, and more. All endpoints follow RESTful conventions and return JSON responses.
|
|
|
|
## 🔐 Authentication
|
|
|
|
### Base URL
|
|
```
|
|
Production: https://api.sojorn.app
|
|
Development: http://localhost:8080
|
|
```
|
|
|
|
### Authentication Methods
|
|
- **JWT Bearer Token**: `Authorization: Bearer <token>`
|
|
- **API Key**: `X-API-Key: <api-key>` (for service-to-service)
|
|
- **Session Cookie**: Automatic cookie-based authentication for web
|
|
|
|
### Token Endpoints
|
|
|
|
#### POST /auth/register
|
|
Register a new user account.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"email": "user@example.com",
|
|
"password": "securePassword123",
|
|
"handle": "username",
|
|
"display_name": "Display Name"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"user": {
|
|
"id": "uuid",
|
|
"email": "user@example.com",
|
|
"handle": "username",
|
|
"display_name": "Display Name",
|
|
"created_at": "2026-02-17T12:00:00Z"
|
|
},
|
|
"token": "jwt_token_here",
|
|
"refresh_token": "refresh_token_here"
|
|
}
|
|
```
|
|
|
|
#### POST /auth/login
|
|
Authenticate user and return tokens.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"email": "user@example.com",
|
|
"password": "securePassword123"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"user": {
|
|
"id": "uuid",
|
|
"email": "user@example.com",
|
|
"handle": "username",
|
|
"display_name": "Display Name"
|
|
},
|
|
"token": "jwt_token_here",
|
|
"refresh_token": "refresh_token_here"
|
|
}
|
|
```
|
|
|
|
#### POST /auth/refresh
|
|
Refresh JWT access token.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"refresh_token": "refresh_token_here"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"token": "new_jwt_token_here",
|
|
"expires_at": "2026-02-18T12:00:00Z"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 👤 User Management
|
|
|
|
### GET /users/me
|
|
Get current user profile.
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"user": {
|
|
"id": "uuid",
|
|
"email": "user@example.com",
|
|
"handle": "username",
|
|
"display_name": "Display Name",
|
|
"bio": "User bio",
|
|
"avatar_url": "https://cdn.sojorn.app/avatars/uuid.jpg",
|
|
"follower_count": 150,
|
|
"following_count": 75,
|
|
"post_count": 42,
|
|
"created_at": "2026-02-17T12:00:00Z",
|
|
"is_verified": true,
|
|
"is_premium": false
|
|
}
|
|
}
|
|
```
|
|
|
|
### PUT /users/me
|
|
Update current user profile.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"display_name": "New Display Name",
|
|
"bio": "Updated bio",
|
|
"avatar_url": "https://cdn.sojorn.app/avatars/new.jpg",
|
|
"location": "San Francisco, CA",
|
|
"website": "https://example.com"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"user": {
|
|
"id": "uuid",
|
|
"display_name": "New Display Name",
|
|
"bio": "Updated bio",
|
|
"avatar_url": "https://cdn.sojorn.app/avatars/new.jpg",
|
|
"location": "San Francisco, CA",
|
|
"website": "https://example.com"
|
|
}
|
|
}
|
|
```
|
|
|
|
### GET /users/{handle}
|
|
Get user profile by handle.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"user": {
|
|
"id": "uuid",
|
|
"handle": "username",
|
|
"display_name": "Display Name",
|
|
"bio": "User bio",
|
|
"avatar_url": "https://cdn.sojorn.app/avatars/uuid.jpg",
|
|
"follower_count": 150,
|
|
"following_count": 75,
|
|
"post_count": 42,
|
|
"is_following": false,
|
|
"is_blocked": false,
|
|
"created_at": "2026-02-17T12:00:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 📝 Posts & Content
|
|
|
|
### GET /posts
|
|
Get posts with filtering and pagination.
|
|
|
|
**Query Parameters:**
|
|
- `limit`: Number of posts to return (default: 20, max: 100)
|
|
- `offset`: Pagination offset (default: 0)
|
|
- `category`: Filter by category
|
|
- `author_id`: Filter by author
|
|
- `has_video`: Filter by video content (true/false)
|
|
- `algorithm`: Use algorithmic ranking (true/false)
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"posts": [
|
|
{
|
|
"id": "uuid",
|
|
"author_id": "uuid",
|
|
"author_handle": "username",
|
|
"author_avatar": "https://cdn.sojorn.app/avatars/uuid.jpg",
|
|
"body": "Post content here",
|
|
"image_url": "https://cdn.sojorn.app/posts/uuid.jpg",
|
|
"video_url": "https://cdn.sojorn.app/videos/uuid.mp4",
|
|
"thumbnail_url": "https://cdn.sojorn.app/thumbnails/uuid.jpg",
|
|
"category": "general",
|
|
"visibility": "public",
|
|
"like_count": 25,
|
|
"comment_count": 8,
|
|
"repost_count": 3,
|
|
"share_count": 2,
|
|
"is_liked": false,
|
|
"is_reposted": false,
|
|
"is_saved": false,
|
|
"created_at": "2026-02-17T12:00:00Z",
|
|
"updated_at": "2026-02-17T12:00:00Z"
|
|
}
|
|
],
|
|
"pagination": {
|
|
"total": 1000,
|
|
"limit": 20,
|
|
"offset": 0,
|
|
"has_more": true
|
|
}
|
|
}
|
|
```
|
|
|
|
### POST /posts
|
|
Create a new post.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"body": "Post content here",
|
|
"category": "general",
|
|
"visibility": "public",
|
|
"image_url": "https://cdn.sojorn.app/posts/uuid.jpg",
|
|
"video_url": "https://cdn.sojorn.app/videos/uuid.mp4",
|
|
"thumbnail_url": "https://cdn.sojorn.app/thumbnails/uuid.jpg",
|
|
"is_nsfw": false,
|
|
"tags": ["tag1", "tag2"]
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"post": {
|
|
"id": "uuid",
|
|
"body": "Post content here",
|
|
"category": "general",
|
|
"visibility": "public",
|
|
"image_url": "https://cdn.sojorn.app/posts/uuid.jpg",
|
|
"video_url": "https://cdn.sojorn.app/videos/uuid.mp4",
|
|
"thumbnail_url": "https://cdn.sojorn.app/thumbnails/uuid.jpg",
|
|
"created_at": "2026-02-17T12:00:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
### PUT /posts/{id}
|
|
Update an existing post.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"body": "Updated post content",
|
|
"category": "general",
|
|
"visibility": "public",
|
|
"is_nsfw": false
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"post": {
|
|
"id": "uuid",
|
|
"body": "Updated post content",
|
|
"updated_at": "2026-02-17T12:30:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
### DELETE /posts/{id}
|
|
Delete a post.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Post deleted successfully"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 💬 Comments
|
|
|
|
### GET /posts/{post_id}/comments
|
|
Get comments for a post.
|
|
|
|
**Query Parameters:**
|
|
- `limit`: Number of comments (default: 50)
|
|
- `offset`: Pagination offset
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"comments": [
|
|
{
|
|
"id": "uuid",
|
|
"post_id": "uuid",
|
|
"author_id": "uuid",
|
|
"author_handle": "username",
|
|
"author_avatar": "https://cdn.sojorn.app/avatars/uuid.jpg",
|
|
"body": "Comment content",
|
|
"like_count": 5,
|
|
"reply_count": 2,
|
|
"is_liked": false,
|
|
"created_at": "2026-02-17T12:00:00Z"
|
|
}
|
|
],
|
|
"pagination": {
|
|
"total": 100,
|
|
"limit": 50,
|
|
"offset": 0,
|
|
"has_more": true
|
|
}
|
|
}
|
|
```
|
|
|
|
### POST /posts/{post_id}/comments
|
|
Create a comment on a post.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"body": "Comment content",
|
|
"parent_id": null
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"comment": {
|
|
"id": "uuid",
|
|
"body": "Comment content",
|
|
"created_at": "2026-02-17T12:00:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🔄 Reposts & Amplification
|
|
|
|
### POST /posts/{id}/repost
|
|
Create a repost.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"type": "standard",
|
|
"comment": "Optional comment for quote repost"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"repost": {
|
|
"id": "uuid",
|
|
"original_post_id": "uuid",
|
|
"author_id": "uuid",
|
|
"type": "standard",
|
|
"comment": null,
|
|
"created_at": "2026-02-17T12:00:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
### POST /posts/{id}/boost
|
|
Boost a post for amplification.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"boost_type": "amplify",
|
|
"boost_amount": 1
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Post boosted successfully"
|
|
}
|
|
```
|
|
|
|
### GET /posts/{id}/amplification
|
|
Get amplification analytics for a post.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"analytics": {
|
|
"post_id": "uuid",
|
|
"total_amplification": 150,
|
|
"amplification_rate": 0.75,
|
|
"repost_counts": {
|
|
"standard": 10,
|
|
"quote": 5,
|
|
"boost": 3,
|
|
"amplify": 2
|
|
},
|
|
"metrics": [
|
|
{
|
|
"total_reach": 1000,
|
|
"engagement_count": 75,
|
|
"engagement_rate": 0.075,
|
|
"new_followers": 5,
|
|
"shares": 20,
|
|
"comments": 15,
|
|
"likes": 40,
|
|
"last_updated": "2026-02-17T12:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 📍 Beacons (Local Safety)
|
|
|
|
### GET /beacons
|
|
Get beacons with geospatial filtering.
|
|
|
|
**Query Parameters:**
|
|
- `lat`: Latitude for center point
|
|
- `lng`: Longitude for center point
|
|
- `radius_km`: Search radius in kilometers (default: 10)
|
|
- `category`: Filter by category
|
|
- `status`: Filter by status
|
|
- `only_official`: Filter for official sources only
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"beacons": [
|
|
{
|
|
"id": "uuid",
|
|
"title": "Community Event",
|
|
"description": "Description of the beacon",
|
|
"category": "event",
|
|
"status": "active",
|
|
"lat": 37.7749,
|
|
"lng": -122.4194,
|
|
"author_id": "uuid",
|
|
"author_handle": "username",
|
|
"is_verified": true,
|
|
"is_official_source": true,
|
|
"organization_name": "City Hall",
|
|
"vouch_count": 25,
|
|
"report_count": 0,
|
|
"confidence_score": 0.95,
|
|
"image_url": "https://cdn.sojorn.app/beacons/uuid.jpg",
|
|
"action_items": [
|
|
"Volunteer at the event",
|
|
"Share with neighbors"
|
|
],
|
|
"neighborhood": "Downtown",
|
|
"created_at": "2026-02-17T12:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### POST /beacons
|
|
Create a new beacon.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"title": "Community Event",
|
|
"description": "Description of the beacon",
|
|
"category": "event",
|
|
"lat": 37.7749,
|
|
"lng": -122.4194,
|
|
"image_url": "https://cdn.sojorn.app/beacons/uuid.jpg",
|
|
"action_items": [
|
|
"Volunteer at the event",
|
|
"Share with neighbors"
|
|
],
|
|
"neighborhood": "Downtown"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"beacon": {
|
|
"id": "uuid",
|
|
"title": "Community Event",
|
|
"created_at": "2026-02-17T12:00:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
### POST /beacons/{id}/vouch
|
|
Vouch for a beacon (positive interaction).
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"vouch_count": 26,
|
|
"confidence_score": 0.96
|
|
}
|
|
```
|
|
|
|
### POST /beacons/{id}/report
|
|
Report a beacon (negative interaction).
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"reason": "inaccurate_information",
|
|
"comment": "This information is not accurate"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"report_count": 1,
|
|
"confidence_score": 0.90
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 👥 Groups
|
|
|
|
### GET /groups
|
|
Get groups with filtering.
|
|
|
|
**Query Parameters:**
|
|
- `limit`: Number of groups (default: 20)
|
|
- `offset`: Pagination offset
|
|
- `category`: Filter by category
|
|
- `is_private`: Filter by privacy setting
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"groups": [
|
|
{
|
|
"id": "uuid",
|
|
"name": "Group Name",
|
|
"description": "Group description",
|
|
"category": "general",
|
|
"is_private": false,
|
|
"member_count": 150,
|
|
"post_count": 500,
|
|
"avatar_url": "https://cdn.sojorn.app/groups/uuid.jpg",
|
|
"banner_url": "https://cdn.sojorn.app/groups/banner/uuid.jpg",
|
|
"created_by": "uuid",
|
|
"created_at": "2026-02-17T12:00:00Z",
|
|
"is_member": false,
|
|
"is_admin": false
|
|
}
|
|
],
|
|
"pagination": {
|
|
"total": 100,
|
|
"limit": 20,
|
|
"offset": 0,
|
|
"has_more": true
|
|
}
|
|
}
|
|
```
|
|
|
|
### POST /groups
|
|
Create a new group.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"name": "Group Name",
|
|
"description": "Group description",
|
|
"category": "general",
|
|
"is_private": false,
|
|
"avatar_url": "https://cdn.sojorn.app/groups/uuid.jpg",
|
|
"banner_url": "https://cdn.sojorn.app/groups/banner/uuid.jpg"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"group": {
|
|
"id": "uuid",
|
|
"name": "Group Name",
|
|
"created_at": "2026-02-17T12:00:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🔐 E2EE Chat
|
|
|
|
### POST /e2ee/register-device
|
|
Register a device for E2EE chat.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"device_name": "iPhone 14",
|
|
"device_type": "mobile",
|
|
"public_key": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"device": {
|
|
"id": "device_uuid",
|
|
"name": "iPhone 14",
|
|
"type": "mobile",
|
|
"public_key": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----",
|
|
"created_at": "2026-02-17T12:00:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
### POST /e2ee/send-message
|
|
Send an encrypted message.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"recipient_id": "uuid",
|
|
"message": "encrypted_message_here",
|
|
"is_encrypted": true
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": {
|
|
"id": "uuid",
|
|
"sender_id": "uuid",
|
|
"recipient_id": "uuid",
|
|
"message": "encrypted_message_here",
|
|
"is_encrypted": true,
|
|
"created_at": "2026-02-17T12:00:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
### GET /e2ee/messages/{user_id}
|
|
Get encrypted messages with a user.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"messages": [
|
|
{
|
|
"id": "uuid",
|
|
"sender_id": "uuid",
|
|
"recipient_id": "uuid",
|
|
"message": "encrypted_message_here",
|
|
"is_encrypted": true,
|
|
"created_at": "2026-02-17T12:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🎬 Video (Quips)
|
|
|
|
### POST /videos/upload
|
|
Upload and process a video.
|
|
|
|
**Request (multipart/form-data):**
|
|
```
|
|
video: [video file]
|
|
thumbnail: [thumbnail file]
|
|
title: "Video Title"
|
|
description: "Video description"
|
|
duration: 30
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"video": {
|
|
"id": "uuid",
|
|
"url": "https://cdn.sojorn.app/videos/uuid.mp4",
|
|
"thumbnail_url": "https://cdn.sojorn.app/thumbnails/uuid.jpg",
|
|
"title": "Video Title",
|
|
"description": "Video description",
|
|
"duration": 30,
|
|
"created_at": "2026-02-17T12:00:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
### POST /videos/process
|
|
Process video with effects.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"video_id": "uuid",
|
|
"filter": "vintage",
|
|
"speed": 1.5,
|
|
"text_overlays": [
|
|
{
|
|
"text": "Hello World",
|
|
"x": 100,
|
|
"y": 100,
|
|
"start_time": 5,
|
|
"end_time": 10
|
|
}
|
|
],
|
|
"audio_track": {
|
|
"url": "https://cdn.sojorn.app/audio/uuid.mp3",
|
|
"volume": 0.5,
|
|
"fade_in": true,
|
|
"fade_out": true
|
|
}
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"processed_video": {
|
|
"url": "https://cdn.sojorn.app/videos/processed/uuid.mp4",
|
|
"processing_time": 15.5
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🤖 AI Moderation
|
|
|
|
### POST /moderation/analyze
|
|
Analyze content for moderation.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"content": "Content to analyze",
|
|
"type": "text",
|
|
"image_url": "https://cdn.sojorn.app/images/uuid.jpg",
|
|
"video_url": "https://cdn.sojorn.app/videos/uuid.mp4"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"analysis": {
|
|
"is_safe": true,
|
|
"score": 0.95,
|
|
"categories": {
|
|
"hate": 0.1,
|
|
"greed": 0.05,
|
|
"delusion": 0.02
|
|
},
|
|
"recommendation": "approve",
|
|
"confidence": 0.98
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🚫 Blocking System
|
|
|
|
### GET /users/me/blocked
|
|
Get blocked users list.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"blocked_users": [
|
|
{
|
|
"id": "uuid",
|
|
"handle": "blocked_user",
|
|
"display_name": "Blocked User",
|
|
"blocked_at": "2026-02-17T12:00:00Z"
|
|
}
|
|
],
|
|
"total": 5
|
|
}
|
|
```
|
|
|
|
### POST /users/{id}/block
|
|
Block a user.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "User blocked successfully"
|
|
}
|
|
```
|
|
|
|
### DELETE /users/{id}/block
|
|
Unblock a user.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "User unblocked successfully"
|
|
}
|
|
```
|
|
|
|
### POST /users/me/blocked/import
|
|
Import blocked users from other platforms.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"platform": "twitter",
|
|
"data": "username1,username2,username3"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"imported": 3,
|
|
"skipped": 0,
|
|
"failed": 0
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 Analytics & Metrics
|
|
|
|
### GET /analytics/feed
|
|
Get feed analytics.
|
|
|
|
**Query Parameters:**
|
|
- `date_range`: 7d, 30d, 90d
|
|
- `category`: Filter by category
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"analytics": {
|
|
"total_posts": 1000,
|
|
"total_engagement": 5000,
|
|
"engagement_rate": 0.05,
|
|
"top_categories": [
|
|
{"category": "general", "count": 400},
|
|
{"category": "hobby", "count": 300}
|
|
],
|
|
"daily_stats": [
|
|
{
|
|
"date": "2026-02-17",
|
|
"posts": 50,
|
|
"engagement": 250
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🔍 Search
|
|
|
|
### GET /search
|
|
Search across the platform.
|
|
|
|
**Query Parameters:**
|
|
- `q`: Search query
|
|
- `type`: posts, users, groups, beacons
|
|
- `limit`: Number of results (default: 20)
|
|
- `offset`: Pagination offset
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"results": {
|
|
"posts": [
|
|
{
|
|
"id": "uuid",
|
|
"body": "Post containing search term",
|
|
"author_handle": "username",
|
|
"created_at": "2026-02-17T12:00:00Z"
|
|
}
|
|
],
|
|
"users": [
|
|
{
|
|
"id": "uuid",
|
|
"handle": "username",
|
|
"display_name": "Display Name",
|
|
"bio": "Bio containing search term"
|
|
}
|
|
],
|
|
"groups": [
|
|
{
|
|
"id": "uuid",
|
|
"name": "Group Name",
|
|
"description": "Description containing search term"
|
|
}
|
|
],
|
|
"beacons": [
|
|
{
|
|
"id": "uuid",
|
|
"title": "Beacon Title",
|
|
"description": "Description containing search term"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 📱 Notifications
|
|
|
|
### GET /notifications
|
|
Get user notifications.
|
|
|
|
**Query Parameters:**
|
|
- `limit`: Number of notifications (default: 50)
|
|
- `offset`: Pagination offset
|
|
- `type`: Filter by notification type
|
|
- `unread_only`: Filter for unread only
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"notifications": [
|
|
{
|
|
"id": "uuid",
|
|
"type": "like",
|
|
"title": "New Like",
|
|
"body": "username liked your post",
|
|
"data": {
|
|
"post_id": "uuid",
|
|
"user_id": "uuid"
|
|
},
|
|
"is_read": false,
|
|
"created_at": "2026-02-17T12:00:00Z"
|
|
}
|
|
],
|
|
"unread_count": 5,
|
|
"pagination": {
|
|
"total": 100,
|
|
"limit": 50,
|
|
"offset": 0,
|
|
"has_more": true
|
|
}
|
|
}
|
|
```
|
|
|
|
### POST /notifications/{id}/read
|
|
Mark notification as read.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Notification marked as read"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## ⚙️ Settings & Preferences
|
|
|
|
### GET /users/me/settings
|
|
Get user settings.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"settings": {
|
|
"notifications": {
|
|
"push_enabled": true,
|
|
"email_enabled": true,
|
|
"likes": true,
|
|
"comments": true,
|
|
"follows": true,
|
|
"mentions": true
|
|
},
|
|
"privacy": {
|
|
"profile_visibility": "public",
|
|
"show_online_status": true,
|
|
"allow_tagging": true,
|
|
"nsfw_blur_enabled": true
|
|
},
|
|
"feed": {
|
|
"algorithm_enabled": true,
|
|
"show_suggested_posts": true,
|
|
"hide_sensitive_content": true
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### PUT /users/me/settings
|
|
Update user settings.
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"notifications": {
|
|
"push_enabled": true,
|
|
"email_enabled": false,
|
|
"likes": true,
|
|
"comments": false,
|
|
"follows": true,
|
|
"mentions": true
|
|
},
|
|
"privacy": {
|
|
"profile_visibility": "public",
|
|
"show_online_status": false,
|
|
"allow_tagging": true,
|
|
"nsfw_blur_enabled": true
|
|
}
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"settings": {
|
|
"notifications": {
|
|
"push_enabled": true,
|
|
"email_enabled": false,
|
|
"likes": true,
|
|
"comments": false,
|
|
"follows": true,
|
|
"mentions": true
|
|
},
|
|
"privacy": {
|
|
"profile_visibility": "public",
|
|
"show_online_status": false,
|
|
"allow_tagging": true,
|
|
"nsfw_blur_enabled": true
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🏥 Health & Monitoring
|
|
|
|
### GET /health
|
|
System health check.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"status": "healthy",
|
|
"timestamp": "2026-02-17T12:00:00Z",
|
|
"uptime": "72h30m15s",
|
|
"version": "3.0.0",
|
|
"environment": "production",
|
|
"checks": {
|
|
"database": {
|
|
"status": "healthy",
|
|
"message": "Database connection successful",
|
|
"duration": "5ms"
|
|
},
|
|
"redis": {
|
|
"status": "healthy",
|
|
"message": "Redis connection successful",
|
|
"duration": "2ms"
|
|
},
|
|
"storage": {
|
|
"status": "healthy",
|
|
"message": "Cloudflare R2 accessible",
|
|
"duration": "150ms"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### GET /metrics
|
|
Application metrics.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"metrics": {
|
|
"requests": {
|
|
"total": 1000000,
|
|
"per_second": 50,
|
|
"error_rate": 0.01
|
|
},
|
|
"database": {
|
|
"connections": 25,
|
|
"queries_per_second": 100,
|
|
"avg_response_time": "25ms"
|
|
},
|
|
"memory": {
|
|
"used_mb": 512,
|
|
"available_mb": 1536,
|
|
"usage_percent": 25
|
|
},
|
|
"cpu": {
|
|
"usage_percent": 15,
|
|
"load_average": [0.5, 0.6, 0.7]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 📚 Error Responses
|
|
|
|
All endpoints return consistent error responses:
|
|
|
|
```json
|
|
{
|
|
"success": false,
|
|
"error": {
|
|
"code": "VALIDATION_ERROR",
|
|
"message": "Invalid input data",
|
|
"details": {
|
|
"field": "email",
|
|
"issue": "Invalid email format"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Common Error Codes
|
|
|
|
- `UNAUTHORIZED`: Authentication required or invalid
|
|
- `FORBIDDEN`: Insufficient permissions
|
|
- `NOT_FOUND`: Resource not found
|
|
- `VALIDATION_ERROR`: Invalid input data
|
|
- `RATE_LIMITED`: Too many requests
|
|
- `INTERNAL_ERROR`: Server error
|
|
- `SERVICE_UNAVAILABLE`: Service temporarily unavailable
|
|
|
|
---
|
|
|
|
## 📝 Rate Limiting
|
|
|
|
API endpoints are rate limited to prevent abuse:
|
|
|
|
- **Authentication**: 5 requests per minute
|
|
- **Content Creation**: 10 requests per minute
|
|
- **Search**: 30 requests per minute
|
|
- **General**: 100 requests per minute
|
|
|
|
Rate limit headers are included in responses:
|
|
```
|
|
X-RateLimit-Limit: 100
|
|
X-RateLimit-Remaining: 95
|
|
X-RateLimit-Reset: 1645123200
|
|
```
|
|
|
|
---
|
|
|
|
## 🔑 API Keys
|
|
|
|
For service-to-service integration, generate API keys in the admin panel:
|
|
|
|
```bash
|
|
# Example API key usage
|
|
curl -H "X-API-Key: your-api-key-here" \
|
|
-H "Content-Type: application/json" \
|
|
https://api.sojorn.app/posts
|
|
```
|
|
|
|
---
|
|
|
|
## 📞 Support
|
|
|
|
### Documentation
|
|
- **API Reference**: Complete endpoint documentation
|
|
- **SDKs**: Official SDKs for popular languages
|
|
- **Examples**: Code examples and tutorials
|
|
- **Changelog**: API version history and changes
|
|
|
|
### Support Channels
|
|
- **Discord**: API development discussion
|
|
- **GitHub**: Issue tracking and feature requests
|
|
- **Email**: api-support@sojorn.app
|
|
- **Status**: api.sojorn.app/status
|
|
|
|
---
|
|
|
|
**🚀 The Sojorn API provides comprehensive, production-ready endpoints for all platform features with proper authentication, rate limiting, and error handling.**
|