> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.instabase.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.instabase.com/_mcp/server.

# Process case

> Configure the Process case step, kwargs, and the packet refiner program for cross-class fields.

Enterprise Single-tenant

The *Process case* step runs a packet refiner program on the combined output of class-level extraction. It computes cross-class (packet-level) fields and writes them into the IB stream. In the flow builder, you connect a refiner module that supplies this program.

> **Info**
>
> For end-to-end pipeline setup, including JSON configuration examples for each cross-class field type, see the [Packet-processing flows](/flow/guides/packet-processing-flows/) guide. For general refiner concepts, see [Creating refiner programs](/flow/step-config-reference/creating-refiner-programs/).

## Parameters

* **Case program** -- Select the refiner module that contains the packet refiner program. The module must be listed under **Modules** in the flow. The runtime loads the JSON program from `case_program_path` (see [Step keywords](#step-keywords-kwargs)); the standard file is `prog/case.ibrefiner` inside that module.

## Step keywords (`kwargs`)

Use these keywords when the step is represented as JSON (exported `.ibflow` definitions, advanced configuration, or APIs that accept `step_json_str`):

| Keyword             | Description                                                                                                                                                                                                                                                                                                                                                |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `input_folder`      | Folder key for combined packet IB input after class-level extraction -- typically the output folder of the preceding *Combine* step.                                                                                                                                                                                                                       |
| `output_folder`     | Folder key where this step writes IB output with cross-class fields merged in.                                                                                                                                                                                                                                                                             |
| `case_program_path` | Path to the packet refiner program inside the flow bundle. Typical value: `modules/case.refiner/prog/case.ibrefiner`. The file can be named anything -- the name is determined by the path you set here. When creating the module manually through the flow interface, you must create the `prog` folder yourself and move your `.ibrefiner` file into it. |
| `settings`          | Optional map of extra settings. Often `{}` when defaults are sufficient.                                                                                                                                                                                                                                                                                   |

## JSON shape

Step identifier for JSON: `process_case` (`internalName`). Example:

```json
{
  "kwargs": {
    "input_folder": "s4_combine",
    "output_folder": "s5_case",
    "case_program_path": "modules/case.refiner/prog/case.ibrefiner",
    "settings": {}
  },
  "option": { "internalName": "process_case", "name": "Process Case" }
}
```

Keys such as `s4_combine` are the folder aliases you set on upstream and downstream steps, not full file paths.

## Packet refiner module layout

The packet refiner program lives in the flow bundle at:

```
modules/case.refiner/
modules/case.refiner/prog/case.ibrefiner
```

> **Note**
>
> When you create a refiner module through the flow interface, the default file path is `modules/<STEP-NAME>.refiner/<n>.ibrefiner`. To match the expected path, use the file explorer to create a `prog` folder inside the `.refiner` folder, then move your `.ibrefiner` file into it. If you create your schema in a project, then [export the project to the flow editor](/automate/projects#exporting-and-importing-projects), the `prog` folder is created for you.

*Process case* resolves only the JSON file at `case_program_path`. The file does not have to be named `case.ibrefiner` -- the name is determined by the path you set in `case_program_path`. Per-class refiner programs and `.ibvalidations` files for class-level checkpoints live in separate module folders.

## Authoring packet refiner programs

The *Process case* step uses a packet refiner program (`.ibrefiner`). Unlike per-class refiner programs which run on individual document files, this program runs at the packet level, after all class-level extraction is complete. Its job is to consolidate class-extracted values into cross-class fields.

You can edit the program in the refiner app or maintain it directly as JSON in the flow bundle. Output columns appear in project order for cross-class fields.

### Program structure

The top-level `fields` array has two sections:

**Fixed prefix** -- Columns that build the inputs for packet-level logic, in this order:

1. A class-field manifest (`get_input_fields_per_class_field`) that declares which extracted fields from which document classes feed into cross-class rules.
2. One bridge column per referenced `(class name, field name)` pair, each with a stable label (typically `__ClassName_FieldName_<uuid>`) that downstream cross-class formulas reference. Two patterns exist for these bridge columns -- see [Native functions in the fixed prefix](#native-functions-in-the-fixed-prefix).

**Cross-class field columns** -- One field object per cross-class field, appended after the bridges in project order. Each uses a `choice_type` that determines how the field is computed.

### Native functions in the fixed prefix

Two patterns exist for the bridge columns, depending on how the program was generated.

**Pattern A: `get_intra_class_field` per bridge (common)**

Each bridge column handles its own aggregation. This is the pattern generated in projects exported from the app editor.

| Function                           | Role                                                                                                                                                                                                                                                                              |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `get_input_fields_per_class_field` | Declares which class-level extracted fields feed packet logic, via the `class_fields` argument -- a map of document class names to lists of field names.                                                                                                                          |
| `get_intra_class_field`            | One bridge column per `(class, field)` pair. Aggregates values across files for that pair using its own `field_selection_strategy` and exposes the result under a stable label. The `kwargs` input is required by the refiner schema but ignored at runtime; use `"value": "{}"`. |

**Pattern B: `get_all_intra_class_fields` + `get_intra_class_field_from_calculated` (two-step)**

A shared aggregation column runs once, then individual bridge columns each extract one `(class, field)` pair from it.

| Function                                | Role                                                                                                                                                                                                                                                                                                |
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `get_input_fields_per_class_field`      | Same as Pattern A.                                                                                                                                                                                                                                                                                  |
| `get_all_intra_class_fields`            | Aggregates values across files for all declared class fields in one pass, using a shared `field_selection_strategy` (such as `"best_field_value"`). For `custom_udf` strategies, pass an extra `udf_json` argument. The `kwargs` input is schema-required and runtime-ignored; use `"value": "{}"`. |
| `get_intra_class_field_from_calculated` | One bridge column per `(class, field)` pair. Extracts a single pair from the aggregated bundle and exposes it under a stable label. The `kwargs` input is schema-required and runtime-ignored; use `"value": "{}"`.                                                                                 |

### Cross-class field types (`choice_type`)

Choose the cross-class field type that matches how you want to consolidate data across classes. Each type maps to a `choice_type` value in the program JSON.

* `AGGREGATED` (ranked) -- Used to select the best result among multiple input fields based on criteria you specify: first valid field, highest field confidence, or highest OCR confidence. If your ranking logic specifies **First valid field**, select input fields in prioritized order. For confidence-based ranking logic, the order of input fields doesn't matter.

* `DERIVED` -- Used to generate values based on class fields. In the **Prompt**, reference fields by field name: either type the field name or select it from the dropdown. For example, *Generate a risk score by combining **Tax document: Annual income**, **Bank statement: Average balance**, and **Application: Loan amount** using the formula: (income + balance) / loan amount.* When referencing table or list extraction fields, derived fields try to match the input format. For consistent results, especially when combining different field types, consider normalizing tables or lists as text first.

* `UDF` (custom function) -- Used to compute values or import third-party data with a custom Python function. For more details, see [Cross-class custom function fields](#cross-class-custom-function-fields).

The following table shows how each type maps to native refiner functions in the JSON program.

| `choice_type` | Typical native functions                                                                                                                                                                                                                                                                                                   |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `AGGREGATED`  | Two-line pattern: a selector function (such as `first_valid` when `selection_logic` is `FIRST_VALID`) followed by `ranked_value_unwrap` referencing the first line by label and index (such as `Applicant_Name@0`). Other ranking functions follow the same pattern: `ocr_confidence`, `field_confidence`, `first_ranked`. |
| `DERIVED`     | `refine_field_v2`. Chain prompt lines using `previous_line`; wire `prompt_arg_vals` to bridge labels. The first line sets `previous_line` to `null`; later lines reference the prior line as `{label}@{n-1}`.                                                                                                              |
| `UDF`         | `run_case_udf_in_lambda_v2`, with script path, lambda identifiers, a `class_fields` map of human-readable names to bridge labels, and an `args` list of inputs. ENUM-style fields may add `select_options` and `output_type: "SELECT"` on the column object.                                                               |

Prompts and ranking rules must use your class and field labels. Bridge labels must match the manifest and bridge blocks in the fixed prefix.

For JSON examples of each field type, see [Authoring packet refiner programs](/flow/guides/packet-processing-flows#authoring-packet-refiner-programs) in the packet-processing flows guide.