@elevasis/sdk 0.4.9 → 0.4.11

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.
@@ -0,0 +1,927 @@
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, hitl, 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