Building a declarative n8n node for ClickSend
Why I finally wrote this down
I was wiring ClickSend SMS and MMS into n8n workflows for a side project. The first pass used HTTP Request nodes with Basic auth headers and raw paths. By the third workflow copy, rotating the API key meant editing every node. Operations were invisible in the UI. Reviewers had to open JSON to see whether a node calculated price or actually sent a message.
n8n's declarative node style maps resources and operations to request routing without writing a full programmatic execute loop. That was the right shape for ClickSend's REST groups. I published n8n-nodes-clicksend so the next instance inherits labeled ops instead of another brittle paste.
Why declarative nodes
Labels over URLs: the editor shows Account / SMS / MMS / Upload with named operations, not
/v3/sms/send.Credentials own auth: username and API key live in an n8n credential type. Rotations update one place.
Versioned package: community node installs beat exporting workflow JSON across playground and production.
Lifecycle hooks when needed: declarative nodes still allow
preSendtransforms for timestamp formatting or debug baseURL swaps against webhook.site while building.
Structure that worked
One credential type for ClickSend Basic auth. One node file that declares resources. Separate description modules per resource so adding MMS after SMS was mostly a copy of fields plus a media parameter.
Account: get details, get usage.
SMS: history, calculate price, send.
MMS: history, calculate price, send (extra media field).
Upload: convert binary media to a ClickSend-compatible URL before MMS send.
Price calculation and send share the same field shapes on purpose. Operators can flip between estimate and send without rebuilding the node config. Upload stays a first-class operation because MMS media often needs conversion first unless the file is already in a supported format.
When HTTP nodes are still fine
One-off prototypes and internal-only webhooks do not need a custom node. Promote to a package when you hit the third copy-paste, when auth rotation touches more than one workflow, or when a non-author has to discover operations without reading the API docs.
I also reviewed a Zapier app covering the same vendor. That checklist drove the send and upload gaps I would have missed if I only mirrored my first two HTTP nodes.
Failure modes I keep debugging
README copy-paste from another node package: wrong product name in install docs confuses every first-time installer.
Secrets in sample workflows: credential placeholders get replaced with live keys during local demos and then committed.
Send without upload for MMS: media URL fails because the file was never converted.
Date fields as ISO strings against an epoch API: use routing transforms so the UI stays human and the wire format stays correct.
Quick review before publish
Do operations show clear labels for estimate vs send?
Is auth only in credentials, never in workflow JSON?
Can a teammate install the package on a second n8n instance without paste?
Does the README name this package, not the last one you forked?