API Documentation

Welcome to the Disciply API documentation. This guide will help you integrate with our RESTful API to manage discipleship programs, groups, challenges, and more.


Getting Started

The Disciply API provides programmatic access to your discipleship management platform. To get started with the API, you'll need to:

  1. Register for an account at https://disciply.app/register
  2. Log in to your Disciply account
  3. Subscribe to a Pro plan - API access requires an active Pro subscription
  4. Generate your API token - Follow the authentication steps below
Note: All API requests must be made over HTTPS. Requests made over plain HTTP will fail. API requests without authentication will also fail.

Base URL

https://disciply.app/api

Authentication

The Disciply API uses Laravel Sanctum for authentication. You'll need to include a Bearer token in the Authorization header of your API requests.

Generating Your API Token

To generate a Bearer token for API access:

  1. Log in to your account by making a POST request to the login endpoint:
POST /api/login
POST https://disciply.app/api/login
Request Body
{ "email": "your-email@example.com", "password": "your-password" }
Response
{ "user": { "id": 1, "name": "John Doe", "email": "your-email@example.com" }, "token": "1|abcdefghijklmnopqrstuvwxyz1234567890" }

Using Your API Token

Include the token in the Authorization header of all API requests:

Authorization: Bearer 1|abcdefghijklmnopqrstuvwxyz1234567890

Example Request with cURL

curl -X GET https://disciply.app/api/groups \ -H "Authorization: Bearer YOUR_TOKEN_HERE" \ -H "Content-Type: application/json" \ -H "Accept: application/json"

Groups API

Manage discipleship groups, memberships, and group activities.

🔄 Important Update - October 2025: The Groups API has been updated to include a new group_type field. All groups now have a type of either 'group' (regular groups) or 'global' (organization-wide groups). Please update your mobile apps to handle these types appropriately.

Group Types

Groups in Disciply are now categorized into two types:

  • Regular Groups (group_type: 'group'): Traditional small groups with specific members, leaders, and full functionality
  • Global Groups (group_type: 'global'): Organization-wide groups where all members of an organization are automatically enrolled

Global Group Characteristics

Feature Regular Groups Global Groups
Membership Invite/join based Auto-enrolled (all org members)
Who can post All members Organization admins only
Comments allowed Yes No
Member list visible Yes Count only (privacy)
Can edit/delete Yes (with permissions) No (system-managed)
Displayed in app Mixed with other groups Sorted to top of list
Mobile Implementation Note: Global groups should be displayed separately at the top of your groups list in a dedicated "Global" or "Organization-wide" section. They function as announcement boards where only admins can post updates to all members.
GET List All Groups
GET /api/groups

Retrieve a list of all groups the authenticated user is a member of. Global groups are automatically included and sorted to the top.

Response Example
{ "data": [ { "id": 25, "name": "General", "code": "general-abc123", "purpose": "Welcome! This is our messaging board for all members.", "organization_id": 1, "group_type": "global", "type": null, "status": "active", "member_count": 45, "leadership": { "id": 5, "name": "Jane Smith", "email": "jane@example.com" }, "created_at": "2024-01-15T10:30:00.000000Z" }, { "id": 12, "name": "Youth Discipleship Group", "code": "YDG-xyz789", "purpose": "Weekly meeting for young adults", "organization_id": 1, "group_type": "group", "type": "Discipleship", "status": "active", "member_count": 12, "leadership": { "id": 8, "name": "John Doe", "email": "john@example.com" }, "created_at": "2024-02-20T14:30:00.000000Z" } ] }
Important Fields
Field Type Description
group_type string NEW: Either 'group' or 'global'. Use this to determine group behavior.
type string|null Group category (e.g., "Discipleship", "Bible Study"). Only used for regular groups.
status string Group status: 'active', 'draft', or 'inactive'
Breaking Change: The legacy virtual group (ID: 0) is no longer returned by this endpoint. All organizations now have a real global group with an actual database ID. Update your code to remove any special handling for group ID 0.
GET Get Available Groups
GET /api/groups/available

Retrieve a list of groups available for the user to join.

GET Get Single Group
GET /api/groups/{group}

Retrieve detailed information about a specific group.

Parameters
Parameter Type Required Description
group integer REQUIRED The ID of the group
POST Create Group
POST /api/groups

Create a new discipleship group.

Request Body
{ "name": "New Group Name", "description": "Group description", "organization_id": 1, "type": "discipleship" }
PUT Update Group
PUT /api/groups/{group}

Update an existing group's information.

Parameters
Parameter Type Required Description
group integer REQUIRED The ID of the group
name string OPTIONAL Updated group name
description string OPTIONAL Updated description
DELETE Delete Group
DELETE /api/groups/{group}

Delete a group. Requires group leader or admin privileges.

POST Join Group
POST /api/groups/{group}/join

Join a discipleship group.

Request Body
{ "group_id": 1 }
POST Leave Group
POST /api/groups/{group}/leave

Leave a discipleship group.

GET Get Group Members
GET /api/groups/{group}/members

Retrieve a list of all members in a group.

Response Example
{ "data": [ { "id": 1, "name": "John Doe", "email": "john@example.com", "role": "member", "joined_at": "2024-01-20T14:30:00.000000Z" } ] }
GET Get Group Posts
GET /api/groups/{group}/posts

Retrieve all posts and discussions within a group.

POST Create Group Post
POST /api/groups/{id}/post

Create a new post in a group.

⚠️ Global Group Restriction: For groups with group_type: 'global', only organization administrators can create posts. Regular members attempting to post will receive a 403 Forbidden error.
Request Body
{ "content": "This is my post content", "type": "text" }
Error Response (Global Group - Non-Admin)
{ "error": "Only organization administrators can post to global groups" }
Mobile Implementation Tips
  • Check the group_type field before showing the "Create Post" button
  • For global groups, verify the user is an org admin before allowing post creation
  • Display a helpful message like "Only administrators can post announcements to this group"
POST Comment on Group Post
POST /api/groups/{group_id}/post/comment

Add a comment to a group post.

⚠️ Global Group Restriction: Comments are disabled for all global group posts. Attempting to comment will return a 403 Forbidden error.
Request Body
{ "post_id": 123, "comment": "Great post!", "parent_id": null }
Error Response (Global Group)
{ "error": "Comments are not allowed on global group posts" }
Mobile Implementation Tips
  • Hide the comment input box for posts in global groups
  • Check group_type === 'global' before showing comment UI
  • Display a note like "Comments are disabled for organization-wide announcements"
POST Rate Group
POST /api/groups/{group}/rate

Submit a rating for a group.

Request Body
{ "rating": 5, "comment": "Great group experience!" }

Challenges API

Manage discipleship challenges and track user progress through various courses and activities.

GET List All Challenges
GET /api/challenges

Retrieve a list of all available challenges.

Response Example
{ "data": [ { "id": 1, "title": "30-Day Prayer Challenge", "description": "Develop a consistent prayer habit", "duration_days": 30, "difficulty": "beginner", "participants_count": 145 } ] }
GET Get Available Challenges
GET /api/challenges/get_challenges

Retrieve challenges available for the authenticated user.

POST Create Challenge
POST /api/challenges

Create a new challenge. Requires leadership or admin privileges.

Request Body
{ "title": "Bible Reading Challenge", "description": "Read through the entire Bible in 90 days", "duration_days": 90, "difficulty": "intermediate", "organization_id": 1 }
GET Get User Challenge Progress
GET /api/challenges/progress

Retrieve the authenticated user's progress across all challenges.

Response Example
{ "data": [ { "challenge_id": 1, "title": "30-Day Prayer Challenge", "progress_percentage": 73, "days_completed": 22, "days_total": 30, "started_at": "2024-01-01T00:00:00.000000Z" } ] }
POST Start Challenge
POST /api/challenges/start/{challenge}

Enroll the authenticated user in a challenge.

Parameters
Parameter Type Required Description
challenge integer REQUIRED The ID of the challenge
POST Complete Challenge
POST /api/challenges/complete/{challenge}

Mark a challenge as completed.

Parameters
Parameter Type Required Description
challenge integer REQUIRED The ID of the challenge
GET Get Challenge Statistics
GET /api/manage/challenges/stats

Retrieve statistics for challenges (admin/leader only).

Response Example
{ "total_challenges": 15, "active_participants": 342, "completion_rate": 67.5, "most_popular": { "id": 1, "title": "30-Day Prayer Challenge", "participants": 145 } }
GET Get Challenge Completions
GET /api/manage/challenges/completions

Retrieve a list of recent challenge completions (admin/leader only).


Journal API

Manage personal journal entries for spiritual growth and reflection.

GET List Journal Entries
GET /api/journal

Retrieve all journal entries for the authenticated user.

Response Example
{ "data": [ { "id": 1, "title": "Morning Devotion Reflection", "content": "Today I reflected on...", "created_at": "2024-10-14T08:30:00.000000Z", "updated_at": "2024-10-14T08:30:00.000000Z" } ] }
POST Create Journal Entry
POST /api/journal

Create a new journal entry.

Request Body
{ "title": "My Journal Entry", "content": "Today I learned about...", "date": "2024-10-14" }
Parameters
Parameter Type Required Description
title string REQUIRED Title of the journal entry
content string REQUIRED Content of the journal entry
date date OPTIONAL Date of the entry (defaults to today)
GET Get Single Journal Entry
GET /api/journal/{journal}

Retrieve a specific journal entry.

Parameters
Parameter Type Required Description
journal integer REQUIRED The ID of the journal entry
POST Update Journal Entry
POST /api/journal/{journal}

Update an existing journal entry.

Request Body
{ "title": "Updated Title", "content": "Updated content...", "_method": "PUT" }
POST Delete Journal Entry
POST /api/journal/{journal}/delete

Delete a journal entry.


Journey AI API

Leverage AI-powered insights and guidance for your spiritual journey.

GET Get Journey Data
GET /api/journey

Retrieve the user's spiritual journey data and milestones.

Response Example
{ "data": { "total_days": 127, "milestones_completed": 8, "current_focus": "Prayer and Meditation", "journey_data": [ { "date": "2024-10-14", "activity": "Morning Prayer", "duration_minutes": 30 } ] } }
POST Create Journey Entry
POST /api/journey

Log a new activity or milestone in your spiritual journey.

Request Body
{ "activity_type": "prayer", "duration_minutes": 30, "notes": "Focused on gratitude today", "date": "2024-10-14" }
Parameters
Parameter Type Required Description
activity_type string REQUIRED Type of activity (prayer, study, service, etc.)
duration_minutes integer OPTIONAL Duration in minutes
notes string OPTIONAL Additional notes or reflections
date date OPTIONAL Date of the activity (defaults to today)
GET Get Journey Progress
GET /api/journey/progress

Retrieve AI-powered insights and progress analytics for your journey.

Response Example
{ "data": { "overall_progress": 67, "consistency_score": 8.5, "areas_of_growth": [ "Prayer consistency improved by 45%", "Community engagement increased" ], "ai_recommendations": [ "Consider joining a prayer group", "Continue morning devotion habit" ], "streak_days": 14 } }

Training API

Manage training programs, qualifications, and leadership development with rich media content and AI-generated assessments.

🎓 Enhanced Training Features: Training programs now support multimedia content (audio files, video links), series organization, and AI-generated multiple-choice quizzes for comprehensive assessment.
GET Get Available Qualifications
GET /api/qualifications/get_qualifications

Retrieve all available training qualifications and certifications with full media and assessment details.

Response Example
{ "data": [ { "id": 1, "title": "Small Group Leader Certification", "type": "Leadership Training", "series": "Discipleship 101", "content": "Comprehensive training for leading small groups...", "audio_path": "/storage/qualifications/audio/1/training.mp3", "video_link": "https://youtube.com/watch?v=abc123", "quiz_type": "multiple_choice", "quiz_data": { "questions": [ { "question": "What is the primary role of a small group leader?", "options": [ "To teach only", "To facilitate discussion and spiritual growth", "To enforce rules", "To manage finances" ], "correct_answer_index": 1 } ] }, "visibility": "everyone", "is_required_for_leadership": true, "organization_id": 1, "created_at": "2024-10-14T08:30:00.000000Z" } ] }
Important Fields
Field Type Description
series string|null NEW: Optional series name to group related training programs
audio_path string|null NEW: Path to audio training resource (MP3, WAV, M4A, AAC, OGG)
video_link string|null NEW: URL to video resource (YouTube, Vimeo, Dailymotion, Wistia)
quiz_type string|null NEW: Type of assessment: 'completion_consent' or 'multiple_choice'
quiz_data object|null NEW: Quiz questions with options and correct answers (for multiple_choice type)
visibility string Who can view: 'everyone', 'assigned_only', 'leadership_only', 'members_only'
is_required_for_leadership boolean Whether completion is required to be qualified as a group leader
Quiz Types
  • completion_consent: User simply confirms they have completed the training
  • multiple_choice: AI-generated quiz based on training content with multiple-choice questions
GET Get User Qualifications Progress
GET /api/qualifications/progress

Retrieve the authenticated user's progress across all qualifications, including quiz scores and completion status.

Response Example
{ "data": [ { "qualification_id": 1, "title": "Small Group Leader Certification", "type": "Leadership Training", "series": "Discipleship 101", "progress_percentage": 75, "quiz_score": 85, "quiz_passed": true, "completed": false, "started_at": "2024-08-01T00:00:00.000000Z", "completed_at": null, "has_audio": true, "has_video": true, "quiz_type": "multiple_choice" } ] }
Progress Fields
Field Type Description
quiz_score integer|null User's score on the quiz (0-100) if quiz completed
quiz_passed boolean Whether the user passed the required quiz
has_audio boolean Indicates if training includes audio content
has_video boolean Indicates if training includes video content
quiz_type string|null Type of assessment required
POST Start Qualification
POST /api/qualifications/start/{qualification}

Enroll the authenticated user in a training qualification.

Parameters
Parameter Type Required Description
qualification integer REQUIRED The ID of the qualification
POST Update Qualification Progress
POST /api/qualifications/update-progress/{qualification}

Update progress for a specific qualification module or requirement.

Request Body
{ "module_id": 3, "status": "completed", "notes": "Completed all reading materials" }
Parameters
Parameter Type Required Description
qualification integer REQUIRED The ID of the qualification
module_id integer REQUIRED The module being updated
status string REQUIRED Status (in_progress, completed)
POST Submit Quiz Answers
POST /api/qualifications/{qualification}/submit-quiz

Submit quiz answers for a training qualification and receive immediate scoring.

Request Body - Completion Consent
{ "consent": true }
Request Body - Multiple Choice
{ "answers": [ { "question_index": 0, "selected_answer_index": 1 }, { "question_index": 1, "selected_answer_index": 2 } ] }
Response Example
{ "success": true, "score": 80, "passed": true, "correct_answers": 4, "total_questions": 5, "results": [ { "question_index": 0, "correct": true }, { "question_index": 1, "correct": false, "correct_answer_index": 3 } ] }
Parameters
Parameter Type Required Description
qualification integer REQUIRED The ID of the qualification
consent boolean OPTIONAL For completion_consent type quizzes
answers array OPTIONAL For multiple_choice type quizzes
Passing Score: Multiple choice quizzes require a minimum score of 70% to pass.
POST Complete Qualification
POST /api/qualifications/complete/{qualification}

Mark a qualification as completed and request certification. Note: User must pass required quiz (if any) before completing.

Parameters
Parameter Type Required Description
qualification integer REQUIRED The ID of the qualification
Prerequisites: To complete a qualification with a quiz, the user must first submit quiz answers and achieve a passing score.

Mobile Implementation Guide for Training Features

Best practices for implementing the enhanced training features in your mobile application:

1. Displaying Training Content

// Check for media content if (qualification.audio_path) { // Display audio player <AudioPlayer src={qualification.audio_path} /> } if (qualification.video_link) { // Embed video or show link const embedUrl = getVideoEmbedUrl(qualification.video_link); <VideoPlayer embedUrl={embedUrl} /> } // Show series badge if part of a series if (qualification.series) { <Badge>{qualification.series}</Badge> }

2. Handling Quiz Types

function renderQuiz(qualification) { if (!qualification.quiz_type) { return null; // No quiz required } if (qualification.quiz_type === 'completion_consent') { return ( <Checkbox label="I confirm I have completed this training" onChange={(checked) => submitConsent(checked)} /> ); } if (qualification.quiz_type === 'multiple_choice') { return ( <QuizComponent questions={qualification.quiz_data.questions} onSubmit={(answers) => submitQuizAnswers(answers)} /> ); } }

3. Video Platform Support

The API returns video URLs from various platforms. Your app should support embedding:

  • YouTube: Convert to embed URL format
  • Vimeo: Use player.vimeo.com embed URLs
  • Dailymotion: Convert to embed format
  • Wistia: Use fast.wistia.net embed URLs

4. Audio Playback

Supported audio formats: MP3, WAV, M4A, AAC, OGG. Implement:

  • Play/pause controls
  • Progress bar with seek capability
  • Download option for offline access
  • Playback speed controls (optional)

5. Quiz Submission Flow

async function handleQuizSubmission(qualificationId, answers) { try { const response = await fetch( `/api/qualifications/${qualificationId}/submit-quiz`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ answers }) } ); const result = await response.json(); if (result.passed) { // Show success message alert(`Congratulations! You scored ${result.score}%`); // Allow user to complete the qualification } else { // Show failure message with option to retry alert(`Score: ${result.score}%. You need 70% to pass. Try again?`); } } catch (error) { console.error('Quiz submission failed:', error); } }

6. Series Organization

Group trainings by series for better UX:

const groupedByKey = trainings.reduce((acc, training) => { const key = training.series || 'Other'; if (!acc[key]) acc[key] = []; acc[key].push(training); return acc; }, {}); // Display in sections Object.keys(groupedBySeries).map(series => ( <Section title={series}> {groupedBySeries[series].map(training => ( <TrainingCard training={training} /> ))} </Section> ));

POST Assign Training
POST /api/qualifications/assign

Assign a training qualification to one or more users (admin/leader only).

Request Body
{ "qualification_id": 1, "user_ids": [5, 12, 18], "due_date": "2024-12-31" }
Parameters
Parameter Type Required Description
qualification_id integer REQUIRED The ID of the qualification to assign
user_ids array REQUIRED Array of user IDs to assign training to
due_date date OPTIONAL Due date for completion
GET Get Users with Progress
GET /api/qualifications/users-progress

Retrieve training progress for all users in your organization (admin/leader only).

Response Example
{ "data": [ { "user_id": 5, "name": "John Doe", "qualifications": [ { "qualification_id": 1, "title": "Small Group Leader Certification", "progress_percentage": 75, "status": "in_progress" } ] } ] }

Error Handling

The API uses conventional HTTP response codes to indicate success or failure of requests.

HTTP Status Codes

Code Meaning
200 OK - Request succeeded
201 Created - Resource successfully created
400 Bad Request - Invalid request parameters
401 Unauthorized - Invalid or missing authentication token
403 Forbidden - Authenticated but insufficient permissions
404 Not Found - Resource does not exist
422 Unprocessable Entity - Validation errors
429 Too Many Requests - Rate limit exceeded
500 Internal Server Error - Something went wrong on our end

Standard Error Response Format

{ "message": "The given data was invalid.", "errors": { "email": [ "The email field is required." ] } }

Groups API Specific Error Responses

When joining or managing groups, the API returns specific error codes to help you handle business logic errors appropriately.

422 Group Full Error

Returned when attempting to join a group that has reached its maximum member capacity.

Error Response
{ "message": "This group is full (50/50 members)", "error_type": "group_full", "group_id": 123, "current_members": 50, "max_members": 50 }
Fields
Field Type Description
error_type string Always "group_full"
group_id integer The ID of the full group
current_members integer Current number of members in the group
max_members integer Maximum members allowed (configured by system admin)
422 Group Not Live Error

Returned when attempting to join a group that is still in draft mode and not yet accepting members.

Error Response
{ "message": "This group is not yet live. Please contact your organization administrator.", "error_type": "group_not_live", "group_id": 123, "status": "draft" }
Fields
Field Type Description
error_type string Always "group_not_live"
group_id integer The ID of the group
status string Current group status (draft, active, inactive)
Note: Groups must have a qualified leader assigned before they become active and can accept members.
422 Leader Not Qualified Error

Returned when attempting to assign a leader to a group who has not completed required training/qualifications. This only occurs when the organization has enabled the "enforce_leader_qualifications" setting.

Error Response
{ "message": "This leader has not completed their required training yet.", "error_type": "leader_not_qualified", "leader_id": 456, "redirect_url": "/manage/team" }
Fields
Field Type Description
error_type string Always "leader_not_qualified"
leader_id integer The ID of the unqualified leader
redirect_url string Suggested URL to manage qualifications/training
Handling this error: Direct users to the training/qualifications page where they can assign required training to the leader or verify their qualification status.
422 Leader Limit Reached Error

Returned when attempting to assign a leader to a group who has already reached their maximum number of active group assignments.

Error Response
{ "message": "This leader is already assigned to 5 active groups (maximum: 5).", "error_type": "leader_limit_reached", "leader_id": 456, "current_groups": 5, "max_groups": 5 }
Fields
Field Type Description
error_type string Always "leader_limit_reached"
leader_id integer The ID of the leader who has reached their limit
current_groups integer Number of active groups currently assigned to this leader
max_groups integer Maximum number of active groups allowed per leader (configured by system admin)
Note: Only active groups count toward the limit. Draft and inactive groups do not count. System administrators can adjust the global limit in the super-admin settings.

Error Handling Best Practices

When building mobile or web applications, we recommend:

  1. Check error_type field: Use the error_type field to programmatically handle different error scenarios rather than parsing the message text.
  2. Display user-friendly messages: The message field contains human-readable text suitable for displaying to end users.
  3. Handle redirects: When a redirect_url is provided, consider navigating the user to that page for resolution.
  4. Show specific details: Use fields like current_members, max_members, current_groups, etc. to provide context to users.
  5. Implement retry logic: For transient errors (5xx codes), implement exponential backoff retry logic.

Example Error Handling (JavaScript)

try { const response = await fetch('https://disciply.app/api/groups/join', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_TOKEN', 'Content-Type': 'application/json' }, body: JSON.stringify({ joinCode: 'ABC123' }) }); const data = await response.json(); if (!response.ok) { // Handle specific error types switch (data.error_type) { case 'group_full': alert(`Group is full (${data.current_members}/${data.max_members})`); break; case 'group_not_live': alert('This group is not accepting members yet'); break; case 'leader_not_qualified': // Redirect to training page window.location.href = data.redirect_url; break; case 'leader_limit_reached': alert(`Leader has reached limit: ${data.current_groups}/${data.max_groups}`); break; default: alert(data.message); } return; } // Success case console.log('Joined group:', data); } catch (error) { console.error('Network error:', error); }

Migration Guide: Global Groups Update

This section provides guidance for mobile developers on migrating to the new global groups architecture.

What Changed

Summary of Changes
  • Added new group_type field to all group objects
  • Removed virtual group with ID 0 from API responses
  • All organizations now have a real global group with an actual database ID
  • Global groups are automatically sorted to the top of group lists
  • Global groups have restricted functionality (admin-only posts, no comments)

Required Changes in Your Mobile App

1. Update Group Model

Add the new group_type field to your group data model:

// Before interface Group { id: number; name: string; type: string | null; // Category like "Bible Study" status: string; // ...other fields } // After interface Group { id: number; name: string; type: string | null; // Category like "Bible Study" group_type: string; // NEW: 'group' or 'global' status: string; // ...other fields }

2. Remove Virtual Group (ID 0) Handling

Search your codebase for any special handling of group ID 0 and remove it:

// ❌ REMOVE THIS CODE if (group.id === 0) { // Special virtual group handling return renderVirtualGroup(group); } // ✅ No special handling needed anymore // All groups including global groups are now real database records

3. Display Global Groups Separately

Update your groups list UI to sort and display global groups at the top:

// Separate groups by type const globalGroups = groups.filter(g => g.group_type === 'global'); const regularGroups = groups.filter(g => g.group_type === 'group'); // Display in UI <View> <Text style={styles.sectionHeader}>Organization Announcements</Text> {globalGroups.map(group => <GlobalGroupCard group={group} />)} <Text style={styles.sectionHeader}>My Groups</Text> {regularGroups.map(group => <GroupCard group={group} />)} </View>

4. Restrict Post Creation for Global Groups

Only show the "Create Post" button for admins when viewing global groups:

function canCreatePost(group, user) { // For global groups, only admins can post if (group.group_type === 'global') { return user.is_org_admin; } // For regular groups, all members can post return true; } // In your UI {canCreatePost(group, currentUser) && ( <Button onPress={handleCreatePost}> Create Post </Button> )}

5. Disable Comments for Global Groups

Hide comment UI for posts in global groups:

function PostComponent({ post, group }) { const commentsDisabled = group.group_type === 'global'; return ( <View> <PostContent post={post} /> {!commentsDisabled && ( <CommentSection post={post} /> )} {commentsDisabled && ( <Text style={styles.infoText}> Comments are disabled for organization-wide announcements </Text> )} </View> ); }

6. Hide Member List for Global Groups

For privacy, only show member count for global groups, not the full member list:

function GroupMembersSection({ group }) { if (group.group_type === 'global') { return ( <Text>{group.member_count} members</Text> ); } // For regular groups, show full member list return ( <MembersList groupId={group.id} /> ); }

7. Prevent Edit/Delete for Global Groups

Global groups are system-managed and cannot be edited or deleted by users:

function GroupActions({ group, user }) { // Hide edit/delete for global groups if (group.group_type === 'global') { return null; } return ( <View> {user.can_edit_group && ( <Button onPress={handleEdit}>Edit Group</Button> )} {user.can_delete_group && ( <Button onPress={handleDelete}>Delete Group</Button> )} </View> ); }

Testing Checklist

Before releasing your updated app, verify the following:

  • ✅ Global groups display at the top of the groups list
  • ✅ Non-admin users cannot see "Create Post" button in global groups
  • ✅ Comment input is hidden for all global group posts
  • ✅ Member list shows count only (not full list) for global groups
  • ✅ Edit/Delete buttons are hidden for global groups
  • ✅ No code references to group ID 0 remain
  • ✅ Group sorting works correctly (global groups first)

Backward Compatibility

Good News

The API maintains backward compatibility for most features. Existing group endpoints continue to work, and the new group_type field is always present in responses. However, the virtual group (ID 0) has been permanently removed, so any code relying on it must be updated.

Need Help?

If you encounter issues during migration or have questions about implementing these changes:


Support

Need help with the API? We're here to assist you:

  • Documentation Issues: If you find errors or have suggestions for improving this documentation, please contact us.
  • Technical Support: For API-related questions or issues, reach out to our support team at support form.
  • Feature Requests: Have ideas for new API endpoints? We'd love to hear from you through our contact form.
Rate Limits

To ensure fair usage, API requests are rate-limited. Pro plan users receive higher rate limits. Contact support if you need increased limits for your use case.