API Reference
Version 1 · Base URL https://api.chaosdata.net
Overview
ChaosData turns a relational schema into production-realistic test data,
then hides edge cases inside it: emoji, unicode overflows, boundary
numbers, malformed strings and more. Post a SQL schema, get back ordered
INSERT statements or a structured JSON payload.
- Deterministic. Pass a
seedfor byte-for-byte reproducible output. - Dialect auto-detection. PostgreSQL, MySQL and SQLite dumps are recognized from a small prefix.
- Constraint-aware. Keys, foreign keys,
NOT NULL,UNIQUE, lengths, unsigned ranges and simpleCHECKs are respected.
/openapi.json (OpenAPI 3.1).
Quickstart
Send a schema and receive SQL:
curl -X POST "https://api.chaosdata.net/api/v1/quick-generate?rows=50&chaos=15" \
-H "Accept: text/sql" \
--data-binary @schema.sql
Or structured JSON:
curl -X POST "https://api.chaosdata.net/api/v1/quick-generate?rows=50&chaos=15" \
-H "Accept: application/json" \
--data-binary @schema.sql
A typical schema.sql:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
age INT CHECK (age >= 0)
);
Waitlist
No key is required: quick-generate is public and anonymous.
Accounts are not open yet, so there is nothing to sign up for. Join the
waitlist at /waitlist and we will email
you (once you confirm) when API keys, usage history and higher limits ship.
POST /api/v1/waitlistrecords interest and sends a double opt-in link. It answers the same way whether or not the address was already present.POST /api/v1/waitlist/confirmconsumes the emailed token.
Generate data
POST/api/v1/quick-generate
Query parameters
| Name | Type | Default | Description |
|---|---|---|---|
rows | integer | 25 | Rows generated per table (1–100). |
chaos | integer | 0 | Percent chance that any eligible value becomes an anomaly (0–100). |
seed | int64 | random | Reproducible output; the same seed yields identical bytes. |
dialect | string | auto | postgres, mysql, sqlite or auto. |
validate_only | boolean | false | Validate and summarize the schema without generating data. |
Request headers
| Header | Description |
|---|---|
Accept | text/sql or application/json. Anything else returns 406. |
X-Chaos-Hints | Override per-column semantic types. See Column hints. |
Request body
The raw SQL DDL (CREATE TABLE statements). It is parsed as a
stream, so the server validates incrementally and, on the first syntax
error, stops reading and closes the connection after returning
400. Non-DDL statements (SET, GRANT,
CREATE INDEX, MySQL table options, SQLite STRICT,
PRAGMA, …) are tolerated and skipped.
CHAOSDATA_MAX_BODY_BYTES, 2 MiB by default) returns
413. The dialect is detected from a 64 KiB prefix, so a
dump can be piped in without extra flags.
Responses
Accept: text/sql: a metadata header, a transaction and parent-first multi-row inserts:
-- ChaosData | seed=42 rows=5 chaos=15 anomalies=2
SET client_encoding TO 'UTF8';
BEGIN;
INSERT INTO "users" ("id", "email", "age") VALUES
(1, 'alex🚀@example.com', 0);
COMMIT;
Accept: application/json: a metadata block plus a table-keyed data object:
{
"metadata": {
"seed": 42,
"rows_per_table": 5,
"chaos": 15,
"anomalies_injected": 2,
"duration_ms": 4,
"tables": [ { "name": "users", "rows": 5, "anomalies": 2, "order": 0 } ]
},
"data": {
"users": [ { "id": 1, "email": "alex🚀@example.com", "age": 0 } ]
}
}
validate_only=true returns a summary instead, including the
resolved semantic type of every column:
{
"valid": true,
"input_dialect": "postgres",
"tables": [ { "name": "users", "foreign_keys": 0,
"columns": [ { "name": "email", "semantic": "email" } ] } ]
}
Column hints
ChaosData infers each column's semantic type from its name and
SQL type (email → email, user_id →
identifier, created_at → timestamp).
When the name is ambiguous, tell us with X-Chaos-Hints. It
affects both the realistic base values and which anomalies apply.
curl -X POST "https://api.chaosdata.net/api/v1/quick-generate?rows=100&chaos=20" \
-H "X-Chaos-Hints: users.user_id=identifier; users.email=email; orders.total=money" \
-H "Accept: application/json" \
--data-binary @schema.sql
- Pairs are
[schema.]table.column=typeor a barecolumn=type, semicolon-separated; the header may be repeated. - Keys are case-insensitive; a bare column name applies to every table that has it.
- Validation is strict: an unknown type, a type incompatible with the column's SQL kind, or a hint that matches no column returns
400. - A hint overrides name inference. Use
text/unknownto disable it.
Datatypes
Live from GET /api/v1/datatypes. A datatype is the
semantic content of a column; these are the values accepted by
X-Chaos-Hints, along with their aliases and the anomalies
that can apply. unknown, none and
opaque are aliases of text.
| Datatype | Category | Aliases | Example | Anomalies |
|---|---|---|---|---|
| Loading datatypes… | ||||
Anomaly catalog
Live from GET /api/v1/anomalies. Each anomaly lists the
datatypes it can apply to. Only unique-safe
anomalies are used on UNIQUE columns.
| Anomaly | Datatypes | Unique-safe |
|---|---|---|
| Loading catalog… | ||
Other endpoints
GET/api/v1/datatypes
Returns every datatype with its category, aliases, an example and the anomalies that apply to it.
GET/api/v1/anomalies
Returns the datatype names (datatypes) and the anomaly catalog (anomalies).
GET/api
Service descriptor: name, description, homepage and the endpoint list.
GET/healthz
Returns {"status":"ok"}. Useful for load balancers and uptime checks.
Direct pipe
Dump a schema, pipe it through ChaosData, load it into a test database. One line, every time. The target tables must already exist.
# MySQL
mysqldump --no-data mydb | curl -s -X POST \
"https://api.chaosdata.net/api/v1/quick-generate?rows=50&chaos=10" \
-H "Accept: text/sql" --data-binary @- | mysql mydb_test
# PostgreSQL
pg_dump --schema-only mydb | curl -s -X POST \
"https://api.chaosdata.net/api/v1/quick-generate?rows=50&chaos=10" \
-H "Accept: text/sql" --data-binary @- | psql mydb_test
# SQLite
sqlite3 mydb .schema | curl -s -X POST \
"https://api.chaosdata.net/api/v1/quick-generate?rows=50&chaos=10" \
-H "Accept: text/sql" --data-binary @- | sqlite3 mydb_test
Errors
Errors use RFC 9457 application/problem+json. This is an example error response:
{
"type": "about:blank",
"title": "Bad Request",
"status": 400,
"detail": "line 1, column 26: unexpected character \"@\"",
"instance": "/api/v1/quick-generate"
}
Rate limits
Anonymous requests are limited per client address.
| Scope | Limit |
|---|---|
| Per client | 60 requests per minute |
| Rows per table | 100 |
Limits are token buckets, so short bursts are allowed on top. Larger
rows cost more than one request. Over-limit requests return
429 with a Retry-After header, and IPv6 clients
are counted by network prefix.
Need something else? Email hello@chaosdata.net.