Registrations Data Model
Overview
The Registrations module contains 11 entity tables and 3 relationship tables supporting event registration, attendee management, emergency contacts, and signup tracking.
Complete Schema Reference
This guide provides a comprehensive reference for all Planning Center Registrations tables available in Parable. Understanding this data model will help you write accurate queries and build meaningful reports for your event management needs.
Visual Data Model
The diagram below shows the core entities and their relationships in the Registrations module. Use it as a visual reference while exploring the detailed table definitions below.
Core Entity Relationships
Open diagram in new tab →
Key Relationships Explained
Registration Structure:
REGISTRATION defines an event or program accepting signups
CATEGORY organizes signup options (e.g., T-shirt size, Meal preference)
SELECTION_TYPE provides specific choices within categories
Signup Flow:
- Person creates a
SIGNUP for a registration
ATTENDEE(s) are added (self or others)
SIGNUP_TIME(s) specify when attendees will participate
SIGNUP_LOCATION(s) define where events occur
EMERGENCY_CONTACT(s) provide safety information
Person vs Attendee:
PERSON is the signup submitter (from People module)
ATTENDEE can be the submitter or someone else (child, guest, etc.)
- One signup can include multiple attendees
- Each attendee has their own emergency contacts
Time and Location:
SIGNUP_TIME tracks session/workshop times
SIGNUP_LOCATION tracks event venues
- Both linked to parent signup, not individual attendees
- Supports multi-day, multi-location events
Generic Relationship Pattern:
- Campus associations via
registrations_registration_relationships
- Additional metadata via relationship tables
Query Requirements
Schema Prefix
IMPORTANT: All tables in the Planning Center Registrations module are in the planning_center schema. You MUST prefix all table names with planning_center. in your queries.
✅ CORRECT: SELECT * FROM planning_center.registrations_signups
❌ INCORRECT: SELECT * FROM registrations_signups
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.
Entity Tables
registrations_signups
Event signup forms and their configuration.
| Column | Type | Description |
|---|
id | UUID | Parable’s unique identifier |
signup_id | VARCHAR(64) | Planning Center’s signup ID |
name | VARCHAR(255) | Event name |
description | TEXT | Event description |
archived | BOOLEAN | Whether the signup is archived |
open_at | TIMESTAMP | When registration opens |
close_at | TIMESTAMP | When registration closes |
logo_url | VARCHAR(2048) | URL to event logo/image |
new_registration_url | VARCHAR(2048) | Direct link to registration form |
created_at | TIMESTAMP | When signup was created |
updated_at | TIMESTAMP | Last update time |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data sync 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 |
registrations_attendees
Individual attendee records for events.
| Column | Type | Description |
|---|
id | UUID | Parable’s unique identifier |
attendee_id | VARCHAR(64) | Planning Center’s attendee ID |
active | BOOLEAN | Whether registration is active |
canceled | BOOLEAN | Whether registration was canceled |
waitlisted | BOOLEAN | Whether attendee is waitlisted |
waitlisted_at | TIMESTAMP | When added to waitlist |
created_at | TIMESTAMP | When attendee record was created |
updated_at | TIMESTAMP | Last update time |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data sync status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
registrations_registrations
Registration submissions (minimal fields in current implementation).
| Column | Type | Description |
|---|
id | UUID | Parable’s unique identifier |
registration_id | VARCHAR(64) | Planning Center’s registration ID |
created_at | TIMESTAMP | When registration was created |
updated_at | TIMESTAMP | Last update time |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data sync status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
registrations_categories
Event categories for grouping and filtering.
| Column | Type | Description |
|---|
id | UUID | Parable’s unique identifier |
category_id | VARCHAR(64) | Planning Center’s category ID |
name | VARCHAR(255) | Category name |
created_at | TIMESTAMP | When category was created |
updated_at | TIMESTAMP | Last update time |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data sync status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
registrations_selection_types
Pricing tiers and registration options.
| Column | Type | Description |
|---|
id | UUID | Parable’s unique identifier |
selection_type_id | VARCHAR(64) | Planning Center’s selection type ID |
name | VARCHAR(255) | Selection type name |
price_cents | INTEGER | Price in cents (divide by 100 for dollars) |
publicly_available | BOOLEAN | Whether available to public |
created_at | TIMESTAMP | When created |
updated_at | TIMESTAMP | Last update time |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data sync status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
registrations_signup_locations
Event venues with geographic coordinates.
| Column | Type | Description |
|---|
id | UUID | Parable’s unique identifier |
signup_location_id | VARCHAR(64) | Planning Center’s location ID |
name | VARCHAR(255) | Location name |
formatted_address | VARCHAR(512) | Short formatted address |
full_formatted_address | VARCHAR(512) | Complete formatted address |
latitude | DOUBLE PRECISION | Geographic latitude |
longitude | DOUBLE PRECISION | Geographic longitude |
location_type | VARCHAR(50) | Type of location |
subpremise | VARCHAR(255) | Room/unit number |
url | VARCHAR(2048) | URL for location info/maps |
created_at | TIMESTAMP | When created |
updated_at | TIMESTAMP | Last update time |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data sync status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
registrations_signup_times
Event date and time slots.
| Column | Type | Description |
|---|
id | UUID | Parable’s unique identifier |
signup_time_id | VARCHAR(64) | Planning Center’s time ID |
starts_at | TIMESTAMP | Event start time |
ends_at | TIMESTAMP | Event end time |
all_day | BOOLEAN | Whether this is an all-day event |
created_at | TIMESTAMP | When created |
updated_at | TIMESTAMP | Last update time |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data sync status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
Emergency contact information for attendees.
| Column | Type | Description |
|---|
id | UUID | Parable’s unique identifier |
emergency_contact_id | VARCHAR(64) | Planning Center’s contact ID |
name | VARCHAR(255) | Contact name |
phone_number | VARCHAR(255) | Contact phone number |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data sync status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
registrations_people
Basic person information for registrations.
| Column | Type | Description |
|---|
id | UUID | Parable’s unique identifier |
person_id | VARCHAR(64) | Planning Center’s person ID |
first_name | VARCHAR(255) | First name |
last_name | VARCHAR(255) | Last name |
name | VARCHAR(255) | Full name |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data sync status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
registrations_campuses
Church campus locations.
| Column | Type | Description |
|---|
id | UUID | Parable’s unique identifier |
campus_id | VARCHAR(64) | Planning Center’s campus ID |
name | VARCHAR(255) | Campus name |
created_at | TIMESTAMP | When created |
updated_at | TIMESTAMP | Last update time |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data sync status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
registrations_organizations
Organization settings and configuration.
| Column | Type | Description |
|---|
id | UUID | Parable’s unique identifier |
organization_id | VARCHAR(64) | Planning Center’s organization ID |
name | VARCHAR(255) | Organization name |
created_at | TIMESTAMP | When created |
updated_at | TIMESTAMP | Last update time |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data sync status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
Relationship Tables
registrations_signup_relationships
Links signups to related entities (categories, campuses, locations, times).
| Column | Type | Description |
|---|
id | UUID | Parable’s unique identifier |
signup_id | VARCHAR(64) | Parent signup ID |
relationship_type | VARCHAR(50) | Type of relationship (category, campus, etc.) |
relationship_id | VARCHAR(64) | ID of related entity |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data sync status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
Relationship Types:
category - Links to registrations_categories
campus - Links to registrations_campuses
signup_location - Links to registrations_signup_locations
signup_time - Links to registrations_signup_times
registrations_registration_relationships
Links registrations to related entities.
| Column | Type | Description |
|---|
id | UUID | Parable’s unique identifier |
registration_id | VARCHAR(64) | Parent registration ID |
relationship_type | VARCHAR(50) | Type of relationship |
relationship_id | VARCHAR(64) | ID of related entity |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data sync status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
Relationship Types:
signup - Links to registrations_signups
person - Links to registrations_people
registrations_attendee_relationships
Links attendees to related entities.
| Column | Type | Description |
|---|
id | UUID | Parable’s unique identifier |
attendee_id | VARCHAR(64) | Parent attendee ID |
relationship_type | VARCHAR(50) | Type of relationship |
relationship_id | VARCHAR(64) | ID of related entity |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data sync status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
Relationship Types:
signup - Links to registrations_signups
registration - Links to registrations_registrations
emergency_contact - Links to registrations_emergency_contacts
System Fields
All tables include these system fields for data management:
-
system_status - Tracks data lifecycle:
transferring - Data being synced from Planning Center
active - Current, queryable data
stale - Outdated data pending removal
-
tenant_organization_id - Ensures data isolation between organizations
-
system_created_at - When Parable first received this record
-
system_updated_at - Last sync timestamp
Row Level Security
All tables implement Row Level Security (RLS) policies that:
- Filter data to only show
active records
- Restrict access to the authenticated organization’s data
- Ensure complete data isolation between tenants
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: Cost and fee columns are stored in cents - divide by 100.0 for display
- Registration Status Flags: Use booleans like
archived, canceled, and waitlisted to control visibility instead of relying on system_status
- Direct ID Columns: Core tables like
registrations_signups expose direct ID columns for performance-critical joins
Common Mistakes to Avoid
-
Missing Schema Prefix
- ❌
FROM registrations_signups
- ✅
FROM planning_center.registrations_signups
-
Adding Redundant RLS Filters
- ❌
WHERE tenant_organization_id = 1 AND system_status = 'active'
- ✅ Trust RLS to handle this automatically
-
Joining Without Schema
- ❌
JOIN registrations_attendees a ON ...
- ✅
JOIN planning_center.registrations_attendees a ON ...
-
Skipping Currency Conversion
- ❌
SELECT total_cost_cents as total_cost
- ✅
SELECT total_cost_cents / 100.0 as total_cost
-
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 registration status flags when relevant
- Consider CTEs for complex aggregations
- Use direct ID columns when available instead of relationship tables
Best Practices
- Always join through relationship tables - Relationship tables capture many-to-many links between events and related entities
- Trust RLS policies - Skip manual
tenant_organization_id or system_status filters
- Use Planning Center IDs for lookups - The
*_id fields (e.g., signup_id)
- Consider NULL values - Many fields may be NULL if not provided by Planning Center
- Handle timestamps properly - All timestamps are stored in UTC
Example: Complete Event Details Query
-- Get full event details with all related data
SELECT
s.signup_id,
s.name as event_name,
s.description,
s.open_at,
s.close_at,
cat.name as category,
camp.name as campus,
loc.name as location_name,
loc.full_formatted_address,
tim.starts_at as event_start,
tim.ends_at as event_end,
tim.all_day
FROM planning_center.registrations_signups s
-- Join category
LEFT JOIN planning_center.registrations_signup_relationships sr_cat
ON sr_cat.signup_id = s.signup_id
AND sr_cat.relationship_type = 'category'
LEFT JOIN planning_center.registrations_categories cat
ON cat.category_id = sr_cat.relationship_id
-- Join campus
LEFT JOIN planning_center.registrations_signup_relationships sr_camp
ON sr_camp.signup_id = s.signup_id
AND sr_camp.relationship_type = 'campus'
LEFT JOIN planning_center.registrations_campuses camp
ON camp.campus_id = sr_camp.relationship_id
-- Join location
LEFT JOIN planning_center.registrations_signup_relationships sr_loc
ON sr_loc.signup_id = s.signup_id
AND sr_loc.relationship_type = 'signup_location'
LEFT JOIN planning_center.registrations_signup_locations loc
ON loc.signup_location_id = sr_loc.relationship_id
-- Join time
LEFT JOIN planning_center.registrations_signup_relationships sr_tim
ON sr_tim.signup_id = s.signup_id
AND sr_tim.relationship_type = 'signup_time'
LEFT JOIN planning_center.registrations_signup_times tim
ON tim.signup_time_id = sr_tim.relationship_id
WHERE s.archived = false
ORDER BY tim.starts_at DESC;
This query demonstrates how to properly join multiple related entities through the relationship tables to get complete event information.