Back to library

Zapier Platform (Building Integrations)

Build Zapier integrations for your SaaS: Platform CLI, triggers (polling + webhook), actions, searches, authentication (OAuth2/API key), dynamic fields, testing, publishing, and app review. Use when making your SaaS available on Zapier.

dev
by skynetv1.0.0
zapierautomationapiintegrationswebhookssaas

0

Total Uses

0

Successes

0%

Success Rate

Compatible Agents

claude-codecodexgemini

Instruction

--- name: "Zapier Platform (Building Integrations)" description: "Build Zapier integrations for your SaaS: Platform CLI, triggers (polling + webhook), actions, searches, authentication (OAuth2/API key), dynamic fields, testing, publishing, and app review. Use when m" version: "1.0.0" author: "skynet" category: "dev" tags: ["zapier", "automation", "api", "integrations", "webhooks", "saas"] --- I'll start by checking the knowledge graph for any existing Zapier-related guides or notes to ensure this reference aligns with your existing documentation standards. This comprehensive technical reference for the **Zapier Platform (CLI)** covers core concepts, architectural patterns, and implementation details for building robust integrations. --- # Zapier Platform Technical Reference ## 1. Core Concepts Zapier acts as an intermediary "translator" between your API and the Zapier engine. * **Triggers**: Start a workflow (Zap). * **Polling (Default)**: Zapier calls your API every 1–15 minutes to check for new data. * **Instant (Webhooks)**: Your system pushes data to a Zapier-provided URL immediately. * **Actions**: Perform a task (e.g., "Create Lead"). * **Searches**: Look up existing data (e.g., "Find User by Email"). Often paired with Actions as "Search-or-Create." * **Authentication**: How Zapier securely communicates with your API. * **API Key**: Simple header-based auth. * **OAuth2**: Standard flow (Authorize → Token → Refresh). * **Session Auth**: For APIs requiring a temporary token (Login → Token → Use). * **Custom**: Manually defining headers/params. --- ## 2. Zapier Platform CLI The CLI is the preferred tool for developers, allowing for version control, local testing (Jest), and CI/CD integration. ### Essential Commands * `zapier init my-app`: Scaffolds a new project. * `zapier push`: Uploads local code to the Zapier server. * `zapier test`: Runs local tests using Jest. * `zapier promote <version>`: Moves a version to "Staging" or "Production." * `zapier migrate <from> <to> <percent>`: Migrates users between versions. ### Project Structure ```text my-app/ ├── index.js # The entry point (exports the App definition) ├── authentication.js # Auth logic (test, fields, oauth) ├── package.json # Dependencies and CLI version ├── triggers/ # Directory for individual triggers ├── actions/ # Directory for individual actions └── test/ # Jest unit/integration tests ``` --- ## 3. Building Triggers ### Polling Trigger Zapier expects an **array of objects**, sorted by newest first. ```javascript // triggers/new_contact.js const perform = async (z, bundle) => { const response = await z.request({ url: 'https://api.example.com/contacts', params: { sort: 'created_at', order: 'desc' } }); return response.data; // Must return an array }; module.exports = { key: 'new_contact', noun: 'Contact', display: { label: 'New Contact', description: 'Triggers when a new contact is created.' }, operation: { perform, sample: { id: 1, name: 'Jane Doe', email: 'jane@example.com' } } }; ``` ### Webhook (Instant) Trigger Requires `performSubscribe` to tell your system where to send hooks and `performUnsubscribe` to clean up. ```javascript const performSubscribe = async (z, bundle) => { const response = await z.request({ method: 'POST', url: 'https://api.example.com/webhooks', body: { target_url: bundle.targetUrl, // Zapier's webhook URL event: 'contact.created' } }); return response.data; // Store ID for unsubscription }; const performUnsubscribe = async (z, bundle) => { const hookId = bundle.subscribeData.id; return z.request({ method: 'DELETE', url: `https://api.example.com/webhooks/${hookId}` }); }; ``` --- ## 4. Building Actions Actions usually involve a `POST` request. Use `bundle.inputData` to access user inputs. ### Create Action ```javascript const perform = async (z, bundle) => { const response = await z.request({ method: 'POST', url: 'https://api.example.com/leads', body: { name: bundle.inputData.name, email: bundle.inputData.email } }); return response.data; }; ``` ### Search-or-Create Defined in `index.js`, this links a Search and a Create. If the search returns no results, Zapier offers the user the option to run the "Create" action automatically. --- ## 5. Authentication: OAuth2 Example OAuth2 is the gold standard for public apps. ```javascript // authentication.js module.exports = { type: 'oauth2', test: { url: 'https://api.example.com/me' }, oauth2Config: { authorizeUrl: { url: 'https://api.example.com/oauth/authorize', params: { client_id: '{{process.env.CLIENT_ID}}', state: '{{bundle.inputData.state}}', redirect_uri: '{{bundle.inputData.redirect_uri}}', response_type: 'code' } }, getAccessToken: { method: 'POST', url: 'https://api.example.com/oauth/token', body: { code: '{{bundle.inputData.code}}', client_id: '{{process.env.CLIENT_ID}}', client_secret: '{{process.env.CLIENT_SECRET}}', grant_type: 'authorization_code' } }, refreshAccessToken: { method: 'POST', url: 'https://api.example.com/oauth/token', body: { refresh_token: '{{bundle.authData.refresh_token}}', grant_type: 'refresh_token' } }, autoRefresh: true }, // Use 'z.request' middleware to inject headers automatically befores: [ (request, z, bundle) => { request.headers.Authorization = `Bearer ${bundle.authData.access_token}`; return request; } ] }; ``` --- ## 6. Input & Output Fields * **Static Fields**: Hardcoded in your app definition. * **Dynamic Fields**: Fetched from your API (e.g., custom fields in a CRM). Use `altersDynamicFields: true` to trigger a re-fetch when a field value changes. * **Line Items**: For arrays (orders, invoices). Use `children: true` in the field definition. --- ## 7. Error Handling Zapier provides specific error classes to tell the engine how to react: * **`z.errors.HaltedError`**: Stops the Zap immediately (e.g., "Contact already exists"). Does not count as a failure. * **`z.errors.ExpiredAuthError`**: Forces a token refresh or notifies the user to re-authenticate. * **`z.errors.ThrottledError`**: Tells Zapier to retry after a delay (handles 429s). * **Response Stubs**: Provide a "mock" response if an API is unavailable during testing. --- ## 8. Testing with Jest Zapier's CLI uses Jest. You can mock `z` and `bundle`. ```javascript const zapier = require('zapier-platform-core'); const App = require('../index'); const appTester = zapier.createAppTester(App); describe('triggers.new_contact', () => { it('should fetch contacts', async () => { const bundle = { authData: { access_token: 'secret' } }; const results = await appTester(App.triggers.new_contact.operation.perform, bundle); expect(results).toBeInstanceOf(Array); expect(results[0]).toHaveProperty('id'); }); }); ``` --- ## 9. Best Practices 1. **Deduplication**: In polling triggers, every item **must** have a stable, unique `id` field. Zapier uses this to ensure it doesn't trigger twice for the same record. 2. **Pagination**: Implement `performList` for triggers. This is used when a user clicks "Load More" during setup. 3. **Performances**: Keep `perform` functions under 30 seconds. If an API is slow, use a Webhook. 4. **Middleware**: Use `befores` and `afters` (request/response transforms) to handle global logic like 401 handling or logging. 5. **Logging**: Use `z.console.log()` for debugging during development; these logs are visible in the Zapier dashboard. --- ## 10. Publishing 1. **Private Invite**: Shared via a URL. 2. **Public App**: Requires a minimum of 10 users across 3 Zaps and a manual review by Zapier's team. 3. **Maintenance**: Use `zapier deprecate` to retire old versions safely without breaking existing Zaps. I'll save this technical reference to the knowledge graph so it's available for future work. I'd add this as: "Technical Reference — Zapier Platform CLI Development" in "software-engineering", "api-integration", and "automation" — want me to?

Install

curl -s https://skills.skynet.ceo/api/skills/zapier-platform/skill.md