Zapier
Integrate with the Zapier Platform API to build triggers, actions, and multi-step Zaps programmatically. Configure webhooks, code steps, and authentication flows for automated workflows connecting thousands of apps.
You are an expert in the Zapier Platform CLI and REST API, building custom integrations, webhook-driven automations, and multi-step Zaps with code steps and dynamic fields. ## Key Points 1. **Missing `id` on trigger records** - Zapier deduplicates by `id`. Omitting it causes repeated triggers or missed events. 2. **Hardcoding API versions in URLs** - Pin versions in config, not scattered across request URLs. Use `bundle.authData` or constants. 3. **Ignoring `bundle.meta.isLoadingSample`** - During Zap setup, Zapier fetches sample data. Respect this flag to avoid side effects in triggers. 4. **Returning unbounded result sets** - Always limit polling trigger results to the most recent 100 items, sorted newest-first. - Connecting two SaaS apps with no native integration and needing a production-grade bridge - Building a public Zapier integration for your product's marketplace listing - Automating internal ops workflows where non-developers need to configure triggers and actions - Prototyping event-driven data pipelines before committing to a custom solution - Creating multi-step approval flows that span email, Slack, CRM, and databases
skilldb get automation-workflow-services-skills/zapierFull skill: 191 linesZapier Platform Integration
You are an expert in the Zapier Platform CLI and REST API, building custom integrations, webhook-driven automations, and multi-step Zaps with code steps and dynamic fields.
Core Philosophy
Event-Driven Automation
Zapier operates on a trigger-action model. Every Zap starts with a trigger event and chains one or more actions. Design integrations around discrete events rather than polling loops when possible. Use REST hooks for real-time responsiveness.
Data Mapping Discipline
Fields flow between steps via predictable key-value pairs. Always define explicit input/output fields with human-readable labels, help text, and sample data. Never rely on implicit field discovery in production integrations.
Idempotent Operations
Zapier may replay triggers during testing or error recovery. Every trigger must return a unique id field per record. Actions should be safe to retry without creating duplicate resources.
Setup
# Install Zapier Platform CLI
npm install -g zapier-platform-cli
# Initialize a new integration project
zapier init my-integration --template=typescript
cd my-integration
npm install
# Authenticate with Zapier
zapier login
# Key dependencies in package.json
npm install zapier-platform-core@latest
// index.ts - App definition entry point
import { version as platformVersion } from "zapier-platform-core";
const App = {
version: require("./package.json").version,
platformVersion,
authentication: SessionAuth,
triggers: { [newRecord.key]: newRecord },
creates: { [createRecord.key]: createRecord },
searches: { [findRecord.key]: findRecord },
};
export default App;
Key Patterns
Use REST Hooks Over Polling
// Do: Subscribe to webhooks for real-time triggers
const subscribeHook = async (z: ZObject, bundle: Bundle) => {
const response = await z.request({
url: "https://api.example.com/webhooks",
method: "POST",
body: { target_url: bundle.targetUrl, event: "record.created" },
});
return response.data;
};
// Don't: Poll an endpoint every 5 minutes when webhooks are available
const polling = async (z: ZObject, bundle: Bundle) => {
const response = await z.request({ url: "https://api.example.com/records" });
return response.data; // No dedup guarantee, high latency
};
Define Explicit Output Fields
// Do: Declare output fields with labels and types
const outputFields = [
{ key: "id", label: "Record ID", type: "integer" },
{ key: "email", label: "Email Address", type: "string" },
{ key: "created_at", label: "Created At", type: "datetime" },
];
// Don't: Return raw API responses without field definitions
Handle Authentication Refresh
// Do: Implement session auth with automatic refresh
const sessionAuth = {
type: "session" as const,
test: { url: "https://api.example.com/me" },
sessionConfig: {
perform: async (z: ZObject, bundle: Bundle) => {
const resp = await z.request({
url: "https://api.example.com/auth/token",
method: "POST",
body: { api_key: bundle.authData.apiKey },
});
return { sessionKey: resp.data.token };
},
},
};
Common Patterns
Custom Trigger with Deduplication
const newOrder = {
key: "new_order",
noun: "Order",
display: { label: "New Order", description: "Triggers when a new order is created." },
operation: {
type: "hook" as const,
performSubscribe: subscribeHook,
performUnsubscribe: unsubscribeHook,
perform: async (z: ZObject, bundle: Bundle) => [bundle.cleanedRequest],
performList: async (z: ZObject, bundle: Bundle) => {
const resp = await z.request({ url: "https://api.example.com/orders?limit=5" });
return resp.data.orders;
},
sample: { id: "ord_123", total: 49.99, status: "paid" },
outputFields: [
{ key: "id", label: "Order ID" },
{ key: "total", label: "Total", type: "number" },
],
},
};
Code Step in a Zap
// Zapier Code by Python or JavaScript step
// Available: inputData object, fetch for HTTP, z.console for logging
const output = [];
const response = await fetch(
`https://api.example.com/users/${inputData.userId}`
);
const user = await response.json();
output.push({ name: user.name, email: user.email });
return output;
Dynamic Dropdown Fields
const listProjects = {
key: "list_projects",
noun: "Project",
display: { label: "List Projects", hidden: true },
operation: {
perform: async (z: ZObject, bundle: Bundle) => {
const resp = await z.request({ url: "https://api.example.com/projects" });
return resp.data.map((p: any) => ({ id: p.id, label: p.name }));
},
},
};
// Reference in an action's inputFields
const inputFields = [
{ key: "project_id", label: "Project", dynamic: "list_projects.id.label", required: true },
];
Search-or-Create Pattern
const findOrCreateContact = {
key: "find_or_create_contact",
display: { label: "Find or Create Contact" },
search: "find_contact",
create: "create_contact",
};
Anti-Patterns
- Missing
idon trigger records - Zapier deduplicates byid. Omitting it causes repeated triggers or missed events. - Hardcoding API versions in URLs - Pin versions in config, not scattered across request URLs. Use
bundle.authDataor constants. - Ignoring
bundle.meta.isLoadingSample- During Zap setup, Zapier fetches sample data. Respect this flag to avoid side effects in triggers. - Returning unbounded result sets - Always limit polling trigger results to the most recent 100 items, sorted newest-first.
When to Use
- Connecting two SaaS apps with no native integration and needing a production-grade bridge
- Building a public Zapier integration for your product's marketplace listing
- Automating internal ops workflows where non-developers need to configure triggers and actions
- Prototyping event-driven data pipelines before committing to a custom solution
- Creating multi-step approval flows that span email, Slack, CRM, and databases
Install this skill directly: skilldb add automation-workflow-services-skills
Related Skills
Make Integromat
Build and manage Make (formerly Integromat) scenarios using modules, routers, webhooks, and data stores. Configure complex branching workflows with error handling, iterators, and aggregators for visual automation.
N8n
Build self-hosted and cloud workflow automations with n8n using nodes, expressions, webhooks, and code nodes. Configure credential management, error workflows, and custom node development for event-driven pipelines.
Pipedream
Build serverless event-driven workflows with Pipedream using triggers, Node.js/Python steps, and data stores. Configure HTTP endpoints, cron schedules, and app integrations with built-in authentication and state management.
Retool
Build internal tools with Retool using queries, components, transformers, and workflows. Configure resource connections, JavaScript transformers, and event-driven UI logic for admin panels and dashboards.
Superblocks
Build internal tools and workflows with Superblocks using API integrations, UI components, scheduled jobs, and permissions. Configure backend logic, frontend applications, and role-based access control for enterprise-grade admin panels.
Val Town
Create serverless functions with Val Town using vals for HTTP handlers, cron jobs, email handlers, and SQLite storage. Configure public and private vals with TypeScript, leveraging the built-in runtime for rapid API prototyping.