API
Conversions
The conversion object and every endpoint that opens, uploads, starts, reads, lists and deletes conversions in the IntoSQL API.
A conversion is one file on its way to SQL: the file you send, the spec that says how to read and write it, its status, the engine's report and, once it's done, the address of the output.
The Conversion object
| Field | Type | Description |
|---|---|---|
id |
string | A ULID. |
status |
one of awaiting_upload, queued, running, done, failed, canceled |
Where the conversion is: waiting for its file, waiting for its turn, converting, or ended (done, failed or canceled). |
name |
string | The file's name, as sent or taken from its address. |
bytes |
integer | The file's size; 0 until a file sent by url arrives. |
spec |
object | A conversion request, the same for the browser, the CLI, the API and MCP. |
report |
object | The engine's report once the conversion is done: the table, its columns and types, rows converted and rejected, and every fix. |
error |
object | When status is failed: why, with a stable code. |
output |
object or null | When status is done: the output's size in bytes and a url that downloads it for ten minutes. |
upload |
object or null | In the answer that opens it, while status is awaiting_upload: where to PUT the file, with the headers to send, for an hour. |
created_at |
string or null | When the conversion was opened, in ISO 8601. |
started_at |
string or null | When the engine started on it. |
finished_at |
string or null | When it ended: done, failed or canceled. |
expires_at |
string | When its files are deleted. |
{
"id": "01J9Z8K3M4N5P6Q7R8S9T0V1W2",
"status": "done",
"name": "ventas.csv",
"bytes": 1048576,
"spec": {
"version": 1,
"output": {
"format": "sql",
"dialect": "postgresql",
"table": null
}
},
"report": {
"table": "ventas",
"rows": {
"converted": 18204,
"rejected": 0
},
"fixes": []
},
"error": null,
"output": {
"bytes": 2310455,
"url": "https://files.intosql.com/01J9Z8K3M4/ventas.postgresql.sql?signature=..."
},
"upload": null,
"created_at": "2026-10-16T14:02:11+00:00",
"started_at": "2026-10-16T14:02:13+00:00",
"finished_at": "2026-10-16T14:02:15+00:00",
"expires_at": "2026-10-17T14:02:15+00:00"
}List conversions
GET /conversions
Newest first. Pass meta.next_cursor as cursor for the next page.
Query
| Name | Type | Description |
|---|---|---|
limit |
integer | Conversions per page, 1 to 100. 50 when absent. |
status |
string | Only conversions in this status: awaiting_upload, queued, running, done, failed, canceled. |
cursor |
string | The meta.next_cursor of the page before. |
Answers
| Status | Meaning |
|---|---|
200 |
A page of conversions. |
401 |
No API key, or not a valid one. |
402 |
No Pro plan (needs_pro), or this month's conversions are used up (over_quota). |
403 |
The key can't use conversions, or the account is suspended. |
405 |
The path doesn't take this method. |
422 |
limit or status isn't valid. |
429 |
More than 120 requests a minute with this key (rate_limited), or, when opening or starting a conversion, five already queued or running (too_many_active). Wait Retry-After seconds. |
curl -X GET https://intosql.com/api/v1/conversions \
-H "Authorization: Bearer $INTOSQL_API_KEY"Open a conversion
POST /conversions
Send name and bytes to upload the file yourself, up to 5 GiB: the answer has an address to PUT it to, valid for an hour. Or send url, a public HTTPS address of a file up to 50 GiB: it is downloaded and converted right away, and the answer is 202.
Headers
| Name | Description |
|---|---|
Idempotency-Key |
Optional, up to 255 characters. A retry with the same key gets the first answer instead of doing the work twice. |
Body
Send either a file to upload yourself or the address of one.
| Field | Type | Description |
|---|---|---|
name |
string | The file's name, with its extension. Required to upload; optional with url. |
bytes |
integer | The file's size in bytes, up to 5 GiB. Required to upload. |
url |
string | A public HTTPS address of the file, instead of name and bytes. |
spec |
object | How to read and write the file: the conversion spec. Only output.dialect is required; the rest takes its default. |
Answers
| Status | Meaning |
|---|---|
201 |
The conversion, with its upload address. |
202 |
The conversion of the file at url, queued. |
401 |
No API key, or not a valid one. |
402 |
No Pro plan (needs_pro), or this month's conversions are used up (over_quota). |
403 |
The key can't use conversions, or the account is suspended. |
405 |
The path doesn't take this method. |
409 |
A request with the same Idempotency-Key is still running. |
413 |
The file is larger than a conversion takes. |
422 |
Missing fields, an invalid spec, a url that isn't public HTTPS, or an Idempotency-Key reused for another request. |
429 |
More than 120 requests a minute with this key (rate_limited), or, when opening or starting a conversion, five already queued or running (too_many_active). Wait Retry-After seconds. |
curl -X POST https://intosql.com/api/v1/conversions \
-H "Authorization: Bearer $INTOSQL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "ventas.csv",
"bytes": 1048576,
"spec": {
"output": {
"dialect": "postgresql"
}
}
}'Read a conversion
GET /conversions/{id}
When status is done, output.url downloads the result for ten minutes; read the conversion again for a fresh address. When it is failed, error says why.
Path
| Name | Type | Description |
|---|---|---|
id |
string | The conversion's id, a ULID. |
Answers
| Status | Meaning |
|---|---|
200 |
The conversion. |
401 |
No API key, or not a valid one. |
402 |
No Pro plan (needs_pro), or this month's conversions are used up (over_quota). |
403 |
The key can't use conversions, or the account is suspended. |
404 |
No conversion with that id on this account. |
405 |
The path doesn't take this method. |
429 |
More than 120 requests a minute with this key (rate_limited), or, when opening or starting a conversion, five already queued or running (too_many_active). Wait Retry-After seconds. |
curl -X GET https://intosql.com/api/v1/conversions/01J9Z8K3M4N5P6Q7R8S9T0V1W2 \
-H "Authorization: Bearer $INTOSQL_API_KEY"Start a conversion
POST /conversions/{id}/start
Once the whole file is uploaded. The conversion is queued, then running, then done or failed. Don't retry already_started: the conversion is on its way.
Path
| Name | Type | Description |
|---|---|---|
id |
string | The conversion's id, a ULID. |
Headers
| Name | Description |
|---|---|
Idempotency-Key |
Optional, up to 255 characters. A retry with the same key gets the first answer instead of doing the work twice. |
Answers
| Status | Meaning |
|---|---|
202 |
Queued. |
401 |
No API key, or not a valid one. |
402 |
No Pro plan (needs_pro), or this month's conversions are used up (over_quota). |
403 |
The key can't use conversions, or the account is suspended. |
404 |
No conversion with that id on this account. |
405 |
The path doesn't take this method. |
409 |
Already started, the file isn't uploaded whole yet, or a request with the same Idempotency-Key is still running. |
429 |
More than 120 requests a minute with this key (rate_limited), or, when opening or starting a conversion, five already queued or running (too_many_active). Wait Retry-After seconds. |
curl -X POST https://intosql.com/api/v1/conversions/01J9Z8K3M4N5P6Q7R8S9T0V1W2/start \
-H "Authorization: Bearer $INTOSQL_API_KEY"Cancel a conversion
POST /conversions/{id}/cancel
Stops a conversion that hasn't ended and deletes its files; it stays listed as canceled and doesn't count toward the month. Canceling it again answers the same. A running conversion may finish its work, but the result is thrown away.
Path
| Name | Type | Description |
|---|---|---|
id |
string | The conversion's id, a ULID. |
Headers
| Name | Description |
|---|---|
Idempotency-Key |
Optional, up to 255 characters. A retry with the same key gets the first answer instead of doing the work twice. |
Answers
| Status | Meaning |
|---|---|
200 |
Canceled. |
401 |
No API key, or not a valid one. |
402 |
No Pro plan (needs_pro), or this month's conversions are used up (over_quota). |
403 |
The key can't use conversions, or the account is suspended. |
404 |
No conversion with that id on this account. |
405 |
The path doesn't take this method. |
409 |
It already ended (already_finished). |
429 |
More than 120 requests a minute with this key (rate_limited), or, when opening or starting a conversion, five already queued or running (too_many_active). Wait Retry-After seconds. |
curl -X POST https://intosql.com/api/v1/conversions/01J9Z8K3M4N5P6Q7R8S9T0V1W2/cancel \
-H "Authorization: Bearer $INTOSQL_API_KEY"Delete a conversion
DELETE /conversions/{id}
Deletes its files now instead of after 24 hours. A conversion deleted while it runs sends no webhook.
Path
| Name | Type | Description |
|---|---|---|
id |
string | The conversion's id, a ULID. |
Answers
| Status | Meaning |
|---|---|
204 |
Deleted. |
401 |
No API key, or not a valid one. |
402 |
No Pro plan (needs_pro), or this month's conversions are used up (over_quota). |
403 |
The key can't use conversions, or the account is suspended. |
404 |
No conversion with that id on this account. |
405 |
The path doesn't take this method. |
429 |
More than 120 requests a minute with this key (rate_limited), or, when opening or starting a conversion, five already queued or running (too_many_active). Wait Retry-After seconds. |
curl -X DELETE https://intosql.com/api/v1/conversions/01J9Z8K3M4N5P6Q7R8S9T0V1W2 \
-H "Authorization: Bearer $INTOSQL_API_KEY"Send us a conversion
POST /conversions/{id}/cases
When a file didn't convert well, or at all, send it so we add support for it. With share: file the file goes too (a failed conversion keeps its upload until it expires); otherwise only the report and the spec. Cases are private, kept 90 days, and deleted after; the privacy policy says how they are handled.
Path
| Name | Type | Description |
|---|---|---|
id |
string | The conversion's id, a ULID. |
Headers
| Name | Description |
|---|---|
Idempotency-Key |
Optional, up to 255 characters. A retry with the same key gets the first answer instead of doing the work twice. |
Body
| Field | Type | Description |
|---|---|---|
consent |
boolean | Required, true: the person agrees to send it. |
share |
string | file to send the file and its report, report (the default) for the report only. |
email |
string | Where to say when support lands. |
note |
string | Anything that helps, up to 2,000 characters. |
Answers
| Status | Meaning |
|---|---|
201 |
The case. |
401 |
No API key, or not a valid one. |
402 |
No Pro plan (needs_pro), or this month's conversions are used up (over_quota). |
403 |
The key can't use conversions, or the account is suspended. |
404 |
No conversion with that id on this account. |
405 |
The path doesn't take this method. |
409 |
The conversion hasn't ended (not_finished), or its file is gone (file_gone). |
422 |
consent is missing. |
429 |
More than 120 requests a minute with this key (rate_limited), or, when opening or starting a conversion, five already queued or running (too_many_active). Wait Retry-After seconds. |
curl -X POST https://intosql.com/api/v1/conversions/01J9Z8K3M4N5P6Q7R8S9T0V1W2/cases \
-H "Authorization: Bearer $INTOSQL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"consent": true,
"share": "file",
"note": "Exported from our ERP; the dates come out wrong."
}'