Automate Customer.io from
swamp. This model wraps the Customer.io
App API to snapshot a workspace and run an idempotent per-brand readiness
audit. It lists segments and transactional messages so other models and
workflows can reference them via CEL, and diffs an expected set of segments +
transactional messages for a single brand against live state — writing a
brandReadiness resource (present/missing, captured IDs, and a checklist for the
parts the API can't author). The audit is pure read + diff: it never mutates
Customer.io, so it is safe to re-run, and ready: true means "already set up,
skip."
The App API bearer token is supplied through globalArguments.appApiToken, wired
to a vault expression at model-creation time — never a literal token. US and EU
workspaces are selected with region.
swamp extension pull @goodcraft/customerio# Create the model with the token wired to a vault (never inline)
swamp model create @goodcraft/customerio customerio \
--global-arg appApiToken='${{ vault.get(op-secrets, "Customer.io - GoodCraft/App API Key") }}' \
--global-arg region=us
# Read-only: snapshot segments + transactional messages
swamp model method run customerio sync
# Audit one brand's expected set against live state (read-only)
swamp model method run customerio auditBrand \
--input brand='Acme' \
--input segments='[{"name":"Acme — All Users"}]' \
--input transactional='[{"name":"Acme Welcome","wireTo":"WelcomeMail"}]'sync— snapshot the workspace: list segments and transactional messages (read-only).auditBrand— diff one brand's expected segments + transactional messages against live state;ready=truemeans already set up.
Dynamic (condition-based) segments and transactional message templates are
authored in the Customer.io UI, not the API — so this model audits and captures
their IDs rather than creating them. The diff logic lives in _lib/brand_audit.ts
(zod-free, pure functions) with colocated unit tests; the API methods are thin
wrappers that fetch live state and delegate to it.
MIT — see LICENSE.txt.