# Keep a tool's data out of storage with noPersist

**You will:** Stop the output of a tool from being stored, and know what you give up.

**You need:**
- A key with actions:write
- An action or an MCP server your agent already uses

Some tools return data you do not want Lelemon to keep: a medical record, a bank balance, a card of your back office. Mark the tool `noPersist` and what it returns lives only in the turn that called it.

## Turn it on

`noPersist` is a boolean on actions and MCP servers. It defaults to `false`.

```bash title="cURL"
curl https://api.lelemon.cl/v2/actions \
  -H "Authorization: Bearer $LELEMON_API_KEY" \
  -H "Idempotency-Key: create-balance-action" \
  --json '{
    "name": "get_balance",
    "description": "Returns the balance of the customer account.",
    "request": { "method": "GET", "url": "https://api.mesa.cl/lelemon/balance" },
    "input": { "type": "object", "properties": {} },
    "noPersist": true
  }'
```

```ts title="Node.js"
await lelemon.actions.create({
  name: 'get_balance',
  description: 'Returns the balance of the customer account.',
  request: { method: 'GET', url: 'https://api.mesa.cl/lelemon/balance' },
  input: { type: 'object', properties: {} },
  noPersist: true,
});
```


On an existing tool, send `{ "noPersist": true }` with `PATCH /v2/actions/{id}` or `PATCH /v2/mcp-servers/{id}`. The same field exists when you connect an MCP server.

## What changes

With `noPersist` the result:

- is not kept in the tool memory between turns;
- is not in the execution trace, in approval requests or in run steps;
- is still used by the agent to answer in that turn.

In `GET /v2/cases/{id}/turns` the step of that tool has only `status` and `durationMs`. `input` and `output` are absent.

The same goes for the routes that move its data. `POST /v2/actions/{id}/test` on a `noPersist` action returns the body that your endpoint answered, but it is not kept in the request log of the dashboard, neither the input you sent nor the body that came back, and it is not stored for `Idempotency-Key`: the key is released after the call, so repeating it calls your endpoint again.

```json title="A noPersist step in a turn"
{ "tool": "get_balance", "status": "ok", "durationMs": 310 }
```


The tools of a [data connector](/guides/data-connectors) are always `noPersist`.

## What you give up

- The action cannot be replayed from a stored result.
- A run interrupted in the middle of a round that called it fails. It does not resume.

## What it does not do

The model provider still receives the content, because it is part of the prompt of that turn. `noPersist` is about what Lelemon stores. It does not hide data from the model. Do not return what must not leave your system.

It does not cover what the model repeats either. If the agent writes the balance in its answer, that answer is a message of the case and is stored like any other message, and so is anything the person types. Tell the agent in its instructions not to repeat the data of that tool, or return only what it may say.

An organization can also turn on the `noPersistTraces` setting. Then no trace is kept for any tool.

**TurnStep**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `tool` | string | yes | Name of the tool the agent called. A Lelemon system tool shows its public name (transfer_to_human, save_case_data, send_buttons...), the same one GET /v2/agents/{id}/tools lists. For a tool from an MCP server it is the server slug and the tool name. |
| `status` | enum | yes | `ok`, `error` |
| `durationMs` | integer | yes | Milliseconds the tool took. |
| `input` | object | no | What the agent sent to the tool, with emails, RUTs, phones, cards and secrets masked by shape. Absent when the tool is marked noPersist: those tools leave only status and duration. |
| `output` | string | no | What the tool answered, masked the same way and cut at 4000 characters. Absent when the tool is marked noPersist. |
