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