PealCast API
Version 1.0.0
The PealCast church-facing developer API — the follow-up engine for online church.
PealCast turns your live stream's anonymous crowd into named people with a verified phone
number, then hands your team a weekly Shepherd's Report of who to welcome (New Faces)
and who to quietly check on (Missed You). This API lets you read that same data
programmatically and manage your channels, audience, and go-live notifications.
## Authentication
Every request is authenticated with an opaque bearer token and every token is pinned to
exactly ONE church (organization). You create tokens in the app dashboard under
Developer / API tokens:
- pc_live_… — a production token (talks to https://api.pealcast.io).
- pc_test_… — a non-production token (talks to https://api.dev.pealcast.io).
Access is set per token: a read token can only call GET endpoints, while a
read/write token may also create and update. A read-only token that calls a write
endpoint receives 403 READ_ONLY_TOKEN.
## Player endpoints are public
The Player (public) endpoints power the watch page and take no authentication — they
return only what a viewer's browser is allowed to see.
## AI assistants (MCP)
An MCP server is available at mcp.pealcast.io so AI assistants (Claude and others)
can read your Shepherd's Report and audience with the same church-scoped token.
Base URLs
https://api.pealcast.io— Productionhttps://api.dev.pealcast.io— Development
Authentication
A PealCast API token (pc_live_… / pc_test_…). Create one in the app dashboard under Developer / API tokens. Every token is pinned to one church.
Authorization: Bearer pc_live_your_token_here
Audience
Your owned, verified audience — the real people (watchers/viewers) who have watched a stream, deduped by verified mobile number. A "watcher" (or "viewer") is a person who watched at least one broadcast.
/app/channel-viewersList a channel's viewers
Lists every known watcher for the channel — your owned, verified audience — with their first/last watch and total watch minutes.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
| slug | string | required | The channel slug. |
Example request
curl -X GET "https://api.pealcast.io/app/channel-viewers?slug=sunday&org=your-church" \ -H "Authorization: Bearer pc_live_your_token_here"
Example response
{
"viewers": [
{
"subscriber_id": 123,
"name": "Jordan Rivera",
"mobile": "+15551234567",
"first_watch_at": "2026-07-11T14:30:00Z",
"last_watch_at": "2026-07-11T14:30:00Z",
"watch_minutes": 128
}
],
"viewers_limit": 500,
"viewers_truncated": true
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · The token has no church, or is not permitted for this church (NO_ORG / FORBIDDEN_ORG / FORBIDDEN).404 · No such channel for this church (NO_CHANNEL)./app/viewerGet one viewer's full profile
Returns a single watcher's complete profile: their identity, lifetime totals, every watch session, any prayer/connect submissions, and the go-live notifications they've received.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
| slug | string | required | The channel slug. |
| id | integer | required | The subscriber (viewer) id. |
Example request
curl -X GET "https://api.pealcast.io/app/viewer?slug=sunday&id=123&org=your-church" \ -H "Authorization: Bearer pc_live_your_token_here"
Example response
{
"subscriber": {
"id": 123,
"name": "Jordan Rivera",
"mobile": "+15551234567",
"email": "jordan@example.com",
"first_seen_at": "2026-07-11T14:30:00Z",
"last_seen_at": "2026-07-11T14:30:00Z",
"pco_person_id": "string",
"pco_profile_url": "https://…",
"pco_match_state": "matched"
},
"totals": {
"sessions": 42,
"watch_minutes": 128,
"avg_qoe": 91
},
"sessions": [
{
"broadcast_id": 123,
"date": "2026-07-11T14:30:00Z",
"watch_minutes": 128,
"completion": 0.82,
"qoe": 91,
"platform": "web"
}
],
"submissions": [
{
"type": "prayer",
"fields": {
"brand_color": "#0c1a2e"
},
"at": "2026-07-11T14:30:00Z"
}
],
"notifications": [
{
"integration_key": "native.sms",
"status": "sent",
"provider": "signalwire",
"sent_at": "2026-07-11T14:30:00Z"
}
]
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · The token has no church, or is not permitted for this church (NO_ORG / FORBIDDEN_ORG / FORBIDDEN).404 · No such channel or viewer (NO_CHANNEL / NO_VIEWER)./app/channel-archiveList a channel's recorded broadcasts
Lists the channel's recorded past broadcasts (VOD), with each recording's duration,
playback URL, and watch stats.
Recordings are never deleted automatically — not by PealCast and not by the video
host. A recording stays until someone removes it with DELETE /app/recordings.
Archive kept beyond the plan's included allowance is billed as flat overage blocks
on the monthly invoice.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
| slug | string | required | The channel slug. |
Example request
curl -X GET "https://api.pealcast.io/app/channel-archive?slug=sunday&org=your-church" \ -H "Authorization: Bearer pc_live_your_token_here"
Example response
{
"archive_minutes_used": 1240,
"archive_minutes_included": 1200,
"retention_days": 90,
"recordings": [
{
"id": 123,
"date": "2026-07-11T14:30:00Z",
"ended_at": "2026-07-11T14:30:00Z",
"duration_minutes": 62.5,
"recording_status": "ready",
"asset_id": "string",
"playback_id": "string",
"playback_hls_url": "https://…",
"watchers": 42,
"watch_minutes": 128,
"peak_concurrent": 42
}
],
"recordings_limit": 100,
"recordings_truncated": true
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · The token has no church, or is not permitted for this church (NO_ORG / FORBIDDEN_ORG / FORBIDDEN).404 · No such channel for this church (NO_CHANNEL)./app/recordingsPermanently delete one recording
Permanently removes a single service's recording — both the video at the streaming host and its published on-demand archive. This cannot be undone and there is no backup. One recording per call, by design. Nothing else ever deletes a recording: PealCast runs no retention sweep and the video host's own auto-expiry is disabled, so this endpoint is the only way a service goes away. Archive kept beyond the plan's included allowance is billed as overage blocks rather than deleted. Owner or admin only. If the streaming host refuses the delete, nothing is removed and the call fails — the recording is never marked gone on a failed delete.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
| id | integer | optional | The broadcast id whose recording should be deleted (may also be sent in the body). |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| id | integer | required | The broadcast id whose recording should be deleted. |
Example request
curl -X DELETE "https://api.pealcast.io/app/recordings?org=your-church&id=123" \
-H "Authorization: Bearer pc_live_your_token_here" \
-H "Content-Type: application/json" \
-d '{
"id": 123
}'Example response
{
"ok": true,
"id": 123,
"recording_status": "discarded"
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · The token has no church, or is not permitted for this church (NO_ORG / FORBIDDEN_ORG / FORBIDDEN).404 · No such broadcast (or channel) in this church.409 · That service has no recording to delete.502 · The streaming host refused the delete. Nothing was removed; retry./app/subscriberUpdate an audience member
Updates an audience member's (subscriber's) editable details. The person's verified
mobile number cannot be changed here — it is the dedupe key for your owned audience. Pass
an empty string to clear a field. Requires a read/write token (a read-only token
receives 403 READ_ONLY_TOKEN).
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| id | integer | required | The subscriber (audience member) id. |
| first_name | string | optional | The member's first name. Empty string clears it. |
| last_name | string | optional | The member's last name. Empty string clears it. |
| string | optional | The member's email. Empty string clears it. |
Example request
curl -X POST "https://api.pealcast.io/app/subscriber?org=your-church" \
-H "Authorization: Bearer pc_live_your_token_here" \
-H "Content-Type: application/json" \
-d '{
"id": 123
}'Example response
{
"ok": true,
"subscriber": {
"id": 123,
"first_name": "Jordan",
"last_name": "Rivera",
"full_name": "Jordan Rivera",
"mobile": "+15551234567",
"mobile_verified": true,
"email": "jordan@example.com",
"email_verified": true,
"source": "watch_gate",
"created_at": "2026-07-11T14:30:00Z"
}
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · A read-only token attempted a write (READ_ONLY_TOKEN); may also be FORBIDDEN_ORG/FORBIDDEN.404 · No such audience member for this church (NO_SUBSCRIBER).422 · Invalid field value (INVALID).Shepherd's Report
The weekly follow-up engine: New Faces (new watchers to welcome) and Missed You (drifting watchers to check on), each with a name and a verified phone number, plus the controls to send it on demand.
/app/channel-analyticsGet a channel's Shepherd's Report and analytics
Returns the channel's rollup for the requested window: a summary (unique viewers, watch
minutes, average QoE, broadcasts) plus the two Shepherd's Report queues —
new_watchers (New Faces, people to welcome) and drifting_watchers
(Missed You, regulars who have gone quiet).
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
| slug | string | required | The channel slug. |
| range | 7 | 30 | 90 | 365 | optional | The report window, in days. |
Example request
curl -X GET "https://api.pealcast.io/app/channel-analytics?slug=sunday&org=your-church&range=30" \ -H "Authorization: Bearer pc_live_your_token_here"
Example response
{
"range_days": 30,
"summary": {
"unique_viewers": 42,
"anon_sessions": 42,
"watch_minutes": 128,
"avg_qoe": 91,
"broadcasts": 42,
"subscriber_count": 42
},
"new_watchers": [
{
"subscriber_id": 123,
"name": "Jordan Rivera",
"mobile": "+15551234567",
"first_watch_at": "2026-07-11T14:30:00Z",
"last_watch_at": "2026-07-11T14:30:00Z",
"watch_minutes": 128
}
],
"drifting_watchers": [
{
"subscriber_id": 123,
"name": "Jordan Rivera",
"mobile": "+15551234567",
"first_watch_at": "2026-07-11T14:30:00Z",
"last_watch_at": "2026-07-11T14:30:00Z",
"watch_minutes": 128
}
]
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · The token has no church, or is not permitted for this church (NO_ORG / FORBIDDEN_ORG / FORBIDDEN).404 · No such channel for this church (NO_CHANNEL)./app/send-reportSend the Shepherd's Report now
Sends the church's Shepherd's Report immediately (out of cadence) to the online-ministry
team. Requires a read/write token (a read-only token receives 403 READ_ONLY_TOKEN).
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
Example request
curl -X POST "https://api.pealcast.io/app/send-report?org=your-church" \ -H "Authorization: Bearer pc_live_your_token_here"
Example response
{
"ok": true,
"message": "Your Shepherd's Report is on its way."
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · A read-only token attempted a write (READ_ONLY_TOKEN); may also be FORBIDDEN_ORG/FORBIDDEN.Channels
A church's streaming channels — broadcast (one-to-many service) or conference (two-way prayer line) — and their encoder/ingest configuration.
/app/channelsList the church's channels
Returns the church's channels as a lightweight navigation list (slug, name, type, live status).
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
Example request
curl -X GET "https://api.pealcast.io/app/channels?org=your-church" \ -H "Authorization: Bearer pc_live_your_token_here"
Example response
{
"channels": [
{
"slug": "main-service",
"id": 123,
"name": "Main Service",
"type": "broadcast",
"is_live": true
}
]
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · The token has no church, or is not permitted for this church (NO_ORG / FORBIDDEN_ORG / FORBIDDEN)./app/channelsCreate a channel
Creates a new channel for the church and provisions its live stream on the video host.
Requires a read/write token (a read-only token receives 403 READ_ONLY_TOKEN). Fails
with 402 CHANNEL_LIMIT when the church's plan channel allotment is already used.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | required | Display name for the channel. |
| type | broadcast | conference | optional | broadcast = one-to-many service stream; conference = two-way prayer line.
|
Example request
curl -X POST "https://api.pealcast.io/app/channels?org=your-church" \
-H "Authorization: Bearer pc_live_your_token_here" \
-H "Content-Type: application/json" \
-d '{
"name": "Main Service"
}'Example response
{
"slug": "main-service",
"id": 123,
"name": "Jordan Rivera",
"type": "broadcast",
"description": "string",
"timezone": "America/New_York",
"is_live": true,
"gate_enabled": true,
"gate_free_watch_seconds": 30,
"recording_retention_days": 60,
"retention_min_days": 30,
"retention_max_days": 90,
"sms_keyword": "sunday",
"sms_from_number": "+12075550123",
"notification_methods": [
"native.email"
],
"notification_method_states": [
{
"key": "native.email",
"label": "Email",
"medium": "sms",
"requires_connection": true,
"provider_key": "planning_center",
"deliverable": true,
"available": true,
"enabled": true,
"set_up": true
}
],
"notification_mute": {
"muted": true,
"muted_until": "2026-07-11T14:30:00Z",
"muted_at": "2026-07-11T14:30:00Z",
"muted_by": "string",
"muted_reason": "string",
"max_hours": 42,
"default_hours": 42,
"max_until": "2026-07-11T14:30:00Z"
},
"subscriber_count": 42,
"created_at": "2026-07-11T14:30:00Z",
"stream_info": {
"status": "idle",
"provisioned": true,
"platform": "cloudflare",
"rtmps_url": "rtmps://live.pealcast.io/live/",
"stream_key": "string",
"srt_url": "srt://live.pealcast.io:778?streamid=…&passphrase=…",
"srt_stream_id": "string",
"srt_passphrase": "string",
"hls_playback_url": "https://…",
"sms_from_number": "+15551234567",
"sms_keyword": "sunday"
}
}Responses
BAD_NAME).401 · Missing or invalid token (UNAUTHENTICATED).402 · The plan's channel allotment is used up (CHANNEL_LIMIT).403 · A read-only token attempted a write (READ_ONLY_TOKEN); may also be FORBIDDEN_ORG/FORBIDDEN./app/channelGet one channel
Returns a single channel's full configuration, including its stream_info — the encoder/ingest settings your church uses to go live: the SRT URL (plus its stream id and passphrase separately, for hardware encoders), the RTMPS URL and stream key, and the HLS playback URL. Both protocols are always provisioned; SRT is recommended.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
| slug | string | required | The channel slug. |
Example request
curl -X GET "https://api.pealcast.io/app/channel?slug=sunday&org=your-church" \ -H "Authorization: Bearer pc_live_your_token_here"
Example response
{
"slug": "main-service",
"id": 123,
"name": "Jordan Rivera",
"type": "broadcast",
"description": "string",
"timezone": "America/New_York",
"is_live": true,
"gate_enabled": true,
"gate_free_watch_seconds": 30,
"recording_retention_days": 60,
"retention_min_days": 30,
"retention_max_days": 90,
"sms_keyword": "sunday",
"sms_from_number": "+12075550123",
"notification_methods": [
"native.email"
],
"notification_method_states": [
{
"key": "native.email",
"label": "Email",
"medium": "sms",
"requires_connection": true,
"provider_key": "planning_center",
"deliverable": true,
"available": true,
"enabled": true,
"set_up": true
}
],
"notification_mute": {
"muted": true,
"muted_until": "2026-07-11T14:30:00Z",
"muted_at": "2026-07-11T14:30:00Z",
"muted_by": "string",
"muted_reason": "string",
"max_hours": 42,
"default_hours": 42,
"max_until": "2026-07-11T14:30:00Z"
},
"subscriber_count": 42,
"created_at": "2026-07-11T14:30:00Z",
"stream_info": {
"status": "idle",
"provisioned": true,
"platform": "cloudflare",
"rtmps_url": "rtmps://live.pealcast.io/live/",
"stream_key": "string",
"srt_url": "srt://live.pealcast.io:778?streamid=…&passphrase=…",
"srt_stream_id": "string",
"srt_passphrase": "string",
"hls_playback_url": "https://…",
"sms_from_number": "+15551234567",
"sms_keyword": "sunday"
}
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · The token has no church, or is not permitted for this church (NO_ORG / FORBIDDEN_ORG / FORBIDDEN).404 · No such channel for this church (NO_CHANNEL)./app/channel-settingsUpdate a channel's settings
Updates a channel's editable settings. The channel's slug and type are structural and
are not editable here. Any omitted field is left unchanged. Requires a read/write
token (a read-only token receives 403 READ_ONLY_TOKEN).
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| slug | string | required | The channel slug (identifies which channel to update). |
| name | string | optional | Display name for the channel. |
| description | string | optional | A short public description of the channel. |
| timezone | string | optional | IANA timezone name. |
| gate_enabled | boolean | optional | Whether the capture gate is active for this channel. |
| gate_free_watch_seconds | integer | optional | Seconds a viewer may watch before the gate prompts. |
| recording_retention_days | integer | optional | Recording retention window (days) — the period we promise to KEEP a recording, never an expiry. Clamped to [30, the plan's archive cap]. Nothing is purged on a timer, and it is never pushed to the streaming host's own auto-delete (that field is banned: it deletes provider-side with no hook, so no warning to the church is possible). |
| notification_methods | string[] | optional | Which platform notification methods this channel offers its subscribers — the
exact list the public sign-up page shows. Registry keys (e.g. native.email,
native.sms); a new channel starts with ["native.email"], the only method that
needs nothing bought, registered or connected.
Unknown keys and connection-backed keys (planning_center.*) are dropped:
connecting Planning Center is what enables those, and disconnecting it is what
disables them, so they are not switchable here.
|
Example request
curl -X POST "https://api.pealcast.io/app/channel-settings?org=your-church" \
-H "Authorization: Bearer pc_live_your_token_here" \
-H "Content-Type: application/json" \
-d '{
"slug": "main-service"
}'Example response
{
"ok": true,
"channel": {
"slug": "main-service",
"id": 123,
"name": "Jordan Rivera",
"type": "broadcast",
"description": "string",
"timezone": "America/New_York",
"is_live": true,
"gate_enabled": true,
"gate_free_watch_seconds": 30,
"recording_retention_days": 60,
"retention_min_days": 30,
"retention_max_days": 90,
"sms_keyword": "sunday",
"sms_from_number": "+12075550123",
"notification_methods": [
"native.email"
],
"notification_method_states": [
{
"key": "native.email",
"label": "Email",
"medium": "sms",
"requires_connection": true,
"provider_key": "planning_center",
"deliverable": true,
"available": true,
"enabled": true,
"set_up": true
}
],
"notification_mute": {
"muted": true,
"muted_until": "2026-07-11T14:30:00Z",
"muted_at": "2026-07-11T14:30:00Z",
"muted_by": "string",
"muted_reason": "string",
"max_hours": 42,
"default_hours": 42,
"max_until": "2026-07-11T14:30:00Z"
},
"subscriber_count": 42,
"created_at": "2026-07-11T14:30:00Z",
"stream_info": {
"status": "idle",
"provisioned": true,
"platform": "cloudflare",
"rtmps_url": "rtmps://live.pealcast.io/live/",
"stream_key": "string",
"srt_url": "srt://live.pealcast.io:778?streamid=…&passphrase=…",
"srt_stream_id": "string",
"srt_passphrase": "string",
"hls_playback_url": "https://…",
"sms_from_number": "+15551234567",
"sms_keyword": "sunday"
}
}
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · A read-only token attempted a write (READ_ONLY_TOKEN); may also be FORBIDDEN_ORG/FORBIDDEN.404 · No such channel for this church (NO_CHANNEL).422 · Invalid field value (INVALID).Notifications
Go-live notifications and the delivery integrations behind them (our SMS/email, Planning Center, custom domain) — who is subscribed and what has been sent.
/app/channel-notificationsGet a channel's notifications overview
Returns who is subscribed to go-live notifications for the channel, broken down by delivery integration, plus recently sent notifications and recent unsubscribes.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
| slug | string | required | The channel slug. |
Example request
curl -X GET "https://api.pealcast.io/app/channel-notifications?slug=sunday&org=your-church" \ -H "Authorization: Bearer pc_live_your_token_here"
Example response
{
"methods": [
{
"key": "native.email",
"label": "Email",
"medium": "sms",
"requires_connection": true,
"provider_key": "planning_center",
"deliverable": true,
"available": true,
"enabled": true,
"set_up": true
}
],
"mute": {
"muted": true,
"muted_until": "2026-07-11T14:30:00Z",
"muted_at": "2026-07-11T14:30:00Z",
"muted_by": "string",
"muted_reason": "string",
"max_hours": 42,
"default_hours": 42,
"max_until": "2026-07-11T14:30:00Z"
},
"totals": {
"subscribers": 42,
"subscriptions": 42,
"unsubscribes": 42
},
"by_integration": [
{
"key": "native.sms",
"label": "Text message",
"count": 42
}
],
"people": [
{
"subscriber_id": 123,
"name": "Jordan Rivera",
"mobile": "+15551234567",
"integrations": [
"native.sms",
"native.email"
]
}
],
"recent": [
{
"integration_key": "native.sms",
"status": "ready",
"provider": "signalwire",
"subscriber_id": 123,
"sent_at": "2026-07-11T14:30:00Z",
"created_at": "2026-07-11T14:30:00Z"
}
],
"unsubscribes": [
{
"subscriber_id": 123,
"name": "Jordan Rivera",
"mobile": "+15551234567",
"integration_key": "native.sms",
"unsubscribed_at": "2026-07-11T14:30:00Z"
}
]
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · The token has no church, or is not permitted for this church (NO_ORG / FORBIDDEN_ORG / FORBIDDEN).404 · No such channel for this church (NO_CHANNEL)./app/channel-integrationsGet a channel's connected integrations
Returns the channel's connected systems — Planning Center status, custom-domain entitlement/hostname, and the list of notification-delivery integrations available to this church.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
| slug | string | required | The channel slug. |
Example request
curl -X GET "https://api.pealcast.io/app/channel-integrations?slug=sunday&org=your-church" \ -H "Authorization: Bearer pc_live_your_token_here"
Example response
{
"planning_center": {
"connected": true,
"status": "connected",
"display_name": "First Baptist (Planning Center)",
"last_synced_at": "2026-07-11T14:30:00Z",
"needs_reconnect": true,
"missing_scopes": [
"services",
"publishing"
],
"provision_error": {
"code": "pco_permission",
"stage": "fields",
"missing": 42,
"status": "403",
"message": "string",
"at": "2026-07-11T14:30:00Z"
}
},
"custom_domain": {
"entitled": true,
"hostname": "watch.firstbaptist.org",
"cname_target": "player.pealcast.io"
},
"available_notification_integrations": [
{
"key": "native.sms",
"label": "Text message",
"medium": "sms",
"available": true
}
]
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · The token has no church, or is not permitted for this church (NO_ORG / FORBIDDEN_ORG / FORBIDDEN).404 · No such channel for this church (NO_CHANNEL)./app/integration-healthCheck whether Planning Center actually works
A per-check verdict on the church's Planning Center connection: not "is it connected"
(which stays true through almost every way this integration breaks) but what a live
check FOUND — permissions, the custom tab and its fields, a real test write, webhook
subscriptions and whether Planning Center has switched any off, Services and Publishing
access, and which delivery methods can genuinely send.
Each check carries its own status, a plain-English title and detail — quoting
Planning Center's own wording where we have it — and the action that fixes it.
status is one of ok, warn, fail or unknown. unknown is not a failure: it
means we could not determine the answer, and it is used deliberately for anything
Planning Center does not expose. Text messaging (whether it is switched on, the credit
balance, and whether auto-refill is enabled) lives in Planning Center Accounts, which
has no API at all — so that check reports unknown permanently, with a link, rather than
a green light on something nobody can verify.
Without refresh, the last stored report is returned (one row read); the checks
themselves also run hourly in the background and alert on failure.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
| slug | string | optional | Check a channel-scoped connection. Omit for the church's org-wide connection. |
| refresh | 1 | true | yes | optional | Run the checks now instead of returning the last stored report. |
Example request
curl -X GET "https://api.pealcast.io/app/integration-health?org=your-church&slug=sunday" \ -H "Authorization: Bearer pc_live_your_token_here"
Example response
{
"provider": "planning_center",
"connected": true,
"status": "ok",
"checked_at": "2026-07-11T14:30:00Z",
"summary": {
"ok": 9,
"warn": 3,
"unknown": 1
},
"checks": [
{
"key": "write",
"status": "ok",
"title": "PealCast is not allowed to write",
"detail": "string",
"action": "Reconnect as an Organization Administrator",
"action_url": "https://…",
"informational": true
}
]
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · The token has no church, or is not permitted for this church (NO_ORG / FORBIDDEN_ORG / FORBIDDEN).404 · No such channel for this church (NO_CHANNEL).Account
Your church's plan, trial/billing state, and Shepherd's Report scheduling preferences.
/app/accountGet the church's account and plans
Returns the church's billing/trial state, the catalog of plans, and the Stripe publishable key used by the dashboard to collect a card.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
Example request
curl -X GET "https://api.pealcast.io/app/account?org=your-church" \ -H "Authorization: Bearer pc_live_your_token_here"
Example response
{
"account": {
"state": "active",
"status": "Trial — 9 days left",
"trial_ends_at": "2026-07-11T14:30:00Z",
"trial_days_left": 9,
"free_tier_over_pool": true,
"has_payment_method": true,
"is_founding_member": true,
"founding_intro_active": true,
"founding_discount_until": "string",
"locked_price_cents": 42,
"plan": {
"code": "medium",
"name": "Medium"
},
"next_bill_at": "2026-07-11T14:30:00Z"
},
"plans": [
{
"code": "medium",
"name": "Medium",
"tagline": "For a growing online congregation",
"founding": true,
"is_custom": true,
"price_cents": 11900,
"price_cents_annual": 119000,
"setup_fee_cents": 0,
"trial_days": 30,
"watchers": 25,
"watchers_label": "About 25 watchers",
"included_minutes": 8000,
"included_storage_minutes": 4800,
"archive_note": "4800 minutes (about 80 hours) of recorded services included each month.",
"channels_included": 3,
"overage_block_minutes": 500,
"overage_block_cents": 2500,
"minutes_note": "Based on an 80-minute average view: one watcher ≈ 80 minutes × 4 services = about 320 minutes a month, pooled across your whole church.",
"overage_note": "$25 per 500 extra minutes of viewing or recording storage",
"archive_retention_days": 60,
"archive_label": "4,800 min",
"support_tier": "email+phone",
"dedicated_sms": true,
"dedicated_email": true,
"dedicated_domain": true
}
],
"publishable_key": "pk_live_51ABC…"
}Responses
UNAUTHENTICATED).403 · The token has no church, or is not permitted for this church (NO_ORG / FORBIDDEN_ORG / FORBIDDEN)./app/report-settingsGet Shepherd's Report schedule settings
Returns when the church's weekly Shepherd's Report is delivered (day, hour, timezone) plus the list of selectable timezones.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
Example request
curl -X GET "https://api.pealcast.io/app/report-settings?org=your-church" \ -H "Authorization: Bearer pc_live_your_token_here"
Example response
{
"enabled": true,
"wday": 0,
"hour": 9,
"timezone": "America/New_York",
"last_sent_at": "2026-07-11T14:30:00Z",
"timezones": [
"America/New_York",
"America/Chicago"
]
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · The token has no church, or is not permitted for this church (NO_ORG / FORBIDDEN_ORG / FORBIDDEN)./app/report-settingsUpdate Shepherd's Report schedule settings
Updates when the weekly Shepherd's Report is delivered. Any omitted field is left unchanged.
Requires a read/write token (a read-only token receives 403 READ_ONLY_TOKEN).
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| enabled | boolean | optional | Whether the weekly report is sent at all. |
| wday | integer | optional | Day of week (0 = Sunday … 6 = Saturday). |
| hour | integer | optional | Hour of day (local to timezone). |
| timezone | string | optional | IANA timezone name. |
Example request
curl -X POST "https://api.pealcast.io/app/report-settings?org=your-church" \
-H "Authorization: Bearer pc_live_your_token_here" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"wday": 0,
"hour": 9,
"timezone": "America/New_York"
}'Example response
{
"enabled": true,
"wday": 0,
"hour": 9,
"timezone": "America/New_York",
"last_sent_at": "2026-07-11T14:30:00Z"
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · A read-only token attempted a write (READ_ONLY_TOKEN); may also be FORBIDDEN_ORG/FORBIDDEN./app/organizationUpdate the church's details
Updates the church's (organization's) editable details. Billing, status, plan, and slug
are not editable here. Any omitted field is left unchanged. Requires a read/write
token (a read-only token receives 403 READ_ONLY_TOKEN).
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | optional | The church's display name. |
| timezone | string | optional | IANA timezone name. |
Example request
curl -X POST "https://api.pealcast.io/app/organization?org=your-church" \
-H "Authorization: Bearer pc_live_your_token_here" \
-H "Content-Type: application/json" \
-d '{
"name": "First Baptist",
"timezone": "America/New_York"
}'Example response
{
"ok": true,
"organization": {
"id": 123,
"name": "Jordan Rivera",
"slug": "main-service",
"role": "string",
"status": "ready",
"timezone": "America/New_York"
}
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · A read-only token attempted a write (READ_ONLY_TOKEN); may also be FORBIDDEN_ORG/FORBIDDEN.422 · Invalid field value (INVALID).Player (public)
Public, unauthenticated endpoints that power the watch page — live status, playback URL, and the church's public channel list.
/player/channel-playbackpublicGet a channel's live playback state
Public (no auth). Returns the current live state and playback URL for a channel, plus the gate configuration and the notification methods a viewer can opt into. This is what the watch page calls to render the player.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| c | string | required | The channel slug or id. |
| t | string | optional | A signed watch token that pre-identifies the viewer (from a notification link). |
| host | string | optional | The watch host (used to resolve a custom domain). |
| session_uid | string | optional | The browser's watch-session id. When supplied, the response carries a session_key binding that session to this channel — the proof a later heartbeat presents so it can be attributed to a church without being able to NAME one.
|
| org | string | optional | The church (organization) id or slug. Optional — the token is already pinned to one church; supply this only to disambiguate. |
Example request
curl -X GET "https://api.pealcast.io/player/channel-playback?c=sunday&t=signed-watch-token&host=watch.firstbaptist.org"
Example response
{
"is_live": true,
"broadcast_id": 123,
"hls_url": "https://…",
"playback_id": "string",
"gate_required": true,
"session_key": "string",
"gate_enabled": true,
"gate_free_watch_seconds": 30,
"notification_methods": [
{
"key": "native.sms",
"label": "Text message",
"medium": "sms"
}
],
"sms_consent": {
"version": "2026-08-26",
"sender": "Sunday Service",
"text": "string",
"segments": [
{
"text": "string",
"url": "https://…"
}
]
},
"theme": {
"brand_color": "#0c1a2e"
},
"identified": true,
"viewer_first_name": "Jordan"
}Responses
NO_CHANNEL)./player/orgpublicGet a church's public player profile
Public (no auth). Resolves a church by custom-domain host or slug and returns its public profile plus the list of channels a viewer can watch.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| host | string | optional | The watch host (used to resolve a custom domain). |
| slug | string | optional | The church (organization) slug. |
Example request
curl -X GET "https://api.pealcast.io/player/org?host=watch.firstbaptist.org&slug=sunday"
Example response
{
"org": {
"name": "Jordan Rivera",
"slug": "main-service",
"custom_domain": "string",
"theme": {
"brand_color": "#0c1a2e"
}
},
"channels": [
{
"slug": "main-service",
"name": "Jordan Rivera",
"type": "broadcast",
"is_live": true,
"theme": {
"brand_color": "#0c1a2e"
}
}
]
}Responses
NO_ORG).Streaming
/app/stream-healthIs this channel's stream healthy right now?
The summary a church actually needs during a service, from metrics we pull off the video
host into our own database. Two halves:
encoder — is the church's own upload keeping up? upload_ratio is the number that
predicts a bad Sunday: at or above 1.0 the encoder cannot upload as fast as it records and
playback WILL stall. verdict states that in plain English.
viewers — peak viewers, total view time, and buffering, reported by the players
themselves (CMCD).
Both are time-bucketed 5-minutely; window_minutes picks how far back to summarize.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| slug | string | required | |
| window_minutes | integer | optional | |
| broadcast_id | string | optional |
Example request
curl -X GET "https://api.pealcast.io/app/stream-health?slug=sunday&window_minutes=60&broadcast_id=value" \ -H "Authorization: Bearer pc_live_your_token_here"
Example response
{
"channel": "string",
"is_live": true,
"window_minutes": 128,
"encoder": {
"samples": 42,
"avg_bitrate_bps": 42,
"avg_keyframe_ms": 42,
"avg_upload_ratio": 42,
"max_upload_ratio": 42,
"healthy": true,
"verdict": "string"
},
"viewers": {
"samples": 42,
"peak_viewers": 42,
"view_time_minutes": 128,
"avg_buffer_length_ms": 42,
"avg_buffer_starve_ms": 42
}
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · The token has no church, or is not permitted for this church (NO_ORG / FORBIDDEN_ORG / FORBIDDEN).404 · No such channel for this church (NO_CHANNEL)./app/stream-metricsStream metric series (encoder + viewers)
The chart data behind the health summary — one point per 5-minute bucket, oldest first.
Returns BOTH series unless source narrows it: input (encoder-side — bitrate, keyframe
interval, upload ratio) or player (viewer-side — viewers, view time, buffering).
Pass dimension (resolution or country) to get that breakdown rolled up over the
window instead of a time series — "resolutions delivered" and "viewers by country".
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| slug | string | required | |
| hours | integer | optional | |
| source | input | player | optional | |
| dimension | resolution | country | optional | |
| broadcast_id | string | optional |
Example request
curl -X GET "https://api.pealcast.io/app/stream-metrics?slug=sunday&hours=6&source=input" \ -H "Authorization: Bearer pc_live_your_token_here"
Example response
{
"channel": "string",
"hours": 42,
"encoder": [
{
"at": "2026-07-11T14:30:00Z",
"minutes": 5,
"samples": 42,
"dimension": "string",
"bitrate_bps": 42,
"keyframe_ms": 42,
"upload_ratio": 42,
"max_upload_ratio": 42,
"viewers": 42,
"view_time_ms": 42,
"buffer_length_ms": 42,
"buffer_starve_ms": 42,
"encoded_bitrate": 42,
"throughput": 42
}
],
"viewers": [
{
"at": "2026-07-11T14:30:00Z",
"minutes": 5,
"samples": 42,
"dimension": "string",
"bitrate_bps": 42,
"keyframe_ms": 42,
"upload_ratio": 42,
"max_upload_ratio": 42,
"viewers": 42,
"view_time_ms": 42,
"buffer_length_ms": 42,
"buffer_starve_ms": 42,
"encoded_bitrate": 42,
"throughput": 42
}
],
"dimension": "string",
"totals": [
{
"value": "1280x720",
"viewers": 42,
"view_time_ms": 42
}
]
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · The token has no church, or is not permitted for this church (NO_ORG / FORBIDDEN_ORG / FORBIDDEN).404 · No such channel for this church (NO_CHANNEL)./app/stream-logThis channel's stream event timeline
One timeline combining OUR lifecycle events (went live, ended, recording attached) with the
video host's OWN event log mirrored in as provider_log (encoder connected/disconnected,
provider error codes with their descriptions and the edge that saw them). Newest first.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| slug | string | required | |
| limit | integer | optional | |
| severity | info | warn | error | optional | |
| kind | api_error | webhook | lifecycle | signing | reconcile | provider_log | quota | optional |
Example request
curl -X GET "https://api.pealcast.io/app/stream-log?slug=sunday&limit=100&severity=info" \ -H "Authorization: Bearer pc_live_your_token_here"
Example response
{
"channel": "string",
"count": 42,
"events": [
{
"id": "string",
"occurred_at": "2026-07-11T14:30:00Z",
"provider": "cloudflare",
"kind": "api_error",
"severity": "info",
"operation": "string",
"status_code": 42,
"message": "string",
"elapsed_ms": 42,
"external_id": "string",
"organization_id": "string",
"channel_id": "string",
"broadcast_id": "string",
"alerted_at": "2026-07-11T14:30:00Z",
"detail": {
"brand_color": "#0c1a2e"
}
}
]
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.403 · The token has no church, or is not permitted for this church (NO_ORG / FORBIDDEN_ORG / FORBIDDEN).404 · No such channel for this church (NO_CHANNEL).Integrations
/app/integration-catalogWhat this church can connect, by category
Everything this church could connect, grouped by category — chms (Planning Center,
Breeze, CCB, Rock), notification (Slack, Twilio, Text In Church, plus the transports
included with PealCast), media, archive, and any category added later. Each provider
carries the setup_fields a connect form should render, its capabilities, and whether a
church may connect more than one instance of it.
Also returns the notification capabilities (the delivery adapters), because "what can
reach my people?" is one question to a church even though it spans two axes internally:
a CONNECTION (the church's linked account) and a CAPABILITY (a way to send).
Providers that aren't available to this church are omitted rather than shown broken.
Pass slug to evaluate availability for a specific channel.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| slug | string | optional | Channel slug; omit for org-wide scope. |
Example request
curl -X GET "https://api.pealcast.io/app/integration-catalog?slug=sunday" \ -H "Authorization: Bearer pc_live_your_token_here"
Example response
{
"categories": [
{
"category": "chms",
"label": "Text message",
"summary": "string",
"providers": [
{
"key": "slack",
"category": "notification",
"label": "Text message",
"summary": "string",
"auth_type": "oauth2",
"capabilities": [
"string"
],
"multi_instance": true,
"setup_fields": [
{
"key": null,
"label": null,
"type": null,
"required": null,
"help": null
}
],
"docs_url": "https://…"
}
]
}
],
"notification_capabilities": [
{
"key": "planning_center.sms",
"label": "Text message",
"medium": "sms",
"category": "notification",
"provider_family": "string",
"provider_key": "string",
"requires_connection": true,
"available": true
}
]
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it./app/integrationsWhat this church has connected, by category
Every connection this church has, grouped by category. With slug, the connections that
apply to that channel — channel-scoped plus the org-wide fallbacks, since a
channel-scoped connection overrides the org default rather than replacing the list.
A church may hold 1 or more connections per category per channel, including several
instances of the same provider where it allows it (two Slack workspaces, two S3 buckets);
instance_key distinguishes them and is_primary marks the default one.
Credentials are never returned — they are write-only over this API and encrypted at rest.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| slug | string | optional |
Example request
curl -X GET "https://api.pealcast.io/app/integrations?slug=sunday" \ -H "Authorization: Bearer pc_live_your_token_here"
Example response
{
"channel": "string",
"categories": [
{
"category": "string",
"label": "Text message",
"summary": "string",
"connections": [
{
"id": "string",
"provider": "slack",
"category": "notification",
"label": "Text message",
"instance_key": "string",
"is_primary": true,
"scope": "organization",
"channel_id": "string",
"status": "connected",
"capabilities": [
"string"
],
"multi_instance": true,
"external_id": "string",
"last_synced_at": "2026-07-11T14:30:00Z",
"last_error": "string",
"connected_at": "2026-07-11T14:30:00Z"
}
]
}
]
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it./app/integrationsConnect (or reconnect) one integration instance
Connects one instance of an api_key provider. Omit instance_key for the church's
primary connection; pass a slug (youth, campus-2) for an additional one — allowed only
where the provider declares multi-instance support, otherwise 409 SINGLE_INSTANCE_ONLY.
Reconnecting the same instance updates it in place (and revives a disconnected one) rather
than duplicating.
oauth2 providers are connected by signing in, not here — posting one returns
400 USE_OAUTH. Required setup_fields that are missing return 400 MISSING_FIELDS
naming each one.
Credentials are encrypted at rest and never returned by any endpoint.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| provider | string | required | |
| credentials | object | optional | Keyed by the provider's setup_fields. Write-only. |
| slug | string | optional | Channel slug; omit to connect org-wide. |
| instance_key | string | optional | Empty string = the primary connection; a slug adds another instance. |
| label | string | optional | Human label for this connection. |
| config | object | optional | Non-secret settings. |
Example request
curl -X POST "https://api.pealcast.io/app/integrations" \
-H "Authorization: Bearer pc_live_your_token_here" \
-H "Content-Type: application/json" \
-d '{
"provider": "slack"
}'Example response
{
"ok": true,
"integration": {
"id": "string",
"provider": "slack",
"category": "notification",
"label": "Text message",
"instance_key": "string",
"is_primary": true,
"scope": "organization",
"channel_id": "string",
"status": "connected",
"capabilities": [
"string"
],
"multi_instance": true,
"external_id": "string",
"last_synced_at": "2026-07-11T14:30:00Z",
"last_error": "string",
"connected_at": "2026-07-11T14:30:00Z"
}
}Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.404 · Unknown provider.409 · Provider unavailable, or a second instance where only one is allowed./app/integrationsDisconnect one integration instance
Soft-disconnects ONE instance (the row is retained for audit and easy reconnect — nothing is hard-deleted). Other instances of the same provider are unaffected.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | required |
Example request
curl -X DELETE "https://api.pealcast.io/app/integrations?id=123" \ -H "Authorization: Bearer pc_live_your_token_here"
Responses
UNAUTHENTICATED).402 · The church's account is behind on payment (PAYMENT_REQUIRED) — a failed charge (past_due) or a closed account (locked). ⚠️ Running out of TRIAL is NOT one of them: since the 30-day reverse trial a church that has not chosen a plan is in state free and is never blocked. Returned by EVERY authenticated /app/ and /mcp operation except the ones a church needs in order to pay: /app/account, /app/billing/setup-intent, /app/billing/subscribe, /app/bootstrap, /app/orgs, /app/switch-org, /app/sessions and /app/stop-impersonation. Add a payment method to clear it.404 · Integration not found for this church.Get your API token
Create a free account, open Developer / API tokens, and start building in minutes.
30 days free · no card · cancel anytime.