The brief
The SignerX Zapier App is a connector — a supporting tool for the SignerX API that lets a SignerX user trigger automations off document-signing events without writing code. A Slack notification when a contract is signed, a HubSpot deal advanced when a package is sent, a Google Sheet of recipients kept up to date — all configured by the customer in Zapier, not by us. The published listing on Zapier’s marketplace means it shows up alongside thousands of other integrations, available to any SignerX customer who wants it.
I designed and built both halves. The Zapier app itself (Node, Zapier Platform CLI) and the SignerX API surface that makes the integration possible (Laravel Passport for OAuth2, response-shaping middleware, extended OAuth client metadata so SignerX shows up branded on the authorization screen, not generic).
What I built
OAuth2 with PKCE. SignerX users authorize Zapier through a standard OAuth2 flow with PKCE enabled, the security model Zapier requires for public clients. Auto token refresh on the Zapier side, profile-checking endpoint on the API side, connection labels that surface the user’s email so anyone managing multiple SignerX accounts in Zapier can tell them apart at a glance.
Branded OAuth consent, via extended Passport metadata. The
authorization screen a SignerX user sees when they connect Zapier shows
the SignerX logo, display name, terms-of-service URL, and privacy-policy
URL — not the default Passport scaffolding. That meant extending the
Passport Client model on the Laravel side (icon_url, display_name,
tos_url, pp_url) and feeding that metadata into the consent flow.
Small detail, big trust gain at the moment a user is granting access.
Three triggers, two actions, one published of each. The
user-facing trigger is Package Sent — fires when a SignerX package
is dispatched for signature, with 25+ payload fields exposed for use
in downstream Zaps. The user-facing action is Send Template for
Signatures. The other triggers (Get Packages, Get Templates)
and the second action (Upload Document) are marked hidden: true:
they don’t show up in Zapier’s trigger picker, but they power the
dynamic dropdowns inside the visible actions (when a user is
configuring “Send Template for Signatures,” the template dropdown is
populated at runtime by the hidden get_templates trigger). It’s the
right pattern for surfacing internal API endpoints as helpful UX
without cluttering the choices a user sees.
Zapier-aware response middleware on the API. Zapier expects
specific response shapes — single-item operations return objects, list
operations return arrays, empty arrays on certain endpoints need to be
coerced to objects to avoid bad downstream parsing. A
ZapierReturnArrayMiddleware on the SignerX API detects requests
coming from the Zapier OAuth client (by name) and reshapes the
response on the way out. The Zapier app code stays clean and
declarative; the polymorphism lives in the middleware where it
belongs.
What’s notable about it
The integration is the work; the architecture is what made it maintainable. Two codebases evolved together — the Node app on the Zapier side and the Laravel API on the SignerX side — and the integration glue lives in the right places. Response shaping is on the API; OAuth metadata extends Passport; the Zapier app stays a thin, declarative shell over endpoints that already do the work. That’s what lets a published integration ship through years of product changes without rotting.