Skip to content

Commit 410d6f9

Browse files
committed
feat(plaid): add the Plaid bank-data integration
1 parent b96c053 commit 410d6f9

36 files changed

Lines changed: 2959 additions & 25 deletions

apps/docs/components/icons.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5466,6 +5466,18 @@ export function AsanaIcon(props: SVGProps<SVGSVGElement>) {
54665466
)
54675467
}
54685468

5469+
export function PlaidIcon(props: SVGProps<SVGSVGElement>) {
5470+
return (
5471+
<svg {...props} viewBox='0 0 48 48' fill='none' xmlns='http://www.w3.org/2000/svg'>
5472+
<path
5473+
fill='currentColor'
5474+
fillRule='evenodd'
5475+
d='M18.637 0L4.09 3.81.081 18.439l5.014 5.148L0 28.65l3.773 14.693 14.484 4.047 5.096-5.064 5.014 5.147 14.547-3.81 4.008-14.63-5.013-5.146 5.095-5.063L43.231 4.13 28.745.083l-5.094 5.063L18.637 0zM9.71 6.624l7.663-2.008 3.351 3.44-4.887 4.856L9.71 6.624zm16.822 1.478l3.405-3.383 7.63 2.132-6.227 6.187-4.808-4.936zM4.672 17.238l2.111-7.705 6.125 6.288-4.886 4.856-3.35-3.44zm29.547-1.243l6.227-6.189 1.986 7.74-3.404 3.384-4.809-4.935zm-15.502-.127l4.887-4.856 4.807 4.936-4.886 4.856-4.808-4.936zm-7.814 7.765l4.886-4.856 4.81 4.936-4.888 4.856-4.808-4.936zm15.503.127l4.886-4.856L36.1 23.84l-4.887 4.856-4.807-4.936zM4.57 29.927l3.406-3.385 4.807 4.937-6.225 6.186-1.988-7.738zm14.021 1.598l4.887-4.856 4.808 4.936-4.886 4.856-4.809-4.936zm15.502.128l4.887-4.856 3.351 3.439-2.11 7.705-6.128-6.288zm-24.656 8.97l6.226-6.189 4.81 4.936-3.406 3.385-7.63-2.133zm16.843-1.206l4.886-4.856 6.126 6.289-7.662 2.007-3.35-3.44z'
5476+
/>
5477+
</svg>
5478+
)
5479+
}
5480+
54695481
export function PipedriveIcon(props: SVGProps<SVGSVGElement>) {
54705482
const pathId = useId()
54715483
return (

apps/docs/components/ui/icon-mapping.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ import {
174174
PersonaIcon,
175175
PineconeIcon,
176176
PipedriveIcon,
177+
PlaidIcon,
177178
PolymarketIcon,
178179
PostgresIcon,
179180
PosthogIcon,
@@ -461,6 +462,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
461462
persona: PersonaIcon,
462463
pinecone: PineconeIcon,
463464
pipedrive: PipedriveIcon,
465+
plaid: PlaidIcon,
464466
polymarket: PolymarketIcon,
465467
postgresql: PostgresIcon,
466468
posthog: PosthogIcon,

apps/docs/content/docs/en/integrations/ashby.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1493,7 +1493,7 @@ Trigger workflow when a new job is created
14931493
|`title` | string | Job title |
14941494
|`confidential` | boolean | Whether the job is confidential |
14951495
|`status` | string | Job status \(Open, Closed, Draft, Archived\) |
1496-
|`employmentType` | string | Employment type \(FullTime, PartTime, Intern, Contract\) |
1496+
|`employmentType` | string | Employment type \(FullTime, PartTime, Intern, Contract, Temporary\) |
14971497

14981498

14991499
---

apps/docs/content/docs/en/integrations/logrocket.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,4 @@ Register a release version in LogRocket so uploaded source maps can decode stack
188188
| --------- | ---- | ----------- |
189189
| `version` | string | Release version that was registered |
190190

191+

apps/docs/content/docs/en/integrations/meta.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@
186186
"pinecone",
187187
"pipedrive",
188188
"pipedrive-service-account",
189+
"plaid",
189190
"polymarket",
190191
"postgresql",
191192
"posthog",

apps/docs/content/docs/en/integrations/netsuite.mdx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Manage NetSuite records, queries, datasets, batches, and async jobs
55

66
import { BlockInfoCard } from "@/components/ui/block-info-card"
77

8-
<BlockInfoCard
8+
<BlockInfoCard
99
type="netsuite"
1010
color="#FFFFFF"
1111
/>
@@ -651,3 +651,5 @@ Retrieve REST web-services concurrency limits for the NetSuite account and integ
651651
|`accountUnallocatedConcurrencyLimit` | number | Account concurrency not allocated to integrations |
652652
|`integrationConcurrencyLimit` | number | Concurrency allocated to this integration |
653653
|`integrationLimitType` | string | Limit assignment: integrationSpecific, accountLimit, or internal |
654+
655+
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
---
2+
title: Plaid
3+
description: Read bank accounts, balances, transactions, and identity data via Plaid
4+
---
5+
6+
import { BlockInfoCard } from "@/components/ui/block-info-card"
7+
8+
<BlockInfoCard
9+
type="plaid"
10+
color="#111111"
11+
/>
12+
13+
## Usage Instructions
14+
15+
Integrates Plaid into the workflow. Sync categorized transactions, list linked bank accounts with real-time balances, fetch verified account and routing numbers, retrieve account-holder identity, look up supported institutions, and manage Item tokens across the sandbox and production environments.
16+
17+
18+
19+
## Actions
20+
21+
### Plaid Sync Transactions
22+
23+
Incrementally sync transactions for a linked Item. Omit the cursor on the first call to get full history, then pass the returned cursor to fetch only changes; loop while hasMore is true. If Plaid returns TRANSACTIONS_SYNC_MUTATION_DURING_PAGINATION, discard the pages from the current batch and restart the loop from the cursor the batch started with
24+
25+
#### Input
26+
27+
| Parameter | Type | Required | Description |
28+
| --------- | ---- | -------- | ----------- |
29+
| `cursor` | string | No | Cursor from a previous sync \(nextCursor\); omit to start from the beginning |
30+
| `count` | number | No | Number of updates to fetch per page \(1-500, default 100\) |
31+
| `accountId` | string | No | Scope the sync \(and cursor\) to a single account ID |
32+
| `includeOriginalDescription` | boolean | No | Include the unmodified original_description from the institution |
33+
| `daysRequested` | number | No | Days of history to request \(1-730, default 90\). Only applies before Transactions is initialized on the Item |
34+
35+
#### Output
36+
37+
| Parameter | Type | Description |
38+
| --------- | ---- | ----------- |
39+
| `added` | array | Transactions added since the cursor |
40+
| `modified` | array | Transactions modified since the cursor |
41+
| `removed` | array | Transactions removed since the cursor |
42+
|`transaction_id` | string | ID of the removed transaction |
43+
|`account_id` | string | Account the transaction belonged to |
44+
| `nextCursor` | string | Cursor to pass to the next sync call to fetch only new changes |
45+
| `hasMore` | boolean | Whether more updates are available; if true, call again with nextCursor |
46+
| `updateStatus` | string | Sync readiness: NOT_READY, INITIAL_UPDATE_COMPLETE, or HISTORICAL_UPDATE_COMPLETE |
47+
48+
### Plaid Get Accounts
49+
50+
List the accounts linked to an Item with their names, types, and balances. Balances may be cached; use Get Balances for real-time values
51+
52+
#### Input
53+
54+
| Parameter | Type | Required | Description |
55+
| --------- | ---- | -------- | ----------- |
56+
| `accountIds` | string | No | Comma-separated account IDs to filter to \(defaults to all accounts\) |
57+
58+
#### Output
59+
60+
| Parameter | Type | Description |
61+
| --------- | ---- | ----------- |
62+
| `accounts` | array | Accounts linked to the Item |
63+
| `count` | number | Number of accounts returned |
64+
65+
### Plaid Get Balances
66+
67+
Get real-time balances for the accounts linked to an Item. Forces a live fetch from the institution, so it can take up to 30 seconds
68+
69+
#### Input
70+
71+
| Parameter | Type | Required | Description |
72+
| --------- | ---- | -------- | ----------- |
73+
| `accountIds` | string | No | Comma-separated account IDs to filter to \(defaults to all accounts\) |
74+
| `minLastUpdatedDatetime` | string | No | Oldest acceptable balance timestamp \(ISO 8601\). Only required for Capital One non-depository accounts |
75+
76+
#### Output
77+
78+
| Parameter | Type | Description |
79+
| --------- | ---- | ----------- |
80+
| `accounts` | array | Accounts with refreshed real-time balances |
81+
| `count` | number | Number of accounts returned |
82+
83+
### Plaid Get Identity
84+
85+
Get account-holder identity information (names, emails, phone numbers, and addresses) for the accounts linked to an Item
86+
87+
#### Input
88+
89+
| Parameter | Type | Required | Description |
90+
| --------- | ---- | -------- | ----------- |
91+
| `accountIds` | string | No | Comma-separated account IDs to filter to \(defaults to all accounts\) |
92+
93+
#### Output
94+
95+
| Parameter | Type | Description |
96+
| --------- | ---- | ----------- |
97+
| `accounts` | array | Accounts with their owners identity data |
98+
|`owners` | json | Account owners, each with names, phone_numbers, emails, and addresses arrays |
99+
| `count` | number | Number of accounts returned |
100+
101+
### Plaid Get Auth
102+
103+
Get account and routing numbers for the depository accounts linked to an Item (ACH for US, EFT for Canada, BACS for UK, IBAN/BIC internationally). Check each account verification_status before relying on micro-deposit-verified accounts; null means the institution authenticated instantly
104+
105+
#### Input
106+
107+
| Parameter | Type | Required | Description |
108+
| --------- | ---- | -------- | ----------- |
109+
| `accountIds` | string | No | Comma-separated account IDs to filter to \(defaults to all accounts\) |
110+
111+
#### Output
112+
113+
| Parameter | Type | Description |
114+
| --------- | ---- | ----------- |
115+
| `accounts` | array | Depository accounts on the Item |
116+
| `numbers` | json | Account and routing numbers grouped by scheme |
117+
|`ach` | json | US accounts: account_id, account, routing, wire_routing, and is_tokenized_account_number entries \(tokenized numbers come from institutions like Chase and stop working if the Item is deleted\) |
118+
|`eft` | json | Canadian accounts: account_id, account, institution, and branch entries |
119+
|`international` | json | International accounts: account_id, iban, and bic entries |
120+
|`bacs` | json | UK accounts: account_id, account, and sort_code entries |
121+
122+
### Plaid Get Item
123+
124+
Get metadata and health status for a linked Item, including its institution, enabled products, and any error state
125+
126+
#### Input
127+
128+
| Parameter | Type | Required | Description |
129+
| --------- | ---- | -------- | ----------- |
130+
131+
#### Output
132+
133+
| Parameter | Type | Description |
134+
| --------- | ---- | ----------- |
135+
| `item` | json | Item metadata |
136+
|`item_id` | string | Unique ID of the Item |
137+
|`institution_id` | string | Plaid institution ID the Item is linked to |
138+
|`institution_name` | string | Name of the linked institution |
139+
|`webhook` | string | Webhook URL set on the Item |
140+
|`error` | json | Error state of the Item, null when healthy |
141+
|`available_products` | json | Products available but not yet billed for the Item |
142+
|`billed_products` | json | Products the Item has been billed for |
143+
|`products` | json | All products enabled on the Item |
144+
|`consent_expiration_time` | string | When access consent expires, if the institution enforces expiration |
145+
|`update_type` | string | Item update type \(background or user_present_required\) |
146+
|`created_at` | string | When the Item was created |
147+
| `status` | json | Item health: last successful/failed transaction and investment updates and the last webhook fired |
148+
149+
### Plaid Search Institutions
150+
151+
Search financial institutions supported by Plaid by name
152+
153+
#### Input
154+
155+
| Parameter | Type | Required | Description |
156+
| --------- | ---- | -------- | ----------- |
157+
| `query` | string | Yes | Institution name to search for, e.g. 'Chase' |
158+
| `countryCodes` | string | No | Comma-separated ISO country codes to search in \(defaults to 'US'\) |
159+
| `products` | string | No | Comma-separated products the institutions must support, e.g. 'transactions,auth' |
160+
161+
#### Output
162+
163+
| Parameter | Type | Description |
164+
| --------- | ---- | ----------- |
165+
| `institutions` | array | Institutions matching the search |
166+
| `count` | number | Number of institutions returned |
167+
168+
### Plaid Get Institution
169+
170+
Get details for a financial institution by its Plaid institution ID
171+
172+
#### Input
173+
174+
| Parameter | Type | Required | Description |
175+
| --------- | ---- | -------- | ----------- |
176+
| `institutionId` | string | Yes | Plaid institution ID, e.g. 'ins_109508' |
177+
| `countryCodes` | string | No | Comma-separated ISO country codes \(defaults to 'US'\) |
178+
179+
#### Output
180+
181+
| Parameter | Type | Description |
182+
| --------- | ---- | ----------- |
183+
| `institution` | json | Institution details |
184+
185+
### Plaid Exchange Public Token
186+
187+
Exchange a public token from Plaid Link (or the sandbox) for a permanent access token and Item ID
188+
189+
#### Input
190+
191+
| Parameter | Type | Required | Description |
192+
| --------- | ---- | -------- | ----------- |
193+
| `publicToken` | string | Yes | Public token returned by Plaid Link onSuccess \(or the sandbox token creator\) |
194+
195+
#### Output
196+
197+
| Parameter | Type | Description |
198+
| --------- | ---- | ----------- |
199+
| `accessToken` | string | Access token for the linked Item; store it securely and pass it to the other Plaid operations |
200+
| `itemId` | string | ID of the Item the token belongs to |
201+
202+
### Plaid Create Sandbox Public Token
203+
204+
Create a sandbox public token for a test institution without going through Plaid Link. Sandbox only — exchange the result for an access token to test other operations
205+
206+
#### Input
207+
208+
| Parameter | Type | Required | Description |
209+
| --------- | ---- | -------- | ----------- |
210+
| `secret` | string | No | Plaid sandbox API secret |
211+
| `institutionId` | string | Yes | Sandbox institution ID, e.g. 'ins_109508' \(First Platypus Bank\) |
212+
| `initialProducts` | string | Yes | Comma-separated products to enable, e.g. 'transactions' or 'auth,identity' |
213+
| `webhook` | string | No | Webhook URL to associate with the Item |
214+
215+
#### Output
216+
217+
| Parameter | Type | Description |
218+
| --------- | ---- | ----------- |
219+
| `publicToken` | string | Sandbox public token to exchange for an access token |
220+
221+

apps/docs/content/docs/en/integrations/snowflake.mdx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Query data and manage warehouses and tasks in Snowflake
55

66
import { BlockInfoCard } from "@/components/ui/block-info-card"
77

8-
<BlockInfoCard
8+
<BlockInfoCard
99
type="snowflake"
1010
color="#FFFFFF"
1111
/>
@@ -1316,3 +1316,5 @@ Call a stored procedure with explicitly typed Snowflake bindings.
13161316
|`rowsDeleted` | number | Rows deleted by the statement |
13171317
|`duplicateRowsUpdated` | number | Duplicate rows updated by the statement |
13181318
|`rowsAffected` | number | Total inserted, updated, and deleted rows |
1319+
1320+

apps/docs/content/docs/en/integrations/zoho_desk.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Manage Zoho Desk tickets, comments, threads, and contacts
55

66
import { BlockInfoCard } from "@/components/ui/block-info-card"
77

8-
<BlockInfoCard
8+
<BlockInfoCard
99
type="zoho_desk"
1010
color="#FFFFFF"
1111
/>
@@ -522,3 +522,4 @@ Trigger a workflow when a Zoho Desk event occurs (ticket, comment, thread, conta
522522
| `orgId` | string | Zoho Desk organization ID |
523523
| `payload` | json | The full resource that changed \(ticket, comment, thread, etc.\). Comment and thread events gain a derived plain-text `contentText` alongside the raw `content` + `contentType`; ticket events gain `descriptionText` alongside `description`. |
524524
| `prevState` | json | Previous state of the resource \(update events only\) |
525+

apps/sim/blocks/blocks/brex.ts

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { BrexIcon } from '@/components/icons'
22
import type { BlockConfig, BlockMeta } from '@/blocks/types'
33
import { AuthMode, IntegrationType } from '@/blocks/types'
4-
import { normalizeFileInput } from '@/blocks/utils'
4+
import { normalizeFileInput, toOptionalBoolean, toOptionalFiniteNumber } from '@/blocks/utils'
55
import type { BrexResponse } from '@/tools/brex/types'
66

77
/** Coerces a required money-amount field to a finite number, throwing on blank/non-numeric input rather than silently sending 0 or NaN to Brex. */
@@ -16,23 +16,6 @@ function toRequiredAmount(value: unknown, fieldLabel: string): number {
1616
return parsed
1717
}
1818

19-
/** Coerces an optional numeric field to a finite number, throwing on non-numeric input instead of silently forwarding NaN. Preserves explicit 0. */
20-
function toOptionalFiniteNumber(value: unknown, fieldLabel: string): number | undefined {
21-
if (value == null || (typeof value === 'string' && value.trim() === '')) return undefined
22-
const parsed = Number(value)
23-
if (!Number.isFinite(parsed)) {
24-
throw new Error(`${fieldLabel} must be a valid number`)
25-
}
26-
return parsed
27-
}
28-
29-
/** Normalizes a boolean field that may arrive as a string (e.g. from a dynamic <Block.output> reference) instead of an actual boolean. */
30-
function toOptionalBoolean(value: unknown): boolean | undefined {
31-
if (value == null) return undefined
32-
if (typeof value === 'boolean') return value
33-
return String(value).toLowerCase() === 'true'
34-
}
35-
3619
const PAGINATED_OPERATIONS = new Set([
3720
'list_expenses',
3821
'list_card_transactions',

0 commit comments

Comments
 (0)