# laaambda — BAML on Lambda A POC platform for storing and invoking BAML lambdas over HTTP. - **Base URL:** `https://lambda.promptfiddle.com` - **Status:** open / no auth (proof of concept). - **Source-of-truth contract:** the BAML platform code itself; the routes here are exactly what it implements. ## Quickstart ```bash BASE=https://lambda.promptfiddle.com # 1. Upload a lambda curl -X POST "$BASE/lambdas?name=echo" \ -H 'Content-Type: text/plain' \ --data-binary 'function echo(s: string) -> string { s }' # 2. Invoke it curl -X POST "$BASE/lambdas/echo/invoke?function=echo" \ -H 'Content-Type: application/json' \ --data '{"s":"hello"}' # → "hello" # 3. List curl "$BASE/lambdas" # 4. Delete curl -X DELETE "$BASE/lambdas/echo" ``` ## Routes | Method | Path | Body | Success | Notable errors | |---|---|---|---|---| | `GET` | `/lambdas` | — | `200` + `[{name, updated_at, size_bytes}]` | — | | `POST` | `/lambdas?name=` | `text/plain` `.baml` source | `201` + meta JSON | `400 invalid_name`, `400 invalid_body`, `409 lambda_already_exists`, `422 compile_error` | | `GET` | `/lambdas/` | — | `200` + `{name, source, created_at, updated_at, size_bytes, content_hash}` | `404 lambda_not_found` | | `PUT` | `/lambdas/` | `text/plain` `.baml` source | `200` + meta JSON | `404 lambda_not_found`, `422 compile_error` | | `DELETE` | `/lambdas/` | — | `204` | `404 lambda_not_found` | | `POST` | `/lambdas//invoke?function=` | `application/json` args object | `200` + function return value as JSON | `400 arg_mismatch`, `400 missing_function_param`, `404 lambda_not_found`, `404 function_not_found`, `422 user_throws`, `500 user_panic`, `504 timeout` | | `GET` | `/` | — | `200` + HTML status page | — | | `GET` | `/docs` | — | `200` + this document | — | ### Lambda names - Regex: `^[a-z][a-z0-9-]{0,63}$` - Lowercase ASCII, starts with a letter, may contain digits and hyphens, max 64 chars. - Reserved: `lambdas`, `_internal`, `meta`. ### Why `?name=` + raw body on POST/PUT So you can `curl --data-binary @file.baml '?name=foo'` without JSON-escaping multi-line source. ### `meta` JSON shape ```json { "name": "echo", "created_at": "2026-05-19T16:31:24Z", "updated_at": "2026-05-19T16:31:24Z", "content_hash": "sha256:", "size_bytes": 40 } ``` `GET /lambdas/` adds a `"source": ""` field. ## Error envelope Every non-2xx response uses the same shape: ```json { "error": { "code": "", "message": "", "details": { /* code-specific */ } } } ``` | code | status | meaning | |---|---|---| | `invalid_name` | 400 | name doesn't match the regex | | `invalid_body` | 400 | empty body where one was expected | | `missing_function_param` | 400 | invoke without `?function=` | | `arg_mismatch` | 400 | invoke args don't match the BAML signature | | `lambda_not_found` | 404 | no such lambda | | `function_not_found` | 404 | no such function inside the lambda | | `not_found` | 404 | unknown route | | `lambda_already_exists` | 409 | `POST` of an existing name (use `PUT` to update) | | `compile_error` | 422 | source failed BAML compile; diagnostics in `details.diagnostics` | | `user_throws` | 422 | user lambda threw; value in `details.thrown` | | `internal_error` | 500 | platform-side failure | | `user_panic` | 500 | user lambda panicked; diagnostics in `details.diagnostics` | | `timeout` | 504 | invocation exceeded the platform budget (~25 s) | ## Invoking lambdas — what to send `POST /lambdas//invoke?function=` takes a single JSON **object** whose keys are the named parameters of ``. The return value of the function is serialized as JSON and returned verbatim in the response body (200). A lambda's source can declare multiple functions; pick which one to call via `?function=`. ### Worked examples ```bash # Source: # function add(a: int, b: int) -> int { a + b } # function multiply(a: int, b: int) -> int { a * b } curl -X POST "$BASE/lambdas/add/invoke?function=add" \ -H 'Content-Type: application/json' \ --data '{"a": 2, "b": 3}' # → 5 curl -X POST "$BASE/lambdas/add/invoke?function=multiply" \ -H 'Content-Type: application/json' \ --data '{"a": 4, "b": 5}' # → 20 # Source: # class Person { name: string, mood: string?, } # function hello(p: Person) -> string { ... } curl -X POST "$BASE/lambdas/greet/invoke?function=hello" \ -H 'Content-Type: application/json' \ --data '{"p": {"name": "sam", "mood": "cheerful"}}' # → "hi, sam (cheerful)" # Optional/nullable fields can be omitted: curl -X POST "$BASE/lambdas/greet/invoke?function=hello" \ -H 'Content-Type: application/json' \ --data '{"p": {"name": "sam"}}' # → "hi, sam" ``` ### Type mapping (BAML → JSON in requests/responses) | BAML | JSON | |---|---| | `string` | string | | `int`, `float` | number | | `bool` | boolean | | `T?` | `T` or `null` (omit field for `null`) | | `T[]` | array of `T` | | `map` | object with `T` values | | `class Foo { … }` | object with the field names of `Foo` | | `enum E { A, B }` | one of `"A"` / `"B"` | ## Limits and behavior - Lambda timeout: ~25 s per invoke (504 `timeout` past that). - Cold starts: a few seconds the first time after idle; warm calls are ~hundreds of ms. - One `.baml` file per lambda; declare any classes/enums it needs in that same file. - Concurrency: no locking on writes — two simultaneous `PUT`s to the same name race; last writer wins. - No retention policy on sources; they live until deleted. ## Hints for programmatic / LLM clients - The error code (`error.code`) is the stable contract — use it for branching. Messages may change wording. - To learn a lambda's callable functions without parsing source, GET `/lambdas/` and scan `source` for `function (`; the platform itself does the same regex. - Treat `404 lambda_not_found` vs `404 function_not_found` as distinct paths — the former means "create the lambda first," the latter means "fix the `?function=` param." - `compile_error.details.diagnostics` is plain BAML compiler output (ANSI-colored). Strip ANSI escapes if you want to surface it to a user. - `invoke` returns the function's return value directly as JSON, **not** wrapped in `{"result": …}`. A function returning `string` returns a JSON string; one returning a `class` returns a JSON object.