# How to Use Custom Separators in jsoncsv: CLI and Python API Guide

> Learn to use custom separators in jsoncsv with our guide. Easily change delimiters in the CLI or Python API for flexible JSON data handling.

- Repository: [alingse/jsoncsv](https://github.com/alingse/jsoncsv)
- Tags: how-to-guide
- Published: 2026-02-24

---

**Use the `-s` or `--sep` flag in the CLI (e.g., `jsoncsv -s "|"`) or pass the `separator` parameter to `expand()` or `restore()` in Python to change the default dot (`.`) delimiter when flattening or restoring JSON objects.**

The `jsoncsv` library transforms nested JSON structures into flat key-value pairs and back again, using a separator character to join path components. While the default dot notation works for many use cases, you often need custom separators in jsoncsv when your data contains dots in key names or when integrating with systems that require specific delimiters like pipes or colons.

## Understanding the Default Separator Behavior

By default, jsoncsv uses the dot character (`.`) to concatenate nested keys. For example, a nested object `{"user": {"name": "Alice"}}` becomes `{"user.name": "Alice"}`.

This behavior is hardcoded as the default value in the `expand()` and `restore()` functions found in [`jsoncsv/jsontool.py`](https://github.com/alingse/jsoncsv/blob/main/jsoncsv/jsontool.py). When you need to process JSON with dots in the key names themselves, or when exporting to formats that use dots as data (like floating-point strings), you must configure a custom separator.

## Method 1: Configuring Custom Separators via CLI

The command-line interface provides the `-s` or `--sep` option to specify any single-character delimiter. This value is validated and passed through the conversion pipeline defined in [`jsoncsv/main.py`](https://github.com/alingse/jsoncsv/blob/main/jsoncsv/main.py).

### Separator Validation in main.py

Before processing begins, the `separator_type()` function (lines 16-21 in [`jsoncsv/main.py`](https://github.com/alingse/jsoncsv/blob/main/jsoncsv/main.py)) validates your input. It ensures the separator is exactly one character and not the backslash escape character (`\`), preventing parsing errors during expansion and restoration.

### CLI Usage Examples

To flatten JSON using a pipe character as the separator:

```bash
cat data.json | jsoncsv -s "|" > flat.txt

```

To restore the flattened file back to nested JSON using the same separator:

```bash
cat flat.txt | jsoncsv -s "|" --restore > nested.json

```

## Method 2: Using Custom Separators in the Python API

For programmatic use, the `expand()` and `restore()` functions in [`jsoncsv/jsontool.py`](https://github.com/alingse/jsoncsv/blob/main/jsoncsv/jsontool.py) accept a `separator` parameter that overrides the default dot.

### Flattening JSON with expand()

The `expand()` function (lines 93-104 in [`jsoncsv/jsontool.py`](https://github.com/alingse/jsoncsv/blob/main/jsoncsv/jsontool.py)) traverses nested dictionaries and joins path components using the specified separator. Here is how to use a colon delimiter:

```python
from jsoncsv.jsontool import expand

nested = {
    "user": {
        "name": "Alice",
        "address": {
            "city": "Wonderland",
            "zip": "12345"
        }
    }
}

flat = expand(nested, separator=":")
print(flat)

# Output: {'user:name': 'Alice', 'user:address:city': 'Wonderland', 'user:address:zip': '12345'}

```

### Restoring JSON with restore()

The `restore()` function (lines 108-116 in [`jsoncsv/jsontool.py`](https://github.com/alingse/jsoncsv/blob/main/jsoncsv/jsontool.py)) reverses the process by splitting keys on the separator and rebuilding the nested structure. You must use the same separator that was used during expansion:

```python
from jsoncsv.jsontool import restore

flat = {
    'user:name': 'Alice',
    'user:address:city': 'Wonderland',
    'user:address:zip': '12345'
}

restored = restore(flat, separator=":")
print(restored)

# Output: {'user': {'name': 'Alice', 'address': {'city': 'Wonderland', 'zip': '12345'}}}

```

## Handling Special Characters with Safe Mode

When your JSON keys contain the separator character itself (for example, a key named `user.name` when using `.` as the separator), data loss occurs during restoration. The safe mode feature escapes these occurrences using backslash encoding.

### Safe Mode Encoding and Decoding

The utility functions `encode_safe_key()` (lines 15-19) and `decode_safe_key()` (lines 21-42) in [`jsoncsv/utils.py`](https://github.com/alingse/jsoncsv/blob/main/jsoncsv/utils.py) handle the escaping logic. They prefix the separator with a backslash and escape existing backslashes to ensure lossless round-trips.

To enable safe mode in the CLI, add the `--safe` flag:

```bash
cat tricky.json | jsoncsv -s "|" --safe > safe_flat.txt

```

In Python, pass `safe=True` to `expand()` or `restore()`:

```python
from jsoncsv.jsontool import expand

data = {"user|name": "Alice", "user|age": 30}
flat = expand(data, separator="|", safe=True)

# Keys are escaped to prevent splitting on the literal "|"

```

## Summary

- **Default behavior**: jsoncsv uses the dot (`.`) separator to join nested keys during flattening and restoration.
- **CLI customization**: Use the `-s` or `--sep` flag to specify any single-character delimiter; validation occurs in [`jsoncsv/main.py`](https://github.com/alingse/jsoncsv/blob/main/jsoncsv/main.py).
- **Python API**: Pass the `separator` parameter to `expand()` or `restore()` in [`jsoncsv/jsontool.py`](https://github.com/alingse/jsoncsv/blob/main/jsoncsv/jsontool.py) to override the default programmatically.
- **Safe mode**: Enable with `--safe` (CLI) or `safe=True` (Python) to escape separators appearing within key names, utilizing functions in [`jsoncsv/utils.py`](https://github.com/alingse/jsoncsv/blob/main/jsoncsv/utils.py).

## Frequently Asked Questions

### What is the default separator in jsoncsv?

The default separator is the dot character (`.`). When flattening a nested JSON object, jsoncsv joins path components with dots (e.g., `user.name`), and uses the same character to split keys during restoration unless overridden with the `-s` flag or `separator` parameter.

### Can I use multi-character separators with jsoncsv?

No, jsoncsv strictly enforces single-character separators. The `separator_type()` function in [`jsoncsv/main.py`](https://github.com/alingse/jsoncsv/blob/main/jsoncsv/main.py) (lines 16-21) validates that the input is exactly one character and rejects multi-character strings to prevent parsing ambiguities during key splitting in `restore()`.

### How does safe mode protect my data when using custom separators?

Safe mode prevents data corruption when your JSON keys contain the separator character itself. When enabled, `encode_safe_key()` in [`jsoncsv/utils.py`](https://github.com/alingse/jsoncsv/blob/main/jsoncsv/utils.py) escapes the separator with a backslash and handles existing backslashes, while `decode_safe_key()` reverses this during restoration, ensuring lossless round-trips even with conflicting key names.

### Where are the separator handling functions defined in the source code?

Separator validation resides in [`jsoncsv/main.py`](https://github.com/alingse/jsoncsv/blob/main/jsoncsv/main.py) (the `separator_type()` function). The core expansion and restoration logic using separators is implemented in [`jsoncsv/jsontool.py`](https://github.com/alingse/jsoncsv/blob/main/jsoncsv/jsontool.py) within the `expand()` (lines 93-104) and `restore()` (lines 108-116) functions. Safe-mode encoding utilities are located in [`jsoncsv/utils.py`](https://github.com/alingse/jsoncsv/blob/main/jsoncsv/utils.py).