Docs · API
API keys & automation
Use a personal access token to call the SynthForge REST API from scripts, CI, or local tools without a browser session cookie.
Short answer
Create a key in Settings, send it as Authorization: Bearer sfk_live_... on every request, and call
POST /api/v1/schemas, POST /api/v1/datasets, then
GET /api/v1/datasets/{id}/download. The curl walkthrough below does exactly that.
1. Create a key
- Sign in at app.synthforge.io
- Open Settings → API keys
- Choose a short name (for example
ciorlaptop) and create the key - Copy the secret immediately. It is shown only once.
After that you only see a prefix like
sfk_live_ab12…
Secrets look like sfk_live_….
2. Authenticate
Send the secret as a Bearer token on every request. Base URL for production:
https://api.synthforge.io export SF_API_KEY='sfk_live_…' # paste your secret
export API_BASE='https://api.synthforge.io'
curl -sS -H "Authorization: Bearer $SF_API_KEY" \
"$API_BASE/api/v1/users/me" | jq .
A successful response is your user profile JSON (email, quotas, etc.). A bad or revoked key returns
401.
3. curl: end-to-end generate
Minimal flow: create a schema → start a dataset job → poll status → download the ZIP (CSV, Parquet, SQL loaders, README, quality report).
export SF_API_KEY='sfk_live_…'
export API_BASE='https://api.synthforge.io'
# 1) Create a minimal schema (or use an existing schema id from the app)
SCHEMA_JSON='{
"name": "api-demo",
"schema_data": {
"tables": [
{
"name": "customers",
"columns": [
{ "name": "id", "field_type": "integer_sequence", "primary_key": true },
{ "name": "email", "field_type": "email" },
{ "name": "full_name", "field_type": "full_name" }
]
},
{
"name": "orders",
"columns": [
{ "name": "id", "field_type": "integer_sequence", "primary_key": true },
{
"name": "customer_id",
"field_type": "integer",
"foreign_key": { "table": "customers", "column": "id" }
},
{ "name": "amount", "field_type": "currency_amount" }
]
}
]
}
}'
SCHEMA_ID=$(curl -sS -X POST "$API_BASE/api/v1/schemas" \
-H "Authorization: Bearer $SF_API_KEY" \
-H "Content-Type: application/json" \
-d "$SCHEMA_JSON" | jq -r .id)
# 2) Start generation (flat formats stream out-of-core on the server)
DATASET_ID=$(curl -sS -X POST "$API_BASE/api/v1/datasets" \
-H "Authorization: Bearer $SF_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"schema_id\": \"$SCHEMA_ID\",
\"name\": \"api-demo-run\",
\"row_counts\": { \"customers\": 100, \"orders\": 400 },
\"formats\": [\"csv\", \"parquet\"],
\"seed\": 42
}" | jq -r .id)
# 3) Poll until completed / failed / cancelled
while true; do
STATUS=$(curl -sS -H "Authorization: Bearer $SF_API_KEY" \
"$API_BASE/api/v1/datasets/$DATASET_ID/status")
S=$(echo "$STATUS" | jq -r .status)
echo "status=$S"
case "$S" in completed|failed|cancelled) break ;; esac
sleep 2
done
# 4) Presigned download URL → ZIP bundle
URL=$(curl -sS -H "Authorization: Bearer $SF_API_KEY" \
"$API_BASE/api/v1/datasets/$DATASET_ID/download" | jq -r .url)
curl -sS -L -o dataset.zip "$URL"
echo "wrote dataset.zip"
Prefer schemas you already built in the visual editor? Skip step 1 and pass that schema’s UUID as
schema_id. List yours with
GET /api/v1/schemas.
Client libraries
Useful endpoints
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/users/me | Account + quota snapshot |
| GET / POST | /api/v1/schemas | List or create schemas |
| POST | /api/v1/datasets | Start generation (row_counts, formats, seed, locale…) |
| GET | /api/v1/datasets/:id/status | Poll until completed / failed / cancelled |
| GET | /api/v1/datasets/:id/download | JSON with presigned url for the ZIP |
| POST | /api/v1/datasets/:id/cancel | Cooperative cancel of an in-flight job |
| GET | /openapi.json | Full OpenAPI document (no auth) |
Machine-readable catalog: https://api.synthforge.io/openapi.json
Security notes
- Treat keys like passwords. Prefer environment variables or a secret manager. Never commit them.
- Store CI secrets as
SF_API_KEY(and optionalSF_API_BASE). - Revoke compromised keys in Settings; rotation is create-new then revoke-old (or re-run
synthforge loginwith the same key name). - API-key auth cannot create more keys (session required for key management).
- Keys inherit your account quotas (rows, storage, concurrency). Very large jobs may return
413if they exceed plan limits, especially nested JSON formats.