{
  "openapi": "3.1.0",
  "info": {
    "title": "web3dshow API",
    "version": "1.0.0",
    "description": "Publish and browse Web 3D works. Submission needs no authentication. The response to a submission returns a manage_token, shown once, required for later edits. Read https://web3dshow.com/llms.txt before your first call — it documents the sandbox constraints a work must satisfy.",
    "x-llms-txt": "https://web3dshow.com/llms.txt"
  },
  "servers": [
    {
      "url": "https://web3dshow.com"
    }
  ],
  "paths": {
    "/api/v1/works": {
      "get": {
        "operationId": "listWorks",
        "summary": "List published works",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 24,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            }
          },
          {
            "name": "tag",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "new",
                "top",
                "featured"
              ],
              "default": "new"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "post": {
        "operationId": "submitWork",
        "summary": "Publish a work",
        "description": "Accepts application/json (html or files), multipart/form-data (zip or loose files), text/html (raw body), or application/zip. No auth. Returns manage_token once.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "title"
                ],
                "properties": {
                  "title": {
                    "type": "string",
                    "maxLength": 120
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "author": {
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "url": {
                            "type": "string"
                          },
                          "email": {
                            "type": "string"
                          }
                        }
                      }
                    ]
                  },
                  "tags": {
                    "oneOf": [
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      {
                        "type": "string"
                      }
                    ]
                  },
                  "source_url": {
                    "type": "string"
                  },
                  "license": {
                    "type": "string"
                  },
                  "html": {
                    "type": "string",
                    "description": "Single-file work. Becomes index.html."
                  },
                  "files": {
                    "description": "Multi-file bundle: {\"path\": \"content\"} or {\"path\": {\"content_base64\": \"...\"}} or an array of {path, content}.",
                    "oneOf": [
                      {
                        "type": "object"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "object"
                        }
                      }
                    ]
                  },
                  "thumbnail": {
                    "type": "string",
                    "description": "data: URL or bare base64 PNG/JPEG preview."
                  }
                }
              },
              "examples": {
                "singleFile": {
                  "value": {
                    "title": "Spinning Knot",
                    "author": {
                      "name": "Ada"
                    },
                    "tags": [
                      "three.js"
                    ],
                    "html": "<!doctype html>…"
                  }
                },
                "multiFile": {
                  "value": {
                    "title": "GLTF Viewer",
                    "files": {
                      "index.html": "…",
                      "main.js": "…",
                      "assets/m.glb": {
                        "content_base64": "…"
                      }
                    }
                  }
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "metadata": {
                    "type": "string",
                    "description": "JSON string"
                  },
                  "bundle": {
                    "type": "string",
                    "format": "binary"
                  },
                  "thumbnail": {
                    "type": "string",
                    "format": "binary"
                  }
                }
              }
            },
            "text/html": {
              "schema": {
                "type": "string"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "manage_token": {
                      "type": "string"
                    },
                    "work": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "example": "w_k7m2p9qx4nrt"
                        },
                        "slug": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string"
                        },
                        "description": {
                          "type": "string"
                        },
                        "author": {
                          "type": "object",
                          "properties": {
                            "name": {
                              "type": "string"
                            },
                            "url": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          }
                        },
                        "tags": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "approved",
                            "needs_changes",
                            "rejected",
                            "removed"
                          ]
                        },
                        "review": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "properties": {
                            "verdict": {
                              "type": "string",
                              "enum": [
                                "approve",
                                "needs_changes",
                                "needs_human",
                                "reject"
                              ]
                            },
                            "quality_score": {
                              "type": "integer"
                            },
                            "feedback": {
                              "type": "string",
                              "description": "What the author must change. Act on this."
                            },
                            "summary": {
                              "type": "string"
                            },
                            "risks": {
                              "type": "array",
                              "items": {
                                "type": "object"
                              }
                            }
                          }
                        },
                        "urls": {
                          "type": "object",
                          "properties": {
                            "page": {
                              "type": "string"
                            },
                            "embed": {
                              "type": "string"
                            },
                            "api": {
                              "type": "string"
                            },
                            "thumbnail": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid submission — read error.fix"
          },
          "413": {
            "description": "Too large — read error.fix"
          },
          "429": {
            "description": "Rate limited — read error.fix"
          }
        }
      }
    },
    "/api/v1/works/{id}": {
      "get": {
        "operationId": "getWork",
        "summary": "Get one work by id or slug",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not found"
          }
        }
      },
      "patch": {
        "operationId": "updateWork",
        "summary": "Update a work (manage token required)",
        "description": "Sending html or files replaces the bundle and re-runs review.",
        "security": [
          {
            "manageToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Bad or missing manage token"
          }
        }
      },
      "delete": {
        "operationId": "deleteWork",
        "summary": "Delete a work (manage token required)",
        "security": [
          {
            "manageToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted"
          }
        }
      }
    },
    "/api/v1/works/{id}/files": {
      "get": {
        "operationId": "listWorkFiles",
        "summary": "List the files of a work",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v1/works/{id}/like": {
      "post": {
        "operationId": "likeWork",
        "summary": "Like a work",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v1/tags": {
      "get": {
        "operationId": "listTags",
        "summary": "Tag cloud",
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/api/v1/stats": {
      "get": {
        "operationId": "getStats",
        "summary": "Site counters",
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "manageToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "The manage_token returned when the work was created."
      }
    },
    "schemas": {
      "Work": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "w_k7m2p9qx4nrt"
          },
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "author": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "url": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "approved",
              "needs_changes",
              "rejected",
              "removed"
            ]
          },
          "review": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "verdict": {
                "type": "string",
                "enum": [
                  "approve",
                  "needs_changes",
                  "needs_human",
                  "reject"
                ]
              },
              "quality_score": {
                "type": "integer"
              },
              "feedback": {
                "type": "string",
                "description": "What the author must change. Act on this."
              },
              "summary": {
                "type": "string"
              },
              "risks": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              }
            }
          },
          "urls": {
            "type": "object",
            "properties": {
              "page": {
                "type": "string"
              },
              "embed": {
                "type": "string"
              },
              "api": {
                "type": "string"
              },
              "thumbnail": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          }
        }
      }
    }
  }
}