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 the planning_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
DO NOT add these filters to your WHERE clause - they are applied automatically:
  • WHERE tenant_organization_id = 1 (unnecessary)
  • WHERE system_status = 'active' (unnecessary)
The RLS policies ensure you only access data you’re authorized to see, making these filters redundant and potentially causing performance issues.

Complete Table Inventory

Core Content Tables

1. publishing_episodes

Individual sermons, messages, and content pieces.
ColumnTypeDescription
idUUIDUnique internal identifier
episode_idVARCHAR(64)Planning Center episode ID
titleTEXTEpisode title
descriptionTEXTEpisode description
series_idVARCHAR(64)Associated series ID
channel_idVARCHAR(64)Primary channel ID
published_live_atTIMESTAMPWhen episode went live
published_to_library_atTIMESTAMPWhen added to library
video_urlTEXTPrimary video URL
video_thumbnail_urlTEXTVideo thumbnail image
library_video_urlTEXTLibrary video URL
library_video_thumbnail_urlTEXTLibrary thumbnail
library_audio_urlTEXTLibrary audio URL
library_streaming_serviceVARCHAR(255)Streaming provider
sermon_audioJSONBAudio file metadata
artJSONBArtwork/images metadata
church_center_urlTEXTChurch Center app URL
stream_typeVARCHAR(255)Live/recorded/hybrid
streaming_serviceVARCHAR(255)Streaming platform
page_actionsJSONBAvailable page actions
needs_library_audio_or_video_urlBOOLEANMissing media flag
needs_video_urlBOOLEANMissing video flag
services_plan_remote_identifierVARCHAR(64)Services app plan ID
services_service_type_remote_identifierVARCHAR(64)Service type ID
created_atTIMESTAMPCreation timestamp
updated_atTIMESTAMPLast update timestamp
tenant_organization_idINTEGEROrganization identifier
system_statusVARCHAR(50)Data lifecycle status
system_created_atTIMESTAMPSystem creation time
system_updated_atTIMESTAMPSystem update time

2. publishing_series

Sermon series and content collections.
ColumnTypeDescription
idUUIDUnique internal identifier
series_idVARCHAR(64)Planning Center series ID
titleVARCHAR(255)Series title
descriptionTEXTSeries description
channel_idVARCHAR(64)Primary channel ID
artJSONBSeries artwork metadata
church_center_urlVARCHAR(255)Church Center URL
started_atTIMESTAMPSeries start date
ended_atTIMESTAMPSeries end date
episodes_countINTEGERNumber of episodes
publishedBOOLEANPublication status
created_atTIMESTAMPCreation timestamp
updated_atTIMESTAMPLast update timestamp
tenant_organization_idINTEGEROrganization identifier
system_statusVARCHAR(50)Data lifecycle status
system_created_atTIMESTAMPSystem creation time
system_updated_atTIMESTAMPSystem update time

3. publishing_channels

Distribution channels and platforms.
ColumnTypeDescription
idUUIDUnique internal identifier
channel_idVARCHAR(64)Planning Center channel ID
nameVARCHAR(255)Channel name
kindVARCHAR(100)Channel type (podcast/video/etc)
descriptionTEXTChannel description
artJSONBChannel artwork metadata
streaming_serviceVARCHAR(255)Streaming platform
livestream_urlTEXTLive streaming URL
embed_codeTEXTEmbed HTML code
default_publish_timeTIMEDefault publish time
time_zoneVARCHAR(100)Channel timezone
church_center_enabledBOOLEANChurch Center visibility
created_atTIMESTAMPCreation timestamp
updated_atTIMESTAMPLast update timestamp
tenant_organization_idINTEGEROrganization identifier
system_statusVARCHAR(50)Data lifecycle status
system_created_atTIMESTAMPSystem creation time
system_updated_atTIMESTAMPSystem update time

4. publishing_speakers

Speaker profiles and information.
ColumnTypeDescription
idUUIDUnique internal identifier
speaker_idVARCHAR(64)Planning Center speaker ID
nameVARCHAR(255)Speaker full name
descriptionTEXTSpeaker bio/description
photo_urlTEXTSpeaker photo URL
person_idVARCHAR(64)Link to People app
created_atTIMESTAMPCreation timestamp
updated_atTIMESTAMPLast update timestamp
tenant_organization_idINTEGEROrganization identifier
system_statusVARCHAR(50)Data lifecycle status
system_created_atTIMESTAMPSystem creation time
system_updated_atTIMESTAMPSystem update time

Relationship Tables

5. publishing_speakerships

Links episodes to speakers (junction table).
ColumnTypeDescription
idUUIDUnique internal identifier
speakership_idVARCHAR(64)Planning Center speakership ID
episode_idVARCHAR(64)Associated episode ID
speaker_idVARCHAR(64)Associated speaker ID
tenant_organization_idINTEGEROrganization identifier
system_statusVARCHAR(50)Data lifecycle status
system_created_atTIMESTAMPSystem creation time
system_updated_atTIMESTAMPSystem update time

Resource and Media Tables

6. publishing_episode_resources

Files and resources attached to episodes.
ColumnTypeDescription
idUUIDUnique internal identifier
episode_resource_idVARCHAR(64)Planning Center resource ID
episode_idVARCHAR(64)Associated episode ID
nameVARCHAR(255)Resource name
kindVARCHAR(100)Resource type (notes/slides/etc)
urlTEXTResource download URL
file_sizeBIGINTFile size in bytes
content_typeVARCHAR(255)MIME type
created_atTIMESTAMPCreation timestamp
updated_atTIMESTAMPLast update timestamp
tenant_organization_idINTEGEROrganization identifier
system_statusVARCHAR(50)Data lifecycle status
system_created_atTIMESTAMPSystem creation time
system_updated_atTIMESTAMPSystem update time

7. publishing_note_templates

Templates for sermon notes and outlines.
ColumnTypeDescription
idUUIDUnique internal identifier
note_template_idVARCHAR(64)Planning Center template ID
episode_idVARCHAR(64)Associated episode ID
nameVARCHAR(255)Template name
contentTEXTTemplate content/markdown
kindVARCHAR(100)Template type
created_atTIMESTAMPCreation timestamp
updated_atTIMESTAMPLast update timestamp
tenant_organization_idINTEGEROrganization identifier
system_statusVARCHAR(50)Data lifecycle status
system_created_atTIMESTAMPSystem creation time
system_updated_atTIMESTAMPSystem update time

Scheduling Tables

8. publishing_episode_times

Publishing schedule for episodes on different channels.
ColumnTypeDescription
idUUIDUnique internal identifier
episode_time_idVARCHAR(64)Planning Center time ID
episode_idVARCHAR(64)Associated episode ID
channel_idVARCHAR(64)Target channel ID
published_atTIMESTAMPScheduled publish time
statusVARCHAR(50)Publishing status
created_atTIMESTAMPCreation timestamp
updated_atTIMESTAMPLast update timestamp
tenant_organization_idINTEGEROrganization identifier
system_statusVARCHAR(50)Data lifecycle status
system_created_atTIMESTAMPSystem creation time
system_updated_atTIMESTAMPSystem update time

9. publishing_channel_default_times

Default publishing schedules per channel.
ColumnTypeDescription
idUUIDUnique internal identifier
channel_default_time_idVARCHAR(64)Planning Center default time ID
channel_idVARCHAR(64)Associated channel ID
day_of_weekINTEGERDay (0=Sunday, 6=Saturday)
time_of_dayTIMEDefault publish time
enabledBOOLEANSchedule active flag
created_atTIMESTAMPCreation timestamp
updated_atTIMESTAMPLast update timestamp
tenant_organization_idINTEGEROrganization identifier
system_statusVARCHAR(50)Data lifecycle status
system_created_atTIMESTAMPSystem creation time
system_updated_atTIMESTAMPSystem update time

10. publishing_channel_next_times

Upcoming scheduled publishes per channel.
ColumnTypeDescription
idUUIDUnique internal identifier
channel_next_time_idVARCHAR(64)Planning Center next time ID
channel_idVARCHAR(64)Associated channel ID
next_publish_atTIMESTAMPNext scheduled publish
created_atTIMESTAMPCreation timestamp
updated_atTIMESTAMPLast update timestamp
tenant_organization_idINTEGEROrganization identifier
system_statusVARCHAR(50)Data lifecycle status
system_created_atTIMESTAMPSystem creation time
system_updated_atTIMESTAMPSystem update time

Analytics Tables

11. publishing_episode_statistics

View counts, downloads, and engagement metrics.
ColumnTypeDescription
idUUIDUnique internal identifier
episode_statistic_idVARCHAR(64)Planning Center statistic ID
episode_idVARCHAR(64)Associated episode ID
channel_idVARCHAR(64)Associated channel ID
view_countINTEGERTotal view count
download_countINTEGERTotal download count
unique_viewersINTEGERUnique viewer count
average_watch_timeINTEGERAverage watch time (seconds)
total_watch_timeBIGINTTotal watch time (seconds)
created_atTIMESTAMPStatistic timestamp
updated_atTIMESTAMPLast update timestamp
tenant_organization_idINTEGEROrganization identifier
system_statusVARCHAR(50)Data lifecycle status
system_created_atTIMESTAMPSystem creation time
system_updated_atTIMESTAMPSystem update time

12. publishing_episode_statistic_times

Statistics tracked over time periods.
ColumnTypeDescription
idUUIDUnique internal identifier
episode_statistic_time_idVARCHAR(64)Planning Center stat time ID
episode_statistic_idVARCHAR(64)Parent statistic ID
period_startTIMESTAMPPeriod start time
period_endTIMESTAMPPeriod end time
view_countINTEGERViews in period
download_countINTEGERDownloads in period
unique_viewersINTEGERUnique viewers in period
created_atTIMESTAMPCreation timestamp
updated_atTIMESTAMPLast update timestamp
tenant_organization_idINTEGEROrganization identifier
system_statusVARCHAR(50)Data lifecycle status
system_created_atTIMESTAMPSystem creation time
system_updated_atTIMESTAMPSystem update time

Configuration Tables

13. publishing_organizations

Organization-level publishing settings.
ColumnTypeDescription
idUUIDUnique internal identifier
organization_idVARCHAR(64)Planning Center org ID
nameVARCHAR(255)Organization name
settingsJSONBPublishing settings
default_channel_idVARCHAR(64)Default channel
created_atTIMESTAMPCreation timestamp
updated_atTIMESTAMPLast update timestamp
tenant_organization_idINTEGEROrganization identifier
system_statusVARCHAR(50)Data lifecycle status
system_created_atTIMESTAMPSystem creation time
system_updated_atTIMESTAMPSystem update time

14. publishing_channel_default_episode_resources

Default resources automatically attached to episodes per channel.
ColumnTypeDescription
idUUIDUnique internal identifier
channel_default_episode_resource_idVARCHAR(64)Planning Center default resource ID
channel_idVARCHAR(64)Associated channel ID
nameVARCHAR(255)Resource name
kindVARCHAR(100)Resource type
urlTEXTResource URL
auto_attachBOOLEANAuto-attach flag
created_atTIMESTAMPCreation timestamp
updated_atTIMESTAMPLast update timestamp
tenant_organization_idINTEGEROrganization identifier
system_statusVARCHAR(50)Data lifecycle status
system_created_atTIMESTAMPSystem creation time
system_updated_atTIMESTAMPSystem update time

Administrative Tables

15. publishing_onboardings

Tracks onboarding process for new channels.
ColumnTypeDescription
idUUIDUnique internal identifier
onboarding_idVARCHAR(64)Planning Center onboarding ID
channel_idVARCHAR(64)Associated channel ID
statusVARCHAR(50)Onboarding status
steps_completedJSONBCompleted steps tracking
created_atTIMESTAMPCreation timestamp
updated_atTIMESTAMPLast update timestamp
tenant_organization_idINTEGEROrganization identifier
system_statusVARCHAR(50)Data lifecycle status
system_created_atTIMESTAMPSystem creation time
system_updated_atTIMESTAMPSystem update time

16. publishing_jolt_tokens

Authentication tokens for API access.
ColumnTypeDescription
idUUIDUnique internal identifier
jolt_token_idVARCHAR(64)Planning Center token ID
tokenTEXTAuthentication token
expires_atTIMESTAMPToken expiration
scopesJSONBPermission scopes
created_atTIMESTAMPCreation timestamp
updated_atTIMESTAMPLast update timestamp
tenant_organization_idINTEGEROrganization identifier
system_statusVARCHAR(50)Data lifecycle status
system_created_atTIMESTAMPSystem creation time
system_updated_atTIMESTAMPSystem update time

17. publishing_page_restrictions

Content access restrictions and permissions.
ColumnTypeDescription
idUUIDUnique internal identifier
page_restriction_idVARCHAR(64)Planning Center restriction ID
episode_idVARCHAR(64)Associated episode ID
restriction_typeVARCHAR(100)Type of restriction
required_tagVARCHAR(255)Required person tag
required_list_idVARCHAR(64)Required list membership
created_atTIMESTAMPCreation timestamp
updated_atTIMESTAMPLast update timestamp
tenant_organization_idINTEGEROrganization identifier
system_statusVARCHAR(50)Data lifecycle status
system_created_atTIMESTAMPSystem creation time
system_updated_atTIMESTAMPSystem update time

System Fields

All tables include these system fields for data management:
  • tenant_organization_id - Multi-tenant organization identifier
  • system_status - Data lifecycle status (active, transferring, stale)
  • system_created_at - When the record was created in Parable
  • system_updated_at - When the record was last updated in Parable

Row Level Security

All tables implement Row Level Security (RLS) to ensure tenant isolation:
-- Example RLS policy
CREATE POLICY tenant_read_only ON planning_center.publishing_episodes
  FOR SELECT
  TO PUBLIC
  USING (
    system_status = 'active'
    AND EXISTS (
      SELECT 1 FROM public.tenant_dsn_credentials dsn
      WHERE dsn.role_name = CURRENT_ROLE
        AND dsn.tenant_organization_id = planning_center.publishing_episodes.tenant_organization_id
    )
  );

Data Integrity Rules

  1. Schema Qualification: Always use planning_center. prefix for all table references
  2. Row Level Security: RLS automatically handles multi-tenancy and status filtering - do not add manual filters
  3. Monetary Values: Any monetization or purchase amount columns are stored in cents - divide by 100.0 for display
  4. Media Flags: Use booleans like needs_video_url and needs_library_audio_or_video_url to identify missing assets instead of relying on system_status
  5. Direct ID Columns: Tables such as publishing_episodes, publishing_series, and publishing_speakerships expose direct IDs for performance-sensitive joins

Common Mistakes to Avoid

  1. Missing Schema Prefix
    • FROM publishing_episodes
    • FROM planning_center.publishing_episodes
  2. Adding Redundant RLS Filters
    • WHERE tenant_organization_id = 1 AND system_status = 'active'
    • ✅ Trust RLS to handle this automatically
  3. Joining Without Schema
    • JOIN publishing_series s ON ...
    • JOIN planning_center.publishing_series s ON ...
  4. Skipping Currency Conversion
    • SELECT purchase_price_cents as purchase_price
    • SELECT purchase_price_cents / 100.0 as purchase_price

Performance Considerations

  1. Indexes: All tables have optimized indexes on:
    • Primary keys and entity IDs
    • Join columns and foreign keys
    • Date columns for time-based queries
  2. 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

Data Synchronization

Publishing data is synchronized through Temporal workflows:
  1. Master Workflow - Orchestrates all child workflows
  2. Independent Entities - Channels, Series, Speakers, Organizations
  3. Dependent Entities - Episodes (depends on channels)
  4. Related Data - Resources, times, statistics (depends on episodes)
  5. Junction Tables - Speakerships linking episodes to speakers

Usage Tips

  1. Trust RLS for active data - Skip manual system_status or tenant filters
  2. Join through IDs - Use episode_id, series_id, speaker_id
  3. Consider NULL values - Many fields are optional
  4. Use JSONB operators for nested data in art, settings fields
  5. Aggregate statistics over time periods for trends

Common Join Patterns

Episodes with Series and Speakers

SELECT 
    e.title as episode_title,
    s.title as series_title,
    sp.name as speaker_name
FROM planning_center.publishing_episodes e
LEFT JOIN planning_center.publishing_series s 
    ON e.series_id = s.series_id
LEFT JOIN planning_center.publishing_speakerships ship 
    ON e.episode_id = ship.episode_id
LEFT JOIN planning_center.publishing_speakers sp 
    ON ship.speaker_id = sp.speaker_id;

Episodes with Statistics and Resources

SELECT 
    e.title,
    est.view_count,
    est.download_count,
    er.name as resource_name,
    er.url as resource_url
FROM planning_center.publishing_episodes e
LEFT JOIN planning_center.publishing_episode_statistics est 
    ON e.episode_id = est.episode_id
LEFT JOIN planning_center.publishing_episode_resources er 
    ON e.episode_id = er.episode_id;

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.