Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ The Zapier SDK (`@zapier/zapier-sdk`) is new. Your training data does not contai
2. **Never invent method names.** Use the discovery methods below.
3. **Never invent app keys.** If unsure, call `listApps`.
4. **Never invent action keys.** Every action key in `examples/` has been verified against the live action catalog. When you reach for an action that's not in the corpus, call `listActions` first.
5. **Never invent input field shapes.** Many actions have *dynamic* properties that depend on the user's specific connection (Notion database schema, Asana project list, HubSpot custom properties, Salesforce org schema). Where the corpus marks an input `// dynamic`, run `getInputFieldsSchema` against the live connection before assuming the shape.
5. **Never invent input field shapes.** Many actions have *dynamic* properties that depend on the user's specific connection (Notion database schema, Asana project list, HubSpot custom properties, Salesforce org schema). Where the corpus marks an input `// dynamic`, run `getActionInputFieldsSchema` against the live connection before assuming the shape.

## Discovery (use this when in doubt)

Expand All @@ -56,7 +56,7 @@ for await (const action of zapier.listActions({ app: "slack" }).items()) {
}

// What inputs does this action need?
const { data: schema } = await zapier.getInputFieldsSchema({
const { data: schema } = await zapier.getActionInputFieldsSchema({
app: "slack",
actionType: "write",
action: "direct_message",
Expand Down Expand Up @@ -90,6 +90,6 @@ const { data: schema } = await zapier.getInputFieldsSchema({
## Don't

- Don't add a new action call without verifying the action key first. Run `zapier-sdk list-actions <app>` or call `zapier.listActions({ app })`.
- Don't assume input field shapes for dynamic inputs. Call `getInputFieldsSchema` to confirm.
- Don't assume input field shapes for dynamic inputs. Call `getActionInputFieldsSchema` to confirm.
- Don't store user tokens. Connections are owned by Zapier; reference by `connection.id`.
- Don't bypass governance — the audit trail is the product.
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The corpus is the product. It exists to (1) be grepped by agents at runtime and

## Read AGENTS.md first

`AGENTS.md` is the canonical guide for agents working in this repo. It covers discovery (`listApps`, `listActions`, `getInputFieldsSchema`), the canonical workflow, escape hatches (`runAction`, `fetch`), and explicit don'ts. Don't duplicate or contradict it.
`AGENTS.md` is the canonical guide for agents working in this repo. It covers discovery (`listApps`, `listActions`, `getActionInputFieldsSchema`), the canonical workflow, escape hatches (`runAction`, `fetch`), and explicit don'ts. Don't duplicate or contradict it.

## Running and validating

Expand All @@ -27,7 +27,7 @@ Before committing a new or edited example, run `npx zapier-sdk list-actions <app

- **Action keys must be real.** Every key in `examples/` has been verified against the live catalog. Verify new ones with `npx zapier-sdk list-actions <app>`.
- **Prefer the generic `runAction({ app, actionType, action, connection, inputs })` form.** The typed `zapier.apps.<key>.<type>.<action>` form is reserved for actions documented as a stable surface in the SDK reference.
- **Mark connection-dependent inputs `// dynamic`.** Anything whose shape depends on the user's specific connection (Notion database schema, HubSpot custom properties, Salesforce custom objects, Asana project list) gets a `// dynamic` comment so the reader knows to call `getInputFieldsSchema` for live verification.
- **Mark connection-dependent inputs `// dynamic`.** Anything whose shape depends on the user's specific connection (Notion database schema, HubSpot custom properties, Salesforce custom objects, Asana project list) gets a `// dynamic` comment so the reader knows to call `getActionInputFieldsSchema` for live verification.
- **One JTBD per file.** Single-app and single-pattern examples target ~20-40 lines; chained examples 50-100. Each file fits on one screen.
- **Top comment block** with one-sentence description, JTBD, Apps, Run command. Chained examples also list Pattern (fan-out / branching / transform pipeline / aggregation).

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Rules:

1. **Action keys must be real.** Verify with `npx zapier-sdk list-actions <app>` before submitting. The corpus stays trustworthy because every key has been checked.
2. **Use the generic `runAction` form** unless the typed action (`zapier.apps.<key>.<type>.<action>`) is documented in the [SDK reference](https://docs.zapier.com/sdk/reference). The typed form is reserved for actions we've committed to as a stable surface.
3. **Mark dynamic inputs `// dynamic`.** Anything whose shape depends on the connection's specific config (Notion database schema, HubSpot custom properties, Salesforce org schema, etc.) gets a `// dynamic` comment so readers know to call `getInputFieldsSchema` for live verification.
3. **Mark dynamic inputs `// dynamic`.** Anything whose shape depends on the connection's specific config (Notion database schema, HubSpot custom properties, Salesforce org schema, etc.) gets a `// dynamic` comment so readers know to call `getActionInputFieldsSchema` for live verification.
4. **One JTBD per file, one screen long.** Single-app and single-pattern examples target ~20-40 lines. Chained examples can run 50-100. Keep each file scannable.
5. **Top comment block** with: one-sentence description, JTBD, Apps list, Run command. Chained examples also list the Pattern (fan-out / branching / transform pipeline / aggregation).

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ await slack.write.direct_message({

## For agents

If you are an AI agent: read [AGENTS.md](./AGENTS.md) first. It explains how this repo is laid out, where to find worked examples for any JTBD, and the rules of engagement (no hallucinating method names; use `listActions` / `getInputFieldsSchema` to discover capabilities at runtime).
If you are an AI agent: read [AGENTS.md](./AGENTS.md) first. It explains how this repo is laid out, where to find worked examples for any JTBD, and the rules of engagement (no hallucinating method names; use `listActions` / `getActionInputFieldsSchema` to discover capabilities at runtime).

To install this as a skill in your runtime: `npx skills add zapier/sdk` — adds [`skills/zapier-sdk/SKILL.md`](./skills/zapier-sdk/SKILL.md) to your local skills directory.

Expand All @@ -50,7 +50,7 @@ To install this as a skill in your runtime: `npx skills add zapier/sdk` — adds

- **One auth surface for 9,000+ apps**. OAuth handled. Tokens never leave Zapier.
- **Safe by default**. Org-level governance, audit trail, intercept/log/report what your agents do with your APIs.
- **Discoverable at runtime**. `listApps`, `listActions`, `getInputFieldsSchema` — agents can explore the API without you hardcoding it.
- **Discoverable at runtime**. `listApps`, `listActions`, `getActionInputFieldsSchema` — agents can explore the API without you hardcoding it.
- **Type-safe**. Per-app, per-action types generated from the live integration catalog.

## Examples
Expand Down
6 changes: 3 additions & 3 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ Comments inside explain the *why*, not the what. Method names follow the [SDK re

**About the action keys:** every action key in these examples has been verified against the live Zapier action catalog (`zapier-sdk list-actions <app>`). They are real and current as of this scaffold.

**About the input shapes:** some apps have *dynamic* input fields that depend on the specific connection's configuration (Notion's database schema, Asana's project list, HubSpot's custom properties, Salesforce custom objects). Where an input is dynamic, the example marks it with a `// dynamic` comment and links to `getInputFieldsSchema`. Discover the live shape with:
**About the input shapes:** some apps have *dynamic* input fields that depend on the specific connection's configuration (Notion's database schema, Asana's project list, HubSpot's custom properties, Salesforce custom objects). Where an input is dynamic, the example marks it with a `// dynamic` comment and links to `getActionInputFieldsSchema`. Discover the live shape with:

```typescript
const { data: schema } = await zapier.getInputFieldsSchema({
const { data: schema } = await zapier.getActionInputFieldsSchema({
app: "<app>",
actionType: "<read|write|search>",
action: "<actionKey>",
Expand All @@ -82,7 +82,7 @@ npx tsx examples/chained/stripe-charge-to-onboarding.ts

## Contributing an example

PRs welcome. Keep single-app and single-pattern examples under 40 lines. Chained examples can be longer (50-100) but should still fit on one screen. Verify every action key against `zapier-sdk list-actions <app>` before submitting. For inputs that vary by connection, mark them `// dynamic` and reference `getInputFieldsSchema`.
PRs welcome. Keep single-app and single-pattern examples under 40 lines. Chained examples can be longer (50-100) but should still fit on one screen. Verify every action key against `zapier-sdk list-actions <app>` before submitting. For inputs that vary by connection, mark them `// dynamic` and reference `getActionInputFieldsSchema`.

## See also

Expand Down
2 changes: 1 addition & 1 deletion examples/by-app/notion/create-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* Run: npx tsx examples/by-app/notion/create-page.ts
*
* Notion property shape depends on your database's schema. Verify with:
* zapier.getInputFieldsSchema({ app: "notion", actionType: "write", action: "create_database_item" })
* zapier.getActionInputFieldsSchema({ app: "notion", actionType: "write", action: "create_database_item" })
*/

import { createZapierSdk } from "@zapier/zapier-sdk";
Expand Down
2 changes: 1 addition & 1 deletion examples/by-app/salesforce/create-lead.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*
* Lead field names depend on your Salesforce org schema (standard fields below
* assume an unmodified Lead object). Verify with:
* zapier.getInputFieldsSchema({ app: "salesforce", actionType: "write", action: "create_lead" })
* zapier.getActionInputFieldsSchema({ app: "salesforce", actionType: "write", action: "create_lead" })
*/

import { createZapierSdk } from "@zapier/zapier-sdk";
Expand Down
2 changes: 1 addition & 1 deletion examples/by-pattern/data-sync/hubspot-contacts-mirror.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* Run: npx tsx examples/by-pattern/data-sync/hubspot-contacts-mirror.ts
*
* Notion field shape depends on your database schema. Verify with:
* zapier.getInputFieldsSchema({ app: "notion", actionType: "write", action: "create_database_item" })
* zapier.getActionInputFieldsSchema({ app: "notion", actionType: "write", action: "create_database_item" })
*/

import { createZapierSdk } from "@zapier/zapier-sdk";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*
* Salesforce field names depend on your org's schema. The output below assumes
* standard Lead fields (Id, Email, Company, CreatedDate). Verify with:
* zapier.getInputFieldsSchema({ app: "salesforce", actionType: "search", action: "find_records_v2" })
* zapier.getActionInputFieldsSchema({ app: "salesforce", actionType: "search", action: "find_records_v2" })
*/

import { createZapierSdk } from "@zapier/zapier-sdk";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Run: npx tsx examples/by-pattern/notify-on-event/email-on-typeform-submission.ts
*
* Inputs marked with `// dynamic` depend on the connection's specific config —
* verify shape with: zapier.getInputFieldsSchema({ app, actionType, action }).
* verify shape with: zapier.getActionInputFieldsSchema({ app, actionType, action }).
*/

import { createZapierSdk } from "@zapier/zapier-sdk";
Expand Down
4 changes: 2 additions & 2 deletions examples/chained/inbound-lead-orchestration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* Run: npx tsx examples/chained/inbound-lead-orchestration.ts
*
* Salesforce field names below assume standard Lead fields — verify with:
* zapier.getInputFieldsSchema({ app: "salesforce", actionType: "write", action: "create_lead" })
* zapier.getActionInputFieldsSchema({ app: "salesforce", actionType: "write", action: "create_lead" })
*/

import { createZapierSdk } from "@zapier/zapier-sdk";
Expand Down Expand Up @@ -48,7 +48,7 @@ async function processLead(formId: string) {
object: "Lead",
searchValue: email,
// searchField is dynamic — defaults to Email when searching Leads. Verify
// with: zapier.getInputFieldsSchema({ app: "salesforce", actionType: "search", action: "find_record" })
// with: zapier.getActionInputFieldsSchema({ app: "salesforce", actionType: "search", action: "find_record" })
},
})) as { data: any[] };

Expand Down
2 changes: 1 addition & 1 deletion examples/chained/stripe-charge-to-onboarding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* Run: npx tsx examples/chained/stripe-charge-to-onboarding.ts ch_test_123
*
* Inputs marked `// dynamic` depend on the connection's specific config —
* verify with: zapier.getInputFieldsSchema({ app, actionType, action }).
* verify with: zapier.getActionInputFieldsSchema({ app, actionType, action }).
*/

import { createZapierSdk } from "@zapier/zapier-sdk";
Expand Down
4 changes: 2 additions & 2 deletions examples/chained/support-ticket-with-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*
* HubSpot contact-search inputs are dynamic and depend on the properties you've
* configured — verify with:
* zapier.getInputFieldsSchema({ app: "hubspot", actionType: "search", action: "contactSearch" })
* zapier.getActionInputFieldsSchema({ app: "hubspot", actionType: "search", action: "contactSearch" })
*/

import { createZapierSdk } from "@zapier/zapier-sdk";
Expand Down Expand Up @@ -44,7 +44,7 @@ async function escalate(conversationId: string) {
connection: hsConn.id,
inputs: {
first_search_property_name: "email",
// dynamic: actual search-value field name depends on the property — verify with getInputFieldsSchema
// dynamic: actual search-value field name depends on the property — verify with getActionInputFieldsSchema
first_search_property_value: email,
},
}),
Expand Down
6 changes: 3 additions & 3 deletions skills/zapier-sdk/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ When working with the Zapier SDK:

1. Always verify against the official docs: https://docs.zapier.com/sdk/reference
2. Never hallucinate method names — use only methods documented in the official Zapier SDK reference
3. If unsure about an action's input fields, use `getInputFieldsSchema` or `listInputFields` to discover them at runtime
3. If unsure about an action's input fields, use `getActionInputFieldsSchema` or `listActionInputFields` to discover them at runtime
4. If unsure about available actions for an app, use `listActions` to discover them

## Authentication
Expand Down Expand Up @@ -122,7 +122,7 @@ for await (const action of zapier.listActions({ app: "slack" }).items()) {
}

// Get required inputs for an action
const { data: schema } = await zapier.getInputFieldsSchema({
const { data: schema } = await zapier.getActionInputFieldsSchema({
app: "slack",
actionType: "write",
action: "direct_message",
Expand All @@ -138,7 +138,7 @@ Do not guess method signatures. Look them up in the canonical reference — pref
- **Bundled with the installed package:** `node_modules/@zapier/zapier-sdk/README.md`
- **Live docs:** https://docs.zapier.com/sdk/reference

When in doubt about what an app supports or what inputs an action requires, discover at runtime with `listActions` and `getInputFieldsSchema` — see Core Workflow step 4 above.
When in doubt about what an app supports or what inputs an action requires, discover at runtime with `listActions` and `getActionInputFieldsSchema` — see Core Workflow step 4 above.

## Pagination

Expand Down