JSON to CSV
data.convert_json_csv
Overview
When you send a JSON array or object (inline or file_ref), we flatten nested fields with your path separator and emit RFC 4180 CSV with deterministic header ordering. Arrays can stay as JSON strings, stringify as text, or explode into rows when unambiguous — do not use explode when multiple array fields would conflict.
LLM CSV conversion drops fields and mishandles nesting. We flatten deterministically.
Reliability
Same JSON and same options give the same bytes back, which makes the output safe to diff or checksum. Columns are the union of every field we met, sorted alphabetically unless you keep discovery order, and cells are separated by commas whatever your data looks like. Three refusals, none of them worth retrying unchanged: SIZE_LIMIT_EXCEEDED when the records, or the rows an explode expands them into, pass maxRows — raise maxRows up to 100,000 or split the document; AMBIGUOUS_RESULT when explode meets a record holding two array fields, since we will not guess which one drives the rows — switch that field to json or stringify; and INVALID_INPUT when recordsPath points at nothing — check the path against your document. Sending json and file_ref together, or neither, is refused as well.
Context footprint
Returns csv text plus headers, rowCount, columnCount, flattening, and warnings. A successful call costs 2 execution credits.
When to use it
When you need CSV from JSON records you already have.
When explode mode would hit multiple array fields (AMBIGUOUS_RESULT).
Scope
Non-goals
- Does not parse CSV back to JSON
- Does not fetch remote JSON
Properties
Capabilities
Cost & billing
Flat rate per invocation
File handling
File limits
Constraints this skill applies to your input and generated files. The “Limited by” column shows the static source of each cap; none of these can be raised by upgrading your plan.
| Limit | Value | Limited by |
|---|---|---|
| Maximum size per input file | 2 MiB | Skill maximum |
How we handle your data
What this means
This skill may receive sensitive content and may return submitted, transformed, extracted, or reformatted content.
Squillify guarantees
- Runs inside Squillify
- This skill runs inside Squillify.
- Payloads are not sent to an external service by this skill.
- Squillify does not permanently store submitted payloads.
- Telemetry records metadata only, not submitted content.
- Submitted payloads are not used for training.
- Submitted payloads are not reviewed by humans.
- This skill does not target sensitive data.
- The response may contain submitted or transformed content.
Your responsibility
Squillify does not determine whether submitted content is sensitive. Your application is responsible for deciding what data it is allowed to submit. Your application is responsible for securing the response.
Input schema
| Field | Type | Required | Description |
|---|---|---|---|
| json | object | No | Inline source containing one explicitly open JSON record or up to 100,000 such records; required unless file_ref is used. |
| file_ref | string | No | Tenant-scoped uploaded JSON reference; omit it when json supplies the inline source. |
| recordsPath | string | No | Dot or slash path selecting the record object or array; omit it to convert the source root. |
| pathSeparator | string | No | Non-empty separator joining nested keys into CSV headers; defaults to a period when omitted. |
| arrayMode | string | No | How arrays inside a record are represented; defaults to json when omitted. |
| includeHeader | boolean | No | Whether to emit the CSV header line; defaults to true when omitted. |
| nullValue | string | No | CSV cell text used for explicit JSON null; defaults to an empty string when omitted. |
| missingValue | string | No | CSV cell text used when a record lacks a discovered field; defaults to an empty string when omitted. |
| quoteMode | string | No | Whether to quote minimally or quote every CSV cell; defaults to minimal when omitted. |
| preserveDiscoveryOrder | boolean | No | Whether headers retain first-seen order instead of sorted order; defaults to false when omitted. |
| maxRows | integer | No | Maximum rows accepted after optional array expansion; defaults to 100,000 when omitted. |
Output schema
| Field | Type | Required | Description |
|---|---|---|---|
| csv | string | Yes | Generated RFC 4180 CSV text. |
| headers | array | Yes | From 0 through 10,000 flattened string column names in emitted order. |
| rowCount | integer | Yes | Number of emitted data rows. |
| columnCount | integer | Yes | Number of emitted CSV columns. |
| flattening | object | Yes | Closed receipt object containing the applied pathSeparator and arrayMode properties. |
| warnings | array | Yes | From 0 through 100,000 bounded warning strings; empty when no flattening warning occurred. |
API contract
POST /v1/executecurl -sS -X POST "$BASE/v1/execute" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"skillKey":"data.convert_json_csv","input":{"json":[{"id":1,"name":"Alice"}]}}'import { Squillify } from "@squillify/sdk";
const sq = new Squillify({ apiKey: process.env.SQUILLIFY_API_KEY });
const { output } = await sq.execute("data.convert_json_csv", {"json":[{"id":1,"name":"Alice"}]});Errors
| Code | HTTP | Retryable | Description |
|---|---|---|---|
| VALIDATION_ERROR | 400 | No | The request payload failed schema validation. |
| UNAUTHORIZED | 401 | No | Missing or invalid API key. |
| SKILL_NOT_ACCESSIBLE | 403 | No | The API key is not granted access to this skill. |
| SKILL_NOT_AVAILABLE_FOR_PLAN | 403 | No | This skill is not included in your current plan. |
| PLAN_ELIGIBILITY_UNAVAILABLE | 503 | Yes | Plan eligibility could not be decided. Retry after backoff. |
| SKILL_NOT_FOUND | 404 | No | The requested skill or version does not exist. |
| TENANT_RATE_LIMITED | 429 | Yes | Request rate limit exceeded. Retry after backoff. |
| QUOTA_EXCEEDED | 429 | Yes | Plan quota exhausted. Retryable once the quota period resets. |
| EXECUTION_TIMEOUT | 504 | Yes | Execution exceeded the allowed time budget. |
Other limits
| Limit | Value |
|---|---|
| Recommended inline bytes | 32 KiB |
Limitations
- Does not parse CSV back to JSON
- Does not fetch remote JSON
- Ambiguous multi-array explode
- Datasets beyond maxRows
How to call
POST /v1/execute (requires authentication)
{
"skillKey": "data.convert_json_csv",
"input": {
"json": [
{
"id": 1,
"name": "Alice"
}
]
}
}Examples
Convert a simple object array
{
"json": [
{
"id": 1,
"name": "Alice"
}
]
}{
"rowCount": 1,
"flattening": {
"pathSeparator": ".",
"arrayMode": "json"
},
"csv": "id,name\n1,Alice\n",
"headers": [
"id",
"name"
],
"warnings": [],
"columnCount": 2
}Flatten nested objects with dot paths
{
"json": [
{
"id": 1,
"meta": {
"tag": "x"
}
}
]
}{
"rowCount": 1,
"flattening": {
"pathSeparator": ".",
"arrayMode": "json"
},
"csv": "id,meta.tag\n1,x\n",
"headers": [
"id",
"meta.tag"
],
"warnings": [],
"columnCount": 2
}Recommended use cases
- Spreadsheet export from API JSON
- Reporting pipelines
- Flat file exchange
Avoid for
- Ambiguous multi-array explode
- Datasets beyond maxRows
Related skills
Composable with
Safety & privacy
- Runs without calling any external service.
- Your payloads are never stored permanently.
- Telemetry captures metadata only — never your payload contents.
- We never train models on your payloads.
- No human reviews your payloads.