OpenGlaze API Reference
April 26, 2026 ยท View on GitHub
Current REST API for the Flask app in this repository.
Base URL: http://localhost:8768/api for Docker, http://localhost:8767/api for manual local runs unless FLASK_PORT is set.
Authentication model: default personal mode is single-user and mostly unauthenticated. Studio collaboration uses the lightweight simple-auth token returned by /api/auth/simple-login. Cloud/Ory auth exists in code, but PostgreSQL/cloud mode is not the default launch path.
Health
GET /health
GET /api/health
/health returns a basic status/version payload. /api/health also reports mode, feature flags, and rate-limit stats.
Auth
Simple login
POST /api/auth/simple-login
Content-Type: application/json
{
"display_name": "Jane Potter"
}
Response:
{
"user_id": "u_...",
"display_name": "Jane Potter",
"token": "..."
}
Send the token as:
Authorization: Bearer <token>
Current user
GET /api/auth/me
Authorization: Bearer <token>
Glazes
GET /api/glazes
GET /api/glazes/<glaze_id>
POST /api/glazes
PUT /api/glazes/<glaze_id>
DELETE /api/glazes/<glaze_id>
GET /api/glazes/<glaze_id>/umf?cone=10
Create/update payloads use the glaze fields accepted by Glaze.from_dict, including id, name, family, hex, chemistry, behavior, layering, warning, recipe, catalog_code, food_safe, and notes.
Combinations
GET /api/combinations
GET /api/combinations?type=research-backed
GET /api/combinations?type=user-prediction
GET /api/combinations/grouped
GET /api/combinations/<combo_id>
POST /api/combinations
PUT /api/combinations/<combo_id>
POST /api/combinations/<combo_id>/promote
POST /api/combinations/<combo_id>/simulate
POST /api/combinations/simulate-all
GET /api/combinations/<combo_id>/compatibility?cone=10
Chemistry
POST /api/chemistry/batch
POST /api/chemistry/scale
POST /api/chemistry/compare
POST /api/chemistry/optimize
POST /api/chemistry/substitutions
POST /api/chemistry/defects
Examples:
POST /api/chemistry/optimize
Content-Type: application/json
{
"recipe": "Custer Feldspar 45, Silica 25, Whiting 18, EPK 12",
"target": "reduce_cte",
"max_suggestions": 5
}
POST /api/chemistry/scale
Content-Type: application/json
{
"recipe": "Custer Feldspar 45, Silica 25, Whiting 18, EPK 12",
"batch_size_grams": 1000,
"unit": "grams"
}
POST /api/chemistry/compare
Content-Type: application/json
{
"recipe_a": "Custer Feldspar 45, Silica 25, Whiting 18, EPK 12",
"recipe_b": "Custer Feldspar 40, Silica 30, Whiting 18, EPK 12",
"name_a": "Original",
"name_b": "Revision",
"cone": 10
}
Experiments
GET /api/experiments
GET /api/experiments?stage=ideation
GET /api/experiments/active
GET /api/experiments/stats
GET /api/experiments/<exp_id>
POST /api/experiments
POST /api/experiments/<exp_id>/advance
POST /api/experiments/<exp_id>/result
POST /api/experiments/<exp_id>/archive
POST /api/experiments/<exp_id>/firing-log
POST /api/experiments/<exp_id>/share
Uploads and photos
POST /api/upload
GET /api/photos
Upload expects multipart form-data with a photo field. Supported extensions are JPG, JPEG, PNG, and WebP; max size is 5 MB.
Studio collaboration
Studio endpoints require simple-auth or Ory user context.
POST /api/studios
GET /api/studios
POST /api/studios/join
GET /api/studios/<studio_id>
DELETE /api/studios/<studio_id>
POST /api/studios/<studio_id>/regenerate-code
GET /api/studios/<studio_id>/lab-queue
POST /api/studios/<studio_id>/lab-queue/<combo_id>/claim
POST /api/studios/<studio_id>/lab-queue/<combo_id>/release
GET /api/studios/<studio_id>/my-claims
GET /api/studios/<studio_id>/experiments
Progress, stats, and predictions
These endpoints require authenticated user context and may return 401 in default unauthenticated personal mode.
GET /api/stats
GET /api/progress
POST /api/predictions
GET /api/predictions/leaderboard
Templates
GET /api/templates
GET /api/templates/<template_id>
POST /api/templates/<template_id>/apply
Applying a template requires authenticated user context.
Demo endpoints
GET /api/demo/glazes
POST /api/demo/compatibility
These are public demo/reference endpoints backed by curated demo glaze data when available.
Error format
Most errors are returned as JSON:
{
"error": "Human-readable message"
}
Rate limits return HTTP 429 with a Retry-After header.