---
title: "Quickstart"
description: "Convert your first spreadsheet or CSV into SQL three ways - in the browser, with the intosql command line, and with the API or one of the SDKs."
canonical: https://intosql.com/docs/quickstart
last_updated: 2026-10-15
---

# Quickstart

This page converts one file three ways: in the browser, on the command line and through the API. Each path uses the same engine, so the SQL and the report are the same.

## In the browser

The converter at [intosql.com](https://intosql.com) is free and needs no account. Your file is read in the browser and never uploaded.

1. Open [intosql.com](https://intosql.com). The converter opens on a sample workbook, already converted.
2. Drop your file anywhere on the page, or select **Choose your file**. It takes `.xlsx`, `.xlsm`, `.xls`, `.xlsb`, `.ods`, `.csv`, `.tsv`, `.txt`, `.json`, `.ndjson`, and MySQL or MariaDB dumps as `.sql` or `.sql.gz`.
3. Pick your database under **Your database**: PostgreSQL, MySQL, MariaDB, SQLite, SQL Server or Oracle. The SQL is written again for it right away.
4. Check the fixes. The summary line reads like `5 rows converted, 8 fixes, none rejected`. Each fix has a number, and the same number marks the cell or column it changed on the preview of your file.
5. Select **Download ventas.postgresql.sql**, or **Copy** to put the SQL on the clipboard.

If a column came out wrong, select its header in the preview to rename it, keep it as text or leave it out. [The web converter](/docs/converter) covers every option.

## With the command line

The `intosql` command runs the same engine on your computer. Converting is free.

### Install

```shell
brew install alfonsobries/intosql/intosql
```

Or with npm:

```shell
npm i -g intosql
```

To try it without installing, prefix any command with `npx`, as in `npx intosql convert ventas.xlsx --to postgresql`.

### Convert

```shell
intosql convert ventas.xlsx --to postgresql --output ventas.sql
```

The script goes to `ventas.sql` and a summary goes to standard error:

```text
Converted 4 of 4 rows from ventas.xlsx into ventas for PostgreSQL.
10 fixes made; `intosql inspect ventas.xlsx` lists them.
```

The table is named after the file. `--table` names it yourself, and `--to` takes `postgresql`, `mysql`, `mariadb`, `sqlite`, `sql-server` or `oracle`. Without `--output`, the script goes to standard output.

To see every fix before you convert, run `intosql inspect ventas.xlsx`. To keep the report, add `--report ventas.report.json`.

### Run the script

The script creates the table and inserts the rows inside one transaction:

```sql
-- Written by IntoSQL for PostgreSQL.

SET client_encoding = 'UTF8';
BEGIN;

CREATE TABLE ventas (
    no_cliente text NOT NULL,
    nombre text NOT NULL,
    c_p text NOT NULL,
    alta date NOT NULL,
    activo boolean NOT NULL,
    saldo numeric(6,2)
);
```

Run it with `psql`:

```shell
psql -d tienda -v ON_ERROR_STOP=1 -f ventas.sql
```

To skip the script and load the file straight into a database, use `intosql load`. Loading into SQLite is free; loading into PostgreSQL, MySQL or MariaDB is part of IntoSQL Pro. See [Command line](/docs/cli) for every command and flag.

## With the API

The API converts files on IntoSQL's servers, for code that runs without you. It is part of IntoSQL Pro.

### Create an API key

Sign in, open **Settings**, then **API keys**, and create a key. Keep it in an environment variable:

```shell
export INTOSQL_API_KEY="your-key"
```

Every request sends it as a bearer token: `Authorization: Bearer $INTOSQL_API_KEY`.

### Create a conversion from a URL

The quickest way is to give the API a public HTTPS address of the file. It downloads the file and converts it right away. The `spec` is the conversion request, the same one the command line and the browser use.

```shell
curl -X POST https://intosql.com/api/v1/conversions \
  -H "Authorization: Bearer $INTOSQL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/exports/ventas.csv",
    "spec": {"output": {"dialect": "postgresql"}}
  }'
```

The spec only has to name the database; every other field takes its default ([Conversion spec](/docs/api/spec)). The answer is `202 Accepted`, with the conversion queued and the whole spec filled in. `name` comes from the URL's file name, and `bytes` stays `0` until the file arrives.

```json
{
    "data": {
        "id": "01J9Z8K3M4N5P6Q7R8S9T0V1W2",
        "status": "queued",
        "name": "ventas.csv",
        "bytes": 0,
        "spec": {
            "version": 1,
            "input": {
                "format": null,
                "encoding": null,
                "delimiter": null,
                "sheet": null,
                "header_row": null
            },
            "output": {
                "format": "sql",
                "dialect": "postgresql",
                "table": null,
                "schema": null,
                "create_table": true,
                "column_names": "snake_case",
                "style": "inserts",
                "batch_rows": 500
            },
            "inference": {
                "sample_rows": 10000,
                "date_order": "auto",
                "keep_leading_zeros": true,
                "locale": null
            },
            "columns": []
        },
        "report": null,
        "error": null,
        "output": null,
        "upload": null,
        "created_at": "2026-10-16T14:02:11+00:00",
        "started_at": null,
        "finished_at": null,
        "expires_at": "2026-10-17T14:02:11+00:00"
    }
}
```

To send a file from your computer instead, post `name` and `bytes` in place of `url`, `PUT` the file to the `upload.url` in the answer, then call `POST /api/v1/conversions/{id}/start`. See [Conversions](/docs/api/conversions).

### Wait for it to finish

Read the conversion until `status` is `done` or `failed`. It goes from `queued` to `running` to one of those two.

```shell
curl https://intosql.com/api/v1/conversions/01J9Z8K3M4N5P6Q7R8S9T0V1W2 \
  -H "Authorization: Bearer $INTOSQL_API_KEY"
```

When it is done, `report` holds the full report and `output.url` downloads the result:

```json
{
    "data": {
        "id": "01J9Z8K3M4N5P6Q7R8S9T0V1W2",
        "status": "done",
        "name": "ventas.csv",
        "bytes": 357,
        "spec": {
            "version": 1,
            "input": {
                "format": null,
                "encoding": null,
                "delimiter": null,
                "sheet": null,
                "header_row": null
            },
            "output": {
                "format": "sql",
                "dialect": "postgresql",
                "table": null,
                "schema": null,
                "create_table": true,
                "column_names": "snake_case",
                "style": "inserts",
                "batch_rows": 500
            },
            "inference": {
                "sample_rows": 10000,
                "date_order": "auto",
                "keep_leading_zeros": true,
                "locale": null
            },
            "columns": []
        },
        "report": {
            "version": 1,
            "input": {
                "format": "csv",
                "encoding": "windows-1252",
                "delimiter": ";",
                "sheet": null,
                "bytes": 357
            },
            "dialect": "postgresql",
            "table": "ventas",
            "columns": [
                {
                    "source_name": "Folio",
                    "name": "folio",
                    "sql_type": "text",
                    "kind": "text",
                    "precision": null,
                    "scale": null,
                    "max_chars": 5,
                    "nullable": false,
                    "fixes": [4],
                    "excluded": false,
                    "as_text": false
                },
                {
                    "source_name": "Fecha",
                    "name": "fecha",
                    "sql_type": "date",
                    "kind": "date",
                    "precision": null,
                    "scale": null,
                    "max_chars": null,
                    "nullable": false,
                    "fixes": [5],
                    "excluded": false,
                    "as_text": false
                },
                {
                    "source_name": "Importe",
                    "name": "importe",
                    "sql_type": "numeric(6,2)",
                    "kind": "decimal",
                    "precision": 6,
                    "scale": 2,
                    "max_chars": null,
                    "nullable": true,
                    "fixes": [6, 7],
                    "excluded": false,
                    "as_text": false
                }
            ],
            "rows": { "read": 5, "converted": 5, "rejected": 0 },
            "fixes": [
                {
                    "number": 1,
                    "code": "text_transcoded",
                    "column": null,
                    "row": null,
                    "args": { "encoding": "windows-1252" }
                },
                {
                    "number": 2,
                    "code": "header_found",
                    "column": null,
                    "row": 4,
                    "args": { "row": "4" }
                },
                {
                    "number": 5,
                    "code": "dates_day_first",
                    "column": "Fecha",
                    "row": null,
                    "args": {
                        "column": "Fecha",
                        "evidence": "15/02/2024",
                        "example": "03/02/2024",
                        "reading": "2024-02-03"
                    }
                }
            ],
            "problems": [],
            "timings": { "read_ms": 2, "convert_ms": 1, "total_ms": 3 }
        },
        "error": null,
        "output": {
            "bytes": 686,
            "url": "https://storage.example.com/01J9Z8K3M4N5P6Q7R8S9T0V1W2/ventas.sql?X-Amz-Expires=600&X-Amz-Signature=..."
        },
        "upload": null,
        "created_at": "2026-10-16T14:02:11+00:00",
        "started_at": "2026-10-16T14:02:12+00:00",
        "finished_at": "2026-10-16T14:02:13+00:00",
        "expires_at": "2026-10-17T14:02:11+00:00"
    }
}
```

The report above is shortened to three columns and three fixes; a real one lists every column and every fix. A failed conversion has `status` `failed` and the reason in `error`.

### Download the result

`output.url` is a signed address that works for ten minutes. Read the conversion again for a fresh one.

```shell
curl -o ventas.sql "https://storage.example.com/01J9Z8K3M4N5P6Q7R8S9T0V1W2/ventas.sql?X-Amz-Expires=600&X-Amz-Signature=..."
```

The file and the output are deleted 24 hours after the conversion was created, or right away with `DELETE /api/v1/conversions/{id}`.

### The same with an SDK

The [SDKs](/docs/sdks) for TypeScript, PHP, Python, Java, Go, .NET and Ruby make the same calls. In TypeScript:

```shell
npm install @intosql/sdk
```

`convertUrl` creates the conversion and waits until it is done. `spec()` fills in the same defaults as the curl example.

```ts
import { IntoSQL, spec } from '@intosql/sdk';

const intosql = new IntoSQL({ apiKey: process.env.INTOSQL_API_KEY! });

const conversion = await intosql.convertUrl(
    'https://example.com/exports/ventas.csv',
    {
        spec: spec({ dialect: 'postgresql' }),
    },
);

console.log(conversion.report?.rows.converted, conversion.output?.url);
```

For a file on disk, `convert` uploads it, starts the conversion and waits:

```ts
import { openAsBlob } from 'node:fs';

const conversion = await intosql.convert(await openAsBlob('ventas.xlsx'), {
    name: 'ventas.xlsx',
    spec: spec({ dialect: 'postgresql', table: 'ventas' }),
});
```

A conversion that fails throws `ConversionFailedError`; a refused request throws `IntoSQLError` with a `code` such as `needs_pro` or `over_quota`. See the [TypeScript SDK](/docs/sdks/typescript), or the [SDK](/docs/sdks) for your language.

## Next steps

- [The web converter](/docs/converter): every option, the column editor and the report.
- [How fixes work](/docs/fixes): what each fix means and how to turn it off.
- [Command line](/docs/cli): `convert`, `inspect`, `load` and the local MCP server.
- [API](/docs/api): authentication, limits and every endpoint.
