Core Concepts

Essential concepts and data models for working with the EvangelOS API. Understand organizations, members, permissions, and how data flows through the system.

Understanding the EvangelOS API is more than just knowing which endpoints to call—it's about grasping the underlying concepts that power church management systems. This guide will help you understand the key concepts, data relationships, and architectural patterns that will make you successful with the API.

🏢 Organizations: Your Data Boundary

Everything in EvangelOS is scoped to an organization. Think of an organization as a complete church entity with its own isolated data, settings, and users.

Single Tenant per Session

Each authenticated session belongs to exactly one organization

Complete Data Isolation

Organizations cannot access each other's members, events, or settings

What This Means for Your Code

// When you authenticate, you're authenticated to a specific organization
const loginResponse = await fetch('/api/auth/login', {
  method: 'POST',
  body: JSON.stringify({
    username: '[email protected]',  // This determines the organization
    password: 'password123'
  })
});

// Your session now has access to First Church's data only
const authStatus = await fetch('/api/auth/status');
// Returns: { user: { organizationId: "org_firstchurch_123" } }
💡

Important for Multi-Church Apps If you're building an app that serves multiple churches, you'll need separate authentication sessions for each organization. You cannot access multiple organizations with a single session.


👥 Members vs Users: Understanding the Distinction

One of the most important concepts in EvangelOS is the difference between Members and Users:

Members are the people who attend your church - the congregation, visitors, and community.

{
  "id": "mem_12345",
  "firstName": "Sarah",
  "lastName": "Johnson",
  "email": "[email protected]",
  "memberType": "active_member",
  "joinDate": "2020-03-15",
  // Members have profile info, attendance records, etc.
}
  • What they are: Church attendees, visitors, community members
  • What they do: Attend events, receive communications, have spiritual journeys
  • API access: Members data via /api/members/* endpoints

The Connection

A User might also be a Member of the church, but they're separate records:

// John Smith is both a user (can access the system) and a member (attends the church)
const user = { id: "user_67890", email: "[email protected]", role: "site_admin" };
const member = { id: "mem_11111", email: "[email protected]", memberType: "pastor" };

🔐 Roles and Permissions System

EvangelOS uses a role-based access control system that determines what each authenticated user can see and do.

Core Roles

site_admin

Full Access
Can manage all aspects of the organization including users, settings, and data

editor

Content Management
Can create and edit members, events, and communications but cannot manage users

viewer

Read-Only Access
Can view data and reports but cannot make changes

Permission Categories

Your user's role determines which API endpoints you can access:

// Check your current permissions
const authStatus = await fetch('/api/auth/status');
const permissions = authStatus.session.permissions;

// Example permissions array:
[
  "members:view",      // Can read member data
  "members:edit",      // Can update member records  
  "events:create",     // Can create new events
  "events:manage",     // Can edit/delete events
  "communications:send", // Can send emails/messages
  "reports:generate"   // Can access analytics
]
⚠️

Permission Errors If you try to access an endpoint without proper permissions, you'll get a 403 Forbidden response. Always check your user's permissions before attempting restricted operations.


⏰ Session Lifecycle and Security

Understanding how your authentication session works is crucial for building reliable integrations.

Session Behavior

Session Duration and Expiry

Default Session Length: 7 days of inactivity Sliding Expiration: Each API call extends the session Security: Sessions are tied to IP address and user agent for additional security

// Your session automatically extends with each API call
await fetch('/api/members'); // Session extended for another 7 days

// Check if your session is still valid
const status = await fetch('/api/auth/status');
if (status.status === 401) {
  // Session expired - need to re-authenticate
  await reauthenticate();
}
Session Security Best Practices

Never log session cookies: Session cookies are like temporary passwords Handle expiration gracefully: Always check for 401 responses and re-authenticate Use HTTPS only: Session cookies should only be transmitted over secure connections

// Good: Handle session expiration gracefully
const makeAuthenticatedRequest = async (url, options = {}) => {
  let response = await fetch(url, { credentials: 'include', ...options });
  
  if (response.status === 401) {
    // Session expired - re-authenticate
    await reauthenticate();
    response = await fetch(url, { credentials: 'include', ...options });
  }
  
  return response;
};

🔄 Data Relationships and Models

Understanding how data connects in EvangelOS will help you build more efficient applications.

Core Data Flow

graph TB
    A[Organization] --> B[Members]
    A --> C[Events]
    A --> D[Skills]
    A --> E[Groups]
    
    B --> F[Event RSVPs]
    B --> G[Member Skills]
    B --> H[Group Memberships]
    
    C --> F
    D --> G
    E --> H
    
    A --> I[Communications]
    I --> J[Email Campaigns]
    I --> K[Communication Analytics]

Key Relationships

Members RSVP to Events

// Get all RSVPs for an event
const eventRsvps = await fetch(`/api/events/${eventId}/rsvps`);

// Get all events a member has RSVP'd to
const memberEvents = await fetch(`/api/members/${memberId}/events`);

Data Structure:

  • Members have many Event RSVPs
  • Events have many Member RSVPs
  • RSVP includes: status (yes/no/maybe), attendance, check-in time

🎯 Common Patterns and Best Practices

Efficient Data Loading

Use includes to reduce API calls:

// Instead of multiple requests...
const member = await fetch('/api/members/123');
const skills = await fetch('/api/members/123/skills');
const events = await fetch('/api/members/123/events');

// Use a single request with includes
const member = await fetch('/api/members/123?include=skills,events');

Handling Pagination

Large datasets are automatically paginated:

// Get paginated results
const response = await fetch('/api/members?page=1&limit=50');
const data = await response.json();

console.log(data.pagination);
// {
//   "page": 1,
//   "limit": 50, 
//   "total": 1250,
//   "pages": 25
// }

Error Handling Patterns

Common HTTP status codes and their meanings:

  • 200 OK: Request successful
  • 201 Created: Resource created successfully
  • 400 Bad Request: Invalid data sent (check validation errors)
  • 401 Unauthorized: Session expired or invalid
  • 403 Forbidden: Insufficient permissions for this action
  • 404 Not Found: Resource doesn't exist
  • 422 Unprocessable Entity: Validation failed
  • 429 Too Many Requests: Rate limit exceeded
const handleApiResponse = async (response) => {
  switch (response.status) {
    case 401:
      // Re-authenticate and retry
      await reauthenticate();
      break;
    case 403:
      throw new Error('Insufficient permissions');
    case 422:
      const errors = await response.json();
      throw new ValidationError(errors.message);
    default:
      if (!response.ok) {
        throw new Error(`API error: ${response.status}`);
      }
  }
  return response.json();
};

🚀 Next Steps

Now that you understand the core concepts, you're ready to dive deeper:

Quick Reference

Base URL: https://api.evangelos.app
Authentication: Session-based with cookies
Data Format: JSON
Rate Limits: 1000 requests per hour per organization

💡

Pro Tip The interactive API reference automatically uses your authenticated session, so you can test endpoints directly from the documentation!

Ready to start building? Your understanding of these core concepts will make working with the EvangelOS API much more intuitive and successful! 🎯