| name | zernio-workflow-creator |
| description | Build Zernio conversation Workflows — including 24/7 WhatsApp AI agents — through the Zernio API on command. Tell Claude what the agent should do (answer questions, qualify, book a call) and it builds the whole node graph (trigger → AI node → reply → wait → loop) via Zernio, activates it, and edits it later when you ask — no dragging nodes one by one. Pairs with zernio-comment-to-dm (comment → DM → this AI agent runs the conversation) and zernio-voice-agent (give the SAME number an AI VOICE that answers phone calls — text brain here, voice brain there). Triggers on: "build a Zernio workflow", "make a WhatsApp AI agent", "create an AI agent that answers my DMs", "add a step to the workflow", "edit the workflow", "build a booking agent in Zernio". |
zernio-workflow-creator
Build a Zernio Workflow — a branching conversation automation that can run a 24/7 AI agent on
WhatsApp, Instagram, Facebook, Telegram, and more — just by asking Claude. Claude writes the node
graph, creates it through the Zernio API, activates it, and edits it later on command. No node-by-node
dragging, no cloning workflows.
The skill informs; the agent acts. This file + reference/zernio-workflows-api.md give Claude
the Zernio Workflow API contract + the recipes. Claude executes with curl (or the user's HTTP tool).
You stay in control — Claude shows you the graph and confirms before creating or activating
anything (it goes live on a real audience).
What you can ask
- "Build a WhatsApp AI agent that answers questions and books a call."
- "Make a workflow: when someone DMs PRICING, an AI agent walks them through the plans."
- "Add an email-capture step before the booking question." → Claude edits the graph.
- "Pause / activate / duplicate / roll back the booking workflow."
What Claude needs (ask once, then remember in-session)
- ZERNIO_API_KEY —
Authorization: Bearer <key> (zernio.com → Settings → API keys).
- profileId + accountId — the Zernio profile + connected account (
GET /v1/profiles, GET /v1/accounts).
- platform —
whatsapp (default), instagram, facebook, telegram, twitter, bluesky, reddit.
- The behavior in plain words — what the agent should do, the system prompt's job, the booking link / next step.
WhatsApp prerequisites (one-time)
- A WhatsApp number bought inside Zernio —
POST /v1/whatsapp/phone-numbers/purchase (needs a paid
plan + KYC, which can take days — start early). Test first on the sandbox:
POST /v1/whatsapp/sandbox/sessions.
- For the AI node on Claude (BYOK): store your Anthropic API key in Zernio. Set
provider: anthropic + model on the node to use it; omit provider for Zernio's built-in path.
The recipe (Claude follows this)
1. Design the graph (the core)
A 24/7 conversational AI agent is a small loop with memory. Default shape:
trigger ─▶ add_tag ─▶ condition(route) ─default─▶ ai(agent) ─success─▶ set_variable(remember) ─▶ send_message ─▶ wait_for_reply ─reply─▶ condition(route) (loop)
│ wants_human─▶ handoff │ error─▶ handoff └────timeout─▶ end
- trigger —
inbound_message (optionally gated by keywords + matchType).
- add_tag — tag the contact once (e.g.
whatsapp-ai-lead) so leads are findable. Put it
before the routing/AI so it fires a single time (the loop re-enters at route, not tag).
- condition (route) — the human-escape. Check each inbound message for a human request
(
operator: matches, a regex like (?i)(human|real person|representative)) → handoff; the
'default' handle flows to the AI. If the rule never matches it safely falls through to the agent.
- ai —
provider: anthropic, your model, a systemPrompt defining the job (tone, what to
collect, when to book), userPromptTemplate that feeds memory + the new message, saveAs: "aiReply".
- set_variable (remember) — THE MEMORY TRICK. The AI node has no built-in conversation
history (it only sees
systemPrompt + userPromptTemplate per call). Without memory it
re-greets and re-asks every message. So append each turn to a history variable
(value: "{{history}}\nThem: {{lastMessage}}\nYou: {{aiReply}}") and put {{history}} back in
userPromptTemplate. Now the agent has real multi-turn context.
- send_message —
messageType: text, text: "{{aiReply}}".
- wait_for_reply —
timeoutMinutes + saveAs: "lastMessage" (reuse the same var the AI reads);
'reply' edge loops back to the AI, 'timeout' ends.
- handoff — on the AI
'error' edge, hand the conversation to a human.
Copy-paste starting point: templates/whatsapp-customer-service-agent.json (this exact memory-enabled graph; the systemPrompt is a fill-in-the-blank structure a business owner can complete in plain language).
Full node/edge contract + all 16 node types: reference/zernio-workflows-api.md.
Gaps to design around (learned the hard way)
- Memory — the #1 gap. Always add the
set_variable accumulator above; a stateless agent feels broken.
Two caveats: (1) it grows unbounded — the full transcript is re-sent every turn, so a long
conversation balloons input tokens; for long chats keep a sliding window (last N turns) or a rolling
summary, and set maxTokens on the AI node. (2) The self-referential {{history}} assignment assumes
it reads the old value before writing the new one — not guaranteed by the spec; verify with a live test.
- Empty AI reply — an empty/whitespace text response still takes the AI
'success' edge, so
send_message tries to send a blank message (WhatsApp rejects it) and send_message has no error
handle → the contact silently gets nothing. If it matters, add a condition (aiReply empty →
handoff) before the reply.
userPromptTemplate is REQUIRED on the AI node (the spec marks it optional; the API rejects without it).
The inbound message arrives as {{lastMessage}}.
- BYOK —
provider: anthropic needs the user's Anthropic key stored in Zernio. If it's missing the
AI node errors → the handoff path fires (no reply). Verify by testing, or omit provider for the
built-in path. Always wire an error → handoff edge so failures degrade gracefully.
- Double-reply —
onlyFirstMessage: false + the wait-loop may let a rapid 2nd inbound spawn a
parallel run instead of resuming the waiting one → two replies. The spec does not guarantee one
run per conversation, and onlyFirstMessage is undocumented — so don't blindly flip it to true
(that can permanently silence repeat customers). Test then decide: fire two rapid inbounds on the
sandbox during the wait window and check GET /v1/workflows/{id}/executions — if you see two runs for
the same conversation, the race is real; only then weigh onlyFirstMessage: true.
- Lead capture (advanced) — to persist a booking, give the AI node a
tools:[{name:"save_lead",…}]
and branch the 'tool:save_lead' edge into set_field + add_tag + handoff. Verify how tool-call
args surface as variables before relying on it.
- Graph edits are draft/paused only — to change a live workflow:
pause → PATCH → activate.
2. Create it (one call, draft)
curl -s -X POST "https://zernio.com/api/v1/workflows" \
-H "Authorization: Bearer $ZERNIO_API_KEY" -H "Content-Type: application/json" \
-d @workflow.json
Body = { profileId, accountId, platform, name, description, nodes[], edges[] }. Returns the workflow
id in draft. entryNodeId is derived from the single trigger node.
3. Activate it
curl -s -X POST "https://zernio.com/api/v1/workflows/<id>/activate" -H "Authorization: Bearer $ZERNIO_API_KEY"
Now it matches inbound messages. Pause anytime: POST /v1/workflows/<id>/pause.
4. Edit it later (the "you're still steering" part)
- Graph edits only while
draft or paused (a live edit returns 400). So: pause → PATCH the
graph → activate again.
curl -s -X PATCH "https://zernio.com/api/v1/workflows/<id>" \
-H "Authorization: Bearer $ZERNIO_API_KEY" -H "Content-Type: application/json" \
-d '{ "nodes": [ ... updated ... ], "edges": [ ... updated ... ] }'
- Versioned:
GET /v1/workflows/<id>/versions, restore via POST /v1/workflows/<id>/versions/<v>/restore.
- Fork a working one:
POST /v1/workflows/<id>/duplicate.
5. Inspect runs
GET /v1/workflows/<id>/executions (runs) · .../executions/<execId>/events (per-node timeline).
Guardrails
- Confirm before create + before activate. Show the user the graph (or a plain-English summary of
each node) and the system prompt, get a yes, then POST.
- Never print the API key. It lives in env / the user's secret store.
- Edit only while paused/draft — pause first, then PATCH, then re-activate. Don't attempt a live graph edit.
- Voice: the AI node's
systemPrompt should make the agent sound like the creator — warm, direct,
human, one ask at a time. Not a robotic FAQ bot.
- WhatsApp-only nodes:
template / interactive messages and start_call only work on WhatsApp.
Reference
reference/zernio-workflows-api.md — full endpoint + node/edge contract (verified from docs.zernio.com).
templates/whatsapp-customer-service-agent.json — copy-paste 24/7 WhatsApp customer-service agent (memory + human-escape + handoff); fill in the systemPrompt's [BRACKETS].
Want the agent to TALK too? → zernio-voice-agent
This skill builds the text brain. Its sibling skill zernio-voice-agent gives the SAME number
an AI voice that answers actual phone calls (inbound WhatsApp Calling routed via forwardTo to
a Retell AI agent), plus the front-desk workflow variant where the text agent detects call intent
and sends the number's tap-to-call deep link. If the user mentions calls, voice, "it should pick up
the phone", or an AI receptionist — switch to (or combine with) zernio-voice-agent.