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

# Code Actions

> Run your own TypeScript in a secure sandbox during calls

Code actions let you write TypeScript that runs inside Simple AI when an agent invokes the action — no server to deploy or host. Your code executes in an isolated, ephemeral sandbox with the [Simple AI SDK](/sdk/quickstart) preinstalled and already authenticated for your organization.

Use a code action when the logic is more than one HTTP call — combining lookups, applying business rules, or reading and writing [custom data](/api-reference/custom-data/query) — but you don't want to run your own middleware server (for that, see [Custom Code](/integrations/custom-code)).

## Writing a Code Action

Create an Action in the dashboard and choose the **Code** backend. Default-export a function; `defineAction` from the SDK adds typing and an authenticated client:

```typescript theme={null}
import { defineAction } from '@simple-ai-lab/sdk';

export default defineAction(async ({ inputs, config, client }) => {
  const { records } = await client.data.query({
    tableName: 'customers',
    filters: [{ column: 'email', values: [inputs.email] }],
  });

  if (records.length === 0) {
    return { found: false };
  }
  return { found: true, plan: records[0].plan };
});
```

Your function receives:

* **`inputs`** — the Action's declared inputs, already validated against its input schema
* **`config`** — your organization's configuration variables (for API keys and settings)
* **`client`** — the [Simple AI SDK](/sdk/quickstart), authenticated for your organization automatically; you never handle an API key

The value you return maps to the Action's declared outputs through output mappings rooted at `result` — for example `{{ result.plan }}`.

## Rules and Limits

* **TypeScript or JavaScript**, Node.js 22. The only importable package is `@simple-ai-lab/sdk` (preinstalled in the sandbox).
* **Timeout**: configurable per action, 1–60 seconds (default 30). Voice conversations feel best well under 10 seconds — configure filler speech on the agent for longer actions.
* **Result size**: the returned value must serialize to JSON of at most 1 MB.
* **Logs**: `console.log` / `console.error` output is captured and shown in test runs and call transcripts — it never pollutes the result.
* Each execution runs in a **fresh, isolated sandbox**; nothing persists between runs. Persist state in custom data instead.

## Testing

The Action editor's test panel runs your code in a real sandbox: fill in sample inputs, press **Run test**, and inspect the returned value (click fields to map them as outputs), stdout/stderr logs, and sandbox timings. Syntax errors are rejected when you save; runtime errors surface in the test result with the thrown error's name and message.
