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

# Data Transform

> Real-time field transformations applied at the data boundary.

# Data Transform

**Transform in flight, not in a pipeline.**

Real-time field transformations applied at the data boundary. No ETL pipelines or data duplication required.

<Info>
  Data Transform shares the same field path rules as Data Control. See [Field Targeting](./field-targeting) for nested paths, arrays, and `required` behavior.
</Info>

<Tip>
  You'll see `fields` written two ways in our examples — both are valid YAML and produce identical results:

  ```yaml theme={null}
  # Inline style
  fields: [first_name, last_name]

  # Multi-line style
  fields:
    - first_name
    - last_name
  ```
</Tip>

<Info>
  For a complete Virtual API Configuration, start with `version: "0.3"` and define controls under `objects.<objectName>.controls`. Snippets below that start with `controls:` are fragments meant to live inside an object definition.
</Info>

## Operations

### Combine

Merge two or more string fields into a single new field.

```yaml theme={null}
controls:
  - type: combine
    fields:
      - first_name
      - last_name
    into: full_name
    separator: " "
```

**Input:**

```json theme={null}
{ "first_name": "Jane", "last_name": "Doe", "email": "jane@example.com" }
```

**Output:**

```json theme={null}
{ "first_name": "Jane", "last_name": "Doe", "full_name": "Jane Doe", "email": "jane@example.com" }
```

### Coalesce

Select the first non-empty value from two or more fields. Ideal for fallback logic and data normalization.

```yaml theme={null}
controls:
  - type: coalesce
    fields:
      - mobile_phone
      - home_phone
    into: primary_phone
```

**Input:**

```json theme={null}
{ "mobile_phone": "", "home_phone": "555-1234" }
```

**Output:**

```json theme={null}
{ "mobile_phone": "", "home_phone": "555-1234", "primary_phone": "555-1234" }
```

### Delete

Remove one or more fields entirely from the outbound payload. Use this when you do not want consumers to see that a field exists at all.

```yaml theme={null}
controls:
  - type: delete
    fields:
      - internal_note
      - debug_flags
```

**Input:**

```json theme={null}
{ "full_name": "Jane Doe", "internal_note": "vip", "debug_flags": ["test"], "email": "jane@example.com" }
```

**Output:**

```json theme={null}
{ "full_name": "Jane Doe", "email": "jane@example.com" }
```

## Execution Rules

* Controls execute top-to-bottom. A later control can use a field created by an earlier control.
* `fields` order matters for both `combine` and `coalesce`.
* `combine` only operates on string source fields.
* All `fields` and `into` must share the same parent path when you use nested paths. For example, `address.city`, `address.state`, and `address.location` are valid together.
* `delete` does not use `into`. It removes the fields named in `fields` directly.
* `into` must point to a new field. If the target field already exists, the transform fails instead of overwriting it.
* Set `required: true` when missing inputs should fail the request. That check is full-path strict: if any parent segment or leaf target is missing, the request fails instead of silently skipping the control. For `coalesce`, missing, `null`, and empty-string values are treated as empty, but whitespace-only strings, `0`, and `false` still count as present values.
* `remove_source: true` works for both `combine` and `coalesce`. Use `delete` when you want an explicit cleanup step later in the control pipeline.
* If the matched payload is an array, the full control pipeline runs against each matching object element in order. Non-object elements are skipped.
* Array execution is not transactional across elements. If an earlier element has already been transformed and a later element fails a `required` check, the request still fails, but the earlier successful element changes are not rolled back.

## Nested Paths

Use nested paths when all source fields and the destination share the same parent:

```yaml theme={null}
controls:
  - type: combine
    fields: [address.city, address.state]
    into: address.location
    separator: ", "
```

## Combining with privacy controls

<Warning>
  Controls execute top-to-bottom. If a filter control (like `hash` or `redact`) runs **before** a transform that references the same field, the transform will see the already-modified value. Place transforms before filters when both operate on the same fields.
</Warning>

Apply transformations before or after privacy controls:

```yaml theme={null}
controls:
  # First, combine name fields
  - type: combine
    fields: [first_name, last_name]
    into: full_name
    separator: " "

  # Then, anonymize the combined name
  - type: anonymize
    fields:
      - full_name

  # Redact the original fields
  - type: redact
    fields:
      - first_name
      - last_name
```

## Removing original fields

Optionally remove source fields after transformation. This works on both `combine` and `coalesce`:

```yaml theme={null}
controls:
  - type: combine
    fields: [first_name, last_name]
    into: full_name
    separator: " "
    remove_source: true
```

**Output:**

```json theme={null}
{ "full_name": "Jane Doe", "email": "jane@example.com" }
```

If you prefer to keep the cleanup as a separate ordered step, use `delete` after the transform:

```yaml theme={null}
controls:
  - type: combine
    fields: [first_name, last_name]
    into: full_name
    separator: " "

  - type: delete
    fields: [first_name, last_name]
```

Use `delete` when the field should disappear completely. Use `redact` when the field should remain present but its value should be blanked or masked.

## Next steps

<CardGroup cols={2}>
  <Card title="Field Targeting" icon="crosshair" href="./field-targeting">
    Learn how transform paths work with nested objects and arrays
  </Card>

  <Card title="Data Control" icon="shield" href="./data-control">
    Redaction, tokenization, anonymization
  </Card>

  <Card title="Control Block Reference" icon="code" href="../api-reference/control-block-reference">
    Detailed transform options and execution rules
  </Card>
</CardGroup>
