Planning Center Publishing Data Model - Complete Documentation
This document provides complete documentation of ALL tables in the Planning Center Publishing data model in Parable, including all entity tables and relationship tables with full field definitions.Overview
The Publishing module manages your church’s media content distribution, containing:- 17 entity tables - Episodes, series, channels, speakers, and supporting data
- 1 primary relationship table - Speakerships linking episodes to speakers
- Comprehensive metrics - View counts, downloads, and engagement tracking
Query Requirements
Schema Prefix
IMPORTANT: All tables in the Planning Center Publishing module are in theplanning_center
schema. You MUST prefix all table names with planning_center.
in your queries.
✅ CORRECT: SELECT * FROM planning_center.publishing_episodes
❌ INCORRECT: SELECT * FROM publishing_episodes
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)
Complete Table Inventory
Core Content Tables
1. publishing_episodes
Individual sermons, messages, and content pieces.
Column | Type | Description |
---|---|---|
id | UUID | Unique internal identifier |
episode_id | VARCHAR(64) | Planning Center episode ID |
title | TEXT | Episode title |
description | TEXT | Episode description |
series_id | VARCHAR(64) | Associated series ID |
channel_id | VARCHAR(64) | Primary channel ID |
published_live_at | TIMESTAMP | When episode went live |
published_to_library_at | TIMESTAMP | When added to library |
video_url | TEXT | Primary video URL |
video_thumbnail_url | TEXT | Video thumbnail image |
library_video_url | TEXT | Library video URL |
library_video_thumbnail_url | TEXT | Library thumbnail |
library_audio_url | TEXT | Library audio URL |
library_streaming_service | VARCHAR(255) | Streaming provider |
sermon_audio | JSONB | Audio file metadata |
art | JSONB | Artwork/images metadata |
church_center_url | TEXT | Church Center app URL |
stream_type | VARCHAR(255) | Live/recorded/hybrid |
streaming_service | VARCHAR(255) | Streaming platform |
page_actions | JSONB | Available page actions |
needs_library_audio_or_video_url | BOOLEAN | Missing media flag |
needs_video_url | BOOLEAN | Missing video flag |
services_plan_remote_identifier | VARCHAR(64) | Services app plan ID |
services_service_type_remote_identifier | VARCHAR(64) | Service type ID |
created_at | TIMESTAMP | Creation timestamp |
updated_at | TIMESTAMP | Last update timestamp |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data lifecycle status |
system_created_at | TIMESTAMP | System creation time |
system_updated_at | TIMESTAMP | System update time |
2. publishing_series
Sermon series and content collections.
Column | Type | Description |
---|---|---|
id | UUID | Unique internal identifier |
series_id | VARCHAR(64) | Planning Center series ID |
title | VARCHAR(255) | Series title |
description | TEXT | Series description |
channel_id | VARCHAR(64) | Primary channel ID |
art | JSONB | Series artwork metadata |
church_center_url | VARCHAR(255) | Church Center URL |
started_at | TIMESTAMP | Series start date |
ended_at | TIMESTAMP | Series end date |
episodes_count | INTEGER | Number of episodes |
published | BOOLEAN | Publication status |
created_at | TIMESTAMP | Creation timestamp |
updated_at | TIMESTAMP | Last update timestamp |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data lifecycle status |
system_created_at | TIMESTAMP | System creation time |
system_updated_at | TIMESTAMP | System update time |
3. publishing_channels
Distribution channels and platforms.
Column | Type | Description |
---|---|---|
id | UUID | Unique internal identifier |
channel_id | VARCHAR(64) | Planning Center channel ID |
name | VARCHAR(255) | Channel name |
kind | VARCHAR(100) | Channel type (podcast/video/etc) |
description | TEXT | Channel description |
art | JSONB | Channel artwork metadata |
streaming_service | VARCHAR(255) | Streaming platform |
livestream_url | TEXT | Live streaming URL |
embed_code | TEXT | Embed HTML code |
default_publish_time | TIME | Default publish time |
time_zone | VARCHAR(100) | Channel timezone |
church_center_enabled | BOOLEAN | Church Center visibility |
created_at | TIMESTAMP | Creation timestamp |
updated_at | TIMESTAMP | Last update timestamp |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data lifecycle status |
system_created_at | TIMESTAMP | System creation time |
system_updated_at | TIMESTAMP | System update time |
4. publishing_speakers
Speaker profiles and information.
Column | Type | Description |
---|---|---|
id | UUID | Unique internal identifier |
speaker_id | VARCHAR(64) | Planning Center speaker ID |
name | VARCHAR(255) | Speaker full name |
description | TEXT | Speaker bio/description |
photo_url | TEXT | Speaker photo URL |
person_id | VARCHAR(64) | Link to People app |
created_at | TIMESTAMP | Creation timestamp |
updated_at | TIMESTAMP | Last update timestamp |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data lifecycle status |
system_created_at | TIMESTAMP | System creation time |
system_updated_at | TIMESTAMP | System update time |
Relationship Tables
5. publishing_speakerships
Links episodes to speakers (junction table).
Column | Type | Description |
---|---|---|
id | UUID | Unique internal identifier |
speakership_id | VARCHAR(64) | Planning Center speakership ID |
episode_id | VARCHAR(64) | Associated episode ID |
speaker_id | VARCHAR(64) | Associated speaker ID |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data lifecycle status |
system_created_at | TIMESTAMP | System creation time |
system_updated_at | TIMESTAMP | System update time |
Resource and Media Tables
6. publishing_episode_resources
Files and resources attached to episodes.
Column | Type | Description |
---|---|---|
id | UUID | Unique internal identifier |
episode_resource_id | VARCHAR(64) | Planning Center resource ID |
episode_id | VARCHAR(64) | Associated episode ID |
name | VARCHAR(255) | Resource name |
kind | VARCHAR(100) | Resource type (notes/slides/etc) |
url | TEXT | Resource download URL |
file_size | BIGINT | File size in bytes |
content_type | VARCHAR(255) | MIME type |
created_at | TIMESTAMP | Creation timestamp |
updated_at | TIMESTAMP | Last update timestamp |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data lifecycle status |
system_created_at | TIMESTAMP | System creation time |
system_updated_at | TIMESTAMP | System update time |
7. publishing_note_templates
Templates for sermon notes and outlines.
Column | Type | Description |
---|---|---|
id | UUID | Unique internal identifier |
note_template_id | VARCHAR(64) | Planning Center template ID |
episode_id | VARCHAR(64) | Associated episode ID |
name | VARCHAR(255) | Template name |
content | TEXT | Template content/markdown |
kind | VARCHAR(100) | Template type |
created_at | TIMESTAMP | Creation timestamp |
updated_at | TIMESTAMP | Last update timestamp |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data lifecycle status |
system_created_at | TIMESTAMP | System creation time |
system_updated_at | TIMESTAMP | System update time |
Scheduling Tables
8. publishing_episode_times
Publishing schedule for episodes on different channels.
Column | Type | Description |
---|---|---|
id | UUID | Unique internal identifier |
episode_time_id | VARCHAR(64) | Planning Center time ID |
episode_id | VARCHAR(64) | Associated episode ID |
channel_id | VARCHAR(64) | Target channel ID |
published_at | TIMESTAMP | Scheduled publish time |
status | VARCHAR(50) | Publishing status |
created_at | TIMESTAMP | Creation timestamp |
updated_at | TIMESTAMP | Last update timestamp |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data lifecycle status |
system_created_at | TIMESTAMP | System creation time |
system_updated_at | TIMESTAMP | System update time |
9. publishing_channel_default_times
Default publishing schedules per channel.
Column | Type | Description |
---|---|---|
id | UUID | Unique internal identifier |
channel_default_time_id | VARCHAR(64) | Planning Center default time ID |
channel_id | VARCHAR(64) | Associated channel ID |
day_of_week | INTEGER | Day (0=Sunday, 6=Saturday) |
time_of_day | TIME | Default publish time |
enabled | BOOLEAN | Schedule active flag |
created_at | TIMESTAMP | Creation timestamp |
updated_at | TIMESTAMP | Last update timestamp |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data lifecycle status |
system_created_at | TIMESTAMP | System creation time |
system_updated_at | TIMESTAMP | System update time |
10. publishing_channel_next_times
Upcoming scheduled publishes per channel.
Column | Type | Description |
---|---|---|
id | UUID | Unique internal identifier |
channel_next_time_id | VARCHAR(64) | Planning Center next time ID |
channel_id | VARCHAR(64) | Associated channel ID |
next_publish_at | TIMESTAMP | Next scheduled publish |
created_at | TIMESTAMP | Creation timestamp |
updated_at | TIMESTAMP | Last update timestamp |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data lifecycle status |
system_created_at | TIMESTAMP | System creation time |
system_updated_at | TIMESTAMP | System update time |
Analytics Tables
11. publishing_episode_statistics
View counts, downloads, and engagement metrics.
Column | Type | Description |
---|---|---|
id | UUID | Unique internal identifier |
episode_statistic_id | VARCHAR(64) | Planning Center statistic ID |
episode_id | VARCHAR(64) | Associated episode ID |
channel_id | VARCHAR(64) | Associated channel ID |
view_count | INTEGER | Total view count |
download_count | INTEGER | Total download count |
unique_viewers | INTEGER | Unique viewer count |
average_watch_time | INTEGER | Average watch time (seconds) |
total_watch_time | BIGINT | Total watch time (seconds) |
created_at | TIMESTAMP | Statistic timestamp |
updated_at | TIMESTAMP | Last update timestamp |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data lifecycle status |
system_created_at | TIMESTAMP | System creation time |
system_updated_at | TIMESTAMP | System update time |
12. publishing_episode_statistic_times
Statistics tracked over time periods.
Column | Type | Description |
---|---|---|
id | UUID | Unique internal identifier |
episode_statistic_time_id | VARCHAR(64) | Planning Center stat time ID |
episode_statistic_id | VARCHAR(64) | Parent statistic ID |
period_start | TIMESTAMP | Period start time |
period_end | TIMESTAMP | Period end time |
view_count | INTEGER | Views in period |
download_count | INTEGER | Downloads in period |
unique_viewers | INTEGER | Unique viewers in period |
created_at | TIMESTAMP | Creation timestamp |
updated_at | TIMESTAMP | Last update timestamp |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data lifecycle status |
system_created_at | TIMESTAMP | System creation time |
system_updated_at | TIMESTAMP | System update time |
Configuration Tables
13. publishing_organizations
Organization-level publishing settings.
Column | Type | Description |
---|---|---|
id | UUID | Unique internal identifier |
organization_id | VARCHAR(64) | Planning Center org ID |
name | VARCHAR(255) | Organization name |
settings | JSONB | Publishing settings |
default_channel_id | VARCHAR(64) | Default channel |
created_at | TIMESTAMP | Creation timestamp |
updated_at | TIMESTAMP | Last update timestamp |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data lifecycle status |
system_created_at | TIMESTAMP | System creation time |
system_updated_at | TIMESTAMP | System update time |
14. publishing_channel_default_episode_resources
Default resources automatically attached to episodes per channel.
Column | Type | Description |
---|---|---|
id | UUID | Unique internal identifier |
channel_default_episode_resource_id | VARCHAR(64) | Planning Center default resource ID |
channel_id | VARCHAR(64) | Associated channel ID |
name | VARCHAR(255) | Resource name |
kind | VARCHAR(100) | Resource type |
url | TEXT | Resource URL |
auto_attach | BOOLEAN | Auto-attach flag |
created_at | TIMESTAMP | Creation timestamp |
updated_at | TIMESTAMP | Last update timestamp |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data lifecycle status |
system_created_at | TIMESTAMP | System creation time |
system_updated_at | TIMESTAMP | System update time |
Administrative Tables
15. publishing_onboardings
Tracks onboarding process for new channels.
Column | Type | Description |
---|---|---|
id | UUID | Unique internal identifier |
onboarding_id | VARCHAR(64) | Planning Center onboarding ID |
channel_id | VARCHAR(64) | Associated channel ID |
status | VARCHAR(50) | Onboarding status |
steps_completed | JSONB | Completed steps tracking |
created_at | TIMESTAMP | Creation timestamp |
updated_at | TIMESTAMP | Last update timestamp |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data lifecycle status |
system_created_at | TIMESTAMP | System creation time |
system_updated_at | TIMESTAMP | System update time |
16. publishing_jolt_tokens
Authentication tokens for API access.
Column | Type | Description |
---|---|---|
id | UUID | Unique internal identifier |
jolt_token_id | VARCHAR(64) | Planning Center token ID |
token | TEXT | Authentication token |
expires_at | TIMESTAMP | Token expiration |
scopes | JSONB | Permission scopes |
created_at | TIMESTAMP | Creation timestamp |
updated_at | TIMESTAMP | Last update timestamp |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data lifecycle status |
system_created_at | TIMESTAMP | System creation time |
system_updated_at | TIMESTAMP | System update time |
17. publishing_page_restrictions
Content access restrictions and permissions.
Column | Type | Description |
---|---|---|
id | UUID | Unique internal identifier |
page_restriction_id | VARCHAR(64) | Planning Center restriction ID |
episode_id | VARCHAR(64) | Associated episode ID |
restriction_type | VARCHAR(100) | Type of restriction |
required_tag | VARCHAR(255) | Required person tag |
required_list_id | VARCHAR(64) | Required list membership |
created_at | TIMESTAMP | Creation timestamp |
updated_at | TIMESTAMP | Last update timestamp |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data lifecycle status |
system_created_at | TIMESTAMP | System creation time |
system_updated_at | TIMESTAMP | System update time |
System Fields
All tables include these system fields for data management:tenant_organization_id
- Multi-tenant organization identifiersystem_status
- Data lifecycle status (active
,transferring
,stale
)system_created_at
- When the record was created in Parablesystem_updated_at
- When the record was last updated in Parable
Row Level Security
All tables implement Row Level Security (RLS) to ensure tenant isolation: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 monetization or purchase amount columns are stored in cents - divide by 100.0 for display
- Media Flags: Use booleans like
needs_video_url
andneeds_library_audio_or_video_url
to identify missing assets instead of relying onsystem_status
- Direct ID Columns: Tables such as
publishing_episodes
,publishing_series
, andpublishing_speakerships
expose direct IDs for performance-sensitive joins
Common Mistakes to Avoid
-
Missing Schema Prefix
- ❌
FROM publishing_episodes
- ✅
FROM planning_center.publishing_episodes
- ❌
-
Adding Redundant RLS Filters
- ❌
WHERE tenant_organization_id = 1 AND system_status = 'active'
- ✅ Trust RLS to handle this automatically
- ❌
-
Joining Without Schema
- ❌
JOIN publishing_series s ON ...
- ✅
JOIN planning_center.publishing_series s ON ...
- ❌
-
Skipping Currency Conversion
- ❌
SELECT purchase_price_cents as purchase_price
- ✅
SELECT purchase_price_cents / 100.0 as purchase_price
- ❌
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 by publication state or media availability when relevant
- Consider CTEs for aggregating view/download metrics
- Use direct ID columns when available instead of relationship tables
- Always use the
Data Synchronization
Publishing data is synchronized through Temporal workflows:- Master Workflow - Orchestrates all child workflows
- Independent Entities - Channels, Series, Speakers, Organizations
- Dependent Entities - Episodes (depends on channels)
- Related Data - Resources, times, statistics (depends on episodes)
- Junction Tables - Speakerships linking episodes to speakers
Usage Tips
- Trust RLS for active data - Skip manual
system_status
or tenant filters - Join through IDs - Use
episode_id
,series_id
,speaker_id
- Consider NULL values - Many fields are optional
- Use JSONB operators for nested data in
art
,settings
fields - Aggregate statistics over time periods for trends
Common Join Patterns
Episodes with Series and Speakers
Episodes with Statistics and Resources
Data Quality Notes
- Episode
published_live_at
indicates published content - Series may have NULL
ended_at
for ongoing series - Statistics are point-in-time snapshots, use latest for current counts
- Speakerships table enables many-to-many episode-speaker relationships
- Channel IDs in episodes indicate primary publishing channel
This data model enables comprehensive media analytics and content management for your church’s publishing ministry.