@elevasis/sdk 0.5.12 → 0.5.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/cli.cjs +144 -118
  2. package/dist/index.d.ts +19 -253
  3. package/dist/index.js +20 -9
  4. package/dist/templates.js +62 -59
  5. package/dist/types/worker/adapters/index.d.ts +0 -1
  6. package/dist/worker/index.js +47 -53
  7. package/package.json +1 -1
  8. package/reference/_navigation.md +13 -57
  9. package/reference/{cli/index.mdx → cli.mdx} +568 -505
  10. package/reference/concepts.mdx +164 -0
  11. package/reference/deployment/api.mdx +297 -297
  12. package/reference/deployment/command-center.mdx +226 -0
  13. package/reference/deployment/index.mdx +158 -153
  14. package/reference/framework/agent.mdx +156 -151
  15. package/reference/framework/index.mdx +182 -103
  16. package/reference/{developer → framework}/interaction-guidance.mdx +182 -182
  17. package/reference/framework/memory.mdx +326 -347
  18. package/reference/framework/project-structure.mdx +277 -298
  19. package/reference/framework/tutorial-system.mdx +222 -0
  20. package/reference/{getting-started/index.mdx → getting-started.mdx} +152 -148
  21. package/reference/index.mdx +131 -114
  22. package/reference/platform-tools/adapters.mdx +868 -929
  23. package/reference/platform-tools/index.mdx +354 -195
  24. package/reference/resources/index.mdx +339 -336
  25. package/reference/resources/patterns.mdx +355 -354
  26. package/reference/resources/types.mdx +207 -207
  27. package/reference/{roadmap/index.mdx → roadmap.mdx} +163 -147
  28. package/reference/{runtime/index.mdx → runtime.mdx} +173 -141
  29. package/reference/{troubleshooting/common-errors.mdx → troubleshooting.mdx} +223 -210
  30. package/dist/types/worker/adapters/trello.d.ts +0 -14
  31. package/reference/concepts/index.mdx +0 -203
  32. package/reference/deployment/command-center-ui.mdx +0 -151
  33. package/reference/deployment/command-view.mdx +0 -154
  34. package/reference/framework/documentation.mdx +0 -92
  35. package/reference/platform-tools/examples.mdx +0 -170
  36. package/reference/runtime/limits.mdx +0 -75
  37. package/reference/security/credentials.mdx +0 -141
@@ -1,929 +1,868 @@
1
- ---
2
- title: Typed Adapters
3
- description: Type-safe wrappers over platform.call() for all integrations and platform tools -- Attio, Stripe, Notion, Google Sheets, Trello, and more -- with full autocomplete, compile-time checking, and zero boilerplate
4
- loadWhen: "Using typed adapters instead of raw platform.call(), or needs to know what adapter methods are available"
5
- ---
6
-
7
- Typed adapters are ergonomic wrappers over `platform.call()` that provide full TypeScript autocomplete and compile-time type checking. They eliminate stringly-typed method names, manual `as Promise<T>` casts, and repeated credential passing.
8
-
9
- Both patterns work simultaneously -- adapters compile down to `platform.call()` with zero runtime overhead.
10
-
11
- ```typescript
12
- // Before: raw platform.call()
13
- const records = await platform.call({
14
- tool: 'attio',
15
- method: 'listRecords',
16
- credential: 'my-attio',
17
- params: { object: 'deals' }
18
- }) as unknown as QueryRecordsResult
19
-
20
- // After: typed adapter
21
- const attio = createAttioAdapter('my-attio')
22
- const records = await attio.listRecords({ object: 'deals' })
23
- // ^-- QueryRecordsResult (fully typed, autocomplete on params)
24
- ```
25
-
26
- All adapters are imported from `@elevasis/sdk/worker` -- the same subpath as `platform`.
27
-
28
- ---
29
-
30
- ## Quick Reference
31
-
32
- ### Integration Adapters (factory pattern, credential required)
33
-
34
- | Import | Methods |
35
- |--------|---------|
36
- | `createAttioAdapter(cred)` | 12 |
37
- | `createStripeAdapter(cred)` | 6 |
38
- | `createNotionAdapter(cred)` | 8 |
39
- | `createGoogleSheetsAdapter(cred)` | 13 |
40
- | `createTrelloAdapter(cred)` | 10 |
41
- | `createInstantlyAdapter(cred)` | 5 |
42
- | `createSignatureApiAdapter(cred)` | 4 |
43
- | `createResendAdapter(cred)` | 2 |
44
- | `createDropboxAdapter(cred)` | 2 |
45
- | `createApifyAdapter(cred)` | 1 |
46
- | `createGmailAdapter(cred)` | 1 |
47
- | `createMailsoAdapter(cred)` | 1 |
48
-
49
- ### Platform Adapters (singletons, no credential)
50
-
51
- | Import | Methods |
52
- |--------|---------|
53
- | `lead` | 35 |
54
- | `scheduler` | 9 |
55
- | `storage` | 5 |
56
- | `pdf` | 2 |
57
- | `approval` | 2 |
58
- | `notifications` | 1 |
59
- | `llm` | 1 |
60
- | `execution` | 1 |
61
- | `email` | 1 |
62
-
63
- ### Generic Factory
64
-
65
- | Import | Description |
66
- |--------|-------------|
67
- | `createAdapter<TMap>(tool, methods, cred?)` | Build custom adapters for any tool |
68
-
69
- ```typescript
70
- import {
71
- // Integration adapters
72
- createAttioAdapter, createStripeAdapter, createNotionAdapter,
73
- createGoogleSheetsAdapter, createTrelloAdapter, createInstantlyAdapter,
74
- createSignatureApiAdapter, createResendAdapter, createDropboxAdapter,
75
- createApifyAdapter, createGmailAdapter, createMailsoAdapter,
76
- // Platform adapters
77
- lead, scheduler, storage, pdf, approval, notifications, llm, execution, email,
78
- // Generic factory
79
- createAdapter,
80
- } from '@elevasis/sdk/worker'
81
- ```
82
-
83
- ---
84
-
85
- ## Attio CRM Adapter
86
-
87
- Factory pattern -- bind a credential once, use 12 typed methods.
88
-
89
- ```typescript
90
- const attio = createAttioAdapter('my-attio-credential')
91
- ```
92
-
93
- ### Methods
94
-
95
- | Method | Params | Returns |
96
- |--------|--------|---------|
97
- | `createRecord` | `CreateRecordParams` | `CreateRecordResult` |
98
- | `updateRecord` | `UpdateRecordParams` | `UpdateRecordResult` |
99
- | `listRecords` | `QueryRecordsParams` | `QueryRecordsResult` |
100
- | `getRecord` | `GetRecordParams` | `GetRecordResult` |
101
- | `deleteRecord` | `DeleteRecordParams` | `DeleteRecordResult` |
102
- | `listObjects` | none | `ListObjectsResult` |
103
- | `listAttributes` | `ListAttributesParams` | `ListAttributesResult` |
104
- | `createAttribute` | `CreateAttributeParams` | `CreateAttributeResult` |
105
- | `updateAttribute` | `UpdateAttributeParams` | `UpdateAttributeResult` |
106
- | `createNote` | `CreateNoteParams` | `CreateNoteResult` |
107
- | `listNotes` | `ListNotesParams` | `ListNotesResult` |
108
- | `deleteNote` | `DeleteNoteParams` | `DeleteNoteResult` |
109
-
110
- ### Examples
111
-
112
- ```typescript
113
- // Create a company record
114
- const company = await attio.createRecord({
115
- object: 'companies',
116
- values: {
117
- name: [{ value: 'Acme Corp' }],
118
- domains: [{ domain: 'acme.com' }],
119
- },
120
- })
121
-
122
- // Query deals with filters
123
- const deals = await attio.listRecords({
124
- object: 'deals',
125
- filter: {
126
- operator: 'and',
127
- filters: [
128
- { field: 'stage', operator: 'equals', value: 'proposal' },
129
- ],
130
- },
131
- sorts: [{ field: 'created_at', direction: 'desc' }],
132
- limit: 20,
133
- })
134
-
135
- // Get a specific record
136
- const record = await attio.getRecord({
137
- object: 'people',
138
- recordId: 'rec_abc123',
139
- })
140
-
141
- // List all objects (no params)
142
- const objects = await attio.listObjects()
143
-
144
- // Create a note on a record
145
- await attio.createNote({
146
- parentObject: 'deals',
147
- parentRecordId: 'rec_abc123',
148
- title: 'Discovery call notes',
149
- content: 'Key takeaways from the call...',
150
- })
151
- ```
152
-
153
- Multiple adapters with different credentials work simultaneously:
154
-
155
- ```typescript
156
- const prodAttio = createAttioAdapter('prod-attio')
157
- const testAttio = createAttioAdapter('test-attio')
158
- ```
159
-
160
- ---
161
-
162
- ## Stripe Adapter
163
-
164
- Factory pattern -- 6 methods for payment links and checkout sessions.
165
-
166
- ```typescript
167
- const stripe = createStripeAdapter('my-stripe-credential')
168
- ```
169
-
170
- ### Methods
171
-
172
- | Method | Params | Returns |
173
- |--------|--------|---------|
174
- | `createPaymentLink` | `CreatePaymentLinkParams` | `CreatePaymentLinkResult` |
175
- | `getPaymentLink` | `GetPaymentLinkParams` | `GetPaymentLinkResult` |
176
- | `updatePaymentLink` | `UpdatePaymentLinkParams` | `UpdatePaymentLinkResult` |
177
- | `listPaymentLinks` | `ListPaymentLinksParams` | `ListPaymentLinksResult` |
178
- | `createAutoPaymentLink` | `CreateAutoPaymentLinkParams` | `CreateAutoPaymentLinkResult` |
179
- | `createCheckoutSession` | `CreateCheckoutSessionParams` | `CreateCheckoutSessionResult` |
180
-
181
- ---
182
-
183
- ## Notion Adapter
184
-
185
- Factory pattern -- 8 methods for page and block operations.
186
-
187
- ```typescript
188
- const notion = createNotionAdapter('my-notion-credential')
189
- ```
190
-
191
- ### Methods
192
-
193
- | Method | Params | Returns |
194
- |--------|--------|---------|
195
- | `listAllPages` | none | `ListAllPagesResult` |
196
- | `readPage` | `ReadPageParams` | `ReadPageResult` |
197
- | `createPage` | `CreatePageParams` | `CreatePageResult` |
198
- | `updatePageTitle` | `UpdatePageTitleParams` | `UpdatePageTitleResult` |
199
- | `appendBlocks` | `AppendBlocksParams` | `AppendBlocksResult` |
200
- | `updateBlocks` | `UpdateBlocksParams` | `UpdateBlocksResult` |
201
- | `deletePage` | `DeletePageParams` | `DeletePageResult` |
202
- | `deleteBlocks` | `DeleteBlocksParams` | `DeleteBlocksResult` |
203
-
204
- ---
205
-
206
- ## Google Sheets Adapter
207
-
208
- Factory pattern -- 13 methods including workflow-friendly helpers (getRowByValue, upsertRow, filterRows).
209
-
210
- ```typescript
211
- const sheets = createGoogleSheetsAdapter('my-google-credential')
212
- ```
213
-
214
- ### Methods
215
-
216
- | Method | Params | Returns |
217
- |--------|--------|---------|
218
- | `readSheet` | `ReadSheetParams` | `ReadSheetResult` |
219
- | `writeSheet` | `WriteSheetParams` | `WriteSheetResult` |
220
- | `appendRows` | `AppendRowsParams` | `AppendRowsResult` |
221
- | `clearRange` | `ClearRangeParams` | `ClearRangeResult` |
222
- | `getSpreadsheetMetadata` | `GetSpreadsheetMetadataParams` | `GetSpreadsheetMetadataResult` |
223
- | `batchUpdate` | `BatchUpdateParams` | `BatchUpdateResult` |
224
- | `getHeaders` | `GetHeadersParams` | `GetHeadersResult` |
225
- | `getLastRow` | `GetLastRowParams` | `GetLastRowResult` |
226
- | `getRowByValue` | `GetRowByValueParams` | `GetRowByValueResult` |
227
- | `updateRowByValue` | `UpdateRowByValueParams` | `UpdateRowByValueResult` |
228
- | `upsertRow` | `UpsertRowParams` | `UpsertRowResult` |
229
- | `filterRows` | `FilterRowsParams` | `FilterRowsResult` |
230
- | `deleteRowByValue` | `DeleteRowByValueParams` | `DeleteRowByValueResult` |
231
-
232
- ---
233
-
234
- ## Trello Adapter
235
-
236
- Factory pattern -- 10 methods for boards, lists, cards, and checklists.
237
-
238
- ```typescript
239
- const trello = createTrelloAdapter('my-trello-credential')
240
- ```
241
-
242
- ### Methods
243
-
244
- | Method | Params | Returns |
245
- |--------|--------|---------|
246
- | `getBoard` | `GetBoardParams` | `GetBoardResult` |
247
- | `getLists` | `GetListsParams` | `GetListsResult` |
248
- | `getCards` | `GetCardsParams` | `GetCardsResult` |
249
- | `createCard` | `CreateCardParams` | `CreateCardResult` |
250
- | `updateCard` | `UpdateCardParams` | `UpdateCardResult` |
251
- | `createList` | `TrelloCreateListParams` | `TrelloCreateListResult` |
252
- | `createChecklist` | `CreateChecklistParams` | `CreateChecklistResult` |
253
- | `addChecklistItem` | `AddChecklistItemParams` | `AddChecklistItemResult` |
254
- | `updateChecklistItem` | `UpdateChecklistItemParams` | `UpdateChecklistItemResult` |
255
- | `getCardChecklists` | `GetCardChecklistsParams` | `GetCardChecklistsResult` |
256
-
257
- ---
258
-
259
- ## Instantly Adapter
260
-
261
- Factory pattern -- 5 methods for email campaign management.
262
-
263
- ```typescript
264
- const instantly = createInstantlyAdapter('my-instantly-credential')
265
- ```
266
-
267
- ### Methods
268
-
269
- | Method | Params | Returns |
270
- |--------|--------|---------|
271
- | `sendReply` | `SendReplyParams` | `SendReplyResult` |
272
- | `removeFromSubsequence` | `RemoveFromSubsequenceParams` | `RemoveFromSubsequenceResult` |
273
- | `getEmails` | `GetEmailsParams` | `GetEmailsResult` |
274
- | `updateInterestStatus` | `UpdateInterestStatusParams` | `UpdateInterestStatusResult` |
275
- | `addToCampaign` | `AddToCampaignParams` | `AddToCampaignResult` |
276
-
277
- ---
278
-
279
- ## SignatureAPI Adapter
280
-
281
- Factory pattern -- 4 methods for eSignature envelope operations.
282
-
283
- ```typescript
284
- const signatureApi = createSignatureApiAdapter('my-signatureapi-credential')
285
- ```
286
-
287
- ### Methods
288
-
289
- | Method | Params | Returns |
290
- |--------|--------|---------|
291
- | `createEnvelope` | `CreateEnvelopeParams` | `CreateEnvelopeResult` |
292
- | `voidEnvelope` | `VoidEnvelopeParams` | `VoidEnvelopeResult` |
293
- | `downloadDocument` | `DownloadDocumentParams` | `DownloadDocumentResult` |
294
- | `getEnvelope` | `GetEnvelopeParams` | `GetEnvelopeResult` |
295
-
296
- ---
297
-
298
- ## Resend Adapter
299
-
300
- Factory pattern -- 2 methods for transactional email.
301
-
302
- ```typescript
303
- const resend = createResendAdapter('my-resend-credential')
304
- ```
305
-
306
- ### Methods
307
-
308
- | Method | Params | Returns |
309
- |--------|--------|---------|
310
- | `sendEmail` | `ResendSendEmailParams` | `ResendSendEmailResult` |
311
- | `getEmail` | `ResendGetEmailParams` | `ResendGetEmailResult` |
312
-
313
- ---
314
-
315
- ## Dropbox Adapter
316
-
317
- Factory pattern -- 2 methods for file operations.
318
-
319
- ```typescript
320
- const dropbox = createDropboxAdapter('my-dropbox-credential')
321
- ```
322
-
323
- ### Methods
324
-
325
- | Method | Params | Returns |
326
- |--------|--------|---------|
327
- | `uploadFile` | `UploadFileParams` | `UploadFileResult` |
328
- | `createFolder` | `CreateFolderParams` | `CreateFolderResult` |
329
-
330
- ---
331
-
332
- ## Apify Adapter
333
-
334
- Factory pattern -- 1 method for running web scraping actors.
335
-
336
- ```typescript
337
- const apify = createApifyAdapter('my-apify-credential')
338
- ```
339
-
340
- ### Methods
341
-
342
- | Method | Params | Returns |
343
- |--------|--------|---------|
344
- | `runActor` | `RunActorParams` | `RunActorResult` |
345
-
346
- ---
347
-
348
- ## Gmail Adapter
349
-
350
- Factory pattern -- 1 method for sending email via Gmail API.
351
-
352
- ```typescript
353
- const gmail = createGmailAdapter('my-gmail-credential')
354
- ```
355
-
356
- ### Methods
357
-
358
- | Method | Params | Returns |
359
- |--------|--------|---------|
360
- | `sendEmail` | `GmailSendEmailParams` | `GmailSendEmailResult` |
361
-
362
- ---
363
-
364
- ## Mailso Adapter
365
-
366
- Factory pattern -- 1 method for email verification.
367
-
368
- ```typescript
369
- const mailso = createMailsoAdapter('my-mailso-credential')
370
- ```
371
-
372
- ### Methods
373
-
374
- | Method | Params | Returns |
375
- |--------|--------|---------|
376
- | `verifyEmail` | `MailsoVerifyEmailParams` | `MailsoVerifyEmailResult` |
377
-
378
- ---
379
-
380
- ## Scheduler Adapter
381
-
382
- Singleton -- 9 methods for task schedule management.
383
-
384
- ```typescript
385
- import { scheduler } from '@elevasis/sdk/worker'
386
- ```
387
-
388
- ### Methods
389
-
390
- | Method | Params | Returns |
391
- |--------|--------|---------|
392
- | `createSchedule` | `CreateScheduleInput` | `TaskSchedule` |
393
- | `updateAnchor` | `{ scheduleId, anchorAt }` | `TaskSchedule` |
394
- | `deleteSchedule` | `{ scheduleId }` | `void` |
395
- | `findByIdempotencyKey` | `{ idempotencyKey }` | `TaskSchedule | null` |
396
- | `deleteScheduleByIdempotencyKey` | `{ idempotencyKey }` | `void` |
397
- | `listSchedules` | `{ status?, limit?, offset? }` | `TaskSchedule[]` |
398
- | `getSchedule` | `{ scheduleId }` | `TaskSchedule` |
399
- | `cancelSchedule` | `{ scheduleId }` | `void` |
400
- | `cancelSchedulesByMetadata` | `{ metadata }` | `{ cancelledCount }` |
401
-
402
- ### Examples
403
-
404
- ```typescript
405
- // Create a relative schedule (follow-up sequence)
406
- const schedule = await scheduler.createSchedule({
407
- organizationId: context.organizationId,
408
- name: 'Proposal follow-up',
409
- target: { resourceType: 'workflow', resourceId: 'send-followup' },
410
- scheduleConfig: {
411
- type: 'relative',
412
- anchorAt: '2026-03-15T10:00:00Z',
413
- anchorLabel: 'proposal_sent_date',
414
- items: [
415
- { offset: '+3d', payload: { step: 'first-followup' }, label: 'First follow-up' },
416
- { offset: '+7d', payload: { step: 'second-followup' }, label: 'Second follow-up' },
417
- ],
418
- },
419
- metadata: { dealId: 'deal-123', contactEmail: 'jane@acme.com' },
420
- idempotencyKey: 'proposal-followup-deal-123',
421
- })
422
-
423
- // Reschedule (update anchor)
424
- await scheduler.updateAnchor({
425
- scheduleId: schedule.id,
426
- anchorAt: '2026-03-20T10:00:00Z',
427
- })
428
-
429
- // Find by idempotency key (check if already created)
430
- const existing = await scheduler.findByIdempotencyKey({
431
- idempotencyKey: 'proposal-followup-deal-123',
432
- })
433
-
434
- // Cancel all schedules matching metadata
435
- await scheduler.cancelSchedulesByMetadata({
436
- metadata: { dealId: 'deal-123' },
437
- })
438
-
439
- // List active schedules
440
- const schedules = await scheduler.listSchedules({
441
- status: 'active',
442
- limit: 50,
443
- })
444
- ```
445
-
446
- ---
447
-
448
- ## Storage Adapter
449
-
450
- Singleton -- 5 methods for file storage operations.
451
-
452
- ```typescript
453
- import { storage } from '@elevasis/sdk/worker'
454
- ```
455
-
456
- All paths are relative to the organization's storage prefix. The platform injects the organization prefix server-side.
457
-
458
- ### Methods
459
-
460
- | Method | Params | Returns |
461
- |--------|--------|---------|
462
- | `upload` | `StorageUploadInput` | `StorageUploadOutput` |
463
- | `download` | `StorageDownloadInput` | `StorageDownloadOutput` |
464
- | `createSignedUrl` | `StorageSignedUrlInput` | `StorageSignedUrlOutput` |
465
- | `delete` | `StorageDeleteInput` | `StorageDeleteOutput` |
466
- | `list` | `StorageListInput` | `StorageListOutput` |
467
-
468
- ### Examples
469
-
470
- ```typescript
471
- // Upload a PDF
472
- await storage.upload({
473
- bucket: 'acquisition',
474
- path: 'proposals/deal-123/proposal.pdf',
475
- content: base64PdfContent,
476
- contentType: 'application/pdf',
477
- })
478
-
479
- // Generate a signed URL (temporary access)
480
- const { signedUrl } = await storage.createSignedUrl({
481
- bucket: 'acquisition',
482
- path: 'proposals/deal-123/proposal.pdf',
483
- })
484
-
485
- // Download a file
486
- const file = await storage.download({
487
- bucket: 'acquisition',
488
- path: 'proposals/deal-123/proposal.pdf',
489
- })
490
-
491
- // List files under a prefix
492
- const files = await storage.list({
493
- bucket: 'acquisition',
494
- path: 'proposals/deal-123/',
495
- })
496
-
497
- // Delete a file
498
- await storage.delete({
499
- bucket: 'acquisition',
500
- path: 'proposals/deal-123/old-proposal.pdf',
501
- })
502
- ```
503
-
504
- ---
505
-
506
- ## Notification Adapter
507
-
508
- Singleton -- 1 method for sending in-app team notifications.
509
-
510
- ```typescript
511
- import { notifications } from '@elevasis/sdk/worker'
512
- ```
513
-
514
- `userId` and `organizationId` are injected server-side from the execution context -- you never pass them.
515
-
516
- ### Method
517
-
518
- | Method | Params | Returns |
519
- |--------|--------|---------|
520
- | `create` | `NotificationSDKInput` | `void` |
521
-
522
- `NotificationSDKInput` fields: `category`, `title`, `message`, `actionUrl?`, `metadata?`
523
-
524
- ### Example
525
-
526
- ```typescript
527
- await notifications.create({
528
- category: 'acquisition',
529
- title: 'New lead qualified',
530
- message: 'Acme Corp has been qualified and moved to proposal stage.',
531
- actionUrl: '/deals/deal-123',
532
- })
533
- ```
534
-
535
- ---
536
-
537
- ## LLM Adapter
538
-
539
- Singleton -- 1 method with a generic `<T>` for typed structured output.
540
-
541
- ```typescript
542
- import { llm } from '@elevasis/sdk/worker'
543
- ```
544
-
545
- No API keys needed -- keys are resolved server-side from environment variables.
546
-
547
- ### Method
548
-
549
- | Method | Params | Returns |
550
- |--------|--------|---------|
551
- | `generate<T>` | `Omit<LLMGenerateRequest, 'signal'>` | `LLMGenerateResponse<T>` |
552
-
553
- The `signal` property (AbortSignal) is not serializable over the postMessage boundary. Abort is handled at the worker level via the parent process sending an abort message.
554
-
555
- ### Example
556
-
557
- ```typescript
558
- interface Classification {
559
- category: 'interested' | 'not-interested' | 'bounced'
560
- confidence: number
561
- summary: string
562
- }
563
-
564
- const response = await llm.generate<Classification>({
565
- provider: 'anthropic',
566
- model: 'claude-sonnet-4-5',
567
- messages: [
568
- { role: 'system', content: 'Classify this email reply.' },
569
- { role: 'user', content: emailText },
570
- ],
571
- responseSchema: {
572
- type: 'object',
573
- properties: {
574
- category: { type: 'string', enum: ['interested', 'not-interested', 'bounced'] },
575
- confidence: { type: 'number', minimum: 0, maximum: 1 },
576
- summary: { type: 'string' },
577
- },
578
- required: ['category', 'confidence', 'summary'],
579
- },
580
- temperature: 0.1,
581
- })
582
-
583
- // response.output is typed as Classification
584
- const { category, confidence, summary } = response.output
585
- ```
586
-
587
- ---
588
-
589
- ## Lead Adapter
590
-
591
- Singleton -- 35 methods for acquisition lead management (lists, companies, contacts, deals, deal-sync). `organizationId` is injected server-side -- never pass it.
592
-
593
- ```typescript
594
- import { lead } from '@elevasis/sdk/worker'
595
- ```
596
-
597
- ### Methods
598
-
599
- **List operations:**
600
-
601
- | Method | Params | Returns |
602
- |--------|--------|---------|
603
- | `listLists` | none | `AcqList[]` |
604
- | `createList` | `Omit<CreateListParams, 'organizationId'>` | `AcqList` |
605
- | `updateList` | `{ id } & UpdateListParams` | `AcqList` |
606
- | `deleteList` | `{ id }` | `void` |
607
-
608
- **Company operations:**
609
-
610
- | Method | Params | Returns |
611
- |--------|--------|---------|
612
- | `createCompany` | `Omit<CreateCompanyParams, 'organizationId'>` | `AcqCompany` |
613
- | `upsertCompany` | `Omit<UpsertCompanyParams, 'organizationId'>` | `AcqCompany` |
614
- | `updateCompany` | `{ id } & UpdateCompanyParams` | `AcqCompany` |
615
- | `getCompany` | `{ id }` | `AcqCompany | null` |
616
- | `listCompanies` | `{ filters? }` | `AcqCompany[]` |
617
- | `deleteCompany` | `{ id }` | `void` |
618
-
619
- **Contact operations:**
620
-
621
- | Method | Params | Returns |
622
- |--------|--------|---------|
623
- | `createContact` | `Omit<CreateContactParams, 'organizationId'>` | `AcqContact` |
624
- | `upsertContact` | `Omit<UpsertContactParams, 'organizationId'>` | `AcqContact` |
625
- | `updateContact` | `{ id } & UpdateContactParams` | `AcqContact` |
626
- | `getContact` | `{ id }` | `AcqContact | null` |
627
- | `getContactByEmail` | `{ email }` | `AcqContact | null` |
628
- | `listContacts` | `{ filters?, pagination? }` | `PaginatedResult<AcqContact>` |
629
- | `deleteContact` | `{ id }` | `void` |
630
- | `bulkImportContacts` | `Omit<BulkImportParams, 'organizationId'>` | `BulkImportResult` |
631
-
632
- **Deal operations:**
633
-
634
- | Method | Params | Returns |
635
- |--------|--------|---------|
636
- | `upsertDeal` | `Omit<UpsertDealParams, 'organizationId'>` | `AcqDeal` |
637
- | `getDealByEmail` | `{ email }` | `AcqDeal | null` |
638
- | `getDealByEnvelopeId` | `{ envelopeId }` | `AcqDeal | null` |
639
- | `updateDealEnvelopeId` | `{ attioDealId, envelopeId }` | `AcqDeal | null` |
640
- | `getDealByAttioId` | `{ attioDealId }` | `AcqDeal | null` |
641
-
642
- **Deal-sync operations:**
643
-
644
- | Method | Params | Returns |
645
- |--------|--------|---------|
646
- | `updateDiscoveryData` | `Omit<UpdateDiscoveryDataParams, 'organizationId'>` | `void` |
647
- | `updateProposalData` | `Omit<UpdateProposalDataParams, 'organizationId'>` | `void` |
648
- | `markProposalSent` | `Omit<MarkProposalSentParams, 'organizationId'>` | `void` |
649
- | `markProposalReviewed` | `Omit<MarkProposalReviewedParams, 'organizationId'>` | `void` |
650
- | `updateCloseLostReason` | `Omit<UpdateCloseLostReasonParams, 'organizationId'>` | `void` |
651
- | `updateFees` | `Omit<UpdateFeesParams, 'organizationId'>` | `void` |
652
- | `syncDealStage` | `Omit<SyncDealStageParams, 'organizationId'>` | `void` |
653
- | `setContactNurture` | `Omit<SetContactNurtureParams, 'organizationId'>` | `void` |
654
- | `cancelSchedulesAndHitlByEmail` | `Omit<..., 'organizationId'>` | `{ schedulesCancelled, hitlDeleted }` |
655
- | `cancelHitlByDealId` | `Omit<..., 'organizationId'>` | `{ hitlDeleted }` |
656
- | `clearDealFields` | `Omit<ClearDealFieldsParams, 'organizationId'>` | `void` |
657
- | `deleteDeal` | `Omit<DeleteDealParams, 'organizationId'>` | `void` |
658
-
659
- ### Example
660
-
661
- ```typescript
662
- const deal = await lead.getDealByEmail({ email: 'jane@acme.com' })
663
- if (!deal) {
664
- await lead.upsertDeal({
665
- attioDealId: 'deal-123',
666
- contactEmail: 'jane@acme.com',
667
- })
668
- }
669
-
670
- // Bulk import contacts
671
- await lead.bulkImportContacts({
672
- listId: 'list-abc',
673
- contacts: [
674
- { email: 'a@example.com', firstName: 'Alice' },
675
- { email: 'b@example.com', firstName: 'Bob' },
676
- ],
677
- })
678
- ```
679
-
680
- ---
681
-
682
- ## PDF Adapter
683
-
684
- Singleton -- 2 methods for rendering PDFDocument structures to files or buffers. No credential required.
685
-
686
- ```typescript
687
- import { pdf } from '@elevasis/sdk/worker'
688
- ```
689
-
690
- ### Methods
691
-
692
- | Method | Params | Returns |
693
- |--------|--------|---------|
694
- | `render` | `{ document, theme?, storage: { bucket, path } }` | `{ success, pdfUrl, size }` |
695
- | `renderToBuffer` | `{ document, theme? }` | `{ buffer }` |
696
-
697
- ### Example
698
-
699
- ```typescript
700
- // Render to storage (returns a URL)
701
- const result = await pdf.render({
702
- document: proposalDocument,
703
- storage: { bucket: 'acquisition', path: 'proposals/deal-123/proposal.pdf' },
704
- })
705
- console.log(result.pdfUrl)
706
-
707
- // Render to buffer (for inline processing)
708
- const { buffer } = await pdf.renderToBuffer({
709
- document: proposalDocument,
710
- })
711
- ```
712
-
713
- ---
714
-
715
- ## Approval Adapter
716
-
717
- Singleton -- 2 methods for creating and managing human-in-the-loop (HITL) approval tasks. No credential required.
718
-
719
- ```typescript
720
- import { approval } from '@elevasis/sdk/worker'
721
- ```
722
-
723
- ### Methods
724
-
725
- | Method | Params | Returns |
726
- |--------|--------|---------|
727
- | `create` | `{ actions, context, description?, priority?, humanCheckpoint?, metadata?, expiresAt? }` | `{ id }` |
728
- | `deleteByMetadata` | `{ metadata, status? }` | `{ deleted }` |
729
-
730
- ### Example
731
-
732
- ```typescript
733
- // Create an approval gate
734
- const task = await approval.create({
735
- actions: [
736
- { id: 'approve', label: 'Approve', type: 'primary' },
737
- { id: 'reject', label: 'Reject', type: 'danger' },
738
- ],
739
- context: { dealId: 'deal-123', proposalUrl: 'https://...' },
740
- description: 'Review proposal for Acme Corp',
741
- humanCheckpoint: 'proposal-review',
742
- metadata: { dealId: 'deal-123' },
743
- })
744
-
745
- // Clean up stale tasks
746
- await approval.deleteByMetadata({
747
- metadata: { dealId: 'deal-123' },
748
- status: 'pending',
749
- })
750
- ```
751
-
752
- ---
753
-
754
- ## Execution Adapter
755
-
756
- Singleton -- 1 method for triggering another resource (workflow or agent) as a nested child execution. No credential required.
757
-
758
- ```typescript
759
- import { execution } from '@elevasis/sdk/worker'
760
- ```
761
-
762
- ### Method
763
-
764
- | Method | Params | Returns |
765
- |--------|--------|---------|
766
- | `trigger` | `{ resourceId, input? }` | `{ success, executionId, output, error? }` |
767
-
768
- ### Example
769
-
770
- ```typescript
771
- const result = await execution.trigger({
772
- resourceId: 'send-welcome-sequence',
773
- input: { userId: newUser.id, email: newUser.email },
774
- })
775
-
776
- if (!result.success) {
777
- throw new Error(`Child workflow failed: ${result.error}`)
778
- }
779
- ```
780
-
781
- Nested executions are tracked with depth up to a maximum of 5 levels.
782
-
783
- ---
784
-
785
- ## Email Adapter
786
-
787
- Singleton -- 1 method for sending platform emails to organization members (from `notifications@elevasis.io`). For client-facing emails, use the Resend or Instantly integration adapters instead.
788
-
789
- ```typescript
790
- import { email } from '@elevasis/sdk/worker'
791
- ```
792
-
793
- ### Method
794
-
795
- | Method | Params | Returns |
796
- |--------|--------|---------|
797
- | `send` | `{ subject, html?, text?, userIds?, targetRole?, targetAll?, replyTo?, tags? }` | `{ sent, failed, errors? }` |
798
-
799
- ### Example
800
-
801
- ```typescript
802
- // Notify all org members
803
- await email.send({
804
- subject: 'New deal closed',
805
- text: 'Acme Corp has signed the contract.',
806
- targetAll: true,
807
- })
808
-
809
- // Notify specific users
810
- await email.send({
811
- subject: 'Action required',
812
- html: '\<p\>Please review the proposal.\</p\>',
813
- userIds: ['user-abc', 'user-def'],
814
- })
815
- ```
816
-
817
- ---
818
-
819
- ## Custom Adapters with `createAdapter`
820
-
821
- The generic `createAdapter` factory is exported for building adapters for any tool. Define a type map and call the factory.
822
-
823
- ```typescript
824
- import { createAdapter } from '@elevasis/sdk/worker'
825
-
826
- // 1. Define a type map
827
- type MyToolMap = {
828
- doSomething: { params: { input: string }; result: { output: string } }
829
- listItems: { params: { limit?: number }; result: { items: string[] } }
830
- getStatus: { params: Record<string, never>; result: { healthy: boolean } }
831
- }
832
-
833
- // 2. Create the adapter
834
- const myTool = createAdapter<MyToolMap>('my-tool', [
835
- 'doSomething', 'listItems', 'getStatus',
836
- ], 'my-credential') // credential is optional
837
-
838
- // 3. Use it (fully typed)
839
- const result = await myTool.doSomething({ input: 'hello' })
840
- // ^-- { output: string }
841
- const status = await myTool.getStatus()
842
- // ^-- { healthy: boolean } (zero-arg because params is Record<string, never>)
843
- ```
844
-
845
- Method names are compile-time checked against the type map keys -- misspelling a method name is a compile error.
846
-
847
- ---
848
-
849
- ## When to Use Adapters vs `platform.call()`
850
-
851
- | Scenario | Use |
852
- |----------|-----|
853
- | Tool has a typed adapter (all integrations + platform tools) | Adapter |
854
- | Need autocomplete and type safety | Adapter |
855
- | New dispatcher method added server-side, no SDK update yet | `platform.call()` |
856
- | Tool without a typed adapter (supabase, session-memory, status, http) | `platform.call()` |
857
-
858
- `platform.call()` remains the universal escape hatch. Every adapter call compiles down to it. Both approaches work simultaneously with no conflicts.
859
-
860
- ---
861
-
862
- ## Available Platform Tools (Full Inventory)
863
-
864
- Not all platform tools have typed adapters. Here is the complete list of tools accessible via `platform.call()`:
865
-
866
- ### Integration Adapters (credential required)
867
-
868
- | Tool | Typed Adapter | Methods | Credential Shape |
869
- |------|--------------|---------|-----------------|
870
- | `attio` | `createAttioAdapter` | 12 (CRUD + schema + notes) | `{ apiKey }` |
871
- | `google-sheets` | `createGoogleSheetsAdapter` | 13 (read/write/filter/upsert) | OAuth2 / service account |
872
- | `trello` | `createTrelloAdapter` | 10 (cards/lists/checklists) | `{ apiKey, token }` |
873
- | `notion` | `createNotionAdapter` | 8 (pages + blocks) | `{ token }` |
874
- | `stripe` | `createStripeAdapter` | 6 (payment links + checkout) | `{ secretKey }` |
875
- | `instantly` | `createInstantlyAdapter` | 5 (email campaigns) | `{ apiKey }` |
876
- | `signature-api` | `createSignatureApiAdapter` | 4 (envelopes) | `{ apiKey }` |
877
- | `resend` | `createResendAdapter` | 2 (send/get email) | `{ apiKey }` |
878
- | `dropbox` | `createDropboxAdapter` | 2 (upload/folder) | `{ accessToken }` |
879
- | `apify` | `createApifyAdapter` | 1 (run actor) | `{ token }` |
880
- | `gmail` | `createGmailAdapter` | 1 (send email) | OAuth2 / service account |
881
- | `mailso` | `createMailsoAdapter` | 1 (verify email) | `{ apiKey }` |
882
- | `supabase` | -- | 7 (insert/select/update/delete/upsert/rpc/count) | `{ url, serviceRoleKey }` |
883
-
884
- ### Platform Services (no credential)
885
-
886
- | Tool | Typed Adapter | Methods |
887
- |------|--------------|---------|
888
- | `scheduler` | `scheduler` | `createSchedule`, `updateAnchor`, `deleteSchedule`, `findByIdempotencyKey`, `deleteScheduleByIdempotencyKey`, `listSchedules`, `getSchedule`, `cancelSchedule`, `cancelSchedulesByMetadata` |
889
- | `storage` | `storage` | `upload`, `download`, `createSignedUrl`, `delete`, `list` |
890
- | `notification` | `notifications` | `create` |
891
- | `llm` | `llm` | `generate` |
892
- | `lead` | `lead` | 35 methods (lists, companies, contacts, deals, deal-sync) |
893
- | `email` | `email` | `send` |
894
- | `pdf` | `pdf` | `render`, `renderToBuffer` |
895
- | `approval` | `approval` | `create`, `deleteByMetadata` |
896
- | `execution` | `execution` | `trigger` |
897
- | `http` | -- | Raw HTTP with server-side credential injection |
898
- | `status` | -- | `overview` |
899
- | `session-memory` | -- | `load`, `save` |
900
-
901
- ---
902
-
903
- ## Error Handling
904
-
905
- All adapter calls throw `PlatformToolError` on failure, with a `code` field and `retryable` flag:
906
-
907
- ```typescript
908
- import { PlatformToolError } from '@elevasis/sdk/worker'
909
-
910
- try {
911
- await attio.listRecords({ object: 'deals' })
912
- } catch (err) {
913
- if (err instanceof PlatformToolError) {
914
- console.log(err.message) // Human-readable error
915
- console.log(err.code) // e.g., 'rate_limit_exceeded', 'credentials_missing'
916
- console.log(err.retryable) // true for transient errors
917
- }
918
- }
919
- ```
920
-
921
- Retryable error codes: `rate_limit_exceeded`, `network_error`, `timeout_error`, `api_error`, `service_unavailable`, `server_unavailable`.
922
-
923
- Timeouts: LLM calls have a 120s timeout. All other tool calls have a 60s timeout.
924
-
925
- ---
926
-
927
- **Last Updated:** 2026-03-02
928
-
929
-
1
+ ---
2
+ title: Typed Adapters
3
+ description: Type-safe wrappers over platform.call() for all integrations and platform tools -- Attio, Stripe, Notion, Google Sheets, and more -- with full autocomplete, compile-time checking, and zero boilerplate
4
+ loadWhen: "Using typed adapters instead of raw platform.call(), or needs to know what adapter methods are available"
5
+ ---
6
+
7
+ Typed adapters are ergonomic wrappers over `platform.call()` that provide full TypeScript autocomplete and compile-time type checking. They eliminate stringly-typed method names, manual `as Promise<T>` casts, and repeated credential passing.
8
+
9
+ Both patterns work simultaneously -- adapters compile down to `platform.call()` with zero runtime overhead.
10
+
11
+ **Coverage:** 11 integration adapters (55 methods) + 9 platform tool adapters (57 methods) = 112 total typed methods.
12
+
13
+ ```typescript
14
+ // Before: raw platform.call()
15
+ const records = await platform.call({
16
+ tool: 'attio',
17
+ method: 'listRecords',
18
+ credential: 'my-attio',
19
+ params: { object: 'deals' }
20
+ }) as unknown as QueryRecordsResult
21
+
22
+ // After: typed adapter
23
+ const attio = createAttioAdapter('my-attio')
24
+ const records = await attio.listRecords({ object: 'deals' })
25
+ // ^-- QueryRecordsResult (fully typed, autocomplete on params)
26
+ ```
27
+
28
+ All adapters are imported from `@elevasis/sdk/worker` -- the same subpath as `platform`.
29
+
30
+ ---
31
+
32
+ ## Quick Reference
33
+
34
+ ### Integration Adapters (factory pattern, credential required)
35
+
36
+ | Import | Methods |
37
+ | --------------------------------- | ------- |
38
+ | `createAttioAdapter(cred)` | 12 |
39
+ | `createStripeAdapter(cred)` | 6 |
40
+ | `createNotionAdapter(cred)` | 8 |
41
+ | `createGoogleSheetsAdapter(cred)` | 13 |
42
+ | `createInstantlyAdapter(cred)` | 5 |
43
+ | `createSignatureApiAdapter(cred)` | 4 |
44
+ | `createResendAdapter(cred)` | 2 |
45
+ | `createDropboxAdapter(cred)` | 2 |
46
+ | `createApifyAdapter(cred)` | 1 |
47
+ | `createGmailAdapter(cred)` | 1 |
48
+ | `createMailsoAdapter(cred)` | 1 |
49
+
50
+ ### Platform Adapters (singletons, no credential)
51
+
52
+ | Import | Methods |
53
+ | --------------- | ------- |
54
+ | `lead` | 35 |
55
+ | `scheduler` | 9 |
56
+ | `storage` | 5 |
57
+ | `pdf` | 2 |
58
+ | `approval` | 2 |
59
+ | `notifications` | 1 |
60
+ | `llm` | 1 |
61
+ | `execution` | 1 |
62
+ | `email` | 1 |
63
+
64
+ ### Generic Factory
65
+
66
+ | Import | Description |
67
+ | --------------------------------------------- | ---------------------------------- |
68
+ | `createAdapter<TMap>(tool, methods, cred?)` | Build custom adapters for any tool |
69
+
70
+ ```typescript
71
+ import {
72
+ // Integration adapters
73
+ createAttioAdapter, createStripeAdapter, createNotionAdapter,
74
+ createGoogleSheetsAdapter, createInstantlyAdapter,
75
+ createSignatureApiAdapter, createResendAdapter, createDropboxAdapter,
76
+ createApifyAdapter, createGmailAdapter, createMailsoAdapter,
77
+ // Platform adapters
78
+ lead, scheduler, storage, pdf, approval, notifications, llm, execution, email,
79
+ // Generic factory
80
+ createAdapter,
81
+ } from '@elevasis/sdk/worker'
82
+ ```
83
+
84
+ ---
85
+
86
+ ## Attio CRM Adapter
87
+
88
+ Factory pattern -- bind a credential once, use 12 typed methods.
89
+
90
+ ```typescript
91
+ const attio = createAttioAdapter('my-attio-credential')
92
+ ```
93
+
94
+ ### Methods
95
+
96
+ | Method | Params | Returns |
97
+ | ----------------- | ----------------------- | ----------------------- |
98
+ | `createRecord` | `CreateRecordParams` | `CreateRecordResult` |
99
+ | `updateRecord` | `UpdateRecordParams` | `UpdateRecordResult` |
100
+ | `listRecords` | `QueryRecordsParams` | `QueryRecordsResult` |
101
+ | `getRecord` | `GetRecordParams` | `GetRecordResult` |
102
+ | `deleteRecord` | `DeleteRecordParams` | `DeleteRecordResult` |
103
+ | `listObjects` | none | `ListObjectsResult` |
104
+ | `listAttributes` | `ListAttributesParams` | `ListAttributesResult` |
105
+ | `createAttribute` | `CreateAttributeParams` | `CreateAttributeResult` |
106
+ | `updateAttribute` | `UpdateAttributeParams` | `UpdateAttributeResult` |
107
+ | `createNote` | `CreateNoteParams` | `CreateNoteResult` |
108
+ | `listNotes` | `ListNotesParams` | `ListNotesResult` |
109
+ | `deleteNote` | `DeleteNoteParams` | `DeleteNoteResult` |
110
+
111
+ ### Examples
112
+
113
+ ```typescript
114
+ // Create a company record
115
+ const company = await attio.createRecord({
116
+ object: 'companies',
117
+ values: {
118
+ name: [{ value: 'Acme Corp' }],
119
+ domains: [{ domain: 'acme.com' }],
120
+ },
121
+ })
122
+
123
+ // Query deals with filters
124
+ const deals = await attio.listRecords({
125
+ object: 'deals',
126
+ filter: {
127
+ operator: 'and',
128
+ filters: [
129
+ { field: 'stage', operator: 'equals', value: 'proposal' },
130
+ ],
131
+ },
132
+ sorts: [{ field: 'created_at', direction: 'desc' }],
133
+ limit: 20,
134
+ })
135
+
136
+ // Get a specific record
137
+ const record = await attio.getRecord({
138
+ object: 'people',
139
+ recordId: 'rec_abc123',
140
+ })
141
+
142
+ // List all objects (no params)
143
+ const objects = await attio.listObjects()
144
+
145
+ // Create a note on a record
146
+ await attio.createNote({
147
+ parentObject: 'deals',
148
+ parentRecordId: 'rec_abc123',
149
+ title: 'Discovery call notes',
150
+ content: 'Key takeaways from the call...',
151
+ })
152
+ ```
153
+
154
+ Multiple adapters with different credentials work simultaneously:
155
+
156
+ ```typescript
157
+ const prodAttio = createAttioAdapter('prod-attio')
158
+ const testAttio = createAttioAdapter('test-attio')
159
+ ```
160
+
161
+ ---
162
+
163
+ ## Stripe Adapter
164
+
165
+ Factory pattern -- 6 methods for payment links and checkout sessions.
166
+
167
+ ```typescript
168
+ const stripe = createStripeAdapter('my-stripe-credential')
169
+ ```
170
+
171
+ ### Methods
172
+
173
+ | Method | Params | Returns |
174
+ | ----------------------- | ----------------------------- | ----------------------------- |
175
+ | `createPaymentLink` | `CreatePaymentLinkParams` | `CreatePaymentLinkResult` |
176
+ | `getPaymentLink` | `GetPaymentLinkParams` | `GetPaymentLinkResult` |
177
+ | `updatePaymentLink` | `UpdatePaymentLinkParams` | `UpdatePaymentLinkResult` |
178
+ | `listPaymentLinks` | `ListPaymentLinksParams` | `ListPaymentLinksResult` |
179
+ | `createAutoPaymentLink` | `CreateAutoPaymentLinkParams` | `CreateAutoPaymentLinkResult` |
180
+ | `createCheckoutSession` | `CreateCheckoutSessionParams` | `CreateCheckoutSessionResult` |
181
+
182
+ ---
183
+
184
+ ## Notion Adapter
185
+
186
+ Factory pattern -- 8 methods for page and block operations.
187
+
188
+ ```typescript
189
+ const notion = createNotionAdapter('my-notion-credential')
190
+ ```
191
+
192
+ ### Methods
193
+
194
+ | Method | Params | Returns |
195
+ | ----------------- | ----------------------- | ----------------------- |
196
+ | `listAllPages` | none | `ListAllPagesResult` |
197
+ | `readPage` | `ReadPageParams` | `ReadPageResult` |
198
+ | `createPage` | `CreatePageParams` | `CreatePageResult` |
199
+ | `updatePageTitle` | `UpdatePageTitleParams` | `UpdatePageTitleResult` |
200
+ | `appendBlocks` | `AppendBlocksParams` | `AppendBlocksResult` |
201
+ | `updateBlocks` | `UpdateBlocksParams` | `UpdateBlocksResult` |
202
+ | `deletePage` | `DeletePageParams` | `DeletePageResult` |
203
+ | `deleteBlocks` | `DeleteBlocksParams` | `DeleteBlocksResult` |
204
+
205
+ ---
206
+
207
+ ## Google Sheets Adapter
208
+
209
+ Factory pattern -- 13 methods including workflow-friendly helpers (getRowByValue, upsertRow, filterRows).
210
+
211
+ ```typescript
212
+ const sheets = createGoogleSheetsAdapter('my-google-credential')
213
+ ```
214
+
215
+ ### Methods
216
+
217
+ | Method | Params | Returns |
218
+ | ------------------------ | ------------------------------ | ------------------------------ |
219
+ | `readSheet` | `ReadSheetParams` | `ReadSheetResult` |
220
+ | `writeSheet` | `WriteSheetParams` | `WriteSheetResult` |
221
+ | `appendRows` | `AppendRowsParams` | `AppendRowsResult` |
222
+ | `clearRange` | `ClearRangeParams` | `ClearRangeResult` |
223
+ | `getSpreadsheetMetadata` | `GetSpreadsheetMetadataParams` | `GetSpreadsheetMetadataResult` |
224
+ | `batchUpdate` | `BatchUpdateParams` | `BatchUpdateResult` |
225
+ | `getHeaders` | `GetHeadersParams` | `GetHeadersResult` |
226
+ | `getLastRow` | `GetLastRowParams` | `GetLastRowResult` |
227
+ | `getRowByValue` | `GetRowByValueParams` | `GetRowByValueResult` |
228
+ | `updateRowByValue` | `UpdateRowByValueParams` | `UpdateRowByValueResult` |
229
+ | `upsertRow` | `UpsertRowParams` | `UpsertRowResult` |
230
+ | `filterRows` | `FilterRowsParams` | `FilterRowsResult` |
231
+ | `deleteRowByValue` | `DeleteRowByValueParams` | `DeleteRowByValueResult` |
232
+
233
+ ---
234
+
235
+ ## Instantly Adapter
236
+
237
+ Factory pattern -- 5 methods for email campaign management.
238
+
239
+ ```typescript
240
+ const instantly = createInstantlyAdapter('my-instantly-credential')
241
+ ```
242
+
243
+ ### Methods
244
+
245
+ | Method | Params | Returns |
246
+ | ----------------------- | ----------------------------- | ----------------------------- |
247
+ | `sendReply` | `SendReplyParams` | `SendReplyResult` |
248
+ | `removeFromSubsequence` | `RemoveFromSubsequenceParams` | `RemoveFromSubsequenceResult` |
249
+ | `getEmails` | `GetEmailsParams` | `GetEmailsResult` |
250
+ | `updateInterestStatus` | `UpdateInterestStatusParams` | `UpdateInterestStatusResult` |
251
+ | `addToCampaign` | `AddToCampaignParams` | `AddToCampaignResult` |
252
+
253
+ ---
254
+
255
+ ## SignatureAPI Adapter
256
+
257
+ Factory pattern -- 4 methods for eSignature envelope operations.
258
+
259
+ ```typescript
260
+ const signatureApi = createSignatureApiAdapter('my-signatureapi-credential')
261
+ ```
262
+
263
+ ### Methods
264
+
265
+ | Method | Params | Returns |
266
+ | ------------------ | ------------------------ | ------------------------ |
267
+ | `createEnvelope` | `CreateEnvelopeParams` | `CreateEnvelopeResult` |
268
+ | `voidEnvelope` | `VoidEnvelopeParams` | `VoidEnvelopeResult` |
269
+ | `downloadDocument` | `DownloadDocumentParams` | `DownloadDocumentResult` |
270
+ | `getEnvelope` | `GetEnvelopeParams` | `GetEnvelopeResult` |
271
+
272
+ ---
273
+
274
+ ## Resend Adapter
275
+
276
+ Factory pattern -- 2 methods for transactional email.
277
+
278
+ ```typescript
279
+ const resend = createResendAdapter('my-resend-credential')
280
+ ```
281
+
282
+ ### Methods
283
+
284
+ | Method | Params | Returns |
285
+ | ----------- | ----------------------- | ----------------------- |
286
+ | `sendEmail` | `ResendSendEmailParams` | `ResendSendEmailResult` |
287
+ | `getEmail` | `ResendGetEmailParams` | `ResendGetEmailResult` |
288
+
289
+ ---
290
+
291
+ ## Dropbox Adapter
292
+
293
+ Factory pattern -- 2 methods for file operations.
294
+
295
+ ```typescript
296
+ const dropbox = createDropboxAdapter('my-dropbox-credential')
297
+ ```
298
+
299
+ ### Methods
300
+
301
+ | Method | Params | Returns |
302
+ | -------------- | -------------------- | -------------------- |
303
+ | `uploadFile` | `UploadFileParams` | `UploadFileResult` |
304
+ | `createFolder` | `CreateFolderParams` | `CreateFolderResult` |
305
+
306
+ ---
307
+
308
+ ## Apify Adapter
309
+
310
+ Factory pattern -- 1 method for running web scraping actors.
311
+
312
+ ```typescript
313
+ const apify = createApifyAdapter('my-apify-credential')
314
+ ```
315
+
316
+ ### Methods
317
+
318
+ | Method | Params | Returns |
319
+ | ---------- | ---------------- | ---------------- |
320
+ | `runActor` | `RunActorParams` | `RunActorResult` |
321
+
322
+ ---
323
+
324
+ ## Gmail Adapter
325
+
326
+ Factory pattern -- 1 method for sending email via Gmail API.
327
+
328
+ ```typescript
329
+ const gmail = createGmailAdapter('my-gmail-credential')
330
+ ```
331
+
332
+ ### Methods
333
+
334
+ | Method | Params | Returns |
335
+ | ----------- | ---------------------- | ---------------------- |
336
+ | `sendEmail` | `GmailSendEmailParams` | `GmailSendEmailResult` |
337
+
338
+ ---
339
+
340
+ ## Mailso Adapter
341
+
342
+ Factory pattern -- 1 method for email verification.
343
+
344
+ ```typescript
345
+ const mailso = createMailsoAdapter('my-mailso-credential')
346
+ ```
347
+
348
+ ### Methods
349
+
350
+ | Method | Params | Returns |
351
+ | ------------- | ------------------------- | ------------------------- |
352
+ | `verifyEmail` | `MailsoVerifyEmailParams` | `MailsoVerifyEmailResult` |
353
+
354
+ ---
355
+
356
+ ## Scheduler Adapter
357
+
358
+ Singleton -- 9 methods for task schedule management.
359
+
360
+ ```typescript
361
+ import { scheduler } from '@elevasis/sdk/worker'
362
+ ```
363
+
364
+ ### Methods
365
+
366
+ | Method | Params | Returns |
367
+ | -------------------------------- | ------------------------------ | ---------------------- |
368
+ | `createSchedule` | `CreateScheduleInput` | `TaskSchedule` |
369
+ | `updateAnchor` | `{ scheduleId, anchorAt }` | `TaskSchedule` |
370
+ | `deleteSchedule` | `{ scheduleId }` | `void` |
371
+ | `findByIdempotencyKey` | `{ idempotencyKey }` | `TaskSchedule | null` |
372
+ | `deleteScheduleByIdempotencyKey` | `{ idempotencyKey }` | `void` |
373
+ | `listSchedules` | `{ status?, limit?, offset? }` | `TaskSchedule[]` |
374
+ | `getSchedule` | `{ scheduleId }` | `TaskSchedule` |
375
+ | `cancelSchedule` | `{ scheduleId }` | `void` |
376
+ | `cancelSchedulesByMetadata` | `{ metadata }` | `{ cancelledCount }` |
377
+
378
+ ### Examples
379
+
380
+ ```typescript
381
+ // Create a relative schedule (follow-up sequence)
382
+ const schedule = await scheduler.createSchedule({
383
+ organizationId: context.organizationId,
384
+ name: 'Proposal follow-up',
385
+ target: { resourceType: 'workflow', resourceId: 'send-followup' },
386
+ scheduleConfig: {
387
+ type: 'relative',
388
+ anchorAt: '2026-03-15T10:00:00Z',
389
+ anchorLabel: 'proposal_sent_date',
390
+ items: [
391
+ { offset: '+3d', payload: { step: 'first-followup' }, label: 'First follow-up' },
392
+ { offset: '+7d', payload: { step: 'second-followup' }, label: 'Second follow-up' },
393
+ ],
394
+ },
395
+ metadata: { dealId: 'deal-123', contactEmail: 'jane@acme.com' },
396
+ idempotencyKey: 'proposal-followup-deal-123',
397
+ })
398
+
399
+ // Reschedule (update anchor)
400
+ await scheduler.updateAnchor({
401
+ scheduleId: schedule.id,
402
+ anchorAt: '2026-03-20T10:00:00Z',
403
+ })
404
+
405
+ // Find by idempotency key (check if already created)
406
+ const existing = await scheduler.findByIdempotencyKey({
407
+ idempotencyKey: 'proposal-followup-deal-123',
408
+ })
409
+
410
+ // Cancel all schedules matching metadata
411
+ await scheduler.cancelSchedulesByMetadata({
412
+ metadata: { dealId: 'deal-123' },
413
+ })
414
+
415
+ // List active schedules
416
+ const schedules = await scheduler.listSchedules({
417
+ status: 'active',
418
+ limit: 50,
419
+ })
420
+ ```
421
+
422
+ ---
423
+
424
+ ## Storage Adapter
425
+
426
+ Singleton -- 5 methods for file storage operations.
427
+
428
+ ```typescript
429
+ import { storage } from '@elevasis/sdk/worker'
430
+ ```
431
+
432
+ All paths are relative to the organization's storage prefix. The platform injects the organization prefix server-side.
433
+
434
+ ### Methods
435
+
436
+ | Method | Params | Returns |
437
+ | ----------------- | ----------------------- | ------------------------ |
438
+ | `upload` | `StorageUploadInput` | `StorageUploadOutput` |
439
+ | `download` | `StorageDownloadInput` | `StorageDownloadOutput` |
440
+ | `createSignedUrl` | `StorageSignedUrlInput` | `StorageSignedUrlOutput` |
441
+ | `delete` | `StorageDeleteInput` | `StorageDeleteOutput` |
442
+ | `list` | `StorageListInput` | `StorageListOutput` |
443
+
444
+ ### Examples
445
+
446
+ ```typescript
447
+ // Upload a PDF
448
+ await storage.upload({
449
+ bucket: 'acquisition',
450
+ path: 'proposals/deal-123/proposal.pdf',
451
+ content: base64PdfContent,
452
+ contentType: 'application/pdf',
453
+ })
454
+
455
+ // Generate a signed URL (temporary access)
456
+ const { signedUrl } = await storage.createSignedUrl({
457
+ bucket: 'acquisition',
458
+ path: 'proposals/deal-123/proposal.pdf',
459
+ })
460
+
461
+ // Download a file
462
+ const file = await storage.download({
463
+ bucket: 'acquisition',
464
+ path: 'proposals/deal-123/proposal.pdf',
465
+ })
466
+
467
+ // List files under a prefix
468
+ const files = await storage.list({
469
+ bucket: 'acquisition',
470
+ path: 'proposals/deal-123/',
471
+ })
472
+
473
+ // Delete a file
474
+ await storage.delete({
475
+ bucket: 'acquisition',
476
+ path: 'proposals/deal-123/old-proposal.pdf',
477
+ })
478
+ ```
479
+
480
+ ---
481
+
482
+ ## Notification Adapter
483
+
484
+ Singleton -- 1 method for sending in-app team notifications.
485
+
486
+ ```typescript
487
+ import { notifications } from '@elevasis/sdk/worker'
488
+ ```
489
+
490
+ `userId` and `organizationId` are injected server-side from the execution context -- you never pass them.
491
+
492
+ ### Method
493
+
494
+ | Method | Params | Returns |
495
+ | -------- | ---------------------- | ------- |
496
+ | `create` | `NotificationSDKInput` | `void` |
497
+
498
+ `NotificationSDKInput` fields: `category`, `title`, `message`, `actionUrl?`, `metadata?`
499
+
500
+ ### Example
501
+
502
+ ```typescript
503
+ await notifications.create({
504
+ category: 'acquisition',
505
+ title: 'New lead qualified',
506
+ message: 'Acme Corp has been qualified and moved to proposal stage.',
507
+ actionUrl: '/deals/deal-123',
508
+ })
509
+ ```
510
+
511
+ ---
512
+
513
+ ## LLM Adapter
514
+
515
+ Singleton -- 1 method with a generic `<T>` for typed structured output.
516
+
517
+ ```typescript
518
+ import { llm } from '@elevasis/sdk/worker'
519
+ ```
520
+
521
+ No API keys needed -- keys are resolved server-side from environment variables.
522
+
523
+ ### Method
524
+
525
+ | Method | Params | Returns |
526
+ | --------------- | -------------------------------------- | -------------------------- |
527
+ | `generate<T>` | `Omit<LLMGenerateRequest, 'signal'>` | `LLMGenerateResponse<T>` |
528
+
529
+ The `signal` property (AbortSignal) is not serializable over the postMessage boundary. Abort is handled at the worker level via the parent process sending an abort message.
530
+
531
+ ### Example
532
+
533
+ ```typescript
534
+ interface Classification {
535
+ category: 'interested' | 'not-interested' | 'bounced'
536
+ confidence: number
537
+ summary: string
538
+ }
539
+
540
+ const response = await llm.generate<Classification>({
541
+ provider: 'anthropic',
542
+ model: 'claude-sonnet-4-5',
543
+ messages: [
544
+ { role: 'system', content: 'Classify this email reply.' },
545
+ { role: 'user', content: emailText },
546
+ ],
547
+ responseSchema: {
548
+ type: 'object',
549
+ properties: {
550
+ category: { type: 'string', enum: ['interested', 'not-interested', 'bounced'] },
551
+ confidence: { type: 'number', minimum: 0, maximum: 1 },
552
+ summary: { type: 'string' },
553
+ },
554
+ required: ['category', 'confidence', 'summary'],
555
+ },
556
+ temperature: 0.1,
557
+ })
558
+
559
+ // response.output is typed as Classification
560
+ const { category, confidence, summary } = response.output
561
+ ```
562
+
563
+ ---
564
+
565
+ ## Lead Adapter
566
+
567
+ Singleton -- 35 methods for acquisition lead management (lists, companies, contacts, deals, deal-sync). `organizationId` is injected server-side -- never pass it.
568
+
569
+ ```typescript
570
+ import { lead } from '@elevasis/sdk/worker'
571
+ ```
572
+
573
+ ### Methods
574
+
575
+ **List operations:**
576
+
577
+ | Method | Params | Returns |
578
+ | ------------ | -------------------------------------------- | ----------- |
579
+ | `listLists` | none | `AcqList[]` |
580
+ | `createList` | `Omit<CreateListParams, 'organizationId'>` | `AcqList` |
581
+ | `updateList` | `{ id } & UpdateListParams` | `AcqList` |
582
+ | `deleteList` | `{ id }` | `void` |
583
+
584
+ **Company operations:**
585
+
586
+ | Method | Params | Returns |
587
+ | --------------- | ----------------------------------------------- | -------------------- |
588
+ | `createCompany` | `Omit<CreateCompanyParams, 'organizationId'>` | `AcqCompany` |
589
+ | `upsertCompany` | `Omit<UpsertCompanyParams, 'organizationId'>` | `AcqCompany` |
590
+ | `updateCompany` | `{ id } & UpdateCompanyParams` | `AcqCompany` |
591
+ | `getCompany` | `{ id }` | `AcqCompany | null` |
592
+ | `listCompanies` | `{ filters? }` | `AcqCompany[]` |
593
+ | `deleteCompany` | `{ id }` | `void` |
594
+
595
+ **Contact operations:**
596
+
597
+ | Method | Params | Returns |
598
+ | -------------------- | ----------------------------------------------- | ------------------------------- |
599
+ | `createContact` | `Omit<CreateContactParams, 'organizationId'>` | `AcqContact` |
600
+ | `upsertContact` | `Omit<UpsertContactParams, 'organizationId'>` | `AcqContact` |
601
+ | `updateContact` | `{ id } & UpdateContactParams` | `AcqContact` |
602
+ | `getContact` | `{ id }` | `AcqContact | null` |
603
+ | `getContactByEmail` | `{ email }` | `AcqContact | null` |
604
+ | `listContacts` | `{ filters?, pagination? }` | `PaginatedResult<AcqContact>` |
605
+ | `deleteContact` | `{ id }` | `void` |
606
+ | `bulkImportContacts` | `Omit<BulkImportParams, 'organizationId'>` | `BulkImportResult` |
607
+
608
+ **Deal operations:**
609
+
610
+ | Method | Params | Returns |
611
+ | ---------------------- | -------------------------------------------- | ----------------- |
612
+ | `upsertDeal` | `Omit<UpsertDealParams, 'organizationId'>` | `AcqDeal` |
613
+ | `getDealByEmail` | `{ email }` | `AcqDeal | null` |
614
+ | `getDealByEnvelopeId` | `{ envelopeId }` | `AcqDeal | null` |
615
+ | `updateDealEnvelopeId` | `{ attioDealId, envelopeId }` | `AcqDeal | null` |
616
+ | `getDealByAttioId` | `{ attioDealId }` | `AcqDeal | null` |
617
+
618
+ **Deal-sync operations:**
619
+
620
+ | Method | Params | Returns |
621
+ | ------------------------------- | ------------------------------------------------------- | ------------------------------------- |
622
+ | `updateDiscoveryData` | `Omit<UpdateDiscoveryDataParams, 'organizationId'>` | `void` |
623
+ | `updateProposalData` | `Omit<UpdateProposalDataParams, 'organizationId'>` | `void` |
624
+ | `markProposalSent` | `Omit<MarkProposalSentParams, 'organizationId'>` | `void` |
625
+ | `markProposalReviewed` | `Omit<MarkProposalReviewedParams, 'organizationId'>` | `void` |
626
+ | `updateCloseLostReason` | `Omit<UpdateCloseLostReasonParams, 'organizationId'>` | `void` |
627
+ | `updateFees` | `Omit<UpdateFeesParams, 'organizationId'>` | `void` |
628
+ | `syncDealStage` | `Omit<SyncDealStageParams, 'organizationId'>` | `void` |
629
+ | `setContactNurture` | `Omit<SetContactNurtureParams, 'organizationId'>` | `void` |
630
+ | `cancelSchedulesAndHitlByEmail` | `Omit<..., 'organizationId'>` | `{ schedulesCancelled, hitlDeleted }` |
631
+ | `cancelHitlByDealId` | `Omit<..., 'organizationId'>` | `{ hitlDeleted }` |
632
+ | `clearDealFields` | `Omit<ClearDealFieldsParams, 'organizationId'>` | `void` |
633
+ | `deleteDeal` | `Omit<DeleteDealParams, 'organizationId'>` | `void` |
634
+
635
+ ### Example
636
+
637
+ ```typescript
638
+ const deal = await lead.getDealByEmail({ email: 'jane@acme.com' })
639
+ if (!deal) {
640
+ await lead.upsertDeal({
641
+ attioDealId: 'deal-123',
642
+ contactEmail: 'jane@acme.com',
643
+ })
644
+ }
645
+
646
+ // Bulk import contacts
647
+ await lead.bulkImportContacts({
648
+ listId: 'list-abc',
649
+ contacts: [
650
+ { email: 'a@example.com', firstName: 'Alice' },
651
+ { email: 'b@example.com', firstName: 'Bob' },
652
+ ],
653
+ })
654
+ ```
655
+
656
+ ---
657
+
658
+ ## PDF Adapter
659
+
660
+ Singleton -- 2 methods for rendering PDFDocument structures to files or buffers. No credential required.
661
+
662
+ ```typescript
663
+ import { pdf } from '@elevasis/sdk/worker'
664
+ ```
665
+
666
+ ### Methods
667
+
668
+ | Method | Params | Returns |
669
+ | ---------------- | ------------------------------------------------- | --------------------------- |
670
+ | `render` | `{ document, theme?, storage: { bucket, path } }` | `{ success, pdfUrl, size }` |
671
+ | `renderToBuffer` | `{ document, theme? }` | `{ buffer }` |
672
+
673
+ ### Example
674
+
675
+ ```typescript
676
+ // Render to storage (returns a URL)
677
+ const result = await pdf.render({
678
+ document: proposalDocument,
679
+ storage: { bucket: 'acquisition', path: 'proposals/deal-123/proposal.pdf' },
680
+ })
681
+ console.log(result.pdfUrl)
682
+
683
+ // Render to buffer (for inline processing)
684
+ const { buffer } = await pdf.renderToBuffer({
685
+ document: proposalDocument,
686
+ })
687
+ ```
688
+
689
+ ---
690
+
691
+ ## Approval Adapter
692
+
693
+ Singleton -- 2 methods for creating and managing human-in-the-loop (HITL) approval tasks. No credential required.
694
+
695
+ ```typescript
696
+ import { approval } from '@elevasis/sdk/worker'
697
+ ```
698
+
699
+ ### Methods
700
+
701
+ | Method | Params | Returns |
702
+ | ------------------ | ---------------------------------------------------------------------------------------- | ------------- |
703
+ | `create` | `{ actions, context, description?, priority?, humanCheckpoint?, metadata?, expiresAt? }` | `{ id }` |
704
+ | `deleteByMetadata` | `{ metadata, status? }` | `{ deleted }` |
705
+
706
+ ### Example
707
+
708
+ ```typescript
709
+ // Create an approval gate
710
+ const task = await approval.create({
711
+ actions: [
712
+ { id: 'approve', label: 'Approve', type: 'primary' },
713
+ { id: 'reject', label: 'Reject', type: 'danger' },
714
+ ],
715
+ context: { dealId: 'deal-123', proposalUrl: 'https://...' },
716
+ description: 'Review proposal for Acme Corp',
717
+ humanCheckpoint: 'proposal-review',
718
+ metadata: { dealId: 'deal-123' },
719
+ })
720
+
721
+ // Clean up stale tasks
722
+ await approval.deleteByMetadata({
723
+ metadata: { dealId: 'deal-123' },
724
+ status: 'pending',
725
+ })
726
+ ```
727
+
728
+ ---
729
+
730
+ ## Execution Adapter
731
+
732
+ Singleton -- 1 method for triggering another resource (workflow or agent) as a nested child execution. No credential required.
733
+
734
+ ```typescript
735
+ import { execution } from '@elevasis/sdk/worker'
736
+ ```
737
+
738
+ ### Method
739
+
740
+ | Method | Params | Returns |
741
+ | --------- | ------------------------ | ------------------------------------------ |
742
+ | `trigger` | `{ resourceId, input? }` | `{ success, executionId, output, error? }` |
743
+
744
+ ### Example
745
+
746
+ ```typescript
747
+ const result = await execution.trigger({
748
+ resourceId: 'send-welcome-sequence',
749
+ input: { userId: newUser.id, email: newUser.email },
750
+ })
751
+
752
+ if (!result.success) {
753
+ throw new Error(`Child workflow failed: ${result.error}`)
754
+ }
755
+ ```
756
+
757
+ Nested executions are tracked with depth up to a maximum of 5 levels.
758
+
759
+ ---
760
+
761
+ ## Email Adapter
762
+
763
+ Singleton -- 1 method for sending platform emails to organization members (from `notifications@elevasis.io`). For client-facing emails, use the Resend or Instantly integration adapters instead.
764
+
765
+ ```typescript
766
+ import { email } from '@elevasis/sdk/worker'
767
+ ```
768
+
769
+ ### Method
770
+
771
+ | Method | Params | Returns |
772
+ | ------ | ------------------------------------------------------------------------------- | --------------------------- |
773
+ | `send` | `{ subject, html?, text?, userIds?, targetRole?, targetAll?, replyTo?, tags? }` | `{ sent, failed, errors? }` |
774
+
775
+ ### Example
776
+
777
+ ```typescript
778
+ // Notify all org members
779
+ await email.send({
780
+ subject: 'New deal closed',
781
+ text: 'Acme Corp has signed the contract.',
782
+ targetAll: true,
783
+ })
784
+
785
+ // Notify specific users
786
+ await email.send({
787
+ subject: 'Action required',
788
+ html: '\<p\>Please review the proposal.\</p\>',
789
+ userIds: ['user-abc', 'user-def'],
790
+ })
791
+ ```
792
+
793
+ ---
794
+
795
+ ## Custom Adapters with `createAdapter`
796
+
797
+ The generic `createAdapter` factory is exported for building adapters for any tool. Define a type map and call the factory.
798
+
799
+ ```typescript
800
+ import { createAdapter } from '@elevasis/sdk/worker'
801
+
802
+ // 1. Define a type map
803
+ type MyToolMap = {
804
+ doSomething: { params: { input: string }; result: { output: string } }
805
+ listItems: { params: { limit?: number }; result: { items: string[] } }
806
+ getStatus: { params: Record<string, never>; result: { healthy: boolean } }
807
+ }
808
+
809
+ // 2. Create the adapter
810
+ const myTool = createAdapter<MyToolMap>('my-tool', [
811
+ 'doSomething', 'listItems', 'getStatus',
812
+ ], 'my-credential') // credential is optional
813
+
814
+ // 3. Use it (fully typed)
815
+ const result = await myTool.doSomething({ input: 'hello' })
816
+ // ^-- { output: string }
817
+ const status = await myTool.getStatus()
818
+ // ^-- { healthy: boolean } (zero-arg because params is Record<string, never>)
819
+ ```
820
+
821
+ Method names are compile-time checked against the type map keys -- misspelling a method name is a compile error.
822
+
823
+ ---
824
+
825
+ All typed adapters compile to `platform.call()` internally -- you can use either interchangeably.
826
+
827
+ ## When to Use Adapters vs `platform.call()`
828
+
829
+ | Scenario | Use |
830
+ | --------------------------------------------------------------------- | ----------------- |
831
+ | Tool has a typed adapter (all integrations + platform tools) | Adapter |
832
+ | Need autocomplete and type safety | Adapter |
833
+ | New dispatcher method added server-side, no SDK update yet | `platform.call()` |
834
+ | Tool without a typed adapter (supabase, session-memory, status, http) | `platform.call()` |
835
+
836
+ `platform.call()` remains the universal escape hatch. Every adapter call compiles down to it. Both approaches work simultaneously with no conflicts.
837
+
838
+ ---
839
+
840
+ For the full inventory of all platform tools (including those without typed adapters), see [Platform Tools](index.mdx).
841
+
842
+ ---
843
+
844
+ ## Error Handling
845
+
846
+ All adapter calls throw `PlatformToolError` on failure, with a `code` field and `retryable` flag:
847
+
848
+ ```typescript
849
+ import { PlatformToolError } from '@elevasis/sdk/worker'
850
+
851
+ try {
852
+ await attio.listRecords({ object: 'deals' })
853
+ } catch (err) {
854
+ if (err instanceof PlatformToolError) {
855
+ console.log(err.message) // Human-readable error
856
+ console.log(err.code) // e.g., 'rate_limit_exceeded', 'credentials_missing'
857
+ console.log(err.retryable) // true for transient errors
858
+ }
859
+ }
860
+ ```
861
+
862
+ Retryable error codes: `rate_limit_exceeded`, `network_error`, `timeout_error`, `api_error`, `service_unavailable`, `server_unavailable`.
863
+
864
+ Timeouts: LLM calls have a 120s timeout. All other tool calls have a 60s timeout.
865
+
866
+ ---
867
+
868
+ **Last Updated:** 2026-03-05