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

# Code

> Runs your own Python function on the extracted fields, or on the parsed document, and returns the JSON it produces.

> [!NOTE]
>
> Code is in Beta. Its shape may change without a version.

**Code** runs a function you write. You give it Python source that defines `transform(input_data: Input) -> Output`, and the fields of `Output`. For each document the node runs your function in a sandbox with no network access and stores the JSON object it returns.

No model writes or checks the code when a document runs, and saving the workflow stores the code only. Nothing runs until a document does. In Studio, you can describe what the function should do and ask for a draft. The draft replaces the code in the editor, uses the node's `Input` and the fields of `Output`, and is not run or saved until you do it. Check it before you save.

## The node

```json API theme={null}
{
  "id": "code_1",
  "type": "code",
  "code": "def transform(input_data):\n    total = sum(row.amount or 0 for row in input_data.line_items or [])\n    return Output(total=total)",
  "output_schema": {
    "fields": [{ "name": "total", "data_type": "float", "description": "Sum of the line item amounts." }]
  }
}
```

```python Python theme={null}
import os

from anyformat.sdk import Client
from anyformat.workflow import Schema

client = Client(api_key=os.environ["ANYFORMAT_API_KEY"])

workflow = (
    client.workflow("Invoice total")
    .parse()
    .extract([Schema.float("subtotal", "Subtotal"), Schema.float("tax", "Tax")])
    .code(
        "def transform(input_data):\n    return Output(total=(input_data.subtotal or 0) + (input_data.tax or 0))",
        [Schema.float("total", "Subtotal plus tax")],
    )
    .create()
)
```

```typescript TypeScript theme={null}
import { Anyformat, Schema } from "@anyformat/sdk";

const af = new Anyformat({ apiKey: process.env.ANYFORMAT_API_KEY! });

const workflow = await af
  .workflow("Invoice total")
  .parse()
  .extract([Schema.float("subtotal", "Subtotal"), Schema.float("tax", "Tax")])
  .code(
    "def transform(input_data):\n    return Output(total=(input_data.subtotal or 0) + (input_data.tax or 0))",
    [Schema.float("total", "Subtotal plus tax")],
  )
  .create();
```

## Options

| Field | Type | Default | What it does |
| - | - | - | - |
| `code` | string | required | Python source that defines `def transform(input_data: Input) -> Output`. `Input` and `Output` are pydantic models the sandbox provides. |
| `output_schema` | object | required | The fields of `Output`, in the same format as an [Extract](https://docs.anyformat.ai/guides/nodes/extract.md) schema. A value that does not fit its declared type fails the run. |

The node does not accept the retired `instructions` and `template` fields. The schema the API accepts is generated from the same source: [Code node schema](https://docs.anyformat.ai/api-reference-v3/node-schemas.md#code).

## What the function receives

* After an **Extract**, `Input` has one field for each extracted field, named by the field's sanitized name (the name made safe as a Python identifier). Every value can be `None`. A value that does not fit its declared type arrives as text. There is no confidence and no evidence.
* After a **Parse**, `Input` holds `pages`, and each page holds `number`, `text` and `blocks`.

A node behind a splitter runs once per split.

## Limits

The `code` may not exceed 64 KiB (65,536 bytes of UTF-8). The function runs for at most 60 seconds and 1024 MB of memory. Its output may not exceed 1 MiB. A run that breaks a limit, raises, or returns something that is not a valid `Output` fails the whole run.

## When the function fails

If your function raises, returns something that does not match `output_schema`, writes more than 1 MiB, or runs out of time or memory, the run ends in `error`. It is not retried, because the same code would fail on the same document, and it is not charged. The error message names the exception and the lines of your code that raised it; fix the code and run the document again. The error message is recorded on the node's run, but the public run response carries only `status: error` and no reason yet. An organization with zero data retention records only the exception type.

A succeeded function bills 5 credits for each run of the node, once per split behind a splitter.

## Connects to

[Extract](https://docs.anyformat.ai/guides/nodes/extract.md)

[Code](https://docs.anyformat.ai/guides/nodes/code.md)

Parse or Extract feeds Code, and nothing follows it.

The Python and TypeScript builders attach the node to the single Extract, or to Parse when the workflow has no Extract. Send the node in the API JSON to attach it to one branch of a classified workflow.

## What it returns

The node fills the `code_outputs` section of the [run results](https://docs.anyformat.ai/concepts/runs-and-results.md): one entry per split the node ran for.

```json theme={null}
{
  "code_outputs": [
    {
      "node_id": "code_1",
      "split_id": null,
      "status": "succeeded",
      "output": { "total": 1180.5 }
    }
  ]
}
```

`status` is `succeeded`. A function that fails ends the run in `error`, and a failed run has no results, so the value is always `succeeded`. `output` is the JSON object your function returned, and `null` when its stored output is no longer available. In the SDKs, `result.code_outputs` (Python) and `result.codeOutputs` (TypeScript) hold the same entries.


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