Life Community Church Integration Story

From Zapier Limits to Our Own Unlimited Webhook Box

How we moved the Spiritual Gifts workflow off a five-step Zapier ceiling and onto a church-owned Proxmox webhook server that can parse Jotform submissions, score results, update Planning Center, log failures, and grow without fighting task limits.

Production path: Jotform → home.buckeyemanor.com/webhooks → Planning Center People

I like Zapier. It is genuinely useful for proving an idea quickly. But once the church Spiritual Gifts workflow got real, Zapier started feeling less like automation and more like trying to remodel a kitchen with a pocket knife. Useful tool. Wrong scale.

The original problem sounded simple: someone submits the Spiritual Gifts assessment, we score the gifts, then update their Planning Center profile. But the real workflow is not one tiny action. It is parsing a big form, normalizing names and dates, calculating multiple gift scores, finding the right Planning Center person, loading the right custom-field tab, updating fourteen score fields, writing metadata, and handling errors safely.

That is where the five-step style Zapier workflow started falling apart. So we built our own box.

Why Zapier broke down

Zapier was perfect for the first prototype. It let us prove the shape of the workflow fast:

That was enough to validate the idea. But production workflows are where the gremlins come out of the vents.

5-ish

Step pressure

Every little thing wants to become another Zap step: lookup person, lookup field definitions, update one field, update another field, notify on failure, log a result, branch for missing people. The workflow becomes a Jenga tower.

14+

Fields to update

The Spiritual Gifts assessment has fourteen score categories, plus metadata like Source, Date Updated, and optional Strengths. Updating them as separate Zapier actions is painfully fragile.

The deeper issue was not just cost or task limits. It was control. We needed proper code, not a chain of tiny UI boxes. We needed one place where the workflow could parse weird form payloads, handle edge cases, call Planning Center as many times as needed, and produce logs we could actually use.

AreaZapier prototypeWebhook box
Form payloadsWorks when the trigger maps fields cleanly.Can parse multipart Jotform payloads directly and tolerate odd field names.
Planning Center updatesEasy for one or two fields, ugly for fourteen plus metadata.One code path searches the person, loads fields, and updates all relevant values.
LimitsConstrained by plan, tasks, steps, and Zap action design.Limited by our server resources and the actual third-party API limits.
DebuggingClick through Zap runs and hope the useful payload is visible.Use journal logs, structured errors, dry-run endpoints, and targeted test requests.
SecuritySecrets live inside Zapier input fields.Secrets live in the server environment; public endpoint is token-protected.
Future changesAdd more steps, branches, or another Zap.Edit normal code, validate it, restart the service.

What we built instead

We built a dedicated Life Community Church webhook server on Proxmox. The public domain is home.buckeyemanor.com/webhooks, and the app lives on the webhook server at /opt/church-webhook.

The Spiritual Gifts production path is now:

Jotform submission
  → https://home.buckeyemanor.com/webhooks/webhook/spiritual-gifts?token=...
  → /opt/church-webhook/SpiritualGifts/spiritual-gifts-api.js
  → Planning Center People API
  → Spiritual Gifts tab id 256800

Instead of Zapier orchestrating a bunch of little actions, the church-owned webhook app owns the whole transaction. That lets us make the workflow understandable as code:

The win: the workflow is now one coherent service instead of a fragile stack of automation cards.

Architecture diagram

Before: Zapier prototypeJotformNew assessmentZapier5-step pressureMany tiny actionsfield mappingbranchestask limitsPCOPeople fields After: church-owned webhook serviceJotformDirect webhookmultipart/form-dataCaddyhome.buckeyemanor.com/webhooksTLS + reverse proxypublic endpointWebhookLCC box/opt/church-webhookExpress serviceSpiritualGifts APIsystemd + logsdry-run + live routesLocal logicscore normalizationfield mappingerror handlingPCO PeopleTab 25680014 gift fields Supportjournalctl logshealth endpointrepeatable deploys

Request flow in detail

1. Jotform submits directly to our webhook

Instead of using Zapier as the middleman, Jotform’s Webhooks integration posts straight to:

https://home.buckeyemanor.com/webhooks/webhook/spiritual-gifts?token=...

The token is important. It means the endpoint can be public without accepting random internet noise as a valid church form submission.

2. Express accepts the payload

The Node/Express app receives the request. This mattered more than expected because Jotform sends webhook data as multipart/form-data in real life. A normal JSON parser does not see that body. Early testing showed empty body keys even though the submission was arriving. So we added multipart parsing with multer.

3. The Spiritual Gifts module normalizes the data

Form tools love to send data in whatever shape they feel like sending that day. The webhook code normalizes the useful pieces:

The endpoint also supports a dry-run path, which is one of the best things we gained by leaving Zapier. We can test parsing without writing to Planning Center.

POST /webhook/spiritual-gifts/dry-run?token=...

4. The service updates Planning Center

Planning Center People is updated through the API using credentials stored in the server environment. The code searches by email, loads field definitions, prefers the Spiritual Gifts tab, then updates all relevant fields in one controlled workflow.

That includes the score fields:

AdministrationDiscernmentEncouragementEvangelismFaithGivingServiceKnowledgeLeadershipMercyShepherdingProphecyTeachingWisdom

It can also write metadata like Date Updated, Source, and optional Strengths when the field exists.

Planning Center update logic

The biggest technical detail is that Planning Center custom fields are not just simple key/value properties. The code has to know which field definitions exist, which tab they belong to, and which field names match our gifts.

We specifically prefer the Spiritual Gifts tab with id 256800. That prevents a duplicate field name elsewhere in Planning Center from stealing the update. If a field is missing, the code should make the problem obvious instead of silently skipping it.

Search person by submitted email
  → load Planning Center field definitions
  → filter/prefer Spiritual Gifts tab 256800
  → match gift field labels
  → upsert score field data
  → write Date Updated / Source / Strengths
  → log success or structured skip reason

That kind of logic is possible in Zapier, but it is awkward. In normal code, it is just a function. And functions are much easier to test, read, reuse, and fix at midnight when something inevitably does something spicy.

What “unlimited” really means

Calling this “unlimited” does not mean we can ignore every limit in the universe. Planning Center still has API limits. The server still has CPU, memory, and disk. Jotform still has its own behavior. What changed is that we are no longer boxed into an automation plan’s step count or task model.

No artificial step ceiling

The workflow can make the calls it needs to make. If it takes ten internal operations to handle one submission correctly, that is fine.

No per-field Zap action pileup

Fourteen gift fields plus metadata can be handled in one service flow instead of one UI action per update.

Better retries and diagnostics

We can log exact skip reasons like missing email, no matching person, missing field definition, or Planning Center error.

Reusable platform

The same webhook box can host Spiritual Gifts, HVAC, Caddy-backed support pages, and future church integrations.

Translation: we did not beat API physics. We beat automation-platform friction.

Operations and support

The webhook app is normal Linux infrastructure. That is the whole point. When something breaks, we do not have to click through a maze of Zap history screens. We can inspect the service.

cd /opt/church-webhook
node --check app.js
node --check SpiritualGifts/spiritual-gifts-api.js
systemctl status church-webhook --no-pager
journalctl -u church-webhook --since "10 minutes ago" --no-pager

Useful live checks:

curl -s https://home.buckeyemanor.com/webhooks/spiritual-gifts/health
journalctl -u church-webhook -f | grep "Spiritual Gifts webhook"

The deployment pattern is intentionally boring:

That is not glamorous. It is better than glamorous. It is supportable.

Lessons learned

Zapier is great for prototypes. It let us prove the workflow quickly. The mistake would have been forcing a production integration to stay in prototype clothes.
Direct webhooks are simpler once you own the endpoint. Jotform can post directly to the church server. We do not need a middleman just to receive a form.
Multipart form data matters. The webhook was arriving, but the app could not see the real body until we parsed Jotform’s actual payload format.
Logs beat vibes. A clean journal entry with email, score count, person id, skipped status, and reason is worth more than twenty screenshots of automation cards.
Secrets belong in environment config. Planning Center credentials and webhook tokens should not live in public docs, screenshots, or copy/pasted URLs.
The real win: the church now has a reusable integration platform. Spiritual Gifts was the first big proof. HVAC came next. Future workflows can plug into the same pattern without paying the Zapier tax every time the logic gets interesting.