@alvera-ai/platform-sdk 0.10.0-rc.9 → 0.12.0

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 (67) hide show
  1. package/.agent/AGENTS.md +503 -0
  2. package/.agent/account_management.md +456 -0
  3. package/.agent/action_status_updaters.md +264 -0
  4. package/.agent/ai_agents.md +462 -0
  5. package/.agent/ai_sandbox.md +290 -0
  6. package/.agent/async.md +112 -0
  7. package/.agent/connected_apps.md +408 -0
  8. package/.agent/cookbook/_fixtures/README.md +106 -0
  9. package/.agent/cookbook/_fixtures/accounts_receivable/_customers_accounts_receivable_customer.liquid +32 -0
  10. package/.agent/cookbook/_fixtures/accounts_receivable/_customers_accounts_receivable_mdm.liquid +20 -0
  11. package/.agent/cookbook/_fixtures/accounts_receivable/stripe_customers_batch1.csv +5 -0
  12. package/.agent/cookbook/_fixtures/foundation/_lead_submissions_foundation_generic_table.liquid +33 -0
  13. package/.agent/cookbook/_fixtures/foundation/_lead_submissions_foundation_legal_entity.liquid +88 -0
  14. package/.agent/cookbook/_fixtures/foundation/_lead_submissions_foundation_mdm.liquid +48 -0
  15. package/.agent/cookbook/_fixtures/healthcare/_cahps_appointments_healthcare_appointment.liquid +47 -0
  16. package/.agent/cookbook/_fixtures/healthcare/_cahps_appointments_healthcare_mdm.liquid +24 -0
  17. package/.agent/cookbook/_fixtures/healthcare/_cahps_appointments_healthcare_patient.liquid +38 -0
  18. package/.agent/cookbook/_fixtures/healthcare/memorandum-of-association-01.png +0 -0
  19. package/.agent/cookbook/_fixtures/healthcare/sample_two_page.pdf +43 -0
  20. package/.agent/cookbook/_fixtures/payment_risk/_compliance_screenings_payment_risk_compliance_screening.liquid +59 -0
  21. package/.agent/cookbook/_fixtures/payment_risk/_compliance_screenings_payment_risk_mdm.liquid +36 -0
  22. package/.agent/cookbook/_fixtures/payment_risk/_payment_accounts_payment_risk_mdm.liquid +30 -0
  23. package/.agent/cookbook/_fixtures/payment_risk/_payment_accounts_payment_risk_payment_account.liquid +55 -0
  24. package/.agent/cookbook/_setup/accounts_receivable.md +282 -0
  25. package/.agent/cookbook/_setup/foundation.md +277 -0
  26. package/.agent/cookbook/_setup/healthcare.md +279 -0
  27. package/.agent/cookbook/_setup/payment_risk.md +283 -0
  28. package/.agent/cookbook/action-status-updaters.md +212 -0
  29. package/.agent/cookbook/ai-agent-invoke.md +243 -0
  30. package/.agent/cookbook/appointment-review-sms-workflow.md +761 -0
  31. package/.agent/cookbook/birthday-greeting-sms-trigger.md +656 -0
  32. package/.agent/cookbook/bulk-ingest.md +254 -0
  33. package/.agent/cookbook/contact-us-triage-with-llm.md +622 -0
  34. package/.agent/cookbook/custom-tables.md +201 -0
  35. package/.agent/cookbook/dunning-sms-for-delinquent.md +619 -0
  36. package/.agent/cookbook/invite-team.md +194 -0
  37. package/.agent/cookbook/kyc-notification-on-account-activation.md +619 -0
  38. package/.agent/cookbook/rest-fetch.md +246 -0
  39. package/.agent/cookbook/sanctions-screening-with-agent-review.md +733 -0
  40. package/.agent/cookbook/score-leads-with-llm-categorization.md +624 -0
  41. package/.agent/cookbook/system-templates.md +129 -0
  42. package/.agent/cookbook/talk-to-data.md +139 -0
  43. package/.agent/cookbook/triage-prospects-by-priority.md +533 -0
  44. package/.agent/cookbook/welcome-sms-for-customers.md +607 -0
  45. package/.agent/data_activation_clients.md +559 -0
  46. package/.agent/data_sources.md +235 -0
  47. package/.agent/datalakes.md +769 -0
  48. package/.agent/debugging.md +137 -0
  49. package/.agent/errors.md +190 -0
  50. package/.agent/generic_tables.md +351 -0
  51. package/.agent/interoperability_contracts.md +417 -0
  52. package/.agent/mdm.md +293 -0
  53. package/.agent/mutations.md +126 -0
  54. package/.agent/templates.md +98 -0
  55. package/.agent/tool-call-configs.md +90 -0
  56. package/.agent/tools.md +547 -0
  57. package/.agent/type_naming.md +129 -0
  58. package/.agent/workflows.md +617 -0
  59. package/README.md +178 -0
  60. package/dist/bin/platform-sdk.d.mts +1 -0
  61. package/dist/bin/platform-sdk.mjs +106 -0
  62. package/dist/bin/platform-sdk.mjs.map +1 -0
  63. package/dist/index.d.mts +1395 -44063
  64. package/dist/index.d.mts.map +1 -1
  65. package/dist/index.mjs +1274 -7356
  66. package/dist/index.mjs.map +1 -1
  67. package/package.json +18 -9
@@ -0,0 +1,503 @@
1
+ # AGENTS.md — `@alvera-ai/platform-sdk` corpus
2
+
3
+ This corpus documents the platform's resource surface. It ships
4
+ inside the npm package and is read directly via `node_modules`
5
+ filesystem walk. Consumers include downstream agents writing
6
+ code in CLIs, React apps, integration test suites, and code
7
+ generators.
8
+
9
+ > **Wiring this into your project:** run `npx @alvera-ai/platform-sdk
10
+ > llm-export` from your project root to add a pointer to this corpus in
11
+ > your `AGENTS.md` (and a `@AGENTS.md` import in `CLAUDE.md`). Idempotent.
12
+
13
+ ## ⚠ This file is a LOOKUP ONLY. Read the per-kind MD before emitting code.
14
+
15
+ `AGENTS.md` (this file) is a **DIRECTORY**. It points you to
16
+ per-kind MDs (`tools.md`, `workflows.md`, `data_sources.md`,
17
+ etc.). It is **NOT** a schema reference, and you **CANNOT**
18
+ ground any wire-level claim from this file alone.
19
+
20
+ ### Mandatory protocol before emitting any code that touches a kind
21
+
22
+ 1. **Locate the kind** in the Resources section below.
23
+ 2. **Open the kind's MD** (`<kind>.md`).
24
+ 3. **Read §1 (Wire shape) and §2 (Rules the type cannot encode)**
25
+ at minimum.
26
+ 4. **Every claim you emit** about wire shape, polymorphism,
27
+ constraints, enum values, or required fields **MUST be
28
+ grounded in §1 or §2 of the kind's MD**. If you cannot
29
+ point at the section, re-read before emitting.
30
+
31
+ ### Failure mode this prevents
32
+
33
+ The one-line summaries in the Resources section are
34
+ **navigation labels**, not schemas. Example:
35
+
36
+ > The index line `workflows.md — Filter + decision + action;
37
+ > standard + agent-driven variants` **cannot** tell you whether
38
+ > `variant` is a body field. It is not. `workflows.md` §1 shows
39
+ > the variant is **structural** — an agent-driven workflow simply
40
+ > has one or more AI agents *nested* on its body (the
41
+ > `workflow_ai_agents` array) — **not** a top-level `variant` discriminator.
42
+
43
+ An agent that paraphrases the index into a wire-level claim is
44
+ **hallucinating**. The index summary is too compressed to encode
45
+ polymorphism, constraints, enum values, or required fields.
46
+
47
+ ### Rule of thumb
48
+
49
+ Treat index summaries like file names in a directory listing:
50
+ useful for finding the right file, useless as a substitute for
51
+ opening it. If you find yourself emitting a claim about a kind's
52
+ wire shape without having opened that kind's MD in the current
53
+ session, **stop and open it now**.
54
+
55
+ ---
56
+
57
+ ## If you know MCP — vocabulary mapping
58
+
59
+ The platform's resources don't implement MCP wire format, but
60
+ the conceptual roles map cleanly onto MCP terms. If you've
61
+ landed here from an MCP background, this table tells you which
62
+ corpus page documents the surface you already know:
63
+
64
+ | MCP concept | Alvera resource | Corpus page |
65
+ |-----------------------|------------------------------|-----------------------------------------------|
66
+ | Host | The platform itself | This corpus + `account_management.md` |
67
+ | Client | Data Activation Client | `data_activation_clients.md` |
68
+ | Server | Agentic Workflow | `workflows.md` |
69
+ | Resources | Datasets (per data domain) | `generic_tables.md`, `mdm.md` |
70
+ | Prompts | Interoperability Contracts | `interoperability_contracts.md`, `templates.md` |
71
+ | Sampling | Dataset event triggers | `data_activation_clients.md` §6.4 logs |
72
+ | Tools | Tool Calls (polymorphic body)| `tools.md` |
73
+ | Roots | Datalake boundaries | `datalakes.md` |
74
+ | Human-in-the-loop | Connected Apps + page tokens | `connected_apps.md` |
75
+ | Sandboxed execution | Liquid + SQL fragment lanes | `ai_sandbox.md` |
76
+
77
+ A few caveats on the mapping:
78
+
79
+ - **Capability negotiation is configuration, not runtime
80
+ handshake.** Tools declare their `intent` and `tool_body_type`
81
+ at create time; data activation clients declare their bound
82
+ contracts and tool call shape; workflows declare their event
83
+ dataset and decision keys. The platform doesn't negotiate
84
+ these per session — they're fixed by the resource records.
85
+ - **Sampling is lossless, not subscribed.** Dataset events
86
+ surface through database triggers and per-tenant work queues
87
+ rather than an MCP-style sampling subscription. Consumers
88
+ observe outcomes through the log subresource on the data
89
+ activation client or the workflow, not through a streaming
90
+ channel.
91
+ - **Roots are the tenancy boundary, full stop.** Cross-datalake
92
+ reads and writes are physically blocked at the connection
93
+ layer; a session scoped to one datalake can never reach
94
+ another tenant's data even if the calling code addresses a
95
+ different slug.
96
+
97
+ The rest of this preamble covers the actual SDK auth and client
98
+ construction.
99
+
100
+ ## SDK auth + client construction
101
+
102
+ The SDK is a strict-TypeScript REST client for the Alvera
103
+ platform. Two-step auth + client construction:
104
+
105
+ import {
106
+ createSession,
107
+ createIsolatedPlatformApi,
108
+ type PlatformApi,
109
+ } from '@alvera-ai/platform-sdk'
110
+
111
+ // 1. mint a session
112
+ const session = await createSession({
113
+ baseUrl,
114
+ email,
115
+ password,
116
+ tenantSlug, // optional; omit for tenantless session
117
+ })
118
+
119
+ // 2. build a typed client
120
+ const api: PlatformApi = createIsolatedPlatformApi({
121
+ baseUrl,
122
+ sessionToken: session.sessionToken,
123
+ })
124
+
125
+ Sessions come in three scopes:
126
+ - **root** — Alvera root admin; user signup + confirmation
127
+ - **tenantless** — authenticated user with no tenant chosen yet;
128
+ used once to create a tenant via `api.tenants.create(...)`
129
+ - **tenant-scoped** — the canonical Bearer for tenant operations
130
+
131
+ Consumers holding multiple concurrent clients in the same file
132
+ (e.g. integration tests that need root + tenantless + tenant-
133
+ scoped APIs concurrently) MUST use `createIsolatedPlatformApi`
134
+ rather than the singleton `createPlatformApi`. The singleton
135
+ mutates a shared client; the most-recent construction call
136
+ clobbers earlier instances' auth.
137
+
138
+ ## Using this corpus: building an app vs. writing a test
139
+
140
+ The `api.*` call sequences in this corpus are framework-agnostic — the
141
+ **same** code powers all of these:
142
+
143
+ - **A React / CopilotKit app** — call `api.workflows.create(...)`,
144
+ `api.dataActivationClients.ingest(...)`, etc. from an event handler, a
145
+ server action, or a CopilotKit action; render the typed response.
146
+ - **A backend / Bun / Node script** — drive the client straight through.
147
+ - **A vitest / integration test** — thread the same calls through a test
148
+ closure, asserting on each typed response.
149
+
150
+ What changes between them is only *where you put the calls* (a component
151
+ handler vs. a test body), never the calls themselves. The cookbooks under
152
+ `cookbook/` read as test-style sequences because that is how they are
153
+ validated, but every step is a plain `api.*` call you can lift into an app
154
+ unchanged. The per-capability docs (e.g. `bulk-ingest.md`, `ai-agent-invoke.md`)
155
+ show one capability at a time; the cookbooks weave capabilities into a
156
+ business outcome.
157
+
158
+ ## Resources
159
+
160
+ ```
161
+ INFRASTRUCTURE (stood up before data flows)
162
+ ──────────────
163
+ datalakes.md Storage layer; regulated +
164
+ unregulated tiers.
165
+ data_sources.md External ingestion endpoints.
166
+ tools.md Authenticated connections for
167
+ action execution.
168
+ templates.md Platform-shipped Liquid templates
169
+ consumed by other resources.
170
+ ai_agents.md LLM-backed workers.
171
+ action_status_updaters.md Polling reconcilers.
172
+ connected_apps.md External app bridges.
173
+ mdm.md Entity resolution + identity
174
+ verification across domains.
175
+ ai_sandbox.md Three-layer safety contract
176
+ bounding every AI-authored
177
+ fragment: compliance gates,
178
+ Liquid sandbox, SQL boundary.
179
+
180
+ DATA ACTIVATION (how data flows in)
181
+ ───────────────
182
+ generic_tables.md Schema-on-write tables.
183
+ interoperability_contracts.md Liquid template mappings.
184
+ data_activation_clients.md Ingestion pipelines — both the
185
+ binding row (CRUD) and the
186
+ runtime verbs (.ingest, .ingestFile,
187
+ .runManually, logs, dataset search).
188
+
189
+ WORKFLOWS (composition on top)
190
+ ─────────
191
+ workflows.md Filter + decision + action;
192
+ standard + agent-driven variants.
193
+ ```
194
+
195
+ Axes are mostly disjoint but a few resources cross. AI Agents
196
+ anchor INFRASTRUCTURE and appear in DATA ACTIVATION (they
197
+ tokenize during ingestion) and WORKFLOWS (workflows invoke
198
+ them). Connected Apps anchor INFRASTRUCTURE and tag into
199
+ WORKFLOWS.
200
+
201
+ Each resource is exposed via a TypeScript namespace on the
202
+ typed client. The SDK namespace name follows TS conventions
203
+ (camelCase); the corpus MD filename matches the platform's
204
+ wire name (snake_case):
205
+
206
+ SDK namespace Corpus MD
207
+ ──────────────────── ───────────────────────────
208
+ api.datalakes datalakes.md
209
+ api.dataSources data_sources.md
210
+ api.tools tools.md
211
+ api.aiAgents ai_agents.md
212
+ api.actionStatusUpdaters action_status_updaters.md
213
+ api.connectedApps connected_apps.md
214
+ api.mdm mdm.md
215
+ api.genericTables generic_tables.md
216
+ api.interoperabilityContracts interoperability_contracts.md
217
+ api.dataActivationClients data_activation_clients.md
218
+ api.workflows workflows.md
219
+
220
+ ## Cookbooks (Golden Path scenarios)
221
+
222
+ `.agent/cookbook/<slug>.md` files are pure-markdown scenario
223
+ stories — one business outcome each, told as a numbered API-call
224
+ sequence drawn from a green end-to-end vitest scenario in the
225
+ platform's integration-tests suite. Agents read these directly
226
+ from the filesystem at
227
+ `node_modules/@alvera-ai/platform-sdk/.agent/cookbook/`; there
228
+ is no SDK function and no CLI verb that returns cookbook bytes
229
+ at runtime.
230
+
231
+ Each cookbook structure:
232
+
233
+ - **Front matter** — `title`, `summary`, `industry`, `slug`,
234
+ `vitest_source` (list of integration-test files the snippets
235
+ are lifted from, anchor file first), `status`. The `industry:`
236
+ field also drives automatic discovery of the per-industry
237
+ bootstrap setup file at `_setup/<industry>.md` — see
238
+ "Industry-derived setup files" below.
239
+ - **Problem** — the business-outcome statement in domain terms,
240
+ sourced from the anchor vitest's behaviour (not from
241
+ customer-narrative documentation).
242
+ - **Composition** — table of resources provisioned, mapped to
243
+ the audience skill that owns each (setup / build / compose).
244
+ - **Walkthrough** — numbered `## NNN — <step>` subsections, each
245
+ carrying one fenced TypeScript block lifted from the anchor or
246
+ ancillary vitest. State threads forward across subsections via
247
+ plain JavaScript variables in the validator's generated
248
+ `describe` closure.
249
+ - **Branches** — alternate paths the anchor vitest covers (a
250
+ filter rejection, a transport failure, an agent-classification
251
+ fallback).
252
+ - **Rollback** — teardown order for the resources the cookbook
253
+ provisioned.
254
+ - **Outcome** — author's prose summary of what the scenario
255
+ produces.
256
+ - **See also** — links to relevant per-resource reference MDs
257
+ and to the anchor + ancillary vitest files.
258
+
259
+ ### Industry-derived setup files
260
+
261
+ Cookbook authoring uses per-industry bootstrap setup files
262
+ under `.agent/cookbook/_setup/<industry>.md` to DRY out the
263
+ auth + tenant + datalake + dataset-seeding steps every
264
+ scenario in an industry shares. The convention matches the
265
+ markdown-doctest ecosystem pattern — setup belongs to a
266
+ scope (the industry), and any cookbook in that scope
267
+ inherits the setup by being there. No per-cookbook opt-in
268
+ field is required.
269
+
270
+ - Setup files live under `_setup/`. The leading underscore on
271
+ the directory marks them as fragments (not standalone
272
+ scenarios); the validator's discovery walk skips them and
273
+ the corpus index does not list them under "Available
274
+ cookbooks."
275
+ - The validator reads each scenario cookbook's existing
276
+ `industry:` front-matter field and auto-discovers the
277
+ setup file at `_setup/<industry>.md`. A cookbook in an
278
+ industry that has no setup file gets nothing inlined; the
279
+ validator does not fail if the setup file is absent.
280
+ Cookbook authors write no additional front-matter for
281
+ setup inclusion — the relationship is implicit, by
282
+ convention.
283
+ - The validator inlines the setup file's numbered `it()`
284
+ blocks BEFORE the scenario's own numbered `it()` blocks
285
+ inside the same `describe(...)`. Each `it()` label is
286
+ prefixed with its source slug so failure output
287
+ unambiguously points at the file to open (e.g.
288
+ `_setup/foundation §001 — auth` versus
289
+ `birthday-greeting-sms-trigger §001 — create workflow`).
290
+ Cookbook authors keep clean local §001-§00N numbering
291
+ inside their own markdown.
292
+ - An agent reading a scenario cookbook discovers the matching
293
+ setup file at the predictable conventional path
294
+ `_setup/<industry>.md` — one extra file open at a
295
+ fixed-by-convention location, not via cookbook-specific
296
+ metadata the agent has to learn.
297
+
298
+ ### Vendored fixtures (Liquid templates, CSV bodies)
299
+
300
+ End-to-end cookbooks walk the full data-activation chain
301
+ (data source → interoperability contract → Data Activation
302
+ Client → CSV ingest), which requires Liquid templates that
303
+ map inbound rows into the platform's upsert shapes. Inlining
304
+ those templates verbatim inside every cookbook markdown
305
+ bloats each recipe to several hundred lines of Liquid noise
306
+ that obscures the cookbook's lesson. The corpus ships them
307
+ as **vendored fixtures** instead — same pattern the platform
308
+ repo's own integration tests use.
309
+
310
+ - Fixtures live under
311
+ `.agent/cookbook/_fixtures/<industry>/`. The leading
312
+ underscore marks the directory as fragment infrastructure
313
+ (not a cookbook); the validator's discovery walk skips it.
314
+ Each `<industry>/` subdirectory carries a `README.md`
315
+ listing every template + which cookbook consumes it + the
316
+ production source-of-truth path it was vendored from
317
+ (`platform/priv/liquid_templates/…`).
318
+ - Cookbook code loads fixtures via the
319
+ `COOKBOOK_FIXTURES_DIR` environment variable:
320
+ ```typescript
321
+ import fs from 'node:fs'
322
+ import path from 'node:path'
323
+
324
+ const LE_TEMPLATE = fs.readFileSync(
325
+ path.join(
326
+ process.env.COOKBOOK_FIXTURES_DIR!,
327
+ 'foundation/_lead_submissions_foundation_legal_entity.liquid',
328
+ ),
329
+ 'utf8',
330
+ )
331
+ ```
332
+ Same env-var pattern as the `ALVERA_BASE_URL` /
333
+ `ALVERA_ROOT_EMAIL` / `ALVERA_ROOT_PASSWORD` credentials
334
+ the generated specs already consume.
335
+ `make validate-cookbook` exports
336
+ `COOKBOOK_FIXTURES_DIR=<absolute path to _fixtures>` to the
337
+ spawned `bun test` process; any operator running cookbook
338
+ code directly from a Bun script must set the same variable.
339
+ - The fixtures ship with the `@alvera-ai/platform-sdk` npm
340
+ package via the `files: [.agent]` field, so a consumer
341
+ who installed the package finds the templates at
342
+ `node_modules/@alvera-ai/platform-sdk/.agent/cookbook/_fixtures/`.
343
+ - An agent reading the corpus discovers vendored templates by
344
+ directory walk:
345
+ `_fixtures/` → `<industry>/` → `README.md` lists every
346
+ template plus the cookbooks that depend on it. No need to
347
+ read cookbook code first to know what fixtures exist.
348
+
349
+ ### Two kinds of doc here: business cookbooks vs. capability docs
350
+
351
+ The `cookbook/` directory holds two kinds of recipe, both validated by
352
+ `make validate-cookbook`:
353
+
354
+ - **Business cookbooks** (`<use-case>.md`) — one real business outcome each,
355
+ told as a numbered API-call sequence (e.g. `welcome-sms-for-customers`,
356
+ `dunning-sms-for-delinquent`). Read these to see how resources compose into
357
+ an outcome.
358
+ - **Capability docs** (`<capability>.md`) — one platform capability each,
359
+ shown as the minimal call sequence that proves it (e.g. `bulk-ingest`,
360
+ `ai-agent-invoke`, `custom-tables`, `invite-team`). Read these to learn one
361
+ capability in isolation; cookbooks weave them into outcomes.
362
+
363
+ ### Available cookbooks
364
+
365
+ The nine business-cookbook scenarios. Each is anchored to a green
366
+ end-to-end vitest scenario in the platform's integration-tests suite and is
367
+ verified at dev time by `make validate-cookbook` at the platform-sdk repo root.
368
+ The entries between the managed markers below are what `alvera-sdk-init` lifts
369
+ into consumer `<cwd>/AGENTS.md` files as a managed block.
370
+
371
+ <!-- BEGIN:cookbook-index -->
372
+
373
+ **Healthcare**
374
+
375
+ - [appointment-review-sms-workflow](./cookbook/appointment-review-sms-workflow.md)
376
+ — Send a patient review-request SMS after a fulfilled
377
+ appointment, deep-linked to a connected-app feedback form.
378
+ - [contact-us-triage-with-llm](./cookbook/contact-us-triage-with-llm.md)
379
+ — Triage inbound contact-us messages into three priority
380
+ buckets (appointment / job-application / spam) via an LLM
381
+ agent, route each to a tailored SMS action.
382
+
383
+ **Accounts Receivable**
384
+
385
+ - [welcome-sms-for-customers](./cookbook/welcome-sms-for-customers.md)
386
+ — Send a welcome SMS to newly contracted customers with a
387
+ self-serve billing-portal link.
388
+ - [dunning-sms-for-delinquent](./cookbook/dunning-sms-for-delinquent.md)
389
+ — Send a payment-reminder SMS to delinquent customers
390
+ (filtered on phone-on-file and tax-id-verified) with a
391
+ pay-invoice link.
392
+ - [triage-prospects-by-priority](./cookbook/triage-prospects-by-priority.md)
393
+ — Triage inbound AR customers into priority bands
394
+ (high / medium / low) via an LLM agent, route each band to a
395
+ tailored SMS action.
396
+
397
+ **Payment Risk**
398
+
399
+ - [kyc-notification-on-account-activation](./cookbook/kyc-notification-on-account-activation.md)
400
+ — Send a KYC-notification SMS when a payment account
401
+ transitions to active status.
402
+ - [sanctions-screening-with-agent-review](./cookbook/sanctions-screening-with-agent-review.md)
403
+ — Disambiguate gray-zone sanctions screenings via an LLM
404
+ agent, route confirmed-clean and confirmed-block outcomes to
405
+ distinct SMS actions.
406
+
407
+ **Foundation**
408
+
409
+ - [birthday-greeting-sms-trigger](./cookbook/birthday-greeting-sms-trigger.md)
410
+ — Send a happy-birthday SMS on each contact's next birthday
411
+ using a pure-Liquid trigger (year-roll math).
412
+ - [score-leads-with-llm-categorization](./cookbook/score-leads-with-llm-categorization.md)
413
+ — Score inbound leads into four bands
414
+ (hot / warm / cold / spam) via an LLM agent, route each band
415
+ to a tailored SMS action.
416
+
417
+ <!-- END:cookbook-index -->
418
+
419
+ ### Capability docs
420
+
421
+ One platform capability each — the minimal call sequence that proves it,
422
+ anchored to a green vitest scenario. Read the matching reference MD for the
423
+ full wire shape.
424
+
425
+ - [bulk-ingest](./cookbook/bulk-ingest.md) — load a whole file of records in
426
+ one upload (presigned link → PUT → `ingestFile` → search by batch).
427
+ - [rest-fetch](./cookbook/rest-fetch.md) — pull records from a third-party REST
428
+ API on demand (Bearer + OAuth2), no file upload.
429
+ - [ai-agent-invoke](./cookbook/ai-agent-invoke.md) — read an uploaded
430
+ document/image and pull structured JSON out of it (`aiAgents.invoke` with
431
+ files). The correct file-vision path — the agent reads the file; the DAC
432
+ ingests it.
433
+ - [custom-tables](./cookbook/custom-tables.md) — stand up a custom table the
434
+ built-in datasets don't model; deploy → ingest → search.
435
+ - [action-status-updaters](./cookbook/action-status-updaters.md) — reconcile
436
+ the delivery status of messages you send, on a schedule.
437
+ - [system-templates](./cookbook/system-templates.md) — discover the platform's
438
+ built-in row-mapping Liquid templates.
439
+ - [invite-team](./cookbook/invite-team.md) — invite a teammate into your tenant
440
+ (root / tenantless / tenant-scoped sessions in one flow).
441
+ - [talk-to-data](./cookbook/talk-to-data.md) — turn a datalake conversational:
442
+ natural language → reviewable SQL (`datalakes.textToSql`, data-free by
443
+ construction) → read-only execution returning a `{ data, meta }` row page or a
444
+ CSV export (`datalakes.executeSql`).
445
+
446
+ ## Utility namespaces
447
+
448
+ Cross-resource utilities not documented in this corpus:
449
+
450
+ api.auth signUp + auth helpers
451
+ api.admin confirmUser + admin actions
452
+ api.tenants create + tenant lifecycle
453
+ api.datasets cross-resource search / metadata /
454
+ user-saved searches
455
+ api.templates system-template discovery + per-tenant
456
+ metadata
457
+
458
+ ## Resource page structure
459
+
460
+ Each per-resource MD (e.g. `tools.md`) follows a consistent
461
+ 6-section structure: Wire shape, Rules the type cannot encode,
462
+ Field ownership, Error envelopes, Lifecycle, Gotchas.
463
+
464
+ ## Common sections (apply to all resources)
465
+
466
+ These sibling files cover patterns that apply uniformly across
467
+ all resources. Per-resource MDs reference them by name instead
468
+ of restating:
469
+
470
+ | Topic | File |
471
+ |-----------------------------------------------|------------------|
472
+ | Error envelope shape | `errors.md` |
473
+ | Mutations (`update()` replaces whole; exceptions) | `mutations.md` |
474
+ | Async + readiness | `async.md` |
475
+ | Debugging (HTTP interceptor + safe redaction) | `debugging.md` |
476
+ | Type naming + server-derived fields | `type_naming.md` |
477
+
478
+ ## Just getting started?
479
+
480
+ In your consumer repo, run:
481
+
482
+ ```
483
+ npx @alvera-ai/platform-sdk llm-export
484
+ ```
485
+
486
+ This writes a managed block into your `AGENTS.md` pointing back
487
+ at this corpus, and an `@AGENTS.md` import into `CLAUDE.md` for
488
+ Claude Code compatibility. Re-running replaces only the managed
489
+ block — content outside the markers is preserved.
490
+
491
+ ## Base path
492
+
493
+ All resources are scoped under a tenant + datalake:
494
+
495
+ ```
496
+ /api/v1/tenants/{tenant_slug}/datalakes/{datalake_slug}/<resource>
497
+ ```
498
+
499
+ The `{tenant_slug}` comes from your authenticated session's
500
+ tenant; the `{datalake_slug}` comes from the response of
501
+ `api.datalakes.create(tenantSlug, body)` (server-derived; never
502
+ pre-compute client-side — see `type_naming.md` "Server-derived
503
+ fields auto-excluded from Writable").