LLM Context - Planning Center API Clients
Purpose: Quick reference for AI code editors (Cursor, Copilot) to answer correctly about this monorepo.
Start Here: docs/content/index.mdx | docs/content/concepts.mdx | docs/content/reference/config.mdx | docs/content/api/ | packages/*/src/index.ts
Repository Structure
Monorepo with npm workspaces containing three packages:
- Base (
packages/planning-center-base-ts): Infrastructure (HTTP, auth, rate limiting, errors, JSON:API types, batch operations) - People (
packages/planning-center-people-ts): People API client using base package - Check-Ins (
packages/planning-center-check-ins-ts): Check-Ins API client using base package
Source of Truth: Public API surface = packages/*/src/index.ts. Always check exports there.
Invariants (Must-Always-Be-True)
- Rate Limits: 100 requests per 20 seconds (enforced automatically via
PcoRateLimiter) - JSON:API: All responses follow JSON:API 1.0 specification
- Authentication: Three methods: Personal Access Token, OAuth 2.0 (with required refresh handlers), Basic Auth
- Timestamps: ISO 8601 UTC format (
YYYY-MM-DDTHH:mm:ss.sssZ) - TypeScript: Strict mode enabled, no
anytypes - Monorepo: Always run
npm installfrom root, not package directories - Workspace Dependency: People package uses
"@rachelallyson/planning-center-base-ts": "*"in monorepo (changes to^1.0.0when published) - OAuth Refresh:
onRefreshandonRefreshFailureare REQUIRED for OAuth auth type
Public Surface
Base Package (@rachelallyson/planning-center-base-ts)
Classes: PcoHttpClient, PcoRateLimiter, PaginationHelper, BaseModule, PcoEventEmitter, BatchExecutor, PcoApiError, PcoError
Functions: retryWithBackoff(), withErrorBoundary(), shouldNotRetry(), handleNetworkError(), handleTimeoutError(), handleValidationError()
Types: See packages/planning-center-base-ts/src/index.ts for full list (includes JSON:API types, config types, event types, batch types)
People Package (@rachelallyson/planning-center-people-ts)
Main Export: PcoClient - Main client class with 11 modules
Modules (properties of PcoClient): people, fields, workflows, contacts, households, notes, lists, campus, serviceTime, forms, reports
Types: See packages/planning-center-people-ts/src/index.ts for full list (includes v1.x compatibility exports)
Check-Ins Package (@rachelallyson/planning-center-check-ins-ts)
Main Export: PcoCheckInsClient - Main client class for Check-Ins API
Modules (properties of PcoCheckInsClient): events, checkIns, locations, eventTimes, stations, labels, options, checkInGroups, preChecks, passes, headcounts, attendanceTypes, rosterListPersons, organization, integrationLinks, themes, batch
Types: See packages/planning-center-check-ins-ts/src/index.ts for full list (includes Check-Ins resource types)
Common Tasks
- Creating a client: Use
new PcoClient(config)withPcoClientConfig - Authentication: See config reference - three methods supported
- Finding/creating people:
client.people.findOrCreate()with matching strategies - Pagination: Use
getAllPages()or manual pagination - see pagination guide - Error handling: Catch
PcoApiErrororPcoError, use retry utilities - see error handling guide - Batch operations: Use
client.batch.execute()for multiple operations with dependency resolution
Don’ts (Guardrails)
- ❌ Don’t invent config keys - Only use those in config reference or
docs/content/reference/config.schema.json - ❌ Don’t deep import - Use public exports from package
src/index.tsfiles - ❌ Don’t install from package dirs - Always run
npm installfrom monorepo root - ❌ Don’t use
anytypes - Everything is strictly typed - ❌ Don’t bypass rate limiting -
PcoRateLimiterhandles it automatically - ❌ Don’t call API directly - Use provided HTTP client which handles auth, errors, retries
- ❌ Don’t mutate response objects - They’re typed and should be treated as immutable
- ❌ Don’t create new
PcoHttpClientinstances - Use the one fromPcoClientor share instances - ❌ Don’t use OAuth without refresh handlers -
onRefreshandonRefreshFailureare required
Configuration Truth
Single source: docs/content/reference/config.mdx and docs/content/reference/config.schema.json
Auth types:
PersonalAccessTokenAuth-{ type: 'personal_access_token', personalAccessToken: string }OAuthAuth-{ type: 'oauth', accessToken, refreshToken, onRefresh, onRefreshFailure, clientId?, clientSecret? }(refresh handlers REQUIRED)BasicAuth-{ type: 'basic', appId, appSecret }
Environment variables: PCO_APP_ID, PCO_APP_SECRET (used if not provided in config)
Defaults: See config reference for retry defaults (maxRetries: 3, baseDelay: 1000ms, maxDelay: 10000ms)
Error Handling
Error hierarchy:
PcoApiError- Base API error (status, statusText, errors array)PcoError extends PcoApiError- Enhanced with category, severity, context
Error categories: EXTERNAL_API, VALIDATION, NETWORK, AUTHENTICATION, AUTHORIZATION
Retry strategy: Exponential backoff (1000ms base, max 10000ms, 3 retries by default)
HTTP & API Surface
No HTTP server - These are client libraries only. They call https://api.planningcenteronline.com/people/v2
Auth flow: OAuth refresh handled automatically via onRefresh callback (REQUIRED)
Rate limiting: Automatic (100 req/20s), returns 429 with Retry-After header
Response format: JSON:API 1.0 - always { data: {...}, included?: [...] }
Key Files
- Config types:
packages/planning-center-base-ts/src/types/config.ts - HTTP client:
packages/planning-center-base-ts/src/http-client.ts - Main client:
packages/planning-center-people-ts/src/client.ts - People module:
packages/planning-center-people-ts/src/modules/people.ts - Base module:
packages/planning-center-base-ts/src/base-module.ts
When Uncertain
- Read
src/index.tsof relevant package for exports - Check config reference for configuration
- Look at recipes for patterns
- Review concepts for architecture understanding
- Check People API docs for People API specifics