Good SQL Formatting

Optimize your queries for readability. A fast, opinionated formatter with a Monaco-grade editor and CLI-friendly workflows.

GoogleSQLPostgreSQLMySQLSnowflake+10 dialects
14 dialectsmonaco editorzero installcurl ready
~/query.sql
BigQuery (GoogleSQL)1 lines0 chars
Ready
// automation

Format from anywhere

Integrate formatting into your workflow — as simple as piping a file through curl. No install, no config.

BigQuery · sensible defaults
cat query.sql | curl -X POST --data-binary @- https://api.nidoran.work/format-sql
live · matches the options above
cat query.sql | curl -X POST \
  --data-binary @- \
  "https://api.nidoran.work/format-sql?dialect=bigquery&max_length=120&keyword_handling=upper_case&builtin_function_handling=lower_case&indent_cte_definitions=true&always_break_select=false&always_break_query=true&always_break_pipe=true"
.md
Agent skill — format-sql/SKILL.md
Drop into .agents/skills/ to let agents format SQL automatically.
---
name: format-sql
description: Format a SQL script using the silos formatting API. Pipe SQL text via curl to format with dialect, line length, and casing options.
argument-hint: 'path to .sql file, e.g. query.sql'
---

# Format SQL

Use this skill when the user asks to format, beautify, or prettify a SQL query.

## Command

```bash
cat query.sql | curl -X POST --data-binary @- "https://api.nidoran.work/format-sql?dialect=bigquery&max_length=120&keyword_handling=upper_case"
```

Pipe the SQL file contents to the API. The response is returned as plain text.

## Important Caveats

### Comments may be dropped

The API does not always retain SQL comments. When formatting a query that contains comments (single-line `--` or block `/* */`), compare the original SQL with the formatted output. If comments were dropped, you must re-wire them back into the formatted SQL at the appropriate locations. Preserve the original comment text and place it logically near the code it was annotating.

### Error responses

The API returns `text/plain` for both success and error cases. Check the response content:

- If it starts with `Error:` or `error code:`, formatting failed — report the error reason to the user rather than treating it as formatted SQL.
- A successful response is raw formatted SQL with no prefix.

### Minor syntax fixes

If the API returns a syntax error, you may make **minimal, non-semantic fixes** to the SQL and retry formatting. Allowed fixes:

- Add or adjust `AS` aliases (e.g. `unnest(...) x` → `unnest(...) AS x`)
- Fix missing or trailing commas in SELECT, GROUP BY, etc.
- Fix trivial keyword casing inconsistencies
- Balance unmatched parentheses or quotes
- Fix keyword typos (e.g. `SELEC` → `SELECT`)

Do **not** make changes that alter the query's semantics, logic, or results. When in doubt, show the user the error and ask how they'd like to fix it.

## Available Options (query parameters)

| Parameter                   | Type                            | Default        | Description                                                                                               |
| --------------------------- | ------------------------------- | -------------- | --------------------------------------------------------------------------------------------------------- |
| `dialect`                   | string                          | `"bigquery"`   | SQL dialect. GooglesQL dialects: `"bigquery"`, `"googlesql"`. Any other value falls through to sqlfusion. |
| `max_length`                | int                             | `120`          | Maximum line length before the formatter wraps                                                            |
| `keyword_handling`          | `"upper_case"` / `"lower_case"` | `"upper_case"` | Case for SQL keywords (SELECT, FROM, WHERE, etc.)                                                         |
| `builtin_function_handling` | `"upper_case"` / `"lower_case"` | `"upper_case"` | Case for builtin functions (COUNT, SUM, etc.)                                                             |
| `indent_cte_definitions`    | bool                            | `true`         | Indent CTE definitions                                                                                    |
| `always_break_select`       | bool                            | `false`        | Always put each select item on its own line                                                               |
| `always_break_query`        | bool                            | `false`        | Always put each query clause on its own line                                                              |
| `always_break_pipe`         | bool                            | `false`        | Always break pipe operators to separate lines                                                             |

### Notes

- **GooglesQL dialects** (`"bigquery"`, `"googlesql"`): all options above are supported.
- **Other dialects** (sqlfusion fallback): only `dialect` and `max_length` apply. The dialect value is passed directly to sqlfusion (e.g. `"postgresql"`, `"mysql"`, `"sqlite"`, `"duckdb"`, `"databricks"`, etc.).

### Bool parameter values

Accepted truthy values: `"true"`, `"1"`, `"yes"`, `"on"` (case-insensitive). Anything else is falsy.

### Default request (no options)

```bash
cat query.sql | curl -X POST --data-binary @- "https://api.nidoran.work/format-sql"
```

This formats as GooglesQL/BigQuery with `max_length=120` and `keyword_handling=upper_case`.

### Examples

Format with lower-case keywords and 80-char line length:

```bash
cat query.sql | curl -X POST --data-binary @- "https://api.nidoran.work/format-sql?keyword_handling=lower_case&max_length=80"
```

Format as Postgres:

```bash
cat query.sql | curl -X POST --data-binary @- "https://api.nidoran.work/format-sql?dialect=postgresql&max_length=100"
```
// docs

Under the hood

Two parsers, full AST formatting, broad dialect coverage.

most complete

GoogleSQL (BigQuery) ↗

Parsed with Google’s own GoogleSQL engine into an abstract syntax tree before formatting rules are applied — including scripts and pipe syntax.

everything else

DataFusion SqlParser ↗

All other dialects use the DataFusion SQL parser. It covers most dialects well; a few unusual dialect-specific features may not parse.

Supported dialects
ANSI SQLBigQuery (GoogleSQL)ClickHouseDatabricksDuckDBGeneric SQLHiveMS SQLMySQLOraclePostgreSQLRedshiftSQLiteSnowflake