Zapier and Make skill for Codex
No-code flows that do not double-fire. Codex designs Zaps and Make scenarios on paper first: trigger type, a dedup key from the source record, early filters, and an error route a person will actually see. It writes Code by Zapier steps, picks Make error directives such as Break with stored incomplete executions, estimates task and operation usage at real volume, and tells you when the flow should become code.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- zapier-make Installs to ~/.agents/skills/zapier-make/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install zapier-make The CLI also searches, updates and removes skills. Run it with no arguments to pick from a list. Needs Node 20.12+.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- --project zapier-make Installs to .agents/skills/zapier-make/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/zapier-make.zipunzip -o zapier-make.zip -d ~/.agents/skills/ The archive holds the skill folder with its generated agents/openai.yaml. Unzip into .agents/skills/ to scope it to a repo.
& ([scriptblock]::Create((irm codexskills.dev/install.ps1))) zapier-make PowerShell 5.1 or 7. Installs to %USERPROFILE%\.agents\skills\. Add -Project for the current repo.
104-line POSIX script. No sudo, no telemetry. Read install.sh
Use it in Codex
Start a prompt with $zapier-make, or pick it from /skills.
You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.
What Codex reads before loading it
Designs, debugs and hardens Zapier Zaps and Make (Integromat) scenarios - trigger choice (polling vs instant webhooks), filters, paths and routers, iterators and aggregators, Code by Zapier steps, Make error handler routes, deduplication and task or operation budgets - and decides when a flow has outgrown no-code. Use when the user is building or fixing a Zap or Make scenario, a Zap runs twice or misses items, task usage spikes, or a scenario stops on errors.
Use it when
- You are building or repairing a Zapier Zap or Make scenario
- A flow runs twice, skips items or stops on errors
- Task or operation usage is higher than expected
- You need to decide whether a no-code flow should move to code
Use something else when
- You want a self-hosted, version-controlled workflow tool: use n8n-workflows
- The sync is high volume and needs checkpoints and reconciliation: use data-sync-jobs
How to check the result
Send the same test item twice and confirm the second run is filtered or deduplicated, force a failure to check the alert route, and multiply per-run usage by monthly volume.
The mistake it prevents
Relying on auto-replay or retries with actions that are not idempotent, which turns one transient error into duplicate records.
Done well means: every run is traceable to one trigger item, reruns do not duplicate records, errors stop or route somewhere a human sees them, and the flow stays inside its task or operation budget. Codex cannot click through the Zapier or Make editors; it designs the flow, writes code steps and webhook payloads, reads exported blueprints or run history the user pastes, and gives step-by-step build instructions.
Pick the tool
| Need | Choose |
|---|---|
| Simple linear “when X, do Y” across popular apps, non-technical owners | Zapier |
| Branching, loops over arrays, aggregation, fine-grained error routes, lower cost per step | Make |
| Self-hosting, data residency, version control, heavy custom code | n8n: $n8n-workflows |
| High volume (thousands of items per hour), strict ordering, complex state | Code: $data-sync-jobs or a worker |
Signals the flow has outgrown no-code: more than about 15 steps, logic duplicated across paths, hand-maintained lookup tables in Storage or Data stores, or monthly cost above what a small hosted worker would cost.
Workflow
- [ ] 1. Write the flow as a list: trigger, each step, the data each step needs
- [ ] 2. Pick trigger type (instant webhook if the app offers it, else polling)
- [ ] 3. Decide the dedup key (the source record ID) and where it is checked
- [ ] 4. Build with test data; inspect each step's input/output bundle
- [ ] 5. Add error handling: alerts, retries, a dead-letter destination
- [ ] 6. Estimate tasks/operations per month at real volume
- [ ] 7. Turn on; watch the first day of history
Turning a Zap or scenario on, or replaying history, can send emails, create records or charge cards in connected apps. Confirm with the user before enabling or replaying.
Triggers
| Type | Behaviour | Watch out for |
|---|---|---|
| Polling (Zapier “New X”, Make “Watch X”) | Checks every N minutes depending on plan; dedups by item ID | Edits to old records do not fire “new” triggers; deleted-and-recreated items fire again |
| Instant (app webhook) | Fires on the event | Apps may send duplicates or out of order |
| Catch Hook / Custom webhook | Any system can POST JSON | Validate a shared secret header or token; anyone with the URL can call it |
| Schedule | Fixed times | Runs even when there is nothing to do; add a filter |
Zapier polling dedup is keyed on the item’s id field. A custom polling trigger or code
that returns items without a stable id reprocesses everything each poll.
Zapier specifics
- Filters and Paths stop or branch a run; steps after a failing filter do not use tasks. Put filters as early as possible.
- Looping by Zapier iterates line items; each iteration’s actions count as tasks, so a 500-line order is 500+ tasks.
- Code by Zapier (JavaScript or Python) runs with tight time and memory limits that depend
on the plan. Inputs arrive as strings in
inputData; return a dict/object (or a list to fan out).
// Code by Zapier (JavaScript): normalise and build a dedup key
const email = (inputData.email || '').trim().toLowerCase();
if (!email.includes('@')) {
return { skip: 'true', reason: 'invalid email' }; // follow with a Filter on skip
}
return {
skip: 'false',
email,
dedupKey: `${inputData.source}:${inputData.orderId}`,
amountCents: Math.round(parseFloat(inputData.amount) * 100),
};
- Dedup across runs: use a “Find record” search step on the target with the dedup key, then “Create if not found” only when the app supports it; otherwise Storage by Zapier holding processed keys.
- Autoreplay retries failed steps automatically on paid plans; combined with non-idempotent actions it duplicates. Make actions idempotent before relying on it.
- Error notifications go to the account owner by default. Add an explicit error path or a separate monitoring Zap so the person who owns the process hears about it.
Make specifics
- Each module run is an operation (billed as credits on current plans). An Iterator over 200 items followed by 3 modules is about 600 operations per run.
- Aggregators close a loop: Array aggregator to build a JSON array, Text aggregator for a CSV, Numeric aggregator for sums. Set the aggregator’s “Source module” to the iterator, or it aggregates the wrong bundles.
- Routers fan out; each route has its own filter. Add a fallback route so unmatched bundles are visible, not silently dropped.
- Data stores give dedup and lookups: check “Get a record” by key before acting.
Error handler directives
Attach a handler route to the module that can fail (right-click > Add error handler):
| Directive | Effect | Use for |
|---|---|---|
| Ignore | Drops the bundle, run continues as success | Truly optional steps only |
| Resume | Substitutes fallback output, continues | Lookups with a sensible default |
| Break | Stores an incomplete execution and can retry automatically | Transient API errors (429, 5xx); needs “Allow storing of incomplete executions” |
| Rollback | Stops and reverts transactional modules | What happens when no handler is attached |
| Commit | Stops but keeps what was done | Partial progress is acceptable |
Turn on “Sequential processing” when order matters or when incomplete executions must be resolved before new ones run. Webhook-triggered scenarios queue incoming requests; watch the queue size during bursts.
Data handling
- Dates: both tools pass dates as strings; set the account and scenario time zone
explicitly and format with
formatDate/Formatter to ISO 8601 before writing to APIs. - Numbers from forms are strings; convert before maths (
parseNumberin Make, Formatter Numbers in Zapier). - Line items: map arrays to arrays. Mapping an array field into a text field joins it with commas and loses structure.
- Secrets live in connections, not hard-coded in Code steps or URLs.
Debugging a broken run
- Open the run in Zap History or the scenario’s History; find the first step whose output differs from expectation, not the step that errored.
- Copy the input bundle; reproduce the call with the same payload (curl or the app’s API docs) to see whether the app or the mapping is wrong.
- For “ran twice”: compare trigger item IDs and timestamps of both runs. Same ID means the app sent it twice (dedup needed); different IDs means two source records.
- For “missed items”: check filter conditions against the skipped item, and whether the trigger watches “new” while the user edited an existing record.
Gotchas
- Renaming a field in the source app breaks mappings with no error; the field arrives empty.
- Testing a step sends real data. Point action steps at a sandbox or a test record.
- Polling triggers can miss bursts larger than the per-poll item limit; check the app’s documented limit or use a webhook.
- A webhook URL leaked in client-side code lets anyone trigger the flow; keep it server-side.
Verification
- Feed the same test item twice: the second run is filtered out or finds the existing record.
- Force a failure (bad credential on a test connection) and confirm the alert arrives and, in Make, an incomplete execution is stored.
- Multiply per-run task or operation count by expected monthly volume and compare with the plan.
Design note template
**Flow:** Shopify order paid -> create invoice in Xero -> post to #sales
**Trigger:** Shopify instant webhook (order paid); dedup key = order ID in Data store
**Steps:** 6 modules; iterator over line items (avg 3) -> ~12 operations per order
**Volume:** ~900 orders/month -> ~10,800 operations
**Errors:** Xero 429/5xx -> Break with 3 retries; validation errors -> #ops-alerts
**Owner:** finance-ops; scenario exported blueprint stored in repo /automation/make/ What the zip contains
SKILL.md plus the interface file below. Nothing runs on install.
agents/openai.yaml
Gives the Codex app a display name, a one-line description and a starter prompt for this skill.
interface:
display_name: "Zapier and Make"
short_description: "No-code flows that do not double-fire"
default_prompt: "$zapier-make My Zap creates two HubSpot deals for some Typeform submissions, why?" About this skill
Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.