- TypeScript SDK
- CLI
0.85.0
- Paginated list results now expose
.pages(), a plain async iterable over pages. Unlike iterating the result directly (which still works but is deprecated),.pages()is not also a promise, so returning it from anasyncfunction no longer silently collapses it to the first page..items()is unchanged and remains the way to iterate individual items across pages. ThetoIterable()helper is deprecated in favor of.pages()and now logs a deprecation warning.
0.84.4
- Added a
slugfield (e.g."google-sheets") to connection items returned bygetConnection,listConnections,findFirstConnection, andfindUniqueConnection(and their deprecatedlistAuthentications/getAuthentication/findFirstAuthentication/findUniqueAuthenticationaliases).
0.84.3
- Dynamic parameter pickers now resume from the pagination cursor on “Load more…” instead of re-fetching the first page. This fixes duplicate items and never-ending lists in the table picker and other paginated pickers. The table picker also notes when shared tables are hidden for the account (the connections picker already did), instead of silently showing fewer tables.
0.84.2
- This release contains no user-facing changes.
0.84.1
- Internal refactor of how item-returning methods produce their
{ data }response envelope. No change to the SDK surface.
0.84.0
- Code Substrate methods now use the
/code-substrate-runnerand/code-substrate-workflowsAPI path prefixes across the SDK, the CLI, and the MCP server, andsdk.context.apiand the CLIcurlcommand accept paths built on them. The previous/sdkdurableapiand/durableworkflowzapsprefixes remain supported.
0.83.3
- The app
versionfield is now optional in.zapierrcmanifest entries. A versionless entry resolves to the latest implementation at runtime. The CLI’sbuild-manifestandaddcommands no longer error when an app has no version, writing a versionless entry instead.
0.83.2
- This release contains no user-facing changes.
0.83.1
getWorkflowandlistWorkflowsnow include a nullabledetailsfield on each trigger (e.g.webhook_urlfor catch-hook triggers). Also corrected thetrigger_urlfield description to note that requests must also be authenticated as the account.
0.83.0
-
createZapierSdk(options)is unchanged in usage; the SDK is now built entirely on the module plugin system internally.- Deprecated SDK methods now log a runtime warning when called (once per process).
- New:
disposeSdk(sdk)releases the SDK’s resources (telemetry timers, event listeners) — call it when you’re done with an SDK in a long-lived process. - New for plugin authors:
zapierSdkPlugin(the SDK’s root plugin),PluginSurface<typeof plugin>(derive a plugin’s surface type instead of hand-writing it),resolvePlugin,declareOptionalProperty,SDK_OPTIONS_ID/sdkOptionsPluginRef, explicitMethodPlugin/PropertyPlugin/AggregatePlugindescriptor types, thePluginSummary/LeafSummaryledger types andEventTransport(so a package exporting plugins can emit their inferred types in declarations), andcreateControllerwith itsController*types.
getConnectionnow requires a connection locator —connection(or a deprecatedconnectionId/authenticationIdalias) must be provided. It was previously optional in the type, with nothing sensible to fetch when omitted. Removed without a deprecation cycle (pre-1.0 break):createZapierSdkStack,createOptionsPlugin,createZapierCoreStack— usecreateZapierSdk(options), or compose module plugins withcreateSdk.dangerousContextPlugin— import the specific plugin ref you need (apiPluginRef,sdkOptionsPluginRef, …), or useresolvePluginon a built sdk.- The
authenticationIdResolver/authenticationIdGenericResolveraliases — useconnectionIdResolver/connectionIdGenericResolver.
appKeyResolver,connectionIdResolver,inputsResolver, …) are now model resolvers — bag-form callbacks whose imports bind at build — instead of objects withfetch(sdk, params)callbacks. Attach them through adefineMethod’sresolversmap; they no longer work on a legacy function plugin’smeta.resolvers.
0.82.1
.zapierrcmanifest parsing now validates each entry independently, so a single malformed entry no longer discards the entire manifest. Previously one invalidappsentry caused the whole manifest, including a validconnectionsmap, to be dropped, which could surface as a misleading “connection not found” error. Invalid entries are now dropped individually with a warning identifying the section and key.
0.82.0
- Graduated Triggers and Trigger Inbox methods from the experimental interface to the stable one. Every trigger method (
listTriggers,listTriggerInputFields,createTriggerInbox,ensureTriggerInbox,drainTriggerInbox,watchTriggerInbox, the inbox lifecycle methods, and the message lease/ack/release methods) is now available directly from@zapier/zapier-sdkand thezapier-sdkCLI — no/experimentalimport,--experimentalflag, orZAPIER_EXPERIMENTALenv var required. On the default MCP server the request/response trigger tools (create-trigger-inbox,list-triggers, the lease/ack/release tools, etc.) are now listed; the callback-drivendrainTriggerInboxandwatchTriggerInboxremain SDK/CLI-only. They stay available via the experimental subpath andzapier-sdk-experimentalbinary for backward compatibility.
0.81.1
-
Added
--callback-urltozapier-sdk loginandzapier-sdk signupfor resuming pending non-interactive OAuth flows. Non-interactive login and signup now save pending state and exit immediately; run the same command later with--callback-url <url>to complete authentication from the browser callback URL. Login and signup telemetry now includesused_non_interactive_modeandis_headlesson CLI command and auth lifecycle events.
0.81.0
- Deprecated
namein favor ofkeyfor trigger inboxes.namecontinues to work as a deprecated alias.createTriggerInboxnow accepts an optionalkeyparameter;nameis deprecated.ensureTriggerInboxnow takeskeyas its required idempotency identifier; passingnamestill works but is deprecated.listTriggerInboxesnow accepts akeyfilter; thenamefilter is deprecated.- Trigger inbox locators (the
inboxargument ongetTriggerInbox,updateTriggerInbox, and related methods) now resolve non-UUID values bykey. - Trigger inbox responses now include a
keyfield alongsidename(both hold the same value;keymay benullwhen an inbox has no natural key).
0.80.2
- Decode JSON-string
inputontriggerWorkflowandrunDurable. Theirinputfield is freeform (z.unknown()), which the CLI surfaces as a raw string flag and never JSON-parses, so--input '{"a":1}'reached the API as a string and was double-encoded (server rejected it withexpected object, received string). The input is now normalized at the schema boundary: a{/[-leading JSON string is decoded to its value, while objects and scalar strings pass through unchanged. This also fixes programmatic callers passing a JSON string.
0.80.1
- This release contains no user-facing changes.
0.80.0
- Add a resolution controller that completes a method’s partial input into a fully validated one, prompting a host only when needed (
createController), along with thedefineResolverauthoring API and cancellation signals (CoreCancelledSignal,isCoreSignal).
0.79.0
- Display trusted SDK deprecation notices from Zapier API responses. The SDK sniffs
zapier-sdk-deprecation-*response headers (never on relay responses), warns once per notice id per process — with no opt-out — and emits anapi:deprecation_noticeevent for wrappers. The CLI additionally renders notices as a boxed stderr warning after command output, and the MCP server attaches them to every tool result so agents relay the warning to users.
0.78.0
- Removed the deprecated
sdk.addPlugin(...)chain method (and theWithAddPlugintype / chain-style no-argcreateSdk()doorway). Extend a built SDK with the top-leveladdPlugin(sdk, plugin)instead. @zapier/zapier-sdknow re-exports the plugin-authoring helpers (createSdk,defineMethod/definePlugin/declareMethod/ etc.,selectExports,addPlugin). NotecreateSdkreuses the old doorway’s name but now takes a root plugin, so a stale no-argcreateSdk()call is a compile error rather than silent misbehavior.
0.77.2
- Fixed published type declarations that caused consumer TypeScript builds to fail with
Cannot find modulefor a bundled-only dev dependency. Also fixed stray per-module declarations being published underdist/src.
0.77.1
- This release contains no user-facing changes.
0.77.0
-
triggerWorkflow(andtrigger-workflow) now authenticates with Zapier credentials and runs the workflow as the authenticated account; triggering is limited to workflows that account can access. Changed thetriggerWorkflowresponse shape:The call is unchanged: pass the workflow id and optionalinput.
0.76.2
- This release contains no user-facing changes.
0.76.1
- This release contains no user-facing changes.
0.76.0
- The
./definedurable context types now match@zapier/zapier-durable: awaiting a callback created withtimeoutSecondsis typed as resolving aCallbackResult<T>—{ status: "delivered"; value; at }or{ status: "expired"; at }— instead of the bare payload. The newCallbackResultandCallbackOptionsWithTimeouttypes are exported;CallbackOptionsno longer carriestimeoutSeconds, so deadline call sites type againstCallbackOptionsWithTimeout.
0.75.0
listWorkflowRuns(andlist-workflow-runs) no longer returnoutputon list items. Workflow-run lists no longer carry the (potentially large, soon-externalized) run output; fetch a single run’s output viagetWorkflowRun/get-workflow-run. Usestatus(finished/failed) to know when output is available.
0.74.1
- Surface trigger claim failure reason and workflow disable reason on the experimental
getWorkflow/listWorkflowsresponses (and therefore theget-workflow/list-workflowsCLI commands). Eachtriggers[]entry gainserror(the latest claim’s failure reason, present whenstatusisfailed), and the workflow gains a top-leveldisabled_reason(trigger_claim_failedwhen system-disabled, otherwise null). The two signals stay independent so an enabled workflow with a failed trigger is representable. Both fields are optional.
0.74.0
- This release contains no user-facing changes.
0.73.1
- CamelCase the input params on
runDurableandpublishWorkflowVersion(sourceFiles,zapierDurableVersion,appVersions, and the nested connection / app-version / trigger fields), keeping the old snake_case names as deprecated aliases. Handlers map them back to the snake_case wire body; output fields are unchanged.
0.73.0
- This release contains no user-facing changes.
0.72.0
listWorkflowsnow paginates.pageSize(follows the SDK default page size; values above 100 are rejected) andcursorare honored in the SDK, and via thelist-workflows --page-size/--cursorCLI flags that were previously no-ops. Iterating still returns all workflows; reading a single page now yields at mostpageSizeresults rather than the full list.
0.71.1
- Rename
createWorkflow’sis_privateinput toprivateto matchrunDurable, keepingis_privateas a deprecated alias; the wire field staysis_private. Clarify therun-durableconnections param description to show the required object shape.
0.71.0
-
Add
createConnectionand two lower-level building blocks for connecting an app from code, end to end:createConnection({ app, browser?, timeoutMs?, pollIntervalMs? })— high-level: mints a connection URL, prints it (and opens it in a browser when it’s safe to do so), waits for the user to finish, and returns the new connection.browseris"auto"(default — opens locally, skips CI / SSH / headless Linux),"always", or"never". The URL is always printed, so a skipped or failed open falls back to copy/paste.getConnectionStartUrl({ app })— low-level: mints a short-lived, signed start URL bound to the current user/account. Returns{ url, startedAt, expiresAt, app }.waitForNewConnection({ app, startedAt, timeoutMs?, pollIntervalMs? })— low-level: polls until a connection for the app created at or afterstartedAtappears, then returns{ id, app, title? }. ThrowsZapierTimeoutErroraftertimeoutMs(default 5 minutes).
createConnectionis the right call for most cases. Reach for the two low-level methods when you want to hand off the URL without blocking (callgetConnectionStartUrlalone), or do something custom between minting the URL and waiting — email it, post it to Slack, render a QR code — then callwaitForNewConnection. - Add private-beta support for streaming auto-mode approval review messages and handling terminal failed approvals through the SDK and CLI. Auto mode is only enabled service-side for approved beta users.
0.70.4
- Response-field additions to experimental workflow and durable-run methods:
updateWorkflow,getWorkflow,listWorkflowsresponses now includeis_private,created_by_user_id, and (where applicable)triggerswith live claim status.publishWorkflowVersion,getWorkflowVersion,listWorkflowVersionsresponses now includetrigger,connections, andapp_versions.runDurableinput acceptsnotifications(webhook subscribers for run lifecycle events).
0.70.3
getDurableRunno longer throws whenlast_errorisnullon a successful run.
0.70.2
listActionsnow includes private and unlisted apps the caller can access; results remain access-scoped server-side.
0.70.1
- Workflow and durable-run responses no longer throw a parse error when the server returns unrecognized enum values.
0.70.0
-
watchTriggerInboxnow retries transient drain failures (5xx, 429, network blips) indefinitely with bounded backoff instead of rejecting on the first error; it still rejects immediately on fail-fast handler errors,initialization_failure, and permanent HTTP errors. When those retries persist long enough to saturate the backoff, it warns once on stderr (re-armed on recovery) so a stalled watch isn’t silent. NewApiClient.fetchJsonStream(with theJsonSseMessagetype): likefetchStreambut JSON-parses each frame, surfacing a malformed frame as{ parsed: false, data: null, raw }instead of throwing, so one bad frame can’t kill a long-lived stream. A non-ok response still throws the sharedZapierErrorsubclasses before the first frame. Fixed: a fail-fast handler that throws a falsy value (throw undefined) is no longer silently swallowed, and a handler-thrown AbortError now rejects the watch instead of resolving it cleanly.
0.69.3
- Restored
connections,app_versions, andtriggerinput fields onpublishWorkflowVersion(experimental) that were unintentionally dropped in a prior release, leaving workflows unable to bind connection aliases or wire a trigger. Shape: connections as{alias: {connection_id: ...}}, app_versions as{alias: {implementation_name, version?}}, trigger as a nested object withselected_api+actionrequired.
0.69.2
- Fixed logout so it reliably clears local authentication state even when the server cannot revoke the credential. Previously a failed revocation could abort logout and strand the user with credentials they could not remove. Re-login flows are unaffected; they still surface revocation failures before replacing credentials.
0.69.1
- Fix paginated list results silently truncating to page 1 when the same result is consumed twice (iterating pages then
.items(),.items()then pages, or iterating either one twice). Pages and items are now two views over one page stream, so consuming either drains the other: the second view yields nothing instead of silently replaying page 1. A paginated result is consumed once; call the method again for a fresh result. Awaiting the result to read just the first page is unaffected: it is a repeatable peek that does not start the stream, so awaiting and then iterating still works.
0.69.0
- Switched
watchTriggerInboxfrom backoff polling to a Server-Sent Events subscription, so it now wakes on near-real-time inbox notifications instead of repeatedly polling for new messages.- The
maxDrainIntervalSecondsoption now controls a periodic safety drain that backstops the SSE stream — guaranteeing forward progress if events are missed or the connection drops — and its default changed from 60 to 300 seconds. - Real-time wake-up health is now reported on stderr: a warning when wake-ups pause and the watch falls back to the safety drain, plus transient reconnect notices in debug mode. stdout (including
--jsonNDJSON output) is unaffected. - Added a
fetchStreammethod to the API client, along with an exportedSseMessagetype, for opening Server-Sent Events connections through the standard request pipeline (auth, base URL, 429 retry, approval, and concurrency).
- The
0.68.1
- This release contains no user-facing changes.
0.68.0
- Added
zapier-sdk signupfor browser-based account setup and local SDK credential provisioning.
0.67.0
-
New stack-based composition surface for building on top of the SDK:
createZapierSdkStack(options)(from the root and/experimental) returns the unsealedPluginStackthatcreateZapierSdkmaterializes, andcreatePluginStack,createCorePlugin, andaddPluginare re-exported from the root. Build by chaining.use(...)and sealing with.toSdk(), or extend a sealed SDK in place withaddPlugin(sdk, plugin). The chain-stylecreateSdk().addPlugin(...)pattern is deprecated (now logs a one-time warning) but still works. One behavior change:normalizeErrorno longer wraps thrownErrorsubclasses, so a handler’sTypeErroror a userlandMyAppErrorbubbles through unchanged andinstanceofworks again; only non-Errorthrows get wrapped. -
Route all debug, diagnostic, and telemetry log output to stderr (
console.error) instead of stdout (console.log) across the SDK and CLI packages. The CLI now reserves stdout exclusively for the program’s data payload — command output, JSON envelopes, response bodies — so callers can safely pipe CLI output throughjq,> redirect, orJSON.parseeven when--debugis on or telemetry/logging flags are enabled. Interactive terminal users see no change since both streams interleave in a TTY.
0.66.0
- Added
triggerWorkflow(experimental) to fire a workflow’s trigger with a user-supplied JSON payload. Only available via@zapier/zapier-sdk/experimental. The workflow id is UUID-validated at the input boundary; trigger endpoint failures (non-2xx, or workflow with no published version) surface as descriptive errors. - Limit approval polling waits to at most 5 seconds while preserving the existing generic polling cadence.
- Route
--debuglog output to stderr (console.error) instead of stdout (console.log) inauth.tsandapi/debug.ts. This restores stdout’s Unix contract — stdout carries only the program’s data payload — so callers can safely pipe CLI output throughjq, redirect to a file, orJSON.parseit even when--debugis on. Debug output still appears in CI logs and developer terminals (both streams interleave there).
0.65.0
- Added
listWorkflowRuns,getWorkflowRun, andgetTriggerRun(experimental). All three live behind@zapier/zapier-sdk/experimentalonly — the stable subpath does not surface them.listWorkflowRunsis paginated;getWorkflowRunlooks up a run by id;getTriggerRunwalks from a trigger id to its associated run, useful immediately after firing a trigger when the caller has the trigger id but not yet the run id. All ID inputs are UUID-validated at the schema boundary. Consumers see any richer fields the server adds without an SDK release.
0.64.0
- Added
publishWorkflowVersion,listWorkflowVersions, andgetWorkflowVersion(experimental). All three are registered only in@zapier/zapier-sdk/experimental; the stable subpath does not expose them.listWorkflowVersionsis paginated (cursor + pageSize);publishWorkflowVersiontakessource_files(filename → contents) plus optionaldependencies,zapier_durable_version, andenabled(defaults to true);getWorkflowVersionreturns the full version state including source files. Callers see any richer fields the server adds later without an SDK release. All ID inputs are UUID-validated so non-UUID strings fail with a clear schema error.
0.63.0
- Added
runDurableandcancelDurableRun(experimental). Both are registered only in@zapier/zapier-sdk/experimental; the stable subpath does not expose them.runDurabletakessource_files(filename → contents) plus optionalinput/dependencies/zapier_durable_version/connections/app_versions, and aprivateflag; returns the run ID immediately ininitializedstatus — callers that need terminal status poll viagetDurableRun; no built-in polling.cancelDurableRunreturns{ id, status: "cancelled" }on success, and propagatesZapierNotFoundError(404) andZapierConflictError(409 — run already terminal) so callers can distinguish those outcomes.
0.62.0
- Added
listDurableRunsandgetDurableRun(experimental). Both are registered only in@zapier/zapier-sdk/experimental; the stable subpath does not expose them.listDurableRunsis paginated (cursor + pageSize);getDurableRunreturns the full run state with nested execution and operations journal. Callers see any richer fields the server adds later without an SDK release. The run id input is UUID-validated so non-UUID strings fail with a clear schema error.
0.61.0
-
Added
createWorkflow,updateWorkflow,enableWorkflow,disableWorkflow, anddeleteWorkflow(experimental). All five are registered only in@zapier/zapier-sdk/experimental; the stable subpath does not expose them.deleteWorkflowrequires explicit confirmation before the destructive call. The workflow id input is UUID-validated so non-UUID strings fail with a clear schema error. Callers see any richer fields the server adds later without an SDK release. -
Fix login/logout reliability bugs.
Bug fixes:
logoutnow warns and still clears local keychain/registry state when the server returns 401 during revocation (404 is still silently swallowed; 401 is surfaced as a console warning so users know to verify or revoke the credential manually if needed)- Re-login no longer fails with “already exists” when a locally-orphaned registry entry has the same name as the desired new credential
logoutno longer prompts for confirmation before deleting credentials; it always proceeds immediately, which also fixes hangs in non-TTY/CI environments
--skip-promptsonloginandinitis deprecated in favour of--non-interactive. The old flag continues to work with a deprecation warning.
0.60.0
- Added
listWorkflowsandgetWorkflow(experimental). Both are registered only in@zapier/zapier-sdk/experimental; the stable subpath does not expose them.listWorkflowsis paginated withpageSize/cursor/maxItemsoptions so callers can iterate viafor await (const page of sdk.listWorkflows())ortoIterable(sdk.listWorkflows()).
0.59.0
- This release contains no user-facing changes.
0.58.0
- Export
eventEmissionPlugin(and its config/cleanup helpers) from the package root so consumers can compose their own SDK withcreateSdk. The plugin’s existing helpers and types are now exposed via the plugin module itself instead of being re-listed in the SDK index.
0.57.0
- Added a
trashoption tolistTableRecordsandlistTableFieldsfor controlling soft-deleted item visibility. Accepts"exclude"(default, active items only),"include"(active and soft-deleted), or"only"(soft-deleted items only).
0.56.2
- This release contains no user-facing changes.
0.56.1
- Clarified the
releaseOnErroroption description fordrainTriggerInboxandconsumeTriggerInbox: errors release the message when the drain finishes, not immediately.
0.56.0
- Allow opting into approvals during login
0.55.0
-
Add
hint?: string | string[]toPromptConfig.choices. The CLI renders it after the choice’snameas dimmed parens; an unsethintwith a primitivevalueauto-renders the value. All built-in resolvers migrate to the new shape, so existing dropdowns get small visual cleanups (dim parens, noID:prefix, dash converted to parens, em-dash intableRecordIdgone). Plugin authors who embed the value inname(e.g."Foo (${id})") should drop the embedded parens; the auto-default appends a second otherwise.
0.54.1
- Add optional
nameparameter tocreateTriggerInboxmethod
0.54.0
-
Add type-to-filter to interactive single-select dropdowns: dynamic resolvers (apps, connections, tables, table records, etc.) and SELECT-format field choices.
(Load more...)remains reachable even when a search yields zero matches, so users can pull the next page and try again. Dynamic resolvers also gain aninputType: "search"mode: the CLI prompts for free-form text, hands it tofetchassearch, and either short-circuits on a primitive return (exact match) or renders results as a search-filterable dropdown. Empty results expose(Use "foo" as-is)and(Try a different search)so a required parameter can never strand the user. The built-inappKeyresolver now uses this mode (getAppfor exact match,listApps --searchfor fallback).DynamicResolveris now a discriminated union ofDynamicListResolverandDynamicSearchResolver. Note for plugin authors: theplaceholderfield is now typed asneveron the list variant, so a classic list resolver that was previously setting an unusedplaceholderwill see a TypeScript error. Move it into a search-mode variant (inputType: "search") or drop it — the CLI never read it on list resolvers.
0.53.0
- Trigger inbox fixes and additions:
- Send
connection_id: nullfor trigger inboxes without a connection so connection-less apps (e.g. tables) work correctly. - Add
listTriggers, a read variant oflistActionsthat lists an app’s triggers. - Add interactive resolvers to trigger inbox message methods:
ackTriggerInboxMessagesandreleaseTriggerInboxMessagesprompt formessageswith a multi-select of leased messages;leaseTriggerInboxMessagesprompts forleaseLimitandleaseSeconds. - CLI: coerce static prompt input to the schema’s underlying type so numeric/boolean fields (e.g.
leaseLimit,leaseSeconds) no longer fail Zod validation with “expected number, received string”.
- Send
0.52.0
- Add a configurable concurrency limit so the SDK queues requests beyond
maxConcurrentRequests(FIFO) instead of firing them all at once. Default is 200. Configurable via thecreateZapierSdk({ maxConcurrentRequests })option or theZAPIER_MAX_CONCURRENT_REQUESTSenv var (the option wins). PassInfinityto disable. Slots are held across 429 retries (so server backoff isn’t undermined by extra parallelism) but released as soon as response headers arrive — streaming responses (SSE, long-running chunked reads) do not pin a permit for the lifetime of the body. Queued acquires respectAbortSignal. Queued requests emitapi:concurrency_wait_start/api:concurrency_wait_endevents for diagnostics.
0.51.0
- Default SDK auth to client credentials
- Updated the experimental Triggers notice in all three package READMEs to clarify that the feature is in closed beta, with a link to contact us for access.
0.50.0
-
Collapse the approval-flow surface into a single tri-state
approvalModeoption. What changed:approvalModeis now"disabled" | "poll" | "throw"(was"poll" | "fail")."disabled"is the default. While the approval flow is alpha, callers must opt in explicitly viaapprovalMode: "poll"orapprovalMode: "throw"(or theZAPIER_APPROVAL_MODEenv var). On an approval-required response,"disabled"throws aZapierApprovalErrorwithstatus: "approval_required"without creating an approval.- The
isInteractiveSDK option and theZAPIER_IS_INTERACTIVEenv var have been removed. Their role is subsumed byapprovalMode: choosing"poll"/"throw"is the explicit opt-in that previously requiredisInteractive: true. "fail"has been renamed to"throw"(both the option value and theZAPIER_APPROVAL_MODEenv var value). The behavior is unchanged: throw aZapierApprovalErrorcarrying the approval URL so the caller can surface it.approvalMode,approvalTimeoutMs, andmaxApprovalRetriesare now part of the public API (no longer markedinternal: true).
approvalMode: "fail"andisInteractive: <anything>will fail Zod validation up front.
0.49.0
- Add experimental support for triggers.
0.48.1
- This release contains no user-facing changes.
0.48.0
-
Adds an extension mechanism that lets the CLI and MCP server load additional plugin packages at runtime. Set
ZAPIER_SDK_EXTENSIONSto a comma-separated list of package specifiers, or pass them via the newextensionsoption — methods they contribute show up automatically as CLI commands and MCP tools, no per-project wiring required. When a plugin tries to register a method, context field, or meta entry that’s already registered by another plugin in the chain,addPluginnow logs a warning and skips the duplicate plugin’s contribution rather than silently overwriting. This catches the common foot-gun of an extension accidentally shadowing a built-in SDK method. Intentional duplicates can be expressed viacomposePlugins(...), and meta-only overrides (e.g. tagging a built-in method as deprecated) continue to work unchanged.
0.47.1
- The approval
poll_urlandapproval_urlorigin checks are now skipped whenbaseUrl(orZAPIER_BASE_URL) points atlocalhost/127.0.0.1, so local development works without origin validation errors.
0.47.0
- Add
composePlugins(...subPlugins)for bundling N plugins into a singlePlugin<TSdk, TProvides>so a consumer can calladdPlugin(combined)once. Bag-mode composition: throws on duplicate root keys or duplicatecontext.metakeys, intersects each sub-plugin’s TSdk requirements, and flows through the existing single-pluginaddPluginwithout the type-widening an array overload would impose.
0.46.2
- This release contains no user-facing changes.
0.46.1
- Removed custom error handlers and added definePlugin, createPluginMethod, and createPaginatedPluginMethod to reduce plugin boilerplate.
0.46.0
- Rename the client credentials persistence seam from storage to cache and expose the CLI filesystem/keychain adapter as a best-effort cache.
0.45.2
- Convert API query params from camelCase to snake_case (
appKeys→app_keys,pageSize→page_size) to match the updated API contract.
0.45.1
- This release contains no user-facing changes.
0.45.0
registryPluginis now deprecated, becausegetRegistryis built into the SDK and added after each plugin is added. Plugins will always be registered; there is no need to callcreateZapierSdkWithoutRegistry, add custom plugins, and then.addPlugin(registryPlugin). Because of this,createZapierSdkWithoutRegistryis now deprecated, and calling it will still give you an SDK withgetRegistryon it. CallingaddPlugin(registryPlugin)on that SDK is a no-op.
0.44.0
- Allow UUID connection IDs in the
.zapierrcconnections map.ConnectionEntrySchema.connectionIdnow accepts either a positive integer (legacy form) or a UUID-format string (returned by the Zapier connections API for newer connections).
0.43.0
- Add an experimental interactive approval flow for policy-gated actions. When an action requires approval, the SDK detects the
approval_requiredresponse, prompts for approval in interactive sessions, and automatically retries the original request once approved. Non-interactive sessions receive a clear error explaining that approval is required. This flow is experimental and its behavior may change in future releases.
0.42.1
- Simplify plugin system: plugins now receive sdk as a positional parameter with context at sdk.context. The Plugin type takes 2 generics (input SDK shape, output provides) instead of 3. Context is shallow-frozen to prevent reassignment of top-level properties. createSdk() is now zero-arg; SDK options are injected via createOptionsPlugin(options) through addPlugin like any other state. Plugins that need options declare it as an explicit context dependency. The addPluginOptions second argument to addPlugin has been removed.
0.42.0
- Support maxTime for SDK fetch & CLI curl - Relay extended timeout
0.41.2
- Fix connection resolution for no-auth apps
0.41.1
formatErrorMessagenow rendersZapierRateLimitErrordetails (limit used, time until retry, retry count) instead of just the bare “Rate limited” message. CLI, MCP, and any consumer usingformatErrorMessagenow surface which rate-limit window tripped and how long until it resets.
0.41.0
- Prefer public IDs over numeric IDs in responses
0.40.4
- Replace Node-only imports (timers/promises, os) with browser-safe alternatives and add browser compatibility test suite
0.40.3
- Connections - Replace isExpired with expired
0.40.2
- Make sure CLI only shows non-deprecated positional parameters.
0.40.1
Several top-level method options were renamed so flexible resource references use suffix-less names (app instead of appKey, connection instead of connectionId, and so on). The values you pass are the same as before—slugs, implementation keys, versioned IDs, connection aliases, numeric IDs, and other supported forms. The goal is one obvious parameter per resource and less ambiguity between *Key and *Id now that parameters like connection already accept multiple identifier styles.Note: This is not a breaking change. The old parameter names still work; they are deprecated.