
# CSV tools

Three in-process tabular operations on [Papaparse](https://www.papaparse.com/). Every op is a `POST https://api.relaystation.ai/v1/csv/<op>`. cputools **transforms** tabular text — it never evaluates a cell as a formula, so there is no spreadsheet-formula execution surface.

## Inputs and outputs

Same uniform shape as the [PDF tools](/docs/pdf-tools): the `file` is an **input source** — `{ "inline": "<base64>" }` for ≤ 4 MB, or `{ "inputKey": "..." }` (from `POST /v1/cputools/upload-url`) for up to 50 MB. The result comes back in the uniform **output envelope** (inline base64 ≤ 4 MB, or a presigned `outputUrl` above it), with the right content type — `text/csv`, `text/tab-separated-values`, `application/json`, or `application/x-ndjson`.

## Billing

Per-MB of input, **minimum 1 MiB**, at the operator-tunable `cputools.price.csv.<op>.per_mb_micros` (launch default $0.0002 / MB). The live `402` challenge is authoritative.

| Op | Billed on | Rate |
|---|---|---|
| `convert` | input MB | $0.0002 / MB |
| `dedupe` | input MB | $0.0002 / MB |
| `select` | input MB | $0.0002 / MB |

## convert

Convert between `csv`, `tsv`, `json` (array of row objects), and `ndjson`. `from` defaults to `csv`; `to` is required; `delimiter` overrides the csv/tsv separator.

```json
POST /v1/csv/convert
{ "file": {"inline":"<b64>"}, "from": "csv", "to": "json" }
```

## dedupe

Drop duplicate rows, preserving first-seen order. Pass `columns` to dedupe on a subset of key columns; omit it to dedupe on the whole row.

```json
POST /v1/csv/dedupe
{ "file": {"inline":"<b64>"}, "columns": ["email"] }
```

## select

Project columns: pass **exactly one** of `columns` (keep + reorder) or `drop` (remove).

```json
POST /v1/csv/select
{ "file": {"inline":"<b64>"}, "columns": ["name", "email"] }
```

## Sample

```bash
curl -X POST https://api.relaystation.ai/v1/csv/convert \
  -H 'X-Payment: <base64 EIP-3009 auth>' \
  -H 'Idempotency-Key: convert-export-20260606' \
  -H 'Content-Type: application/json' \
  -d '{"file":{"inline":"bmFtZSxhZ2UKQWxpY2UsMzAK"},"to":"json"}'
```

## Errors

- `402 PAYMENT_REQUIRED` — no valid payment.
- `422 CSV_PARSE_FAILED` — malformed input (e.g. a row with more cells than the header, or non-object JSON elements). Rejected **before** any charge.
- `422 UNKNOWN_COLUMN` — a `columns`/`drop` name isn't in the header (the response lists the offenders).
- `400 VALIDATION_ERROR` — the body failed schema validation (e.g. both `columns` and `drop` on `select`).

## Next

[PDF tools](/docs/pdf-tools) · [Image tools](/docs/image-tools) · [QR & barcode](/docs/qr-tools) · [Pricing](/pricing) · [API reference](/api-reference)
