SQL Simulator

API Reference

Every endpoint your own scripts or CI pipeline can call directly, instead of clicking through the web UI -- add a data source, upload scripts, trigger a run, and read back the results.

Base URL & authentication

Every example below assumes SQL Simulator is running via the docker-compose.yml from Get started, reachable at http://localhost:8080 — the host port every profile maps consistently (see Supported Databases). Adjust the host/port if you've deployed it elsewhere.

No API key, token, or login is required. Auth0 sign-in only gates this website's own Dashboard — a Docker or Kubernetes deployment of SQL Simulator (or 00DB) never uses it, so these endpoints sit at the same trust boundary as the product's own web UI. Anyone who can reach the container's port can call them.

Account setup

POST /api/Account/setup

Sets this deployment's one shared username/password — the same thing the web UI's own Set up this deployment screen does the first time anyone visits it — and pushes that same pair to every database container this deployment's own compose/pod profile actually configured, as their fixed sandbox login. Call this once, right after starting a fresh container, to finish setup entirely from a script instead of opening a browser.

One-time only. The first call wins; every call after that returns 409 Conflict. There is no reset endpoint — if the credential is lost, destroy and recreate the container. The password is never echoed back in the response, and no other endpoint in this API (or this page) ever returns it either.

curl -X POST http://localhost:8080/api/Account/setup -H "Content-Type: application/json" -d "{\"username\":\"admin\",\"password\":\"REDACTED\"}"

Response

{"username":"admin","containersConfigured":1}

containersConfigured is how many database containers this profile had configured at the moment of the call — a container that isn't up yet still counts (its login gets applied automatically the next time a run actually needs it), a container this deployment's profile never configured at all does not.

This credential does not gate anything else in this API — every other endpoint on this page stays exactly as unauthenticated as described above. It only gates the web UI's own /login page and the live sandbox database logins themselves (what you'd type into SSMS, psql, etc. to connect directly).

Data Sources

POST /api/DataSources/Add

Adds a data source, the same information you'd otherwise fill into the Data Sources page's own form. sourceConnectionString is required — a ready-to-use connection string, exactly what you'd type into that form's own field, not decomposed username/host/port parts. simulatedConnectionString is optional: leave it out and the sandbox container's real address and its fixed, reusable login are resolved for you automatically (same as the "Use container address" button); supply it to pin an exact value instead. databaseType is one of SQLSERVER, ORACLE, MYSQL, POSTGRES (case-insensitive). name, sandboxTarget, and selected (default true) are all optional.

curl -X POST http://localhost:8080/api/DataSources/Add -H "Content-Type: application/json" -d "{\"name\":\"Orders DB\",\"databaseType\":\"SQLSERVER\",\"sourceConnectionString\":\"Server=prod-db,1433;Database=Orders;User Id=svc_readonly;Password=REDACTED;TrustServerCertificate=True;\"}"

Response

{"id":1,"name":"Orders DB","engine":0,"sandboxTarget":null,"selected":true}

engine is a plain integer, not a string — see "Connection string syntax by engine" below for the SqlServer=0/Oracle=1/MySql=2/Postgres=3 mapping.

GET /api/DataSources

Lists every data source currently configured, so a script can look up the id an earlier Add call returned without having to capture and thread it through by hand.

curl http://localhost:8080/api/DataSources
POST /api/DataSources/{id}/scripts

Uploads one or more SQL script files to a data source, same as the Data Sources → Scripts page. Send them as multipart/form-data under the files field. An optional programming_language query parameter is accepted for call-shape familiarity but isn't stored — this app already knows a script's engine from its parent data source.

curl -X POST http://localhost:8080/api/DataSources/1/scripts -F "files=@nightly-report.sql"
POST /api/DataSources/{id}/test-connection

Tests both connection strings on a data source — the source database and the sandbox — and returns a result for each independently, matching the two "Test" links Data Sources' own form already gives a human.

curl -X POST http://localhost:8080/api/DataSources/1/test-connection

Response

{"source":{"success":true,"errorMessage":null},"simulated":{"success":true,"errorMessage":null}}
POST /api/DataSources/{id}/destroy

Manually tears down that data source's currently tracked sandbox — the API equivalent of the Simulator screen's "Destroy Image" button. You don't need to call this between runs: Preview Image, Postview Image, and Dry Run all destroy every currently tracked sandbox automatically as their own first step. See Technical Overview for when you'd still want to call this directly.

curl -X POST http://localhost:8080/api/DataSources/1/destroy

Run

Three endpoints, one per run mode described on Technical Overview:

  • POST /api/Run/PreviewImage — schema and scoped data only.
  • POST /api/Run/PostviewImage — also runs your uploaded scripts' DML, sandbox left standing.
  • POST /api/Run/DryRun — same as Postview Image, then tears the sandbox back down immediately.

Each takes an optional dataSourceId query parameter. Omit it and the run acts on every data source currently marked selected (the same set the Simulator screen's own buttons act on). Pass it to scope the call to exactly that one data source without changing what's selected in the web UI — the API temporarily selects only that row for the duration of the call and restores the previous selection afterward, even if the run fails partway through.

curl -X POST "http://localhost:8080/api/Run/PreviewImage?dataSourceId=1"

Response (trimmed)

[{"dataSource":{"id":1,"name":"Orders DB","engine":0,"sandboxTarget":null,"selected":true},"status":"Success","mode":"PreviewImage","sandbox":{"connectionString":"...","..."},"seedTables":["..."],"errorMessage":null}]

One entry per data source the run acted on — including the sandbox's connection details, so a script can connect to it directly after a Postview Image or Preview Image run. As of 2026-08-03, dataSource is deliberately the same connection-string-free shape GET /api/DataSources returns, not the full data source record — it never carries sourceConnectionString/ simulatedConnectionString, which for every engine here means a real database password embedded in plain text. sandbox.connectionString above is a different, freshly provisioned sandbox connection string, not the source database's.

Sandboxes

GET /api/Sandboxes

Lists every data source that currently has a live sandbox standing — the same "tracked sandboxes" list the Simulator screen shows.

curl http://localhost:8080/api/Sandboxes

Response

[{"id":1,"name":"Orders DB","engine":0,"sandboxTarget":null,"selected":true}]

Same connection-string-free shape GET /api/DataSources returns — as of 2026-08-03, this deliberately never includes sourceConnectionString/ simulatedConnectionString, which embed real database passwords.

Connection string syntax by engine

sourceConnectionString must be a real, working connection string in your engine's own syntax. The examples below use placeholder hosts/credentials -- same syntax simulatedConnectionString would need if you supply one explicitly instead of leaving it to auto-resolve.

Engine databaseType engine (response) Example connection string
SQL Server SQLSERVER 0 Server=host,1433;Database=db;User Id=user;Password=pwd;TrustServerCertificate=True;
Oracle ORACLE 1 Data Source=host:1521/FREE;User Id=user;Password=pwd;
MySQL MYSQL 2 Server=host;Port=3306;Database=db;User Id=user;Password=pwd;
PostgreSQL POSTGRES 3 Host=host;Port=5432;Database=db;Username=user;Password=pwd;

Full example

Add a SQL Server data source, upload a script, run a Preview Image against just that data source, then tear it down — the same four calls a CI pipeline would chain together.

curl -X POST http://localhost:8080/api/DataSources/Add -H "Content-Type: application/json" -d "{\"name\":\"Orders DB\",\"databaseType\":\"SQLSERVER\",\"sourceConnectionString\":\"Server=prod-db,1433;Database=Orders;User Id=svc_readonly;Password=REDACTED;TrustServerCertificate=True;\"}"
curl -X POST http://localhost:8080/api/DataSources/1/scripts -F "files=@nightly-report.sql"
curl -X POST "http://localhost:8080/api/Run/PreviewImage?dataSourceId=1"
curl -X POST http://localhost:8080/api/DataSources/1/destroy

The id 1 in the last three commands is whatever id the first call's response actually returns -- substitute your own.