{
 "components": {
  "schemas": {
   "Collection": {
    "properties": {
     "id": {
      "format": "int64",
      "type": "integer"
     },
     "intro": {
      "type": "string"
     },
     "page": {
      "description": "Its page, unless it is private.",
      "format": "uri",
      "type": "string"
     },
     "pieces": {
      "items": {
       "format": "int64",
       "type": "integer"
      },
      "type": "array"
     },
     "slug": {
      "type": "string"
     },
     "title": {
      "type": "string"
     },
     "updated": {
      "format": "date-time",
      "type": "string"
     },
     "visibility": {
      "enum": [
       "private",
       "unlisted",
       "public"
      ]
     }
    },
    "required": [
     "id",
     "slug",
     "title",
     "visibility",
     "pieces",
     "updated"
    ],
    "type": "object"
   },
   "CollectionChange": {
    "properties": {
     "intro": {
      "maxLength": 1200,
      "type": "string"
     },
     "title": {
      "maxLength": 120,
      "minLength": 1,
      "type": "string"
     },
     "visibility": {
      "enum": [
       "private",
       "unlisted",
       "public"
      ]
     }
    },
    "required": [],
    "type": "object"
   },
   "CollectionList": {
    "properties": {
     "collections": {
      "items": {
       "$ref": "#/components/schemas/Collection"
      },
      "type": "array"
     }
    },
    "required": [
     "collections"
    ],
    "type": "object"
   },
   "CollectionPieces": {
    "properties": {
     "pieces": {
      "items": {
       "format": "int64",
       "type": "integer"
      },
      "type": "array"
     }
    },
    "required": [
     "pieces"
    ],
    "type": "object"
   },
   "Error": {
    "properties": {
     "error": {
      "properties": {
       "field": {
        "description": "The field that is wrong, as zones[3].title, when one is.",
        "type": "string"
       },
       "message": {
        "description": "What went wrong, in words to show a person.",
        "type": "string"
       },
       "status": {
        "type": "integer"
       }
      },
      "required": [
       "status",
       "message"
      ],
      "type": "object"
     }
    },
    "required": [
     "error"
    ],
    "type": "object"
   },
   "Exhibit": {
    "$ref": "https://heimdall3d.com/api/v1/schema/exhibit.json"
   },
   "NewCollection": {
    "properties": {
     "title": {
      "maxLength": 120,
      "minLength": 1,
      "type": "string"
     }
    },
    "required": [
     "title"
    ],
    "type": "object"
   },
   "NewPreview": {
    "properties": {
     "days": {
      "default": 7,
      "maximum": 90,
      "minimum": 1,
      "type": "integer"
     },
     "label": {
      "description": "Who it is for, for your own list.",
      "type": "string"
     }
    },
    "required": [],
    "type": "object"
   },
   "NewWebhook": {
    "properties": {
     "events": {
      "items": {
       "enum": [
        "exhibit.published",
        "piece.uploaded"
       ]
      },
      "minItems": 1,
      "type": "array"
     },
     "url": {
      "format": "uri",
      "maxLength": 500,
      "pattern": "^https://",
      "type": "string"
     }
    },
    "required": [
     "url",
     "events"
    ],
    "type": "object"
   },
   "NewWebhookAnswer": {
    "properties": {
     "secret": {
      "description": "Signs every delivery. Shown only now.",
      "type": "string"
     },
     "webhook": {
      "$ref": "#/components/schemas/Webhook"
     }
    },
    "required": [
     "webhook",
     "secret"
    ],
    "type": "object"
   },
   "Piece": {
    "properties": {
     "bytes": {
      "format": "int64",
      "type": "integer"
     },
     "embed": {
      "description": "The address to put in an iframe, for a model.",
      "format": "uri",
      "type": "string"
     },
     "exhibit_changed_at": {
      "format": "date-time",
      "type": "string"
     },
     "has_draft": {
      "description": "Whether the exhibit has changes readers do not see yet.",
      "type": "boolean"
     },
     "has_exhibit": {
      "description": "Whether readers see an exhibit, or a draft of one waits.",
      "type": "boolean"
     },
     "id": {
      "format": "int64",
      "type": "integer"
     },
     "kind": {
      "enum": [
       "model",
       "still"
      ]
     },
     "note": {
      "type": "string"
     },
     "page": {
      "format": "uri",
      "type": "string"
     },
     "title": {
      "type": "string"
     },
     "triangles": {
      "format": "int64",
      "type": "integer"
     },
     "views": {
      "format": "int64",
      "type": "integer"
     }
    },
    "required": [
     "id",
     "kind",
     "title",
     "bytes",
     "has_exhibit",
     "has_draft",
     "views",
     "page"
    ],
    "type": "object"
   },
   "PieceList": {
    "properties": {
     "pieces": {
      "items": {
       "$ref": "#/components/schemas/Piece"
      },
      "type": "array"
     }
    },
    "required": [
     "pieces"
    ],
    "type": "object"
   },
   "Preview": {
    "properties": {
     "created": {
      "format": "date-time",
      "type": "string"
     },
     "expires": {
      "format": "date-time",
      "type": "string"
     },
     "id": {
      "format": "int64",
      "type": "integer"
     },
     "label": {
      "type": "string"
     },
     "state": {
      "type": "string"
     },
     "url": {
      "format": "uri",
      "type": "string"
     }
    },
    "required": [
     "id",
     "url",
     "created",
     "expires",
     "state"
    ],
    "type": "object"
   },
   "PreviewList": {
    "properties": {
     "previews": {
      "items": {
       "$ref": "#/components/schemas/Preview"
      },
      "type": "array"
     }
    },
    "required": [
     "previews"
    ],
    "type": "object"
   },
   "Replacement": {
    "properties": {
     "from": {
      "description": "The piece just uploaded with the new file.",
      "format": "int64",
      "type": "integer"
     }
    },
    "required": [
     "from"
    ],
    "type": "object"
   },
   "Standing": {
    "properties": {
     "draft": {
      "description": "Whether the saved exhibit now differs from what readers see.",
      "type": "boolean"
     }
    },
    "required": [
     "draft"
    ],
    "type": "object"
   },
   "Upload": {
    "properties": {
     "file": {
      "contentMediaType": "application/octet-stream",
      "description": "The file, already converted.",
      "type": "string"
     }
    },
    "required": [
     "file"
    ],
    "type": "object"
   },
   "Uploaded": {
    "properties": {
     "allowance": {
      "description": "Bytes the account may use.",
      "type": "integer"
     },
     "edit": {
      "format": "uri",
      "type": "string"
     },
     "id": {
      "format": "int64",
      "type": "integer"
     },
     "page": {
      "format": "uri",
      "type": "string"
     },
     "used": {
      "description": "Bytes the account now uses.",
      "type": "integer"
     }
    },
    "required": [
     "id"
    ],
    "type": "object"
   },
   "Version": {
    "properties": {
     "at": {
      "format": "date-time",
      "type": "string"
     },
     "by": {
      "description": "The handle of who published it.",
      "type": "string"
     },
     "bytes": {
      "type": "integer"
     },
     "id": {
      "format": "int64",
      "type": "integer"
     },
     "removed": {
      "description": "The publish took the exhibit away.",
      "type": "boolean"
     }
    },
    "required": [
     "id",
     "at",
     "by",
     "bytes"
    ],
    "type": "object"
   },
   "VersionList": {
    "properties": {
     "versions": {
      "items": {
       "$ref": "#/components/schemas/Version"
      },
      "type": "array"
     }
    },
    "required": [
     "versions"
    ],
    "type": "object"
   },
   "Webhook": {
    "properties": {
     "created": {
      "format": "date-time",
      "type": "string"
     },
     "events": {
      "items": {
       "type": "string"
      },
      "type": "array"
     },
     "id": {
      "format": "int64",
      "type": "integer"
     },
     "last_at": {
      "format": "date-time",
      "type": "string"
     },
     "last_status": {
      "description": "How the latest delivery was answered.",
      "type": "string"
     },
     "url": {
      "format": "uri",
      "type": "string"
     }
    },
    "required": [
     "id",
     "url",
     "events",
     "created"
    ],
    "type": "object"
   },
   "WebhookList": {
    "properties": {
     "webhooks": {
      "items": {
       "$ref": "#/components/schemas/Webhook"
      },
      "type": "array"
     }
    },
    "required": [
     "webhooks"
    ],
    "type": "object"
   }
  },
  "securitySchemes": {
   "key": {
    "description": "A workspace key, h3d_ and 64 hex digits, with the scopes read, write, publish.",
    "scheme": "bearer",
    "type": "http"
   }
  }
 },
 "info": {
  "description": "What the Exhibitions workspace does, over HTTP: pieces, exhibits and their drafts, versions and preview links, collections and webhooks. A key is made on the workspace's Keys page and sent as Authorization: Bearer h3d_...; its scopes are read, write (every exhibit change a draft) and publish. A key may make 120 requests a minute. The exhibit format is https://heimdall3d.com/api/v1/schema/exhibit.json.",
  "title": "Skirnir API",
  "version": "1.0.0"
 },
 "openapi": "3.1.0",
 "paths": {
  "/api/v1/collections": {
   "get": {
    "operationId": "get_collections",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CollectionList"
        }
       }
      },
      "description": "OK"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "read"
      ]
     }
    ],
    "summary": "List the collections",
    "tags": [
     "collections"
    ],
    "x-scope": "read"
   },
   "post": {
    "description": "A new collection, private until its visibility is changed.",
    "operationId": "post_collections",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/NewCollection"
       }
      }
     },
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Collection"
        }
       }
      },
      "description": "Created"
     },
     "400": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "The body is wrong; field names where."
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "write"
      ]
     }
    ],
    "summary": "Make a collection",
    "tags": [
     "collections"
    ],
    "x-scope": "write"
   }
  },
  "/api/v1/collections/{id}": {
   "delete": {
    "description": "The collection goes; its pieces stay.",
    "operationId": "delete_collections_by_id",
    "parameters": [
     {
      "in": "path",
      "name": "id",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "No Content"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Not found, or not the key's account's."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "write"
      ]
     }
    ],
    "summary": "Delete a collection",
    "tags": [
     "collections"
    ],
    "x-scope": "write"
   },
   "get": {
    "operationId": "get_collections_by_id",
    "parameters": [
     {
      "in": "path",
      "name": "id",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Collection"
        }
       }
      },
      "description": "OK"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Not found, or not the key's account's."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "read"
      ]
     }
    ],
    "summary": "Read a collection",
    "tags": [
     "collections"
    ],
    "x-scope": "read"
   },
   "patch": {
    "description": "Any of its title, introduction and visibility; what is left out stays.",
    "operationId": "patch_collections_by_id",
    "parameters": [
     {
      "in": "path",
      "name": "id",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CollectionChange"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Collection"
        }
       }
      },
      "description": "OK"
     },
     "400": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "The body is wrong; field names where."
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Not found, or not the key's account's."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "write"
      ]
     }
    ],
    "summary": "Change a collection",
    "tags": [
     "collections"
    ],
    "x-scope": "write"
   }
  },
  "/api/v1/collections/{id}/pieces": {
   "put": {
    "description": "The pieces it holds, in order. A piece that is not the account's is left out.",
    "operationId": "put_collections_by_id_pieces",
    "parameters": [
     {
      "in": "path",
      "name": "id",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CollectionPieces"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Collection"
        }
       }
      },
      "description": "OK"
     },
     "400": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "The body is wrong; field names where."
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Not found, or not the key's account's."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "write"
      ]
     }
    ],
    "summary": "Set a collection's pieces",
    "tags": [
     "collections"
    ],
    "x-scope": "write"
   }
  },
  "/api/v1/openapi.json": {
   "get": {
    "description": "This description. Open to all.",
    "operationId": "get_openapi",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      },
      "description": "OK"
     }
    },
    "security": [],
    "summary": "openapi",
    "tags": [
     "format"
    ]
   }
  },
  "/api/v1/pieces": {
   "get": {
    "description": "Every capture and picture of the account, in the order of its page.",
    "operationId": "get_pieces",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PieceList"
        }
       }
      },
      "description": "OK"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "read"
      ]
     }
    ],
    "summary": "List the pieces",
    "tags": [
     "pieces"
    ],
    "x-scope": "read"
   },
   "post": {
    "description": "A multipart form with one file field, \"file\": a glb, a streamed package (.ssog, .smesh, .spoints) or a picture, already converted on your side. The server stores it and converts nothing. Larger files go in parts, through the resumable upload road.",
    "operationId": "post_pieces",
    "requestBody": {
     "content": {
      "multipart/form-data": {
       "schema": {
        "$ref": "#/components/schemas/Upload"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Uploaded"
        }
       }
      },
      "description": "OK"
     },
     "400": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "The body is wrong; field names where."
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "write"
      ]
     }
    ],
    "summary": "Upload a piece",
    "tags": [
     "pieces"
    ],
    "x-scope": "write"
   }
  },
  "/api/v1/pieces/{id}": {
   "get": {
    "operationId": "get_pieces_by_id",
    "parameters": [
     {
      "in": "path",
      "name": "id",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Piece"
        }
       }
      },
      "description": "OK"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Not found, or not the key's account's."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "read"
      ]
     }
    ],
    "summary": "Read a piece",
    "tags": [
     "pieces"
    ],
    "x-scope": "read"
   }
  },
  "/api/v1/pieces/{id}/exhibit": {
   "get": {
    "description": "The exhibit as its editors see it: the draft when there is one, otherwise what readers see. ?state=published reads what readers see. The X-Exhibit-State header says which it is.",
    "operationId": "get_pieces_by_id_exhibit",
    "parameters": [
     {
      "in": "path",
      "name": "id",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     },
     {
      "description": "published reads what readers see.",
      "in": "query",
      "name": "state",
      "required": false,
      "schema": {
       "enum": [
        "published"
       ]
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Exhibit"
        }
       }
      },
      "description": "OK"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Not found, or not the key's account's."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "read"
      ]
     }
    ],
    "summary": "Read a piece's exhibit",
    "tags": [
     "pieces"
    ],
    "x-scope": "read"
   },
   "put": {
    "description": "The whole exhibit, as /api/v1/schema/exhibit.json describes it. It is kept as a draft that readers do not see until it is published. A field that does not match the format is named in the answer.",
    "operationId": "put_pieces_by_id_exhibit",
    "parameters": [
     {
      "in": "path",
      "name": "id",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/Exhibit"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Standing"
        }
       }
      },
      "description": "OK"
     },
     "400": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "The body is wrong; field names where."
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Not found, or not the key's account's."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "write"
      ]
     }
    ],
    "summary": "Save a piece's exhibit as a draft",
    "tags": [
     "pieces"
    ],
    "x-scope": "write"
   }
  },
  "/api/v1/pieces/{id}/exhibit/draft": {
   "delete": {
    "description": "Throws away changes readers have not seen. 409 when there are none.",
    "operationId": "delete_pieces_by_id_exhibit_draft",
    "parameters": [
     {
      "in": "path",
      "name": "id",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "No Content"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Not found, or not the key's account's."
     },
     "409": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "There is no draft to act on."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "write"
      ]
     }
    ],
    "summary": "Discard the draft",
    "tags": [
     "pieces"
    ],
    "x-scope": "write"
   }
  },
  "/api/v1/pieces/{id}/exhibit/publish": {
   "post": {
    "description": "Readers see the draft from now on; it is kept as a version, and the webhooks told. 409 when there is nothing new to publish.",
    "operationId": "post_pieces_by_id_exhibit_publish",
    "parameters": [
     {
      "in": "path",
      "name": "id",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "No Content"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Not found, or not the key's account's."
     },
     "409": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "There is no draft to act on."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "publish"
      ]
     }
    ],
    "summary": "Publish the draft",
    "tags": [
     "pieces"
    ],
    "x-scope": "publish"
   }
  },
  "/api/v1/pieces/{id}/exhibit/versions": {
   "get": {
    "operationId": "get_pieces_by_id_exhibit_versions",
    "parameters": [
     {
      "in": "path",
      "name": "id",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/VersionList"
        }
       }
      },
      "description": "OK"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Not found, or not the key's account's."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "read"
      ]
     }
    ],
    "summary": "List the published versions",
    "tags": [
     "pieces"
    ],
    "x-scope": "read"
   }
  },
  "/api/v1/pieces/{id}/exhibit/versions/{version}": {
   "get": {
    "operationId": "get_pieces_by_id_exhibit_versions_by_version",
    "parameters": [
     {
      "in": "path",
      "name": "id",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     },
     {
      "in": "path",
      "name": "version",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Exhibit"
        }
       }
      },
      "description": "OK"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Not found, or not the key's account's."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "read"
      ]
     }
    ],
    "summary": "Read a published version",
    "tags": [
     "pieces"
    ],
    "x-scope": "read"
   }
  },
  "/api/v1/pieces/{id}/exhibit/versions/{version}/restore": {
   "post": {
    "description": "The version becomes the draft, to be published or changed further.",
    "operationId": "post_pieces_by_id_exhibit_versions_by_version_restore",
    "parameters": [
     {
      "in": "path",
      "name": "id",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     },
     {
      "in": "path",
      "name": "version",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "No Content"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Not found, or not the key's account's."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "write"
      ]
     }
    ],
    "summary": "Restore a version as the draft",
    "tags": [
     "pieces"
    ],
    "x-scope": "write"
   }
  },
  "/api/v1/pieces/{id}/previews": {
   "get": {
    "operationId": "get_pieces_by_id_previews",
    "parameters": [
     {
      "in": "path",
      "name": "id",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PreviewList"
        }
       }
      },
      "description": "OK"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Not found, or not the key's account's."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "read"
      ]
     }
    ],
    "summary": "List the preview links",
    "tags": [
     "pieces"
    ],
    "x-scope": "read"
   },
   "post": {
    "description": "A link that shows the draft, read only, to whoever has it, for 1 to 90 days.",
    "operationId": "post_pieces_by_id_previews",
    "parameters": [
     {
      "in": "path",
      "name": "id",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/NewPreview"
       }
      }
     },
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Preview"
        }
       }
      },
      "description": "Created"
     },
     "400": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "The body is wrong; field names where."
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Not found, or not the key's account's."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "write"
      ]
     }
    ],
    "summary": "Make a preview link",
    "tags": [
     "pieces"
    ],
    "x-scope": "write"
   }
  },
  "/api/v1/pieces/{id}/previews/{preview}": {
   "delete": {
    "operationId": "delete_pieces_by_id_previews_by_preview",
    "parameters": [
     {
      "in": "path",
      "name": "id",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     },
     {
      "in": "path",
      "name": "preview",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "No Content"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Not found, or not the key's account's."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "write"
      ]
     }
    ],
    "summary": "Withdraw a preview link",
    "tags": [
     "pieces"
    ],
    "x-scope": "write"
   }
  },
  "/api/v1/pieces/{id}/replace": {
   "post": {
    "description": "Upload the new file as a piece first, then name it here: it takes this piece's place, which keeps its id, exhibit, links, embeds, collections and view counts, and the uploaded piece goes. A model is replaced by a model, a picture by a picture.",
    "operationId": "post_pieces_by_id_replace",
    "parameters": [
     {
      "in": "path",
      "name": "id",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/Replacement"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Piece"
        }
       }
      },
      "description": "OK"
     },
     "400": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "The body is wrong; field names where."
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Not found, or not the key's account's."
     },
     "409": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "The file cannot replace this one: another kind, or it has an exhibit."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "write"
      ]
     }
    ],
    "summary": "Replace a piece's file",
    "tags": [
     "pieces"
    ],
    "x-scope": "write"
   }
  },
  "/api/v1/schema/exhibit.json": {
   "get": {
    "description": "The exhibit format as a JSON Schema, every field explained. Open to all.",
    "operationId": "get_exhibit_schema",
    "responses": {
     "200": {
      "content": {
       "application/schema+json": {
        "schema": {
         "type": "object"
        }
       }
      },
      "description": "OK"
     }
    },
    "security": [],
    "summary": "exhibit_schema",
    "tags": [
     "format"
    ]
   }
  },
  "/api/v1/webhooks": {
   "get": {
    "operationId": "get_webhooks",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/WebhookList"
        }
       }
      },
      "description": "OK"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "read"
      ]
     }
    ],
    "summary": "List the webhooks",
    "tags": [
     "webhooks"
    ],
    "x-scope": "read"
   },
   "post": {
    "description": "An https address told of events by a signed POST: X-Heimdall-Signature is t=\u003cunix seconds\u003e,v1=\u003chex HMAC-SHA256 of \"\u003ct\u003e.\u003cbody\u003e\" under the secret\u003e. The secret is answered once. A delivery that is not answered 2xx within ten seconds is tried again, eight times over about two days.",
    "operationId": "post_webhooks",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/NewWebhook"
       }
      }
     },
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/NewWebhookAnswer"
        }
       }
      },
      "description": "Created"
     },
     "400": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "The body is wrong; field names where."
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "write"
      ]
     }
    ],
    "summary": "Add a webhook",
    "tags": [
     "webhooks"
    ],
    "x-scope": "write"
   }
  },
  "/api/v1/webhooks/{id}": {
   "delete": {
    "operationId": "delete_webhooks_by_id",
    "parameters": [
     {
      "in": "path",
      "name": "id",
      "required": true,
      "schema": {
       "format": "int64",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "No Content"
     },
     "401": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Unauthorized"
     },
     "403": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Forbidden"
     },
     "404": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Not found, or not the key's account's."
     },
     "429": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      },
      "description": "Too Many Requests"
     }
    },
    "security": [
     {
      "key": [
       "write"
      ]
     }
    ],
    "summary": "Remove a webhook",
    "tags": [
     "webhooks"
    ],
    "x-scope": "write"
   }
  }
 },
 "servers": [
  {
   "url": "https://heimdall3d.com"
  }
 ],
 "tags": [
  {
   "description": "Captures and pictures, their exhibits, versions and previews.",
   "name": "pieces"
  },
  {
   "description": "Pieces gathered on a page of their own.",
   "name": "collections"
  },
  {
   "description": "Addresses told when something happens.",
   "name": "webhooks"
  },
  {
   "description": "The descriptions themselves.",
   "name": "format"
  }
 ]
}