> ## Documentation Index
> Fetch the complete documentation index at: https://docs.atonom.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Recipes

> Copy practical Lua examples into your own script workspace.

These examples use the Atonom sandbox helpers and the stored-script `transform(context)` contract. Copy each example into a file in your own working folder using the filename shown below. The test commands require [sandbox access](/atonom-script/cli/install#connect-the-sandbox-optional).

## Calculate an order total

Save as `order-total.lua`.

```lua theme={null}
function transform(context)
  local qty = context.qty
  local price = context.unit_price

  if type(qty) ~= "number" or qty < 0 or qty % 1 ~= 0 then
    error("qty must be a non-negative integer")
  end
  if type(price) ~= "number" or price < 0 then
    error("unit_price must be a non-negative number")
  end

  return { qty = qty, total = qty * price }
end
```

```sh theme={null}
atonom eval order-total.lua \
  --transform '{"qty":2,"unit_price":12.5}' --json
```

Expected value: `{"qty":2,"total":25}`. Missing fields, negative numbers, and fractional quantities fail validation. Choose an explicit rounding policy before using this pattern for money.

## Normalize a contact and preserve JSON shape

Save as `normalize-contact.lua`.

```lua theme={null}
function transform(context)
  if type(context.email) ~= "string" then
    error("email must be a string")
  end
  local email = context.email:match("^%s*(.-)%s*$"):lower()
  if email == "" then
    error("email is required")
  end

  local tags = atonom.json.array()
  if context.tags ~= nil then
    if type(context.tags) ~= "table" then
      error("tags must be an array of strings")
    end
    for _, tag in ipairs(context.tags) do
      if type(tag) ~= "string" then
        error("each tag must be a string")
      end
      tags[#tags + 1] = tag
    end
  end

  return { email = email, tags = tags, manager = atonom.json.null }
end
```

```sh theme={null}
atonom eval normalize-contact.lua \
  --transform '{"email":"  ADA@EXAMPLE.COM  ","tags":[]}' --json
```

Expected value: `{"email":"ada@example.com","tags":[],"manager":null}`. This example trims and lowercases an email string; it is not a complete email-address validator. The manager field deliberately returns null.

## Summarize a mocked search result

Save as `search-summary.lua`.

```lua theme={null}
function transform(context)
  if type(context.query) ~= "string" or context.query == "" then
    error("query is required")
  end

  local result, err = atonom.toolcall("web_search", { query = context.query })
  if err then
    return { ok = false, error = err }
  end
  if type(result) ~= "table" or type(result.hits) ~= "table" then
    error("search result must contain hits")
  end

  return { ok = true, count = #result.hits }
end
```

```sh theme={null}
atonom eval search-summary.lua \
  --transform '{"query":"acme"}' \
  --trap-result '{"hits":[{"title":"Acme"},{"title":"Acme Labs"}]}' --json
```

Expected value: `{"ok":true,"count":2}`. `web_search` is an illustrative capability name. Configure the actual available capability and its result contract before using this pattern on the platform.

See [Test & mock tool calls](/atonom-script/cli/testing) for host-failure cases and envelope handling.

## Turn a recipe into a stored tool

Create a tool or pull an existing one, then copy the example's body into the linked local file. Configure the corresponding input schema in the Atonom tool editor. Use [the first-tool walkthrough](/atonom-script/cli/first-tool) to review, sync, test, and enable it.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.