Quick Start Guide
Get up and running with the Planning Center API clients in 5 minutes.
Installation
# People API Client
npm install @rachelallyson/planning-center-people-ts
# Base Package (for building custom clients)
npm install @rachelallyson/planning-center-base-tsRequirements:
- Node.js >= 16.0.0
- TypeScript >= 4.0 (recommended)
Step 1: Create a Client
Choose your authentication method:
Personal Access Token (Recommended for scripts)
Step 1: Create Personal Access Token
- Go to Planning Center Developer AccountÂ
- Click “Personal Access Tokens” in the left sidebar
- Click “New Personal Access Token”
- Give it a name (e.g., “My Integration”)
- Select appropriate scopes (People, Check-Ins, etc.)
- Click “Create Personal Access Token”
- Copy both values immediately (you won’t see them again):
- Client ID (long hex string)
- Client Secret (even longer string)
Step 2: Configure Authentication
Option A: Environment Variables (Recommended for production)
# Set these environment variables
export PCO_PERSONAL_ACCESS_TOKEN="your_client_id_here"
export PCO_PERSONAL_ACCESS_SECRET="your_client_secret_here"const client = new PcoClient({
auth: {
type: 'personal_access_token',
personalAccessToken: process.env.PCO_PERSONAL_ACCESS_TOKEN!
}
});Option B: Direct Configuration (Convenient for development)
const client = new PcoClient({
auth: {
type: 'personal_access_token',
personalAccessToken: 'your_client_id_here',
personalAccessTokenSecret: 'your_client_secret_here'
}
});Note: Both approaches use your Client ID and Client Secret from the Personal Access Token you created in Step 1.
OAuth 2.0 (Required for multi-user apps)
import { PcoClient } from '@rachelallyson/planning-center-people-ts';
const client = new PcoClient({
auth: {
type: 'oauth',
accessToken: 'your-access-token',
refreshToken: 'your-refresh-token',
// REQUIRED: Handle token refresh
onRefresh: async (tokens) => {
// Save new tokens to your database
await saveTokens(tokens);
},
// REQUIRED: Handle refresh failures
onRefreshFailure: async (error) => {
// Handle auth failure (e.g., redirect to login)
console.error('Token refresh failed:', error);
}
}
});Step 2: Basic Operations
Get People
// Get first page of people
const people = await client.people.getAll({ perPage: 25 });
console.log(`Found ${people.data.length} people`);
people.data.forEach(person => {
console.log(`${person.attributes.first_name} ${person.attributes.last_name}`);
});
// Get all pages automatically
const allPeople = await client.people.getAllPages({ perPage: 25 });
console.log(`Total: ${allPeople.data.length} people`);Find or Create a Person
// Find existing person or create new one
const person = await client.people.findOrCreate({
firstName: 'John',
lastName: 'Doe',
email: 'john@example.com',
phone: '555-1234',
matchStrategy: 'fuzzy' // or 'exact'
});
console.log(`Person ID: ${person.id}`);
console.log(`Match found: ${person.match?.found}`);Create a Person
const newPerson = await client.people.create({
first_name: 'Jane',
last_name: 'Smith'
});
// Add contact information
await client.contacts.createEmail(newPerson.id, {
address: 'jane@example.com',
location: 'Home',
primary: true
});
await client.contacts.createPhone(newPerson.id, {
number: '555-5678',
location: 'Home',
primary: true
});Set Custom Fields
// Set field by slug (recommended)
await client.fields.setPersonFieldBySlug(
person.id,
'BIRTHDATE',
'1990-01-01'
);
// Set field by name
await client.fields.setPersonFieldByName(
person.id,
'Membership Status',
'Member'
);Add to Workflow
const workflowCard = await client.workflows.addPersonToWorkflow(
person.id,
'workflow-id',
{
note: 'Added via integration',
skipIfExists: true // Don't add if already exists
}
);Step 3: Error Handling
import { PcoError, ErrorCategory } from '@rachelallyson/planning-center-people-ts';
try {
const person = await client.people.create({ first_name: 'John' });
} catch (error) {
if (error instanceof PcoError) {
switch (error.category) {
case ErrorCategory.AUTHENTICATION:
console.error('Authentication failed - check your token');
break;
case ErrorCategory.RATE_LIMIT:
console.error('Rate limited - retry after:', error.getRetryDelay(), 'ms');
break;
case ErrorCategory.VALIDATION:
console.error('Validation error:', error.message);
break;
default:
console.error('Error:', error.message);
}
} else {
// Non-PCO error
throw error;
}
}Step 4: Advanced Features
Batch Operations
const results = await client.batch.execute([
{
type: 'people.create',
data: {
firstName: 'John',
lastName: 'Doe'
}
},
{
type: 'people.addEmail',
personId: '$0.id', // Reference person from step 0
data: {
address: 'john@example.com',
primary: true
}
},
{
type: 'people.addPhone',
personId: '$0.id',
data: {
number: '555-1234',
primary: true
}
}
]);
console.log(`Success: ${results.successful.length}`);
console.log(`Failed: ${results.failed.length}`);
console.log(`Success rate: ${(results.successRate * 100).toFixed(1)}%`);Event Monitoring
The client emits events throughout its lifecycle. You can listen to these events for monitoring, logging, and debugging:
// Listen to request events
client.on('request:start', (event) => {
console.log(`Starting: ${event.method} ${event.endpoint}`);
});
client.on('request:complete', (event) => {
console.log(`Completed: ${event.status} in ${event.duration}ms`);
});
client.on('error', (event) => {
console.error(`Error in ${event.operation}:`, event.error);
});
client.on('rate:limit', (event) => {
console.warn(`Rate limit: ${event.remaining}/${event.limit} remaining`);
});See Event System Guide for complete documentation of all event types and advanced patterns.
Performance Metrics
// Get performance metrics
const metrics = client.getPerformanceMetrics();
console.log('Average response time:', metrics.averageResponseTime);
console.log('Success rate:', metrics.successRate);
// Get rate limit info
const rateLimitInfo = client.getRateLimitInfo();
console.log('Requests remaining:', rateLimitInfo.remaining);
console.log('Window resets in:', rateLimitInfo.windowResetsIn, 'ms');Complete Example
import { PcoClient } from '@rachelallyson/planning-center-people-ts';
async function main() {
// Create client
const client = new PcoClient({
auth: {
type: 'personal_access_token',
personalAccessToken: process.env.PCO_PERSONAL_ACCESS_TOKEN!
},
caching: {
fieldDefinitions: true,
ttl: 300000 // 5 minutes
},
retry: {
enabled: true,
maxRetries: 3
}
});
try {
// Find or create person
const person = await client.people.findOrCreate({
firstName: 'John',
lastName: 'Doe',
email: 'john@example.com',
matchStrategy: 'fuzzy'
});
console.log(`Person ID: ${person.id}`);
// Set custom fields
await client.fields.setPersonFieldBySlug(person.id, 'BIRTHDATE', '1990-01-01');
// Add to workflow
await client.workflows.addPersonToWorkflow(person.id, 'workflow-id', {
note: 'Added via integration'
});
console.log('Success!');
} catch (error) {
console.error('Error:', error);
process.exit(1);
}
}
main();Next Steps
- Pagination Guide - Learn about pagination patterns
- Error Handling Guide - Comprehensive error handling
- Event System Guide - Complete event monitoring and observability
- Configuration Reference - All configuration options
- Examples & Recipes - More code examples
Last updated on