Documentation Index
Fetch the complete documentation index at: https://docs.zapier.com/llms.txt
Use this file to discover all available pages before exploring further.
"@zapier/zapier-sdk/experimental" to use these
methods. For the CLI, run commands via the zapier-sdk-experimental binary,
pass --experimental to zapier-sdk, or set ZAPIER_EXPERIMENTAL=true in
the environment. Methods and behavior may change between versions.(app, action, connection, inputs) combination. Zapier handles the subscription and buffers incoming events. Your code leases messages from the inbox and processes them at its own pace.
CLI and SDK, complementary by designThe CLI is the fastest way to explore: find the right action key, inspect what inputs a subscription needs, create a trigger inbox, and interactively test it before writing any code. For scripting and one-off runs, the CLI alone may be enough.
When you need a production-grade consumer (a typed handler, a long-running process with graceful shutdown, an AI agent reacting to events in code), reach for the TypeScript SDK. Everything you explored with the CLI transfers directly.
Prerequisites
Install and authenticate the CLI as shown in the quickstart. Experimental entry point — import from@zapier/zapier-sdk/experimental to access Triggers. The factory is the same createZapierSdk you already know:
Key Concepts
Trigger — emits events when something happens in a connected app. Every integration defines its own triggers with their own action keys. UselistTriggers to discover what a specific app supports.
Trigger Inbox — a server-side subscription you register for a specific (app, action, connection, inputs) combination. Zapier connects to the app and buffers incoming events for you.
Inboxes move through a small lifecycle:
initializing(Zapier is setting up the subscription)active(collecting events)paused(collection stopped, buffered messages preserved)deleting(scheduled for removal)initialization_failure(setup failed; checkpaused_reason)
id, created_at, status, a payload with the raw event data from the app, and message_attributes with lease_count (how many times it’s been leased), error_message (last processing error), and possible_duplicate_data (flag if deduplication wasn’t possible).
Lease and ack — messages are leased (hidden from other consumers) while you process them, then acked (permanently removed) when processing succeeds. If your handler throws, the message returns to the available pool when the lease expires. drainTriggerInbox and watchTriggerInbox manage leasing, acking, and retries for you automatically.
Walkthrough: Subscribe to Slack messages
Step 1: Discover triggers for an app
listTriggers returns all triggers available for an app. The key field is what you pass as action when creating an inbox.
TypeScript SDK
CLI
Step 2: Inspect a trigger’s required inputs
UselistTriggerInputFields to see what inputs the subscription requires. These define the scope of events that get buffered — for example, which Slack channel to watch.
TypeScript SDK
CLI
key values are what you’ll pass as inputs when creating the inbox.
Step 3: Ensure an inbox
ensureTriggerInbox is generally recommended for production use: it’s idempotent on name, so restarting your process or re-deploying doesn’t create duplicate subscriptions. Use createTriggerInbox only when you want a throwaway inbox with an auto-generated name.
TypeScript SDK
CLI
Step 4: Drain messages once
drainTriggerInbox leases all currently-available messages, calls your onMessage handler for each, and resolves when the inbox is empty (or maxMessages is reached). Right for one-shot processing: a cron job, a script, or a webhook handler.
TypeScript SDK
message object including message.payload (the raw event data). Return from the handler to ack the message; throw to trigger release or retry behavior.
Key options:
--max-messages/maxMessagescaps how many to drain.--concurrency/concurrencyruns multiple handlers in parallel.--release-on-error/releaseOnErrorreleases failed messages when the drain finishes, instead of waiting for the full lease timeout.
CLI
--exec-shell instead when you need shell features like pipes, redirects, or env expansion (e.g. --exec-shell "./handler | jq .payload").
Refer to the Triggers CLI reference for the full list of options.
Step 5: Watch continuously
watchTriggerInbox wraps drainTriggerInbox in a poll loop with backoff. It runs indefinitely, draining whenever messages are available and backing off when the inbox is empty. Use it for long-running services (e.g. a server-side consumer/worker, or a CLI tool that runs continuously).
TypeScript SDK
AbortController gives you clean shutdown: aborting cancels in-flight HTTP requests, releases unprocessed messages back to the inbox, and resolves the call rather than rejecting it. Hook it to SIGTERM and SIGINT so your process shuts down gracefully.
Run under a process supervisor — for production, keep the watcher alive across crashes and reboots with a supervisor like pm2, systemd (Linux), launchd (macOS), or brew services (macOS, dev). Configure the supervisor to send SIGTERM on stop so the shutdown handling above runs cleanly.
CLI
--max-drain-interval-seconds caps the backoff between empty-inbox polls (default: 60s). --exec and --exec-shell work the same as in drain-trigger-inbox.
Refer to the Triggers CLI reference for the full list of options.
Under the hood: lease, ack, release
drainTriggerInbox and watchTriggerInbox compose three lower-level operations that are worth understanding when debugging unexpected behavior:
Lease — leaseTriggerInboxMessages reserves a batch of messages for a configurable lease window (see the Triggers API reference for defaults and limits). While leased, messages are hidden from other consumers. message_attributes.lease_count increments each time a message is leased.
Once lease_count reaches 5, the message transitions to quarantined. Quarantined messages are no longer returned via lease, drain, or watch, but they remain visible in listTriggerInboxMessages output. Quarantine is a fail-safe for the experimental period: if a bug causes processing to fail at scale, we can identify the cause, fix it, and clear leases server-side. There is no end-user mechanism to recover a quarantined message today, so design your handlers to drop known-bad messages before they hit the threshold (see Ack-to-drop poison messages below).
Ack — ackTriggerInboxMessages permanently removes messages from the inbox. The drain/watch API acks automatically when your handler returns without throwing.
Release — releaseTriggerInboxMessages returns messages to the available pool before the lease expires. Use it when you want to give up on a batch early without waiting for timeout.
Ack-to-drop poison messages — if a message keeps failing for reasons your handler can detect (malformed payload, missing required field, repeated upstream error), check message.message_attributes.lease_count and explicitly ack it to remove it from the inbox before it quarantines. Pairs well with continueOnError: true, so one bad message doesn’t reject the whole drain.
Control-flow signals from onMessage give fine-grained control without rejecting the entire drain:
- Throw
ZapierReleaseTriggerMessageSignalto release just this one message and continue draining. - Throw
ZapierAbortDrainSignalto finish the current batch, then resolve the drain cleanly.
releaseOnError: true — by default, when onMessage throws, the message stays leased until the timeout. Pass releaseOnError: true to release it when the drain finishes instead, so it becomes available for re-processing without waiting out the full lease.
continueOnError: true — by default, the first handler error rejects the entire drain (fail-fast). Pass continueOnError: true to keep draining: handler errors are routed to an optional onError(error, message) observer, and the message is then released-or-left per releaseOnError. SDK-level errors (lease/ack/release HTTP failures) still reject regardless. On the CLI, the equivalent flag is --continue-on-error.
leaseTriggerInboxMessages, ackTriggerInboxMessages, releaseTriggerInboxMessages), see the Triggers API reference.
Inbox management
List inboxes — find inboxes by status or name:TypeScript SDK
CLI
Pause and resume — pausing stops event collection without discarding buffered messages. Resuming restarts it.
TypeScript SDK
CLI
Delete — marks the inbox for deletion and cancels the server-side subscription:
Update — currently only
notificationUrl can be updated on an existing inbox:
Push instead of poll: notificationUrl
By default, watchTriggerInbox polls for messages with exponential backoff. If you’re operating a server with a public endpoint, pass notificationUrl when creating the inbox. Zapier will POST to that URL whenever new messages arrive, so you can call drainTriggerInbox on-demand instead of running a continuous poll loop.
TypeScript SDK
CLI
drainTriggerInbox to process the buffered messages. This eliminates polling delay and is the right pattern when minimizing latency matters.
Next Steps
- Triggers API reference — full parameter docs for every trigger method
- CLI reference — all
zapier-sdk-experimentalcommands - Deploy with client credentials — run your trigger consumer in production without a browser login
- Give feedback — your input shapes what we build next