Flow Platform - API Documentation
Table of Contents
- API Overview
- Authentication
- User Service API
- Event Service API
- Social Service API
- Notification Service API
- WebSocket Events
- Error Handling
- Rate Limiting
- Response Formats
API Overview
Base URLs
| Service | Base URL | Port |
|---|---|---|
| API Gateway | http://localhost:3000 | 3000 |
| User Service | http://localhost:3001 | 3001 |
| Event Service | http://localhost:3002 | 3002 |
| Social Service | http://localhost:3003 | 3003 |
| Notification Service | http://localhost:3004 | 3004 |
| Realtime Service | http://localhost:3005 | 3005 |
| AI Services | http://localhost:8001 | 8001 |
Production: All client requests go through the API Gateway at https://api.flow.app
API Versioning
The Flow API supports versioning through URL prefixes:
- Current Version: v1
- Format:
/api/v1/{resource} - Unversioned:
/api/{resource}(defaults to latest stable version)
Examples:
/api/v1/users
/api/v1/events
/api/users (equivalent to /api/v1/users)
Common Headers
Required Headers
Content-Type: application/json
Authorization: Bearer <access_token>Optional Headers
X-Correlation-ID: <uuid> # Request tracing
X-API-Key: <api_key> # Service-to-service authentication
Accept-Language: en-US # Preferred language
User-Agent: Flow/1.0 # Client identificationAuthentication
Authentication Flow
Flow uses JWT (JSON Web Tokens) for authentication with a dual-token system:
- Access Token: Short-lived (15 minutes), used for API requests
- Refresh Token: Long-lived (7 days), used to obtain new access tokens
Token Structure
{
"header": {
"alg": "HS256",
"typ": "JWT"
},
"payload": {
"sub": "user-id-uuid",
"email": "user@example.com",
"username": "username",
"role": "user",
"permissions": ["read:events", "create:events"],
"sessionId": "session-uuid",
"iss": "flow-app",
"aud": "flow-users",
"iat": 1234567890,
"exp": 1234568790
}
}Authentication Methods
1. Register New User
Endpoint: POST /api/v1/auth/register
Request:
{
"email": "user@example.com",
"username": "johndoe",
"password": "SecurePassword123!",
"firstName": "John",
"lastName": "Doe",
"dateOfBirth": "1990-01-15",
"gender": "male"
}Response: 201 Created
{
"success": true,
"message": "User registered successfully",
"data": {
"user": {
"id": "uuid",
"email": "user@example.com",
"username": "johndoe",
"firstName": "John",
"lastName": "Doe",
"isVerified": false
},
"tokens": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 900
}
}
}2. Login
Endpoint: POST /api/v1/auth/login
Request:
{
"email": "user@example.com",
"password": "SecurePassword123!"
}Response: 200 OK
{
"success": true,
"data": {
"user": {
"id": "uuid",
"email": "user@example.com",
"username": "johndoe",
"firstName": "John",
"lastName": "Doe"
},
"tokens": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 900
}
}
}3. Refresh Token
Endpoint: POST /api/v1/auth/refresh
Request:
{
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}Response: 200 OK
{
"success": true,
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 900
}
}4. Logout
Endpoint: POST /api/v1/auth/logout
Headers: Authorization: Bearer <access_token>
Response: 200 OK
{
"success": true,
"message": "Logged out successfully"
}5. Password Reset Request
Endpoint: POST /api/v1/auth/forgot-password
Request:
{
"email": "user@example.com"
}Response: 200 OK
{
"success": true,
"message": "Password reset email sent"
}6. Reset Password
Endpoint: POST /api/v1/auth/reset-password
Request:
{
"token": "reset-token-from-email",
"newPassword": "NewSecurePassword123!"
}Response: 200 OK
{
"success": true,
"message": "Password reset successfully"
}7. Verify Email
Endpoint: POST /api/v1/auth/verify-email
Request:
{
"token": "verification-token-from-email"
}Response: 200 OK
{
"success": true,
"message": "Email verified successfully"
}User Service API
User Profile Management
Get Current User Profile
Endpoint: GET /api/v1/users/me
Authentication: Required
Response: 200 OK
{
"success": true,
"data": {
"id": "uuid",
"email": "user@example.com",
"username": "johndoe",
"firstName": "John",
"lastName": "Doe",
"fullName": "John Doe",
"age": 34,
"dateOfBirth": "1990-01-15T00:00:00Z",
"gender": "male",
"phoneNumber": "+1234567890",
"location": {
"city": "New York",
"state": "NY",
"country": "USA",
"coordinates": [-74.006, 40.7128]
},
"profilePicture": {
"url": "https://cdn.flow.app/profiles/uuid.jpg",
"publicId": "flow/profiles/uuid"
},
"bio": "Event enthusiast and social connector",
"interests": ["Music", "Sports", "Technology"],
"isVerified": true,
"isPremium": false,
"stats": {
"eventsCreated": 5,
"eventsAttended": 23,
"friendsCount": 142,
"groupsJoined": 8
},
"privacySettings": {
"profileVisibility": "public",
"showLocation": true,
"showAge": true,
"allowMessages": "everyone"
},
"lastActiveAt": "2024-03-10T10:30:00Z",
"onlineStatus": "online",
"createdAt": "2023-01-15T08:00:00Z",
"updatedAt": "2024-03-10T10:30:00Z"
}
}Get User by ID
Endpoint: GET /api/v1/users/:id
Parameters:
id(path): User ID (UUID)
Response: 200 OK
{
"success": true,
"data": {
"id": "uuid",
"username": "johndoe",
"firstName": "John",
"lastName": "Doe",
"profilePicture": {
"url": "https://cdn.flow.app/profiles/uuid.jpg"
},
"bio": "Event enthusiast",
"stats": {
"eventsCreated": 5,
"friendsCount": 142
}
}
}Update User Profile
Endpoint: PUT /api/v1/users/:id
Authentication: Required (must be own profile)
Request:
{
"firstName": "John",
"lastName": "Doe",
"bio": "Updated bio text",
"interests": ["Music", "Art", "Technology"],
"location": {
"city": "San Francisco",
"state": "CA",
"country": "USA"
}
}Response: 200 OK
{
"success": true,
"message": "Profile updated successfully",
"data": {
"id": "uuid",
"firstName": "John",
"lastName": "Doe",
"bio": "Updated bio text",
"updatedAt": "2024-03-10T10:45:00Z"
}
}Upload Profile Picture
Endpoint: POST /api/v1/users/:id/profile-picture
Authentication: Required
Content-Type: multipart/form-data
Request:
profilePicture: [File]
Response: 200 OK
{
"success": true,
"data": {
"profilePicture": {
"url": "https://cdn.flow.app/profiles/uuid.jpg",
"publicId": "flow/profiles/uuid"
}
}
}User Preferences
Get User Preferences
Endpoint: GET /api/v1/preferences
Authentication: Required
Response: 200 OK
{
"success": true,
"data": {
"language": "en",
"timezone": "America/New_York",
"theme": "dark",
"distanceUnit": "miles",
"notificationPreferences": {
"email": {
"eventInvites": true,
"friendRequests": true,
"messages": true,
"eventReminders": true,
"newsletter": false
},
"push": {
"eventInvites": true,
"friendRequests": true,
"messages": true,
"eventReminders": true,
"nearbyEvents": false
}
}
}
}Update User Preferences
Endpoint: PUT /api/v1/preferences
Authentication: Required
Request:
{
"language": "es",
"timezone": "Europe/Madrid",
"theme": "dark",
"notificationPreferences": {
"email": {
"eventInvites": true,
"newsletter": false
}
}
}Response: 200 OK
{
"success": true,
"message": "Preferences updated successfully"
}Event Service API
Event Management
List Events
Endpoint: GET /api/v1/events
Query Parameters:
page(integer): Page number (default: 1)limit(integer): Items per page (default: 20, max: 100)category(string): Filter by categorystatus(string): Filter by status (draft/published/cancelled)type(string): Filter by type (in_person/virtual/hybrid)startDate(ISO date): Events starting after this dateendDate(ISO date): Events ending before this datefeatured(boolean): Only featured eventssearch(string): Full-text searchlat(number): Latitude for nearby searchlng(number): Longitude for nearby searchradius(number): Search radius in km (default: 10)sort(string): Sort field (date/popularity/created)order(string): Sort order (asc/desc)
Example: GET /api/v1/events?category=music&status=published&limit=10
Response: 200 OK
{
"success": true,
"data": {
"events": [
{
"id": "uuid",
"title": "Summer Music Festival",
"slug": "summer-music-festival",
"description": {
"short": "Annual summer music festival featuring top artists",
"full": "Experience an unforgettable weekend..."
},
"category": "music",
"organizer": {
"id": "uuid",
"username": "eventpro",
"firstName": "John",
"lastName": "Doe"
},
"schedule": {
"startDate": "2024-07-15T14:00:00Z",
"endDate": "2024-07-17T23:00:00Z",
"timezone": "America/New_York"
},
"venue": {
"type": "physical",
"physical": {
"venue": {
"id": "uuid",
"name": "Central Park",
"address": "New York, NY"
}
}
},
"images": [
{
"url": "https://cdn.flow.app/events/uuid-1.jpg",
"isPrimary": true
}
],
"capacity": {
"total": 5000,
"available": 1234
},
"ticketing": {
"isFree": false,
"tickets": [
{
"name": "General Admission",
"price": 50,
"currency": "USD",
"quantity": {
"total": 3000,
"available": 800,
"sold": 2200
}
}
]
},
"analytics": {
"views": 15234,
"attendeeCount": 2200,
"likeCount": 345
},
"status": "published",
"createdAt": "2024-01-10T08:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 156,
"pages": 16
}
}
}Get Event by ID
Endpoint: GET /api/v1/events/:id
Parameters:
id(path): Event ID or slug
Response: 200 OK
{
"success": true,
"data": {
"id": "uuid",
"title": "Summer Music Festival",
"slug": "summer-music-festival",
"description": {
"short": "Annual summer music festival",
"full": "Detailed description..."
},
"category": "music",
"organizer": {
"id": "uuid",
"username": "eventpro",
"firstName": "John",
"lastName": "Doe",
"profilePicture": "https://cdn.flow.app/profiles/uuid.jpg"
},
"coOrganizers": [
{
"user": { "id": "uuid", "username": "helper" },
"role": "coordinator",
"permissions": ["manage_attendees", "send_messages"]
}
],
"venue": {
"type": "physical",
"physical": {
"venue": {
"id": "uuid",
"name": "Central Park",
"address": "Manhattan, New York, NY",
"coordinates": [-73.9654, 40.7829]
}
}
},
"schedule": {
"startDate": "2024-07-15T14:00:00Z",
"endDate": "2024-07-17T23:00:00Z",
"timezone": "America/New_York",
"isAllDay": false
},
"capacity": {
"total": 5000,
"available": 1234
},
"ticketing": {
"isFree": false,
"tickets": [
{
"name": "General Admission",
"description": "Access to all festival areas",
"price": 50,
"currency": "USD",
"quantity": {
"total": 3000,
"available": 800,
"sold": 2200
},
"salesPeriod": {
"startDate": "2024-03-01T00:00:00Z",
"endDate": "2024-07-14T23:59:59Z"
},
"perks": ["Festival t-shirt", "Commemorative badge"],
"isActive": true
},
{
"name": "VIP Pass",
"price": 150,
"currency": "USD",
"quantity": {
"total": 500,
"available": 45,
"sold": 455
},
"perks": ["Backstage access", "Meet & greet", "VIP lounge"]
}
],
"refundPolicy": "partial_refund",
"refundDeadline": "2024-07-08T23:59:59Z"
},
"images": [
{
"url": "https://cdn.flow.app/events/uuid-1.jpg",
"alt": "Festival stage",
"isPrimary": true,
"order": 0
},
{
"url": "https://cdn.flow.app/events/uuid-2.jpg",
"alt": "Crowd view",
"order": 1
}
],
"tags": ["music", "festival", "outdoor", "summer"],
"ageRestriction": {
"hasRestriction": true,
"minimumAge": 18
},
"accessibility": {
"wheelchairAccessible": true,
"signLanguageInterpreter": true
},
"requirements": {
"items": ["Valid ID", "Printed ticket"],
"restrictions": ["No outside food", "No professional cameras"]
},
"social": {
"likes": 345,
"shares": 89,
"comments": 67
},
"analytics": {
"views": 15234,
"uniqueViews": 8932,
"registrations": 2200,
"attendanceRate": 85
},
"status": "published",
"visibility": "public",
"createdAt": "2024-01-10T08:00:00Z",
"updatedAt": "2024-03-05T15:30:00Z"
}
}Create Event
Endpoint: POST /api/v1/events
Authentication: Required
Request:
{
"title": "Tech Meetup: AI in 2024",
"description": {
"short": "Monthly tech meetup discussing AI trends",
"full": "Join us for an evening of networking and learning..."
},
"category": "technology",
"venue": {
"type": "physical",
"physical": {
"customLocation": {
"name": "Tech Hub",
"address": "123 Innovation St, San Francisco, CA",
"coordinates": [-122.4194, 37.7749]
}
}
},
"schedule": {
"startDate": "2024-04-20T18:00:00Z",
"endDate": "2024-04-20T21:00:00Z",
"timezone": "America/Los_Angeles"
},
"capacity": {
"total": 50
},
"ticketing": {
"isFree": true
},
"tags": ["technology", "AI", "networking"],
"status": "published",
"visibility": "public"
}Response: 201 Created
{
"success": true,
"message": "Event created successfully",
"data": {
"id": "uuid",
"title": "Tech Meetup: AI in 2024",
"slug": "tech-meetup-ai-in-2024",
"status": "published",
"createdAt": "2024-03-10T10:00:00Z"
}
}Update Event
Endpoint: PUT /api/v1/events/:id
Authentication: Required (must be organizer)
Request:
{
"title": "Updated Event Title",
"description": {
"short": "Updated short description"
},
"capacity": {
"total": 75
}
}Response: 200 OK
{
"success": true,
"message": "Event updated successfully",
"data": {
"id": "uuid",
"title": "Updated Event Title",
"updatedAt": "2024-03-10T11:00:00Z"
}
}Delete Event
Endpoint: DELETE /api/v1/events/:id
Authentication: Required (must be organizer)
Response: 200 OK
{
"success": true,
"message": "Event deleted successfully"
}Event Registration
Register for Event
Endpoint: POST /api/v1/events/:id/attend
Authentication: Required
Request:
{
"ticketType": "General Admission",
"notes": "Vegetarian meal preference"
}Response: 201 Created
{
"success": true,
"message": "Successfully registered for event",
"data": {
"attendeeId": "uuid",
"status": "registered",
"ticketType": "General Admission",
"registeredAt": "2024-03-10T12:00:00Z"
}
}Cancel Event Registration
Endpoint: DELETE /api/v1/events/:id/attend
Authentication: Required
Response: 200 OK
{
"success": true,
"message": "Event registration cancelled"
}Check-in to Event
Endpoint: POST /api/v1/events/:id/check-in
Authentication: Required
Response: 200 OK
{
"success": true,
"message": "Checked in successfully",
"data": {
"checkInTime": "2024-07-15T14:30:00Z",
"status": "attended"
}
}Event Interactions
Like Event
Endpoint: POST /api/v1/events/:id/like
Authentication: Required
Response: 200 OK
{
"success": true,
"message": "Event liked",
"data": {
"likeCount": 346
}
}Unlike Event
Endpoint: DELETE /api/v1/events/:id/like
Authentication: Required
Response: 200 OK
{
"success": true,
"message": "Event unliked",
"data": {
"likeCount": 345
}
}Comment on Event
Endpoint: POST /api/v1/events/:id/comments
Authentication: Required
Request:
{
"content": "Looks amazing! Can't wait to attend!"
}Response: 201 Created
{
"success": true,
"data": {
"id": "uuid",
"content": "Looks amazing! Can't wait to attend!",
"user": {
"id": "uuid",
"username": "johndoe"
},
"createdAt": "2024-03-10T13:00:00Z"
}
}Special Queries
Get Nearby Events
Endpoint: GET /api/v1/events/nearby
Query Parameters:
lat(required): Latitudelng(required): Longituderadius(optional): Radius in km (default: 10)limit(optional): Max results (default: 20)
Example: GET /api/v1/events/nearby?lat=40.7128&lng=-74.0060&radius=15
Response: 200 OK
{
"success": true,
"data": {
"events": [
{
"id": "uuid",
"title": "Central Park Concert",
"distance": 2.3,
"distanceUnit": "km",
"location": {
"name": "Central Park",
"coordinates": [-73.9654, 40.7829]
}
}
]
}
}Get Featured Events
Endpoint: GET /api/v1/events/featured
Query Parameters:
limit(optional): Max results (default: 5)
Response: 200 OK
{
"success": true,
"data": {
"events": [...]
}
}Get Upcoming Events
Endpoint: GET /api/v1/events/upcoming
Query Parameters:
limit(optional): Max results (default: 10)
Response: 200 OK
{
"success": true,
"data": {
"events": [...]
}
}Social Service API
Connection Management
Send Connection Request
Endpoint: POST /api/v1/social/connections/request
Authentication: Required
Request:
{
"recipientId": "user-uuid",
"connectionType": "friend",
"requestMessage": "Hey! We met at the music festival last week."
}Response: 201 Created
{
"success": true,
"message": "Connection request sent",
"data": {
"connectionId": "uuid",
"status": "pending",
"createdAt": "2024-03-10T14:00:00Z",
"expiresAt": "2024-04-09T14:00:00Z"
}
}Accept Connection Request
Endpoint: POST /api/v1/social/connections/:id/accept
Authentication: Required
Response: 200 OK
{
"success": true,
"message": "Connection request accepted",
"data": {
"connectionId": "uuid",
"status": "accepted",
"acceptedAt": "2024-03-10T15:00:00Z"
}
}Decline Connection Request
Endpoint: POST /api/v1/social/connections/:id/decline
Authentication: Required
Response: 200 OK
{
"success": true,
"message": "Connection request declined"
}Get User Connections
Endpoint: GET /api/v1/social/connections
Authentication: Required
Query Parameters:
status(optional): Filter by status (pending/accepted/blocked)limit(optional): Max results (default: 50)skip(optional): Skip results (default: 0)
Response: 200 OK
{
"success": true,
"data": {
"connections": [
{
"id": "uuid",
"user": {
"id": "uuid",
"username": "janedoe",
"firstName": "Jane",
"lastName": "Doe",
"profilePicture": "https://cdn.flow.app/profiles/uuid.jpg"
},
"status": "accepted",
"connectionType": "friend",
"acceptedAt": "2024-02-15T10:00:00Z",
"interactions": {
"messagesCount": 45,
"eventsAttendedTogether": 3,
"groupsInCommon": 2,
"lastInteraction": "2024-03-09T18:30:00Z"
},
"connectionStrength": 23.5
}
],
"pagination": {
"total": 142,
"limit": 50,
"skip": 0
}
}
}Get Connection Suggestions
Endpoint: GET /api/v1/social/connections/suggestions
Authentication: Required
Query Parameters:
limit(optional): Max results (default: 10)
Response: 200 OK
{
"success": true,
"data": {
"suggestions": [
{
"user": {
"id": "uuid",
"username": "mikebrown",
"firstName": "Mike",
"lastName": "Brown",
"profilePicture": "https://cdn.flow.app/profiles/uuid.jpg"
},
"mutualConnectionsCount": 15,
"mutualConnections": [
{
"id": "uuid",
"username": "janedoe"
}
],
"reason": "15 mutual friends",
"score": 85
}
]
}
}Block User
Endpoint: POST /api/v1/social/connections/:id/block
Authentication: Required
Request:
{
"reason": "Inappropriate behavior"
}Response: 200 OK
{
"success": true,
"message": "User blocked successfully"
}Group Management
Create Group
Endpoint: POST /api/v1/social/groups
Authentication: Required
Request:
{
"name": "Tech Enthusiasts NYC",
"description": "A group for tech lovers in New York City",
"type": "public",
"category": "technology",
"tags": ["technology", "networking", "NYC"],
"settings": {
"requireApproval": false,
"allowMemberPosts": true,
"allowMemberInvites": true
}
}Response: 201 Created
{
"success": true,
"message": "Group created successfully",
"data": {
"id": "uuid",
"name": "Tech Enthusiasts NYC",
"slug": "tech-enthusiasts-nyc",
"type": "public",
"memberCount": 1,
"createdAt": "2024-03-10T16:00:00Z"
}
}Get Groups
Endpoint: GET /api/v1/social/groups
Query Parameters:
type(optional): Filter by type (public/private)category(optional): Filter by categorysearch(optional): Search by namelimit(optional): Max results (default: 20)
Response: 200 OK
{
"success": true,
"data": {
"groups": [
{
"id": "uuid",
"name": "Tech Enthusiasts NYC",
"slug": "tech-enthusiasts-nyc",
"description": "A group for tech lovers...",
"type": "public",
"category": "technology",
"memberCount": 234,
"coverImage": "https://cdn.flow.app/groups/uuid.jpg",
"creator": {
"id": "uuid",
"username": "techguru"
},
"isMember": false,
"createdAt": "2024-01-10T08:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 45
}
}
}Join Group
Endpoint: POST /api/v1/social/groups/:id/join
Authentication: Required
Response: 200 OK
{
"success": true,
"message": "Joined group successfully",
"data": {
"groupId": "uuid",
"role": "member",
"joinedAt": "2024-03-10T17:00:00Z"
}
}Leave Group
Endpoint: POST /api/v1/social/groups/:id/leave
Authentication: Required
Response: 200 OK
{
"success": true,
"message": "Left group successfully"
}Posts (Deprecated)
Note: Posts functionality has been deprecated in favor of event-based and group-based social interactions. The endpoints below are maintained for backward compatibility but may be removed in future versions.
Create Post
Endpoint: POST /api/v1/social/posts
Authentication: Required
Request:
{
"content": "Just attended an amazing tech conference!",
"imageUrls": ["https://cdn.flow.app/posts/uuid-1.jpg"]
}Response: 201 Created
{
"success": true,
"data": {
"id": "uuid",
"content": "Just attended an amazing tech conference!",
"likesCount": 0,
"commentsCount": 0,
"createdAt": "2024-03-10T18:00:00Z"
}
}Notification Service API
Notification Management
Get User Notifications
Endpoint: GET /api/v1/notifications
Authentication: Required
Query Parameters:
status(optional): Filter by status (sent/delivered/failed)type(optional): Filter by typecategory(optional): Filter by categoryunreadOnly(boolean): Only unread notificationslimit(optional): Max results (default: 20)skip(optional): Skip results (default: 0)
Response: 200 OK
{
"success": true,
"data": {
"notifications": [
{
"id": "uuid",
"title": "New Connection Request",
"message": "John Doe sent you a connection request",
"type": "connection_request",
"category": "social",
"priority": "normal",
"data": {
"connectionId": "uuid",
"senderId": "uuid"
},
"channels": {
"inApp": {
"enabled": true,
"read": false
},
"push": {
"enabled": true,
"sent": true,
"sentAt": "2024-03-10T19:00:00Z"
}
},
"action": {
"type": "navigate",
"payload": {
"screen": "ConnectionRequest",
"params": {
"connectionId": "uuid"
}
}
},
"createdAt": "2024-03-10T19:00:00Z"
}
],
"unreadCount": 5,
"pagination": {
"total": 156,
"limit": 20,
"skip": 0
}
}
}Get Unread Count
Endpoint: GET /api/v1/notifications/unread/count
Authentication: Required
Response: 200 OK
{
"success": true,
"data": {
"unreadCount": 5,
"byCategory": {
"social": 3,
"event": 2,
"system": 0
}
}
}Mark Notification as Read
Endpoint: PUT /api/v1/notifications/:id/read
Authentication: Required
Response: 200 OK
{
"success": true,
"message": "Notification marked as read"
}Mark All as Read
Endpoint: PUT /api/v1/notifications/read-all
Authentication: Required
Response: 200 OK
{
"success": true,
"message": "All notifications marked as read"
}Delete Notification
Endpoint: DELETE /api/v1/notifications/:id
Authentication: Required
Response: 200 OK
{
"success": true,
"message": "Notification deleted"
}Notification Preferences
Get Notification Preferences
Endpoint: GET /api/v1/notifications/preferences
Authentication: Required
Response: 200 OK
{
"success": true,
"data": {
"channels": {
"push": {
"enabled": true,
"categories": {
"social": true,
"event": true,
"system": true,
"security": true,
"marketing": false
}
},
"email": {
"enabled": true,
"categories": {
"social": true,
"event": true,
"system": true,
"security": true,
"marketing": false
},
"frequency": "realtime"
},
"sms": {
"enabled": false,
"categories": {
"social": false,
"event": true,
"system": false,
"security": true,
"marketing": false
}
}
},
"quietHours": {
"enabled": true,
"startTime": "22:00",
"endTime": "08:00",
"timezone": "America/New_York"
},
"language": "en"
}
}Update Notification Preferences
Endpoint: PUT /api/v1/notifications/preferences
Authentication: Required
Request:
{
"channels": {
"push": {
"enabled": true,
"categories": {
"marketing": false
}
},
"email": {
"frequency": "daily"
}
},
"quietHours": {
"enabled": true,
"startTime": "23:00",
"endTime": "07:00"
}
}Response: 200 OK
{
"success": true,
"message": "Preferences updated successfully"
}WebSocket Events
Connection
Endpoint: ws://localhost:3005/socket.io
Authentication: JWT token required
Connection Flow:
import io from 'socket.io-client';
const socket = io('http://localhost:3005', {
auth: {
token: 'Bearer <access_token>'
},
transports: ['websocket', 'polling']
});
socket.on('connect', () => {
console.log('Connected:', socket.id);
});
socket.on('authenticated', (data) => {
console.log('Authenticated:', data);
});
socket.on('connect_error', (error) => {
console.error('Connection error:', error);
});Message Events
Send Message
Event: message:send
Payload:
socket.emit('message:send', {
recipientId: 'user-uuid',
content: 'Hello! How are you?',
type: 'text'
});Response: message:sent
socket.on('message:sent', (data) => {
// {
// messageId: 'uuid',
// status: 'sent',
// timestamp: '2024-03-10T20:00:00Z'
// }
});Receive Message
Event: message:received
Payload:
socket.on('message:received', (message) => {
// {
// id: 'uuid',
// sender: {
// id: 'uuid',
// username: 'johndoe',
// profilePicture: 'https://...'
// },
// content: 'Hi! I am doing great!',
// type: 'text',
// timestamp: '2024-03-10T20:01:00Z'
// }
});Mark Message as Read
Event: message:read
Payload:
socket.emit('message:read', {
messageId: 'uuid'
});Typing Indicator
Event: typing:start / typing:stop
Payload:
socket.emit('typing:start', {
recipientId: 'user-uuid'
});
// Stop after user stops typing
socket.emit('typing:stop', {
recipientId: 'user-uuid'
});Listen:
socket.on('user:typing', (data) => {
// {
// userId: 'uuid',
// username: 'johndoe',
// isTyping: true
// }
});Room Events
Join Room
Event: room:join
Payload:
socket.emit('room:join', {
roomId: 'room-uuid'
});Response: room:joined
socket.on('room:joined', (data) => {
// {
// roomId: 'uuid',
// participants: [...],
// lastMessages: [...]
// }
});Leave Room
Event: room:leave
Payload:
socket.emit('room:leave', {
roomId: 'room-uuid'
});Room Message
Event: room:message
Broadcast to room:
socket.on('room:message', (message) => {
// Received by all participants in the room
// {
// id: 'uuid',
// roomId: 'room-uuid',
// sender: {...},
// content: 'Group message',
// timestamp: '2024-03-10T20:05:00Z'
// }
});Presence Events
Update Status
Event: presence:update
Payload:
socket.emit('presence:update', {
status: 'online' // online/away/busy/offline
});User Online
Event: presence:online
socket.on('presence:online', (data) => {
// {
// userId: 'uuid',
// username: 'johndoe',
// status: 'online',
// timestamp: '2024-03-10T20:10:00Z'
// }
});User Offline
Event: presence:offline
socket.on('presence:offline', (data) => {
// {
// userId: 'uuid',
// username: 'johndoe',
// lastSeen: '2024-03-10T20:15:00Z'
// }
});Real-time Notifications
Notification Received
Event: notification:new
socket.on('notification:new', (notification) => {
// {
// id: 'uuid',
// title: 'Event Reminder',
// message: 'Your event starts in 1 hour',
// type: 'event_reminder',
// category: 'event',
// data: {...},
// timestamp: '2024-03-10T13:00:00Z'
// }
});Event Updates
Event Updated
Event: event:updated
socket.on('event:updated', (data) => {
// {
// eventId: 'uuid',
// changes: {
// startDate: '2024-07-16T14:00:00Z',
// venue: {...}
// },
// updatedAt: '2024-03-10T21:00:00Z'
// }
});Event Cancelled
Event: event:cancelled
socket.on('event:cancelled', (data) => {
// {
// eventId: 'uuid',
// reason: 'Venue unavailable',
// cancelledAt: '2024-03-10T21:05:00Z'
// }
});Error Handling
Error Response Format
All API errors follow a consistent format:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": [
{
"field": "email",
"message": "Email is required"
},
{
"field": "password",
"message": "Password must be at least 8 characters"
}
],
"timestamp": "2024-03-10T22:00:00Z",
"path": "/api/v1/auth/register",
"correlationId": "uuid"
}
}HTTP Status Codes
| Code | Meaning | Description |
|---|---|---|
| 200 | OK | Request successful |
| 201 | Created | Resource created successfully |
| 204 | No Content | Request successful, no content to return |
| 400 | Bad Request | Invalid request parameters |
| 401 | Unauthorized | Authentication required or failed |
| 403 | Forbidden | Insufficient permissions |
| 404 | Not Found | Resource not found |
| 409 | Conflict | Resource already exists |
| 422 | Unprocessable Entity | Validation error |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Server error |
| 503 | Service Unavailable | Service temporarily unavailable |
Common Error Codes
| Code | Description |
|---|---|
VALIDATION_ERROR | Request validation failed |
AUTHENTICATION_REQUIRED | Authentication token missing |
INVALID_TOKEN | JWT token is invalid or expired |
INSUFFICIENT_PERMISSIONS | User lacks required permissions |
RESOURCE_NOT_FOUND | Requested resource doesn’t exist |
DUPLICATE_RESOURCE | Resource already exists (email, username, etc.) |
RATE_LIMIT_EXCEEDED | Too many requests |
SERVICE_UNAVAILABLE | Backend service temporarily unavailable |
INTERNAL_ERROR | Unexpected server error |
INVALID_CREDENTIALS | Email or password is incorrect |
ACCOUNT_LOCKED | Account locked due to failed login attempts |
EVENT_FULL | Event has reached maximum capacity |
ALREADY_REGISTERED | User already registered for event |
PAYMENT_REQUIRED | Payment needed for paid event |
CONNECTION_EXISTS | Connection already exists |
SELF_CONNECTION | Cannot connect with yourself |
Error Examples
Validation Error
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Email is required",
"statusCode": 422
}
}Authentication Error
{
"success": false,
"error": {
"code": "INVALID_TOKEN",
"message": "The provided token is invalid or expired",
"statusCode": 401
}
}Not Found Error
{
"success": false,
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "Event not found",
"statusCode": 404
}
}Rate Limit Error
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests. Maximum 100 requests per 15 minutes.",
"retryAfter": 900,
"statusCode": 429
}
}Rate Limiting
Global Rate Limits
API Gateway:
- Window: 15 minutes
- Max Requests: 100 per IP address
- Slow Down: Starts at 50 requests (adds 500ms delay)
- Max Delay: 20 seconds
Headers:
RateLimit-Limit: 100
RateLimit-Remaining: 45
RateLimit-Reset: 1710097200Endpoint-Specific Limits
| Endpoint Pattern | Limit | Window |
|---|---|---|
POST /api/v1/auth/login | 5 attempts | 15 minutes |
POST /api/v1/auth/register | 3 attempts | 1 hour |
POST /api/v1/auth/forgot-password | 3 attempts | 1 hour |
POST /api/v1/events | 10 events | 1 hour |
POST /api/v1/social/connections/request | 20 requests | 1 hour |
POST /api/v1/notifications | 100 notifications | 1 hour |
User-Based Rate Limiting
Authenticated users have higher limits:
- Max Requests: 200 per 15 minutes (2x IP-based limit)
- Tracked per user ID from JWT token
Handling Rate Limits
429 Response Example:
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests from this IP, please try again later.",
"retryAfter": 900
}
}Client Implementation:
async function makeRequest(url, options) {
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After');
console.log(`Rate limited. Retry after ${retryAfter} seconds`);
// Wait and retry
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
return makeRequest(url, options);
}
return response.json();
}Response Formats
Success Response
Format:
{
"success": true,
"message": "Operation completed successfully",
"data": {
// Response data
},
"meta": {
// Optional metadata
}
}Pagination Response
Format:
{
"success": true,
"data": {
"items": [...],
"pagination": {
"page": 1,
"limit": 20,
"total": 156,
"pages": 8,
"hasNext": true,
"hasPrev": false
}
}
}Error Response
Format:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": [...],
"statusCode": 400,
"timestamp": "2024-03-10T22:00:00Z",
"path": "/api/v1/resource",
"correlationId": "uuid"
}
}Date/Time Format
All timestamps use ISO 8601 format with UTC timezone:
2024-03-10T14:30:00Z
Currency Format
Currency amounts are represented in cents (integers) to avoid floating-point precision issues:
{
"price": 5000, // $50.00
"currency": "USD"
}Best Practices
1. Always Include Authentication
For protected endpoints, always include the JWT token:
fetch('https://api.flow.app/api/v1/users/me', {
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
}
});2. Handle Token Expiration
Implement automatic token refresh:
async function makeAuthenticatedRequest(url, options) {
let response = await fetch(url, {
...options,
headers: {
...options.headers,
'Authorization': `Bearer ${getAccessToken()}`
}
});
if (response.status === 401) {
// Token expired, refresh it
await refreshAccessToken();
// Retry with new token
response = await fetch(url, {
...options,
headers: {
...options.headers,
'Authorization': `Bearer ${getAccessToken()}`
}
});
}
return response.json();
}3. Use Correlation IDs
For debugging, include correlation IDs in requests:
import { v4 as uuidv4 } from 'uuid';
fetch('https://api.flow.app/api/v1/events', {
headers: {
'X-Correlation-ID': uuidv4()
}
});4. Implement Exponential Backoff
For failed requests, use exponential backoff:
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch(url, options);
if (response.ok) {
return await response.json();
}
if (response.status >= 500) {
// Server error, retry
const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
// Client error, don't retry
throw new Error(response.statusText);
} catch (error) {
if (i === maxRetries - 1) throw error;
}
}
}5. Validate Input Client-Side
Always validate input before sending to API:
function validateEmail(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}
function validatePassword(password) {
return password.length >= 8;
}API Client Examples
JavaScript/TypeScript (Axios)
import axios from 'axios';
const api = axios.create({
baseURL: 'https://api.flow.app/api/v1',
timeout: 30000,
headers: {
'Content-Type': 'application/json'
}
});
// Request interceptor to add auth token
api.interceptors.request.use(config => {
const token = localStorage.getItem('accessToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
// Response interceptor for error handling
api.interceptors.response.use(
response => response.data,
error => {
if (error.response?.status === 401) {
// Handle token expiration
refreshToken();
}
return Promise.reject(error.response?.data || error);
}
);
// Usage
const getEvents = async () => {
const data = await api.get('/events', {
params: { category: 'music', limit: 10 }
});
return data;
};Flutter/Dart (Dio)
import 'package:dio/dio.dart';
class FlowApiClient {
late Dio _dio;
FlowApiClient() {
_dio = Dio(BaseOptions(
baseUrl: 'https://api.flow.app/api/v1',
connectTimeout: Duration(seconds: 30),
receiveTimeout: Duration(seconds: 30),
headers: {
'Content-Type': 'application/json',
},
));
_dio.interceptors.add(InterceptorsWrapper(
onRequest: (options, handler) {
final token = getAccessToken();
if (token != null) {
options.headers['Authorization'] = 'Bearer $token';
}
return handler.next(options);
},
onError: (error, handler) {
if (error.response?.statusCode == 401) {
// Handle token expiration
refreshToken();
}
return handler.next(error);
},
));
}
Future<List<Event>> getEvents({
String? category,
int limit = 20,
}) async {
final response = await _dio.get('/events', queryParameters: {
'category': category,
'limit': limit,
});
return (response.data['data']['events'] as List)
.map((e) => Event.fromJson(e))
.toList();
}
}Python (Requests)
import requests
from typing import Optional, Dict, Any
class FlowAPIClient:
def __init__(self, base_url: str = "https://api.flow.app/api/v1"):
self.base_url = base_url
self.session = requests.Session()
self.session.headers.update({
'Content-Type': 'application/json'
})
def set_token(self, token: str):
self.session.headers.update({
'Authorization': f'Bearer {token}'
})
def get_events(
self,
category: Optional[str] = None,
limit: int = 20
) -> Dict[str, Any]:
params = {'limit': limit}
if category:
params['category'] = category
response = self.session.get(
f'{self.base_url}/events',
params=params
)
response.raise_for_status()
return response.json()
# Usage
client = FlowAPIClient()
client.set_token('your-access-token')
events = client.get_events(category='music', limit=10)API Version: 1.0 Last Updated: 2024-03-10 Maintained By: Flow Development Team Support: api-support@flowapp.com Documentation: https://docs.flowapp.com