Skills sheet-generation-api
Generate CSV, Markdown, and XLSX spreadsheets from structured tabular data.
git clone https://github.com/iterationlayer/skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/iterationlayer/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/sheet-generation-api" ~/.claude/skills/iterationlayer-skills-sheet-generation-api && rm -rf "$T"
skills/sheet-generation-api/SKILL.mdSheet Generation API
Generate CSV, Markdown, and XLSX spreadsheets from structured tabular data.
Cost: 2 credits per request
Prerequisites
You need an Iteration Layer API key. Get one at platform.iterationlayer.com — free trial credits included, no credit card required.
For full integration guidance (SDKs, auth, MCP, error handling), see the Iteration Layer Integration Guide.
API Reference
Generate CSV, Markdown, and XLSX spreadsheets from a single API call. Send column definitions and row data as structured JSON, and receive the rendered spreadsheet as base64-encoded JSON in the response.
Key Features
- Three Output Formats -- Generate CSV, Markdown tables, or XLSX from one unified input structure.
- Positional Rows -- Rows are arrays of cells matching column order. No key mapping needed.
- Cell Formatting -- Format types: text, number, decimal, currency, percentage, date, datetime, time, custom.
- Currency Support -- ISO 4217 currency codes with configurable number separator styles.
- Rich Styling -- Base styles for headers and body, with per-cell overrides for font, color, alignment, and more (XLSX).
- Custom Fonts -- Upload font files (base64-encoded) with weight and style metadata (XLSX).
- Multiple Sheets -- XLSX supports multiple worksheets. Markdown renders each sheet as a headed table. CSV supports a single sheet.
- Merged Cells -- Combine cells across rows and columns using from/to ranges on individual cells (XLSX).
- Formulas -- Any cell value starting with
is treated as a formula. Native in XLSX, server-evaluated for CSV and Markdown.=
Overview
The Sheet Generation API creates spreadsheets from a JSON definition. You send a format, column definitions, row data, and optional styles, and receive the rendered spreadsheet as base64-encoded JSON.
Endpoint:
POST /sheet-generation/v1/generate
Supported output formats: CSV, Markdown, XLSX
Request Format
<!-- tabs -->curl -X POST \ https://api.iterationlayer.com/sheet-generation/v1/generate \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "format": "xlsx", "sheets": [ { "name": "Invoices", "columns": [ { "name": "Company", "width": 20 }, { "name": "Total", "width": 15 } ], "rows": [ [ { "value": "Acme Corp" }, { "value": 1500.50, "format": "currency", "currency_code": "EUR" } ] ] } ] }'
import { IterationLayer } from "iterationlayer"; const client = new IterationLayer({ apiKey: "YOUR_API_KEY", }); const result = await client.generateSheet({ format: "xlsx", sheets: [ { name: "Invoices", columns: [ { name: "Company", width: 20, }, { name: "Total", width: 15, }, ], rows: [ [ { value: "Acme Corp", }, { value: 1500.50, format: "currency", currency_code: "EUR", }, ], ], }, ], }); // result.data.buffer is base64-encoded // result.data.mime_type is "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
from iterationlayer import IterationLayer client = IterationLayer(api_key="YOUR_API_KEY") result = client.generate_sheet( format="xlsx", sheets=[ { "name": "Invoices", "columns": [ { "name": "Company", "width": 20 }, { "name": "Total", "width": 15 }, ], "rows": [ [ { "value": "Acme Corp" }, { "value": 1500.50, "format": "currency", "currency_code": "EUR", }, ], ], }, ], ) # result["data"]["buffer"] is base64-encoded # result["data"]["mime_type"] is "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
<!-- response -->import il "github.com/iterationlayer/sdk-go" client := il.NewClient("YOUR_API_KEY") result, err := client.GenerateSheet( il.GenerateSheetRequest{ Format: "xlsx", Sheets: []il.Sheet{ { Name: "Invoices", Columns: []il.SheetColumn{ { Name: "Company", Width: 20, }, { Name: "Total", Width: 15, }, }, Rows: [][]il.SheetCell{ { { Value: "Acme Corp", }, { Value: 1500.50, Format: "currency", CurrencyCode: "EUR", }, }, }, }, }, }, ) // result.Data.Buffer is base64-encoded // result.Data.MimeType is "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
<!-- /tabs -->{ "success": true, "data": { "buffer": "UEsDBBQAAAAIAA...", "mime_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" } }
Request Structure
The top-level request has the following fields:
| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | Output format: , , or |
| array | Yes | Array of sheet definitions (see below) |
| object | No | Base styles for headers and body cells |
| array | No | Custom font definitions (base64-encoded font files, XLSX only) |
| string | No | HTTPS URL to receive results asynchronously. If provided, returns 201 immediately. See Webhooks. |
Async Mode
Add a
webhook_url parameter to process the request in the background. The API returns 201 Accepted immediately and delivers the result to your webhook URL when processing completes. See Webhooks for payload format and retry behavior.
Sheets
Each sheet definition contains:
| Field | Type | Required | Description |
|---|---|---|---|
| string | No | Sheet name (default: "Sheet1") |
| array | Yes | Column definitions (see below) |
| array | No | Positional array of rows. Each row is an array of cells matching column order. |
Columns
| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | Display header name (min 1 character) |
| number | No | Column width (XLSX only, must be greater than 0) |
Rows and Cells
Each row is an array of cells, where each cell's position corresponds to the column at the same index. A cell can be a bare value (string, number, boolean, or null) or a structured object with formatting:
Bare value:
[ "Acme Corp", 1500.50 ]
Structured cells with format and styles:
[ { "value": "Acme Corp" }, { "value": 1500.50, "format": "currency", "currency_code": "EUR", "styles": { "is_bold": true, "font_color": "#008000" } } ]
You can mix bare values and structured cells in the same row. A row may have fewer cells than columns -- trailing cells default to empty.
Cell Fields
| Field | Type | Required | Description |
|---|---|---|---|
| any | No | Cell value. Strings starting with are treated as formulas. |
| string | No | Cell format (default: ). See Cell Formats below. |
| string | No | ISO 4217 currency code (default: ). Used with format. |
| string | No | Number separator style (default: ). Used with , , and formats. |
| string | No | Excel date format code (e.g., ). Used with , , and formats. See Date Styles below. |
| object | No | Per-cell style overrides (XLSX only). See Cell Styles below. |
| integer | No | Start column for merge range (0-based). See Merged Cells. |
| integer | No | End column for merge range (0-based). See Merged Cells. |
| integer | No | Start row for merge range (0-based). See Merged Cells. |
| integer | No | End row for merge range (0-based). See Merged Cells. |
Cell Formats
| Format | Description | CSV/Markdown Example | XLSX Format Code |
|---|---|---|---|
| Plain text (default) | | -- |
| Integer with thousands separator | | |
| Two decimal places | | |
| Currency symbol with decimals | | |
| Multiplied by 100 with % | | |
| Date string | | (default, customizable via ) |
| Date and time string | | (default, customizable via ) |
| Time string | | (default, customizable via ) |
| Custom Excel format code | (as-is) | Via in styles |
Cell Styles
Cell-level style overrides (XLSX only, ignored for CSV/Markdown):
| Field | Type | Description |
|---|---|---|
| string | Font family name |
| number | Font size in points (>= 1) |
| boolean | Bold text |
| boolean | Italic text |
| string | Font color as hex (e.g., ) |
| string | Cell background color as hex |
| string | One of: , , |
| string | Custom Excel number format code (used with ) |
Styles
The top-level
styles object defines base styles for header and body cells:
{ "styles": { "header": { "font_family": "Helvetica", "font_size_in_pt": 12, "is_bold": true, "background_color": "#4472C4", "font_color": "#FFFFFF" }, "body": { "font_family": "Helvetica", "font_size_in_pt": 11, "font_color": "#000000" } } }
Header styles apply to the column header row. Body styles apply to all data cells. Per-cell
styles overrides take precedence.
Custom Fonts
Upload custom fonts as base64-encoded buffers (XLSX only). Each font definition requires a name, weight, style, and the font file data.
| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | Font family name (min 1 character) |
| string | Yes | One of: , , , , , , , , |
| string | Yes | One of: , |
| string | Yes | Base64-encoded font file (TTF, OTF, WOFF, or WOFF2) |
Merged Cells
Merge a range of cells by setting
from_col, to_col, from_row, and to_row on the cell itself (XLSX only). The merge range is 0-based and inclusive. The cell's value is displayed in the merged area.
{ "format": "xlsx", "sheets": [ { "name": "Report", "columns": [ { "name": "A", "width": 20 }, { "name": "B", "width": 20 }, { "name": "C", "width": 20 } ], "rows": [ [ { "value": "Summary", "from_col": 0, "to_col": 2, "from_row": 0, "to_row": 0, "styles": { "is_bold": true, "horizontal_alignment": "center" } } ], [ "Detail A", "Detail B", "Detail C" ] ] } ] }
In this example, the first row's single cell spans all three columns (columns 0 through 2). The second row has three separate cells.
Formulas
Any cell whose
value is a string starting with = is treated as a formula. No separate formula array is needed -- formulas are just cells.
{ "format": "xlsx", "sheets": [ { "name": "Totals", "columns": [ { "name": "Item", "width": 20 }, { "name": "Amount", "width": 15 } ], "rows": [ [ "Widget A", { "value": 100.00, "format": "currency" } ], [ "Widget B", { "value": 250.00, "format": "currency" } ], [ { "value": "Total", "styles": { "is_bold": true } }, { "value": "=SUM(B2:B3)", "format": "currency" } ] ] } ] }
For XLSX, formulas are written natively and evaluated by Excel. For CSV and Markdown, simple aggregation formulas (SUM, AVERAGE, COUNT, MIN, MAX) are evaluated server-side. Unsupported formulas are written as raw strings.
Multiple Sheets
XLSX and Markdown support multiple sheets. CSV supports only one sheet.
XLSX: Each sheet becomes a separate worksheet in the workbook.
Markdown: Each sheet is rendered as a
## Sheet Name heading followed by a markdown table:
## Invoices | Company | Total | | --- | --- | | Acme Corp | EUR 1,500.50 | ## Payments | Date | Amount | | --- | --- | | 2026-01-15 | $500.00 |
CSV: If more than one sheet is provided, the API returns a 400 error.
Currency Codes
The
currency_code field accepts any ISO 4217 currency code. It is used with the currency format to determine the currency symbol displayed in the cell. Defaults to USD if not specified.
[ { "value": 1500.50, "format": "currency", "currency_code": "EUR" }, { "value": 2400.00, "format": "currency", "currency_code": "JPY" }, { "value": 899.99, "format": "currency", "currency_code": "GBP" } ]
Number Styles
The
number_style field controls the thousands and decimal separators for number, decimal, and currency formats. Defaults to comma_period if not specified.
| Style | Thousands Separator | Decimal Separator | Example |
|---|---|---|---|
| | | |
| | | |
| | | |
| | | |
[ { "value": 1500.50, "format": "decimal", "number_style": "period_comma" } ]
Date Styles
The
date_style field accepts an Excel date format code string to control how date, datetime, and time values are displayed. The format code is passed directly to XLSX as the cell number format, and interpreted for CSV/Markdown rendering.
| Token | Description | Example |
|---|---|---|
| 4-digit year | |
| 2-digit year | |
| Full month name | |
| Abbreviated month name | |
| 2-digit month (or minutes after /) | |
| Month without leading zero (or minutes after /) | |
| 2-digit day | |
| Day without leading zero | |
| 2-digit hour | |
| Hour without leading zero | |
| 2-digit seconds | |
| Seconds without leading zero | |
Default values if
date_style is not specified:
:dateyyyy-mm-dd
:datetimeyyyy-mm-dd hh:mm:ss
:timehh:mm:ss
[ { "value": "2026-03-21", "format": "date", "date_style": "dd/mm/yyyy" }, { "value": "2026-03-21 14:30:00", "format": "datetime", "date_style": "d mmmm yyyy hh:mm:ss" }, { "value": "14:30:00", "format": "time", "date_style": "hh:mm" } ]
Feature Comparison by Format
| Feature | XLSX | CSV | Markdown |
|---|---|---|---|
| Multiple Sheets | ✅ | ❌ | ✅ |
| Cell Formatting | ✅ | ❌ | ❌ |
| Custom Fonts | ✅ | ❌ | ❌ |
| Merged Cells | ✅ | ❌ | ❌ |
| Formulas | ✅ (native) | ✅ (server-evaluated) | ✅ (server-evaluated) |
| Number Formats | ✅ (native) | ✅ (string rendering) | ✅ (string rendering) |
| Currency Codes | ✅ | ✅ | ✅ |
| Number Styles | ✅ | ✅ | ✅ |
| Date Styles | ✅ | ✅ | ✅ |
| Column Widths | ✅ | ❌ | ❌ |
| Header/Body Styles | ✅ | ❌ | ❌ |
Recipes
For complete, runnable examples see the Recipes page.
Error Responses
| Status | Description |
|---|---|
| 400 | Invalid request (validation errors, missing required fields, CSV with multiple sheets) |
| 401 | Missing or invalid API key |
| 422 | Processing error (spreadsheet rendering failure) |
| 429 | Rate limit exceeded |