Planning Center Services API
Plan and schedule worship services. Manage service types, plans and their items, songs and arrangements, teams and team members, and the people scheduled to serve on each plan.
Plan and schedule worship services. Manage service types, plans and their items, songs and arrangements, teams and team members, and the people scheduled to serve on each plan.
openapi: 3.0.3
info:
title: Planning Center API
description: >-
A representative OpenAPI description of the Planning Center suite of church
management APIs. Planning Center exposes a documented public REST API for each
of its products - People, Services, Giving, Groups, Check-Ins, Calendar,
Registrations, Publishing - plus a cross-product Webhooks API, all under the
shared base host https://api.planningcenteronline.com. Every product is
versioned under its own path prefix (for example /people/v2, /services/v2,
/giving/v2). All responses conform to the JSON:API 1.0 specification: resource
objects are wrapped in a top-level `data` member (an object or an array), each
with `id`, `type`, `attributes`, and `relationships`, and collections support
`include`, `where[]` filtering, `order`, and offset-based pagination via
`per_page` and `offset`. Authenticate with HTTP Basic using a Personal Access
Token (application id / secret) or with an OAuth 2.0 bearer token. A
`User-Agent` header is required on every request.
Endpoint coverage: the resource collections and base paths modeled here are
grounded in Planning Center's published documentation. Individual method/path
combinations are a representative CRUD-shaped subset; consult the live API
reference at developer.planning.center for the authoritative, exhaustive list
and per-resource attributes.
version: '2.0'
contact:
name: Planning Center Developers
url: https://developer.planning.center/docs/
license:
name: Proprietary
url: https://www.planningcenter.com/terms
servers:
- url: https://api.planningcenteronline.com
description: Planning Center API (all products)
security:
- basicAuth: []
- oauth2:
- people
- services
- giving
- groups
- check_ins
- calendar
- registrations
- publishing
tags:
- name: People
description: People, households, contact info, lists, forms, and workflows.
- name: Services
description: Service planning - service types, plans, songs, teams.
- name: Giving
description: Donations, funds, batches, payment sources, and pledges.
- name: Groups
description: Small groups, memberships, and group events.
- name: Check-Ins
description: Attendance, events, locations, and stations.
- name: Calendar
description: Church calendaring, events, and facility resources.
- name: Registrations
description: Event signups, attendees, categories, and campuses.
- name: Publishing
description: Sermon channels, series, episodes, and speakers (read-only).
- name: Webhooks
description: Cross-product event subscriptions and deliveries.
paths:
# ---------------- People ----------------
/people/v2/people:
get:
operationId: listPeople
tags: [People]
summary: List people
description: Lists people in the account. Supports include, where[] filters, order, and offset pagination.
parameters:
- $ref: '#/components/parameters/PerPage'
- $ref: '#/components/parameters/Offset'
- $ref: '#/components/parameters/Include'
responses:
'200':
$ref: '#/components/responses/Collection'
'401':
$ref: '#/components/responses/Unauthorized'
'429':
$ref: '#/components/responses/RateLimited'
post:
operationId: createPerson
tags: [People]
summary: Create a person
requestBody:
$ref: '#/components/requestBodies/JsonApiBody'
responses:
'201':
$ref: '#/components/responses/Resource'
'401':
$ref: '#/components/responses/Unauthorized'
'422':
$ref: '#/components/responses/UnprocessableEntity'
/people/v2/people/{id}:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getPerson
tags: [People]
summary: Get a person
responses:
'200':
$ref: '#/components/responses/Resource'
'404':
$ref: '#/components/responses/NotFound'
patch:
operationId: updatePerson
tags: [People]
summary: Update a person
requestBody:
$ref: '#/components/requestBodies/JsonApiBody'
responses:
'200':
$ref: '#/components/responses/Resource'
'422':
$ref: '#/components/responses/UnprocessableEntity'
delete:
operationId: deletePerson
tags: [People]
summary: Delete a person
responses:
'204':
description: Deleted.
/people/v2/people/{id}/emails:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: listPersonEmails
tags: [People]
summary: List a person's emails
responses:
'200':
$ref: '#/components/responses/Collection'
/people/v2/emails:
get:
operationId: listEmails
tags: [People]
summary: List email addresses
responses:
'200':
$ref: '#/components/responses/Collection'
/people/v2/addresses:
get:
operationId: listAddresses
tags: [People]
summary: List addresses
responses:
'200':
$ref: '#/components/responses/Collection'
/people/v2/phone_numbers:
get:
operationId: listPhoneNumbers
tags: [People]
summary: List phone numbers
responses:
'200':
$ref: '#/components/responses/Collection'
/people/v2/households:
get:
operationId: listHouseholds
tags: [People]
summary: List households
responses:
'200':
$ref: '#/components/responses/Collection'
/people/v2/lists:
get:
operationId: listLists
tags: [People]
summary: List people lists
responses:
'200':
$ref: '#/components/responses/Collection'
/people/v2/field_definitions:
get:
operationId: listFieldDefinitions
tags: [People]
summary: List custom field definitions
responses:
'200':
$ref: '#/components/responses/Collection'
/people/v2/forms:
get:
operationId: listForms
tags: [People]
summary: List forms
responses:
'200':
$ref: '#/components/responses/Collection'
/people/v2/workflows:
get:
operationId: listWorkflows
tags: [People]
summary: List workflows
responses:
'200':
$ref: '#/components/responses/Collection'
# ---------------- Services ----------------
/services/v2/service_types:
get:
operationId: listServiceTypes
tags: [Services]
summary: List service types
responses:
'200':
$ref: '#/components/responses/Collection'
/services/v2/service_types/{service_type_id}/plans:
parameters:
- name: service_type_id
in: path
required: true
schema: { type: string }
get:
operationId: listPlans
tags: [Services]
summary: List plans for a service type
responses:
'200':
$ref: '#/components/responses/Collection'
/services/v2/service_types/{service_type_id}/plans/{plan_id}:
parameters:
- name: service_type_id
in: path
required: true
schema: { type: string }
- name: plan_id
in: path
required: true
schema: { type: string }
get:
operationId: getPlan
tags: [Services]
summary: Get a plan
responses:
'200':
$ref: '#/components/responses/Resource'
/services/v2/songs:
get:
operationId: listSongs
tags: [Services]
summary: List songs
responses:
'200':
$ref: '#/components/responses/Collection'
post:
operationId: createSong
tags: [Services]
summary: Create a song
requestBody:
$ref: '#/components/requestBodies/JsonApiBody'
responses:
'201':
$ref: '#/components/responses/Resource'
/services/v2/teams:
get:
operationId: listTeams
tags: [Services]
summary: List teams
responses:
'200':
$ref: '#/components/responses/Collection'
/services/v2/people:
get:
operationId: listServicesPeople
tags: [Services]
summary: List people in Services
responses:
'200':
$ref: '#/components/responses/Collection'
# ---------------- Giving ----------------
/giving/v2/donations:
get:
operationId: listDonations
tags: [Giving]
summary: List donations
responses:
'200':
$ref: '#/components/responses/Collection'
post:
operationId: createDonation
tags: [Giving]
summary: Create a donation
description: Create a donation, including its designations to one or more funds and a payment source.
requestBody:
$ref: '#/components/requestBodies/JsonApiBody'
responses:
'201':
$ref: '#/components/responses/Resource'
'422':
$ref: '#/components/responses/UnprocessableEntity'
/giving/v2/donations/{id}:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getDonation
tags: [Giving]
summary: Get a donation
responses:
'200':
$ref: '#/components/responses/Resource'
/giving/v2/donations/{id}/issue_refund:
parameters:
- $ref: '#/components/parameters/Id'
post:
operationId: issueRefund
tags: [Giving]
summary: Issue a refund for a donation
responses:
'200':
$ref: '#/components/responses/Resource'
/giving/v2/funds:
get:
operationId: listFunds
tags: [Giving]
summary: List funds
responses:
'200':
$ref: '#/components/responses/Collection'
/giving/v2/batches:
get:
operationId: listBatches
tags: [Giving]
summary: List batches
responses:
'200':
$ref: '#/components/responses/Collection'
post:
operationId: createBatch
tags: [Giving]
summary: Create a batch
requestBody:
$ref: '#/components/requestBodies/JsonApiBody'
responses:
'201':
$ref: '#/components/responses/Resource'
/giving/v2/payment_sources:
get:
operationId: listPaymentSources
tags: [Giving]
summary: List payment sources
responses:
'200':
$ref: '#/components/responses/Collection'
/giving/v2/recurring_donations:
get:
operationId: listRecurringDonations
tags: [Giving]
summary: List recurring donations
responses:
'200':
$ref: '#/components/responses/Collection'
/giving/v2/pledges:
get:
operationId: listPledges
tags: [Giving]
summary: List pledges
responses:
'200':
$ref: '#/components/responses/Collection'
# ---------------- Groups ----------------
/groups/v2/groups:
get:
operationId: listGroups
tags: [Groups]
summary: List groups
responses:
'200':
$ref: '#/components/responses/Collection'
/groups/v2/groups/{id}:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getGroup
tags: [Groups]
summary: Get a group
responses:
'200':
$ref: '#/components/responses/Resource'
/groups/v2/group_types:
get:
operationId: listGroupTypes
tags: [Groups]
summary: List group types
responses:
'200':
$ref: '#/components/responses/Collection'
/groups/v2/groups/{group_id}/memberships:
parameters:
- name: group_id
in: path
required: true
schema: { type: string }
get:
operationId: listGroupMemberships
tags: [Groups]
summary: List memberships for a group
responses:
'200':
$ref: '#/components/responses/Collection'
post:
operationId: createGroupMembership
tags: [Groups]
summary: Add a member to a group
requestBody:
$ref: '#/components/requestBodies/JsonApiBody'
responses:
'201':
$ref: '#/components/responses/Resource'
/groups/v2/events:
get:
operationId: listGroupEvents
tags: [Groups]
summary: List group events
responses:
'200':
$ref: '#/components/responses/Collection'
# ---------------- Check-Ins ----------------
/check-ins/v2/check_ins:
get:
operationId: listCheckIns
tags: [Check-Ins]
summary: List check-ins
responses:
'200':
$ref: '#/components/responses/Collection'
/check-ins/v2/events:
get:
operationId: listCheckInEvents
tags: [Check-Ins]
summary: List check-in events
responses:
'200':
$ref: '#/components/responses/Collection'
/check-ins/v2/events/{event_id}/event_times:
parameters:
- name: event_id
in: path
required: true
schema: { type: string }
get:
operationId: listEventTimes
tags: [Check-Ins]
summary: List event times for an event
responses:
'200':
$ref: '#/components/responses/Collection'
/check-ins/v2/locations:
get:
operationId: listCheckInLocations
tags: [Check-Ins]
summary: List check-in locations
responses:
'200':
$ref: '#/components/responses/Collection'
/check-ins/v2/stations:
get:
operationId: listStations
tags: [Check-Ins]
summary: List stations
responses:
'200':
$ref: '#/components/responses/Collection'
# ---------------- Calendar ----------------
/calendar/v2/events:
get:
operationId: listCalendarEvents
tags: [Calendar]
summary: List calendar events
responses:
'200':
$ref: '#/components/responses/Collection'
/calendar/v2/event_instances:
get:
operationId: listEventInstances
tags: [Calendar]
summary: List event instances
responses:
'200':
$ref: '#/components/responses/Collection'
/calendar/v2/resources:
get:
operationId: listResources
tags: [Calendar]
summary: List resources (rooms and equipment)
responses:
'200':
$ref: '#/components/responses/Collection'
/calendar/v2/resource_bookings:
get:
operationId: listResourceBookings
tags: [Calendar]
summary: List resource bookings
responses:
'200':
$ref: '#/components/responses/Collection'
/calendar/v2/conflicts:
get:
operationId: listConflicts
tags: [Calendar]
summary: List scheduling conflicts
responses:
'200':
$ref: '#/components/responses/Collection'
# ---------------- Registrations ----------------
/registrations/v2/signups:
get:
operationId: listSignups
tags: [Registrations]
summary: List signups
responses:
'200':
$ref: '#/components/responses/Collection'
/registrations/v2/signups/{signup_id}/attendees:
parameters:
- name: signup_id
in: path
required: true
schema: { type: string }
get:
operationId: listAttendees
tags: [Registrations]
summary: List attendees for a signup
responses:
'200':
$ref: '#/components/responses/Collection'
/registrations/v2/categories:
get:
operationId: listCategories
tags: [Registrations]
summary: List categories
responses:
'200':
$ref: '#/components/responses/Collection'
/registrations/v2/campuses:
get:
operationId: listCampuses
tags: [Registrations]
summary: List campuses
responses:
'200':
$ref: '#/components/responses/Collection'
# ---------------- Publishing ----------------
/publishing/v2/channels:
get:
operationId: listChannels
tags: [Publishing]
summary: List channels
responses:
'200':
$ref: '#/components/responses/Collection'
/publishing/v2/channels/{channel_id}/episodes:
parameters:
- name: channel_id
in: path
required: true
schema: { type: string }
get:
operationId: listEpisodes
tags: [Publishing]
summary: List episodes for a channel
responses:
'200':
$ref: '#/components/responses/Collection'
/publishing/v2/series:
get:
operationId: listSeries
tags: [Publishing]
summary: List series
responses:
'200':
$ref: '#/components/responses/Collection'
/publishing/v2/speakers:
get:
operationId: listSpeakers
tags: [Publishing]
summary: List speakers
responses:
'200':
$ref: '#/components/responses/Collection'
# ---------------- Webhooks ----------------
/webhooks/v2/subscriptions:
get:
operationId: listWebhookSubscriptions
tags: [Webhooks]
summary: List webhook subscriptions
responses:
'200':
$ref: '#/components/responses/Collection'
post:
operationId: createWebhookSubscription
tags: [Webhooks]
summary: Create a webhook subscription
description: Subscribe to an available event. Deliveries are outbound HTTPS POST to the subscription URL.
requestBody:
$ref: '#/components/requestBodies/JsonApiBody'
responses:
'201':
$ref: '#/components/responses/Resource'
/webhooks/v2/subscriptions/{id}:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getWebhookSubscription
tags: [Webhooks]
summary: Get a webhook subscription
responses:
'200':
$ref: '#/components/responses/Resource'
delete:
operationId: deleteWebhookSubscription
tags: [Webhooks]
summary: Delete a webhook subscription
responses:
'204':
description: Deleted.
/webhooks/v2/available_events:
get:
operationId: listAvailableEvents
tags: [Webhooks]
summary: List available webhook events
responses:
'200':
$ref: '#/components/responses/Collection'
/webhooks/v2/subscriptions/{subscription_id}/events:
parameters:
- name: subscription_id
in: path
required: true
schema: { type: string }
get:
operationId: listWebhookDeliveries
tags: [Webhooks]
summary: List delivered events for a subscription
responses:
'200':
$ref: '#/components/responses/Collection'
components:
securitySchemes:
basicAuth:
type: http
scheme: basic
description: HTTP Basic auth using a Personal Access Token - application id as the username and secret as the password.
oauth2:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://api.planningcenteronline.com/oauth/authorize
tokenUrl: https://api.planningcenteronline.com/oauth/token
scopes:
people: Access the People product
services: Access the Services product
giving: Access the Giving product
groups: Access the Groups product
check_ins: Access the Check-Ins product
calendar: Access the Calendar product
registrations: Access the Registrations product
publishing: Access the Publishing product
parameters:
Id:
name: id
in: path
required: true
schema: { type: string }
description: The resource ID.
PerPage:
name: per_page
in: query
required: false
schema: { type: integer, default: 25, maximum: 100 }
description: Number of records per page (JSON:API pagination).
Offset:
name: offset
in: query
required: false
schema: { type: integer, default: 0 }
description: Zero-based offset for pagination. Offsets above 30,000 are subject to a stricter rate limit.
Include:
name: include
in: query
required: false
schema: { type: string }
description: Comma-separated list of related resources to sideload (JSON:API include).
requestBodies:
JsonApiBody:
required: true
description: A JSON:API single-resource document.
content:
application/json:
schema:
$ref: '#/components/schemas/JsonApiResourceDocument'
responses:
Resource:
description: A single JSON:API resource.
content:
application/json:
schema:
$ref: '#/components/schemas/JsonApiResourceDocument'
Collection:
description: A JSON:API collection of resources.
content:
application/json:
schema:
$ref: '#/components/schemas/JsonApiCollectionDocument'
Unauthorized:
description: Missing or invalid credentials.
content:
application/json:
schema:
$ref: '#/components/schemas/JsonApiErrorDocument'
NotFound:
description: Resource not found.
content:
application/json:
schema:
$ref: '#/components/schemas/JsonApiErrorDocument'
UnprocessableEntity:
description: Validation failed.
content:
application/json:
schema:
$ref: '#/components/schemas/JsonApiErrorDocument'
RateLimited:
description: Rate limit exceeded (100 requests per 20 seconds per user).
headers:
Retry-After:
schema: { type: integer }
description: Seconds to wait before retrying.
X-PCO-API-Request-Rate-Limit:
schema: { type: integer }
X-PCO-API-Request-Rate-Period:
schema: { type: integer }
X-PCO-API-Request-Rate-Count:
schema: { type: integer }
content:
application/json:
schema:
$ref: '#/components/schemas/JsonApiErrorDocument'
schemas:
JsonApiResource:
type: object
description: A JSON:API resource object.
properties:
id:
type: string
type:
type: string
attributes:
type: object
additionalProperties: true
relationships:
type: object
additionalProperties: true
links:
type: object
additionalProperties: true
JsonApiResourceDocument:
type: object
required: [data]
properties:
data:
$ref: '#/components/schemas/JsonApiResource'
included:
type: array
items:
$ref: '#/components/schemas/JsonApiResource'
JsonApiCollectionDocument:
type: object
required: [data]
properties:
data:
type: array
items:
$ref: '#/components/schemas/JsonApiResource'
included:
type: array
items:
$ref: '#/components/schemas/JsonApiResource'
meta:
type: object
properties:
total_count:
type: integer
count:
type: integer
links:
type: object
properties:
self:
type: string
next:
type: string
JsonApiErrorDocument:
type: object
properties:
errors:
type: array
items:
type: object
properties:
status:
type: string
title:
type: string
detail:
type: string