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

# Code

> Process data with Python and use the output in later blocks.

Use **Code** to transform, compare, or calculate data with Python. The block receives values from the flow and returns output that later blocks can use.

Use [Filter](/blocks/flow-control-and-routing/filter) for straightforward routing conditions. Use Code when the flow needs a calculation, data transformation, or business rule that is clearer to express in Python.

## Choose where it runs

Place the block where its inputs are available and where its output will be used.

| Stage | Use it when |
| :- | :- |
| **Pre-call** | The output is needed before the call starts |
| **Live call** | The output affects the active conversation or its routing |
| **Post-call** | Process data after a call that reached the connected live-call block |

Inputs can use only variables available before Code runs. If the code needs information collected during the conversation, place it after the block that collects it.

If the output is needed only after the call, use post-call so the caller does not wait for the processing.

## Configure inputs

Under **Input Variables**, create a key for each value the function needs. Set its value using fixed text, a variable available at the block, or both.

Use **Manual** to configure inputs as key-value rows, or switch to **Code** to edit the same inputs as a JSON object. Phonely converts the current inputs when you switch views. Name every populated input before switching to Code, and fix invalid JSON before switching back to Manual.

| Field | Purpose |
| :- | :- |
| **Variable name** | The key used to access the value in `input_dict` |
| **Set variables** | The value passed to that key |

Use short, unique names such as `subtotal`, `customer_tier`, or `appointment_date`. Lowercase names with underscores are easiest to read in the code.

When an input contains only a selected variable, it retains that variable's type, including text, number, boolean, array, or object. An empty resolved value is passed to the function as `None`. Handle missing or empty values in the code instead of assuming every input is present.

## Generate code with AI

Expand the **Generate with AI** strip at the top of the panel, describe what the code should do, and start a focused Ask AI task for this block alone. Ask AI can write the Python function, map its inputs, and define its expected outputs. In **Review** mode, inspect and apply the proposal; **Auto apply** writes the requested edit directly to the draft. See [Choose how flow changes are applied](/key-concepts/ask-ai#choose-how-flow-changes-are-applied), and check the generated result before publishing. Generation is offered only on an editable draft, not in version previews, comparisons, or to viewers.

Review the generated inputs, code, and outputs before continuing. You still need to validate the code and run a successful block test before its output variables can be used reliably by later blocks.

## Write the Python function

The editor provides the required function structure. Keep the function name and parameter unchanged, and return a dictionary:

```python theme={null}
def function(input_dict: dict) -> dict:
    output_dict = {}
    return output_dict
```

Read each configured input by its key and return the values that later blocks need. For example:

```python theme={null}
def function(input_dict: dict) -> dict:
    subtotal = float(input_dict.get("subtotal") or 0)
    tax_rate = float(input_dict.get("tax_rate") or 0)

    total = round(subtotal * (1 + tax_rate), 2)

    return {
        "total": total
    }
```

The keys in the returned dictionary define the block's outputs. A successful block test makes them available to later blocks. Keep output names stable once downstream blocks use them.

### Use supported libraries

Code runs in a restricted environment. You can import `math`, `datetime`, `json`, `random`, and `time`. Other libraries and dynamic imports with `__import__` are not supported.

Use [API Request](/blocks/api-request) or an integration block to communicate with an external service. Use Code to process the data those blocks return.

## Validate the code

Select **Validate** after configuring the inputs and writing the function. Validation checks the Python syntax, the required `function(input_dict)` signature, and whether its imports are supported.

Validation does not run the function or confirm its results. Continue to the Test step to verify the logic with sample inputs.

Editing the Python code clears its previous validation. Validate again before testing or publishing the flow.

## Test and create output variables

Run the block test before using its output in another block.

1. Enter representative sample values for each input.
2. Select **Test** and inspect `output`, `stdout`, and `stderr`.
3. Test any missing, empty, boundary, or unexpected values the flow may provide.

After a successful test, choose which parts of the returned dictionary later blocks can use. The result panel shows the output as an expandable tree beside the complete raw JSON, with each value's type.

For the example above, you can select the entire dictionary as `output` or select `total` on its own. Selecting a parent includes the values nested inside it, and you can search by path or value when the output is large.

The first successful test on a new block selects the complete output for you. After that, only what you select becomes a variable under the block's name, available to later blocks from **Available Variables**.

If the returned structure changes, test the block again and review your selection along with any downstream fields that use its variables. Reselecting outputs keeps existing references working, and a failed retest leaves your last successful selection in place.

<Note>
  `print()` output appears in `stdout` for debugging. It does not create a flow variable. Return a value from the function to use it in later blocks.
</Note>

## Configure shared settings

Pre-call and live-call Code blocks support interim messages, Error Handling, and Call Outcome Tagging. See [Common Block Settings](/blocks/common-settings) for how these options affect the caller, connections, and reporting.

Post-call Code blocks do not provide these settings.

## Verify the flow behavior

After the block test succeeds:

1. Test each route that can reach the block using representative inputs.
2. If **Error Handling** is enabled, trigger a controlled error and confirm the **Error** route runs.
3. Confirm that downstream blocks receive the intended output values.
4. Complete an end-to-end flow test before using the flow for live calls.

During a Web Chat test, expand Code in the action trace. After a phone call, open **Call Details**, select **Blocks**, and expand Code. Review its inputs, output, stdout, stderr, and execution time.

## Troubleshooting

<AccordionGroup>
  <Accordion title="Validation fails">
    Read the validation message for the affected line or rule. Confirm that the code is valid Python, defines `function` with exactly one parameter named `input_dict`, and uses only permitted imports.
  </Accordion>

  <Accordion title="The code validates but fails when it runs">
    Validation checks the code structure, not every input or execution path. Review `stderr` and `stdout`, reproduce the failure with representative test values, and handle the affected type, missing value, or operation in the function.
  </Accordion>

  <Accordion title="An input is missing or has the wrong type">
    Confirm that the input name matches the key read from `input_dict` and that **Set variables** contains the intended fixed value or an available variable. Test with the same data type the flow will provide, and handle missing or empty values in the function.
  </Accordion>

  <Accordion title="An output variable is missing">
    Return a dictionary containing that key, then run a successful test. If the output structure changed, test again and replace downstream references that no longer exist.
  </Accordion>
</AccordionGroup>


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