Services Data Model
This document provides complete documentation of the Planning Center Services data model in Parable, including all tables, fields, and relationships.Overview
The Services module contains 63 tables supporting worship planning, volunteer scheduling, song management, and service coordination across your entire ministry.Query Requirements
Schema Prefix
IMPORTANT: All tables in the Planning Center Services module are in theplanning_center
schema. You MUST prefix all table names with planning_center.
in your queries.
✅ CORRECT: SELECT * FROM planning_center.services_plans
❌ INCORRECT: SELECT * FROM services_plans
Row Level Security (RLS)
This database uses Row Level Security (RLS) to automatically filter data based on:- tenant_organization_id: You only see data for your current organization
- system_status: You only see ‘active’ records by default
- ❌
WHERE tenant_organization_id = 1
(unnecessary) - ❌
WHERE system_status = 'active'
(unnecessary)
Core Tables Overview
Primary Entity Tables
services_service_types
- Service categories (Sunday morning, youth, special events)services_plans
- Individual service plans with dates and detailsservices_teams
- Volunteer and worship teamsservices_people
- People who serve in ministryservices_songs
- Song library and metadataservices_arrangements
- Song arrangements and keysservices_items
- Service elements and orderservices_schedules
- Person scheduling informationservices_plan_people
- People scheduled for specific plansservices_attachments
- Files, charts, and media
Supporting Entity Tables
services_plan_times
- Service times (9am service, 11am service, etc.)services_plan_templates
- Reusable service templatesservices_team_positions
- Roles within teams (drummer, vocalist, etc.)services_person_team_position_assignments
- Who can serve in what rolesservices_needed_positions
- Unfilled positions for servicesservices_blockouts
- When people are unavailableservices_blockout_dates
- Specific unavailable datesservices_live
- Live service control and streamingservices_media
- Media files and videosservices_folders
- Organizational structure
Relationship Tables
services_plan_relationships
- Links plans to other entitiesservices_team_relationships
- Links teams to service typesservices_item_relationships
- Links items to songs, arrangements, etc.services_person_relationships
- Links people to teams and positions
Table Definitions
services_service_types
Service types define categories of services (Sunday Morning, Youth Service, etc.).Column | Type | Description |
---|---|---|
id | UUID | Internal unique identifier |
service_type_id | VARCHAR(64) | Planning Center service type ID |
name | VARCHAR(255) | Service type name |
sequence | INTEGER | Display order |
permissions | VARCHAR(50) | Permission level |
attachment_types_enabled | BOOLEAN | Whether attachment types are enabled |
scheduled_publish | BOOLEAN | Whether scheduled publishing is enabled |
frequency | VARCHAR(50) | Service frequency (Weekly, Monthly, etc.) |
archived_at | TIMESTAMP | When service type was archived |
created_at | TIMESTAMP | When created in Planning Center |
updated_at | TIMESTAMP | Last update in Planning Center |
deleted_at | TIMESTAMP | When deleted in Planning Center |
custom_item_types | JSONB | Custom service item types configuration |
standard_item_types | JSONB | Standard item types (Header, Song, Media) |
background_check_permissions | VARCHAR(50) | Background check requirement level |
comment_permissions | VARCHAR(50) | Who can comment on plans |
last_plan_from | VARCHAR(50) | How last plan was created |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status: ‘active’, ‘transferring’, ‘stale’ |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
services_plans
Individual service plans containing all details for a specific service date.Column | Type | Description |
---|---|---|
id | UUID | Internal unique identifier |
plan_id | VARCHAR(64) | Planning Center plan ID |
service_type_id | VARCHAR(64) | Associated service type |
title | VARCHAR(255) | Plan title |
series_title | VARCHAR(255) | Sermon series title |
public | BOOLEAN | Whether plan is publicly visible |
can_view_order | BOOLEAN | Whether order is viewable |
rehearsable | BOOLEAN | Whether rehearsal is scheduled |
multi_day | BOOLEAN | Whether plan spans multiple days |
items_count | INTEGER | Total number of service items |
plan_people_count | INTEGER | Number of scheduled people |
needed_positions_count | INTEGER | Number of unfilled positions |
plan_notes_count | INTEGER | Number of plan notes |
service_time_count | INTEGER | Number of service times |
rehearsal_time_count | INTEGER | Number of rehearsal times |
other_time_count | INTEGER | Number of other scheduled times |
total_length | INTEGER | Total service length in seconds |
sort_date | TIMESTAMP | Date used for chronological sorting |
last_time_at | TIMESTAMP | Last service time |
dates | VARCHAR(255) | Human-readable date string |
short_dates | VARCHAR(100) | Abbreviated date string |
files_expire_at | TIMESTAMP | When attached files expire |
planning_center_url | VARCHAR(2048) | Direct link to plan |
reminders_disabled | BOOLEAN | Whether reminders are turned off |
created_at | TIMESTAMP | When created |
updated_at | TIMESTAMP | Last update |
permissions | VARCHAR(50) | User permissions for this plan |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When created in Parable |
system_updated_at | TIMESTAMP | Last update in Parable |
services_teams
Teams of volunteers and staff who serve in ministry.Column | Type | Description |
---|---|---|
id | UUID | Internal unique identifier |
team_id | VARCHAR(64) | Planning Center team ID |
service_type_id | VARCHAR(64) | Associated service type |
name | VARCHAR(255) | Team name |
rehearsal_team | BOOLEAN | Whether team attends rehearsals |
secure_team | BOOLEAN | Whether team requires background checks |
sequence | INTEGER | Display order |
schedule_to | VARCHAR(50) | Scheduling type (‘plan’ or ‘time’) |
default_status | VARCHAR(50) | Default response status |
default_prepare_notifications | BOOLEAN | Default notification setting |
assigned_directly | BOOLEAN | Whether people are assigned directly |
viewers_see | INTEGER | What viewers can see |
stage_color | VARCHAR(50) | Color for stage display |
stage_variant | VARCHAR(50) | Stage display variant |
archived_at | TIMESTAMP | When team was archived |
created_at | TIMESTAMP | When created |
updated_at | TIMESTAMP | Last update |
last_plan_from | VARCHAR(50) | How last plan was created |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When created in Parable |
system_updated_at | TIMESTAMP | Last update in Parable |
services_people
People who participate in services as volunteers, staff, or worship team members.Column | Type | Description |
---|---|---|
id | UUID | Internal unique identifier |
person_id | VARCHAR(64) | Planning Center person ID |
first_name | VARCHAR(100) | First name |
last_name | VARCHAR(100) | Last name |
full_name | VARCHAR(255) | Complete name |
nickname | VARCHAR(100) | Preferred name |
given_name | VARCHAR(100) | Given name |
middle_name | VARCHAR(100) | Middle name |
birthdate | DATE | Date of birth |
anniversary | DATE | Anniversary date |
photo_url | VARCHAR(2048) | Profile photo URL |
photo_thumbnail_url | VARCHAR(2048) | Thumbnail photo URL |
preferred_app | VARCHAR(50) | Preferred Planning Center app |
assigned_to_rehearsal_team | BOOLEAN | Whether on rehearsal team |
archived | BOOLEAN | Whether person is archived |
site_administrator | BOOLEAN | Whether site admin |
permissions | VARCHAR(50) | General permissions |
media_permissions | VARCHAR(50) | Media access permissions |
song_permissions | VARCHAR(50) | Song access permissions |
status | VARCHAR(50) | Active status |
notes | TEXT | Personal notes |
passed_background_check | BOOLEAN | Background check status |
access_media_attachments | BOOLEAN | Can access media |
access_plan_attachments | BOOLEAN | Can access plan files |
access_song_attachments | BOOLEAN | Can access song files |
preferred_max_plans_per_day | INTEGER | Daily scheduling limit |
preferred_max_plans_per_month | INTEGER | Monthly scheduling limit |
praise_charts_enabled | BOOLEAN | PraiseCharts integration |
ical_code | VARCHAR(100) | Calendar feed code |
logged_in_at | TIMESTAMP | Last login time |
created_at | TIMESTAMP | When created |
updated_at | TIMESTAMP | Last update |
archived_at | TIMESTAMP | When archived |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When created in Parable |
system_updated_at | TIMESTAMP | Last update in Parable |
services_songs
Complete song library with metadata for worship planning.Column | Type | Description |
---|---|---|
id | UUID | Internal unique identifier |
song_id | VARCHAR(64) | Planning Center song ID |
title | VARCHAR(255) | Song title |
author | VARCHAR(255) | Song author/composer |
copyright | VARCHAR(500) | Copyright information |
admin | VARCHAR(255) | Administrator/publisher |
ccli_number | INTEGER | CCLI license number |
hidden | BOOLEAN | Whether song is hidden |
notes | TEXT | Song notes |
themes | VARCHAR(500) | Song themes/tags |
last_scheduled_at | TIMESTAMP | When last used in service |
last_scheduled_short_dates | VARCHAR(100) | Short date of last use |
created_at | TIMESTAMP | When created |
updated_at | TIMESTAMP | Last update |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When created in Parable |
system_updated_at | TIMESTAMP | Last update in Parable |
services_arrangements
Different arrangements and keys for songs.Column | Type | Description |
---|---|---|
id | UUID | Internal unique identifier |
arrangement_id | VARCHAR(64) | Planning Center arrangement ID |
song_id | VARCHAR(64) | Associated song |
name | VARCHAR(255) | Arrangement name |
bpm | DECIMAL(5,1) | Beats per minute |
length | INTEGER | Length in seconds |
meter | VARCHAR(10) | Time signature (4/4, 3/4, etc.) |
notes | TEXT | Arrangement notes |
chord_chart | TEXT | Chord chart content |
lyrics | TEXT | Song lyrics |
sequence | JSONB | Song section sequence |
sequence_short | JSONB | Abbreviated sequence |
sequence_full | JSONB | Full detailed sequence |
chord_chart_key | VARCHAR(10) | Musical key |
chord_chart_font | VARCHAR(50) | Display font |
chord_chart_font_size | INTEGER | Font size |
chord_chart_columns | INTEGER | Column layout |
has_chords | BOOLEAN | Whether chords exist |
has_chord_chart | BOOLEAN | Whether chart exists |
lyrics_enabled | BOOLEAN | Whether lyrics are enabled |
number_chart_enabled | BOOLEAN | Nashville number system |
numeral_chart_enabled | BOOLEAN | Roman numeral system |
print_margin | VARCHAR(20) | Print margins |
print_orientation | VARCHAR(20) | Portrait/landscape |
print_page_size | VARCHAR(20) | Paper size |
archived_at | TIMESTAMP | When archived |
created_at | TIMESTAMP | When created |
updated_at | TIMESTAMP | Last update |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When created in Parable |
system_updated_at | TIMESTAMP | Last update in Parable |
services_items
Individual elements within a service plan.Column | Type | Description |
---|---|---|
id | UUID | Internal unique identifier |
item_id | VARCHAR(64) | Planning Center item ID |
plan_id | VARCHAR(64) | Associated plan |
title | VARCHAR(255) | Item title |
sequence | INTEGER | Order in service |
length | INTEGER | Duration in seconds |
item_type | VARCHAR(50) | Type (song, header, media, item) |
service_position | VARCHAR(50) | Position (pre, during, post) |
description | TEXT | Item description |
key_name | VARCHAR(10) | Musical key |
html_details | TEXT | Formatted details |
custom_arrangement_sequence | JSONB | Custom sequence |
song_id | VARCHAR(64) | Associated song |
arrangement_id | VARCHAR(64) | Associated arrangement |
created_at | TIMESTAMP | When created |
updated_at | TIMESTAMP | Last update |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When created in Parable |
system_updated_at | TIMESTAMP | Last update in Parable |
services_plan_people
People scheduled to serve in specific service plans.Column | Type | Description |
---|---|---|
id | UUID | Internal unique identifier |
plan_person_id | VARCHAR(64) | Planning Center plan person ID |
plan_id | VARCHAR(64) | Associated plan |
person_id | VARCHAR(64) | Associated person |
team_id | VARCHAR(64) | Associated team |
status | VARCHAR(20) | Status (C=Confirmed, U=Unconfirmed, D=Declined) |
team_position_name | VARCHAR(100) | Position/role name |
photo_thumbnail | VARCHAR(2048) | Person’s photo |
decline_reason | TEXT | Why declined |
notes | TEXT | Scheduling notes |
prepare_notification | BOOLEAN | Whether to send prep notification |
can_accept_partial | BOOLEAN | Can accept partial scheduling |
notification_sent_at | TIMESTAMP | When notified |
notification_read_at | TIMESTAMP | When read notification |
notification_prepared_at | TIMESTAMP | When notification prepared |
notification_changed_at | TIMESTAMP | When notification changed |
notification_changed_by_name | VARCHAR(255) | Who changed notification |
notification_sender_name | VARCHAR(255) | Who sent notification |
status_updated_at | TIMESTAMP | When status changed |
scheduled_by_name | VARCHAR(255) | Who scheduled this person |
created_at | TIMESTAMP | When created |
updated_at | TIMESTAMP | Last update |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When created in Parable |
system_updated_at | TIMESTAMP | Last update in Parable |
services_schedules
Individual scheduling records for people across all services.Column | Type | Description |
---|---|---|
id | UUID | Internal unique identifier |
schedule_id | VARCHAR(64) | Planning Center schedule ID |
person_id | VARCHAR(64) | Associated person |
service_type_id | VARCHAR(64) | Associated service type |
plan_id | VARCHAR(64) | Associated plan |
team_id | VARCHAR(64) | Associated team |
organization_name | VARCHAR(255) | Organization name |
service_type_name | VARCHAR(255) | Service type name |
team_name | VARCHAR(255) | Team name |
team_position_name | VARCHAR(100) | Position name |
person_name | VARCHAR(255) | Person’s full name |
sort_date | TIMESTAMP | Date for sorting |
dates | VARCHAR(255) | Service dates |
short_dates | VARCHAR(100) | Short date format |
status | VARCHAR(20) | Schedule status |
decline_reason | TEXT | Reason if declined |
can_accept_partial | BOOLEAN | Can accept partial |
can_accept_partial_one_time | BOOLEAN | One-time partial |
can_rehearse | BOOLEAN | Available for rehearsal |
plan_visible | BOOLEAN | Can see plan |
plan_visible_to_me | BOOLEAN | Plan visible to user |
position_display_times | VARCHAR(255) | When position shows |
responds_to_name | VARCHAR(255) | Who responds to |
organization_time_zone | VARCHAR(100) | Time zone |
organization_twenty_four_hour_time | BOOLEAN | 24-hour format |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When created in Parable |
system_updated_at | TIMESTAMP | Last update in Parable |
services_attachments
Files attached to plans, songs, or other resources.Column | Type | Description |
---|---|---|
id | UUID | Internal unique identifier |
attachment_id | VARCHAR(64) | Planning Center attachment ID |
filename | VARCHAR(255) | File name |
file_size | BIGINT | Size in bytes |
content_type | VARCHAR(100) | MIME type |
url | VARCHAR(2048) | Download URL |
thumbnail_url | VARCHAR(2048) | Thumbnail URL |
linked_url | VARCHAR(2048) | External link |
pco_type | VARCHAR(50) | Planning Center type |
display_name | VARCHAR(255) | Display name |
filetype | VARCHAR(50) | File type |
remote_link | VARCHAR(2048) | Remote file link |
page_order | VARCHAR(50) | Page ordering |
licenses_purchased | INTEGER | Number of licenses |
licenses_remaining | INTEGER | Remaining licenses |
licenses_used | INTEGER | Used licenses |
allow_mp3_download | BOOLEAN | MP3 download allowed |
web_streamable | BOOLEAN | Can stream on web |
downloadable | BOOLEAN | Can be downloaded |
transposable | BOOLEAN | Can transpose |
streamable | BOOLEAN | Can stream |
has_preview | BOOLEAN | Preview available |
attachable_type | VARCHAR(50) | What it’s attached to |
attachable_id | VARCHAR(64) | Parent resource ID |
created_at | TIMESTAMP | When created |
updated_at | TIMESTAMP | Last update |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When created in Parable |
system_updated_at | TIMESTAMP | Last update in Parable |
Relationship Tables
services_plan_relationships
Links plans to series, previous/next plans, and service types.Column | Type | Description |
---|---|---|
id | UUID | Internal unique identifier |
plan_id | VARCHAR(64) | Plan ID |
related_entity_type | VARCHAR(50) | Type of related entity |
related_entity_id | VARCHAR(64) | Related entity ID |
relationship_type | VARCHAR(50) | Type of relationship |
tenant_organization_id | INTEGER | Organization identifier |
services_team_relationships
Links teams to service types and parent teams.Column | Type | Description |
---|---|---|
id | UUID | Internal unique identifier |
team_id | VARCHAR(64) | Team ID |
service_type_id | VARCHAR(64) | Service type ID |
relationship_type | VARCHAR(50) | Type of relationship |
tenant_organization_id | INTEGER | Organization identifier |
services_item_relationships
Links service items to songs, arrangements, and media.Column | Type | Description |
---|---|---|
id | UUID | Internal unique identifier |
item_id | VARCHAR(64) | Item ID |
related_entity_type | VARCHAR(50) | Type (song, arrangement, media) |
related_entity_id | VARCHAR(64) | Related entity ID |
tenant_organization_id | INTEGER | Organization identifier |
Data Relationships
Key Relationships
-
Service Planning Hierarchy
- Service Types → Plans → Items
- Plans → Plan Times → Plan People
-
Team Structure
- Teams → Team Positions → Person Team Position Assignments
- Teams → Plan People → Schedules
-
Song Management
- Songs → Arrangements → Items
- Songs → Attachments (chord charts, lead sheets)
-
Scheduling Flow
- People → Schedules → Plan People
- People → Blockouts → Blockout Dates
-
Resource Attachments
- Plans → Attachments
- Songs → Attachments
- Items → Media
Query Patterns
Finding Scheduled Volunteers
Analyzing Song Usage
Data Integrity Rules
- Schema Qualification: Always use
planning_center.
prefix for all table references - Row Level Security: RLS automatically handles multi-tenancy and status filtering - do not add manual filters
- Monetary Values: Any cost or fee columns are stored in cents - divide by 100.0 for display
- Scheduling Status Flags: Use fields like
status
anddecline_reason
to interpret plan assignments instead of checkingsystem_status
- Direct ID Columns: Core tables such as
services_plans
andservices_plan_people
expose direct IDs for performance-sensitive joins
Common Mistakes to Avoid
-
Missing Schema Prefix
- ❌
FROM services_plan_people
- ✅
FROM planning_center.services_plan_people
- ❌
-
Adding Redundant RLS Filters
- ❌
WHERE tenant_organization_id = 1 AND system_status = 'active'
- ✅ Trust RLS to handle this automatically
- ❌
-
Joining Without Schema
- ❌
JOIN services_people p ON ...
- ✅
JOIN planning_center.services_people p ON ...
- ❌
-
Forgetting Duration Conversion
- ❌
SELECT duration_seconds as minutes
- ✅
SELECT duration_seconds / 60.0 as minutes
- ❌
Performance Considerations
-
Indexes: All tables have optimized indexes on:
- Primary keys and entity IDs
- Join columns and foreign keys
- Date columns for time-based queries
-
Query Optimization:
- Always use the
planning_center.
schema prefix - RLS handles tenant and status filtering automatically
- Filter scheduling status or declined responses when relevant
- Consider CTEs for complex aggregations
- Use direct ID columns when available instead of relationship tables
- Always use the
Data Synchronization
All Services tables use the standard Parable synchronization pattern:- system_status: Tracks data lifecycle (‘transferring’ → ‘active’ → ‘stale’)
- system_created_at: When record entered Parable
- system_updated_at: Last Parable update
- created_at/updated_at: Original Planning Center timestamps
Notes
- Status codes often use single letters: C=Confirmed, U=Unconfirmed, D=Declined
- All timestamps are stored in UTC
- JSONB fields store complex nested data structures
- File URLs may expire based on
files_expire_at
timestamps - Person records link to the main People app for complete profiles