npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

churchsuite-api

v1.0.0

Published

Unofficial TypeScript SDK for the ChurchSuite API

Readme

churchsuite-api

CI npm version License: MIT

Unofficial TypeScript SDK for the ChurchSuite API. Zero runtime dependencies -- uses native fetch.

Note: This package is not affiliated with or endorsed by ChurchSuite. It is a community-maintained wrapper around their public API.

Install

npm install churchsuite-api

Requires Node.js 18 or later.

Quick Start

import { ChurchSuite } from 'churchsuite-api';

const cs = new ChurchSuite({
  account: 'your-account',     // X-Account header
  application: 'my-app',       // X-Application header
  auth: 'your-api-key',        // X-Auth header
});

// List contacts
const { contacts } = await cs.addressBook.contacts.list({ q: 'John' });

// Get a single contact
const contact = await cs.addressBook.contacts.get(42);

// Create a contact
const newContact = await cs.addressBook.contacts.create({
  first_name: 'Joe',
  last_name: 'Bloggs',
});

// Auto-paginate through all results
for await (const contact of cs.addressBook.contacts.listAll()) {
  console.log(contact.first_name);
}

Configuration

interface ChurchSuiteConfig {
  account: string;          // Your ChurchSuite account identifier
  application: string;      // Your application name
  auth?: string;            // API key or login token
  baseUrl?: string;         // Override API base URL (default: https://api.churchsuite.com/v1)
  fetch?: typeof fetch;     // Override fetch implementation (useful for testing)
}

API Reference

Account

cs.account.getModule('addressbook');    // Get module details
cs.account.getProfile();                // Get current user profile
cs.account.whoAmI();                    // Get current authentication info

Address Book

Contacts

cs.addressBook.contacts.list({ q: 'John', page: 1 });
cs.addressBook.contacts.listAll({ q: 'Smith' });        // async generator
cs.addressBook.contacts.get(42);
cs.addressBook.contacts.create({ first_name: 'Joe', last_name: 'Bloggs' });
cs.addressBook.contacts.update(42, { first_name: 'Jane' });
cs.addressBook.contacts.delete(42);
cs.addressBook.contacts.getTags(42);
cs.addressBook.contacts.getKeyDates(42);

Tags

cs.addressBook.tags.list();
cs.addressBook.tags.get(5);
cs.addressBook.tags.getContacts(5, { page: 1 });

Flows

cs.addressBook.flows.list();
cs.addressBook.flows.get(3);
cs.addressBook.flows.getStages(3);
cs.addressBook.flows.getTracking(3);
cs.addressBook.flows.addTracking(3, { contact_id: 42 });

Key Dates

cs.addressBook.keyDates.list();
cs.addressBook.keyDates.get(7);
cs.addressBook.keyDates.getContacts(7);

Calendar

Events

cs.calendar.events.list({ date_start: '2025-01-01' });
cs.calendar.events.listAll({ category_id: 2 });         // async generator
cs.calendar.events.get(10);                              // by ID
cs.calendar.events.get('abc123');                         // by identifier

Categories

cs.calendar.categories.list();

Children

cs.children.children.list({ q: 'Emma' });
cs.children.children.listAll();                          // async generator
cs.children.children.get(15);
cs.children.children.create({ first_name: 'Emma', last_name: 'Smith' });
cs.children.children.update(15, { first_name: 'Emily' });
cs.children.children.delete(15);
cs.children.children.getTags(15);
cs.children.children.getKeyDates(15);
cs.children.children.getGroups(15);

Small Groups

Groups

cs.smallGroups.groups.list({ view: 'active' });
cs.smallGroups.groups.listAll();                         // async generator
cs.smallGroups.groups.get(8);
cs.smallGroups.groups.getMembers(8);
cs.smallGroups.groups.setMembers(8, {
  members: [{ contact_id: 42, roles: 'leader' }],
});

Clusters

cs.smallGroups.clusters.list();
cs.smallGroups.clusters.get(2);

My

cs.my.getDetails();
cs.my.getContacts();
cs.my.getChildren();
cs.my.getChild(15);

Embed (Public, No Auth)

The embed module accesses public-facing endpoints that don't require authentication.

const events = await cs.embed.calendarEvents({ num_results: 10 });
const groups = await cs.embed.smallGroups({ cluster_id: 2 });

Auto-Pagination

Resources with paginated list endpoints expose a listAll() method that returns an async generator. It handles page iteration automatically, so you can iterate through every result without managing pages yourself.

for await (const contact of cs.addressBook.contacts.listAll({ q: 'Smith' })) {
  console.log(contact.id, contact.first_name);
}

// Or collect into an array
const allEvents: Event[] = [];
for await (const event of cs.calendar.events.listAll()) {
  allEvents.push(event);
}

Error Handling

All API errors throw typed exceptions that you can catch and inspect.

import {
  ChurchSuiteHttpError,
  ChurchSuiteNotFoundError,
  ChurchSuiteValidationError,
} from 'churchsuite-api';

try {
  await cs.addressBook.contacts.get(999999);
} catch (error) {
  if (error instanceof ChurchSuiteNotFoundError) {
    // 404 - resource not found
    console.log(error.status);  // 404
  } else if (error instanceof ChurchSuiteValidationError) {
    // 400 - validation failed
    console.log(error.errors);  // { field: ['message'] }
  } else if (error instanceof ChurchSuiteHttpError) {
    // Any other HTTP error
    console.log(error.status, error.message);
  }
}

| HTTP Status | Error Class | Properties | |---|---|---| | 400 | ChurchSuiteValidationError | status, body, errors | | 404 | ChurchSuiteNotFoundError | status, body | | Other | ChurchSuiteHttpError | status, body |

Testing Your Code

You can inject a custom fetch to mock API calls in your own tests:

const cs = new ChurchSuite({
  account: 'test',
  application: 'test',
  auth: 'test-key',
  fetch: myMockFetch,
});

Requirements

  • Node.js >= 18
  • TypeScript >= 5.0 (for type-only consumers)

Contributing

See CONTRIBUTING.md for development setup, scripts, and PR guidelines.

Security

See SECURITY.md for how to report vulnerabilities.

License

MIT