{
  "openapi": "3.1.0",
  "info": { "title": "Keyboard Abyss REST API", "version": "0.0.0" },
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "servers": [
    { "url": "https://abyss.keyboard-hub.com", "description": "Production" }
  ],
  "paths": {
    "/oauth/authorize": {
      "get": {
        "tags": ["OAuth"],
        "summary": "Start OAuth authorization",
        "description": "Redirect the user to the Keyboard Abyss consent flow for a registered OAuth client.",
        "operationId": "authorizeOAuthClient",
        "x-developer-group": "OAuth",
        "x-developer-scope": "PKCE request",
        "parameters": [
          {
            "name": "response_type",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "const": "code" }
          },
          {
            "name": "client_id",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "minLength": 1 }
          },
          {
            "name": "redirect_uri",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "format": "uri" }
          },
          {
            "name": "scope",
            "in": "query",
            "schema": { "type": "string", "minLength": 1 }
          },
          { "name": "state", "in": "query", "schema": { "type": "string" } },
          {
            "name": "code_challenge",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "minLength": 1 }
          },
          {
            "name": "code_challenge_method",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "const": "S256" }
          }
        ],
        "responses": {
          "302": { "description": "Redirects to the consent page." },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" }
        }
      }
    },
    "/oauth/token": {
      "post": {
        "tags": ["OAuth"],
        "summary": "Exchange an OAuth code or refresh token",
        "description": "Exchange a PKCE authorization code or refresh token for a bearer access token.",
        "operationId": "createOAuthToken",
        "x-developer-group": "OAuth",
        "x-developer-scope": "PKCE verifier",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "grant_type",
                      "client_id",
                      "redirect_uri",
                      "code",
                      "code_verifier"
                    ],
                    "properties": {
                      "grant_type": {
                        "type": "string",
                        "const": "authorization_code"
                      },
                      "client_id": { "type": "string", "minLength": 1 },
                      "redirect_uri": { "type": "string", "format": "uri" },
                      "code": { "type": "string", "minLength": 1 },
                      "code_verifier": { "type": "string", "minLength": 1 }
                    }
                  },
                  {
                    "type": "object",
                    "additionalProperties": false,
                    "required": ["grant_type", "client_id", "refresh_token"],
                    "properties": {
                      "grant_type": {
                        "type": "string",
                        "const": "refresh_token"
                      },
                      "client_id": { "type": "string", "minLength": 1 },
                      "refresh_token": { "type": "string", "minLength": 1 }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OAuth token response.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/OAuthTokenResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" }
        }
      }
    },
    "/oauth/revoke": {
      "post": {
        "tags": ["OAuth"],
        "summary": "Revoke a refresh token",
        "description": "Revoke a Keyboard Abyss OAuth refresh token.",
        "operationId": "revokeOAuthToken",
        "x-developer-group": "OAuth",
        "x-developer-scope": "client_id",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": ["token", "client_id"],
                "properties": {
                  "token": { "type": "string", "minLength": 1 },
                  "client_id": { "type": "string", "minLength": 1 }
                }
              }
            }
          }
        },
        "responses": { "200": { "$ref": "#/components/responses/Ok" } }
      }
    },
    "/oauth/userinfo": {
      "get": {
        "tags": ["OAuth"],
        "summary": "Read the authorized user profile",
        "description": "Return OpenID-style profile metadata for the user represented by the bearer token.",
        "operationId": "getOAuthUserinfo",
        "x-developer-group": "OAuth",
        "security": [{ "oauth2": ["profile:read"] }],
        "responses": {
          "200": {
            "description": "Authorized user profile.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/OAuthUserInfo" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" }
        }
      }
    },
    "/api/v1/me/keymaps": {
      "get": {
        "tags": ["Keymaps"],
        "summary": "List the authorized user's keymaps",
        "operationId": "listMyKeymaps",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Find keymaps",
        "security": [{ "oauth2": ["keymap:read"] }],
        "parameters": [
          {
            "name": "visibility",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["all", "public", "private"],
              "default": "all"
            }
          },
          {
            "name": "keyboard",
            "in": "query",
            "schema": { "type": "string", "minLength": 1 }
          },
          {
            "name": "layoutId",
            "in": "query",
            "schema": { "type": "string", "minLength": 1 }
          },
          {
            "name": "layoutVariationId",
            "in": "query",
            "schema": { "type": "string", "minLength": 1 }
          },
          { "$ref": "#/components/parameters/Page" },
          { "$ref": "#/components/parameters/Limit" }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/Json" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" }
        }
      }
    },
    "/api/v1/keymaps": {
      "get": {
        "tags": ["Keymaps"],
        "summary": "List public keymaps",
        "operationId": "listPublicKeymaps",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Find keymaps",
        "x-developer-scope": "public",
        "parameters": [
          { "$ref": "#/components/parameters/Page" },
          { "$ref": "#/components/parameters/Limit" }
        ],
        "responses": { "200": { "$ref": "#/components/responses/Json" } }
      }
    },
    "/api/v1/keymaps/{id}": {
      "get": {
        "tags": ["Keymaps"],
        "summary": "Read one keymap by ID",
        "operationId": "getKeymap",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Manage keymaps",
        "security": [{ "oauth2": ["keymap:read"] }],
        "parameters": [{ "$ref": "#/components/parameters/KeymapId" }],
        "responses": {
          "200": { "$ref": "#/components/responses/Json" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      },
      "put": {
        "tags": ["Keymaps"],
        "summary": "Append a new keymap version",
        "operationId": "updateKeymapData",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Manage keymaps",
        "security": [{ "oauth2": ["keymap:write"] }],
        "parameters": [{ "$ref": "#/components/parameters/KeymapId" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/UpdateKeymapRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Keymap write result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateKeymapResponse"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      },
      "patch": {
        "tags": ["Keymaps"],
        "summary": "Update keymap metadata",
        "operationId": "patchKeymap",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Manage keymaps",
        "security": [{ "oauth2": ["keymap:write"] }],
        "parameters": [{ "$ref": "#/components/parameters/KeymapId" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/PatchKeymapRequest" }
            }
          }
        },
        "responses": {
          "200": { "$ref": "#/components/responses/Json" },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      },
      "delete": {
        "tags": ["Keymaps"],
        "summary": "Delete an owned keymap",
        "operationId": "deleteKeymap",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Manage keymaps",
        "security": [{ "oauth2": ["keymap:write"] }],
        "parameters": [{ "$ref": "#/components/parameters/KeymapId" }],
        "responses": {
          "200": { "$ref": "#/components/responses/Ok" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      }
    },
    "/api/v1/keymaps/{id}/share": {
      "post": {
        "tags": ["Keymaps"],
        "summary": "Create or reuse a keymap share URL",
        "description": "Generate the OGP JPEG preview for a public keymap and return the stable crawler URL used for X sharing.",
        "operationId": "createKeymapShareUrl",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Share keymaps",
        "x-developer-scope": "public",
        "parameters": [{ "$ref": "#/components/parameters/KeymapId" }],
        "responses": {
          "200": {
            "description": "Keymap share URL.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/KeymapShareResponse" }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      }
    },
    "/api/v1/keyboards/{keyboardSlug}/keymaps/{username}/{name}": {
      "get": {
        "tags": ["Keymaps"],
        "summary": "Read a keymap by public namespace",
        "operationId": "getKeymapByNamespace",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Find keymaps",
        "security": [{ "oauth2": ["keymap:read"] }],
        "parameters": [
          { "$ref": "#/components/parameters/KeyboardSlug" },
          { "$ref": "#/components/parameters/Username" },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "minLength": 1 }
          }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/Json" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      }
    },
    "/api/v1/layout-variations/{variationId}/keymaps": {
      "get": {
        "tags": ["Keymaps"],
        "summary": "List keymaps for a layout variation",
        "operationId": "listLayoutVariationKeymaps",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Layout-based keymaps",
        "security": [{ "oauth2": ["keymap:read"] }],
        "parameters": [{ "$ref": "#/components/parameters/VariationId" }],
        "responses": {
          "200": { "$ref": "#/components/responses/Json" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      },
      "post": {
        "tags": ["Keymaps"],
        "summary": "Create a keymap against a layout variation",
        "operationId": "createKeymap",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Layout-based keymaps",
        "security": [{ "oauth2": ["keymap:write"] }],
        "parameters": [{ "$ref": "#/components/parameters/VariationId" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/CreateKeymapRequest" }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created keymap.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateKeymapResponse"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" },
          "409": { "$ref": "#/components/responses/ConflictError" }
        }
      }
    },
    "/api/v1/layout-versions/{versionId}/keymaps": {
      "get": {
        "tags": ["Keymaps"],
        "summary": "List keymaps for a layout version",
        "operationId": "listLayoutVersionKeymaps",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Layout-based keymaps",
        "security": [{ "oauth2": ["keymap:read"] }],
        "parameters": [{ "$ref": "#/components/parameters/VersionId" }],
        "responses": {
          "200": { "$ref": "#/components/responses/Json" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      },
      "post": {
        "tags": ["Keymaps"],
        "summary": "Create a keymap against a layout version",
        "operationId": "createKeymapByLayoutVersion",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Layout-based keymaps",
        "security": [{ "oauth2": ["keymap:write"] }],
        "parameters": [{ "$ref": "#/components/parameters/VersionId" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/CreateKeymapRequest" }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created keymap.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateKeymapResponse"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" },
          "409": { "$ref": "#/components/responses/ConflictError" }
        }
      }
    },
    "/api/v1/keymaps/import": {
      "post": {
        "tags": ["Keymaps"],
        "summary": "Import a KeyboardHub keymap",
        "operationId": "importKeymap",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Manage keymaps",
        "security": [{ "oauth2": ["keymap:write"] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ImportKeymapRequest" }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Imported keymap.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateKeymapResponse"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" },
          "409": { "$ref": "#/components/responses/ConflictError" }
        }
      }
    },
    "/api/v1/keymaps/{id}/versions": {
      "get": {
        "tags": ["Keymaps"],
        "summary": "List keymap versions",
        "operationId": "listKeymapVersions",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Version history",
        "security": [{ "oauth2": ["keymap:read"] }],
        "parameters": [{ "$ref": "#/components/parameters/KeymapId" }],
        "responses": {
          "200": { "$ref": "#/components/responses/Json" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      }
    },
    "/api/v1/keymaps/{id}/versions/{version}": {
      "get": {
        "tags": ["Keymaps"],
        "summary": "Read a historical keymap version",
        "operationId": "getKeymapVersion",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Version history",
        "security": [{ "oauth2": ["keymap:read"] }],
        "parameters": [
          { "$ref": "#/components/parameters/KeymapId" },
          { "$ref": "#/components/parameters/VersionNumber" }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/Json" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      },
      "delete": {
        "tags": ["Keymaps"],
        "summary": "Delete a keymap version",
        "operationId": "deleteKeymapVersion",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Version history",
        "security": [{ "oauth2": ["keymap:write"] }],
        "parameters": [
          { "$ref": "#/components/parameters/KeymapId" },
          { "$ref": "#/components/parameters/VersionNumber" }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/Ok" },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      }
    },
    "/api/v1/keymaps/{id}/versions/{version}/revert": {
      "post": {
        "tags": ["Keymaps"],
        "summary": "Revert to a historical keymap version",
        "operationId": "revertKeymapVersion",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Version history",
        "security": [{ "oauth2": ["keymap:write"] }],
        "parameters": [
          { "$ref": "#/components/parameters/KeymapId" },
          { "$ref": "#/components/parameters/VersionNumber" }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/Json" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      }
    },
    "/api/v1/keymaps/{id}/export/{format}": {
      "get": {
        "tags": ["Keymaps"],
        "summary": "Export a keymap",
        "description": "Download KeyboardHub JSON, ZMK, QMK C/JSON, VIA, or KLE output.",
        "operationId": "exportKeymap",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Export and reuse",
        "security": [{ "oauth2": ["keymap:read"] }],
        "parameters": [
          { "$ref": "#/components/parameters/KeymapId" },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "schema": { "$ref": "#/components/schemas/KeymapExportFormat" }
          }
        ],
        "responses": {
          "200": { "description": "Export artifact." },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      }
    },
    "/api/v1/keymaps/{id}/fork": {
      "post": {
        "tags": ["Keymaps"],
        "summary": "Fork a readable keymap",
        "operationId": "forkKeymap",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Export and reuse",
        "security": [{ "oauth2": ["keymap:write"] }],
        "parameters": [{ "$ref": "#/components/parameters/KeymapId" }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ForkKeymapRequest" }
            }
          }
        },
        "responses": {
          "201": { "$ref": "#/components/responses/Json" },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" },
          "409": { "$ref": "#/components/responses/ConflictError" }
        }
      }
    },
    "/api/v1/keymaps/{id}/convert": {
      "post": {
        "tags": ["Keymaps"],
        "summary": "Convert a keymap to another layout",
        "operationId": "convertKeymap",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Export and reuse",
        "security": [{ "oauth2": ["keymap:write"] }],
        "parameters": [{ "$ref": "#/components/parameters/KeymapId" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ConvertKeymapRequest" }
            }
          }
        },
        "responses": {
          "201": { "$ref": "#/components/responses/Json" },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" },
          "409": { "$ref": "#/components/responses/ConflictError" }
        }
      }
    },
    "/api/v1/keymaps/{id}/forks": {
      "get": {
        "tags": ["Keymaps"],
        "summary": "List public forks of a keymap",
        "operationId": "listKeymapForks",
        "x-developer-group": "Keymaps",
        "x-developer-section": "Export and reuse",
        "x-developer-scope": "public",
        "parameters": [
          { "$ref": "#/components/parameters/KeymapId" },
          { "$ref": "#/components/parameters/Page" },
          { "$ref": "#/components/parameters/Limit" }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/Json" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      }
    },
    "/api/v1/keyboards/{keyboardId}/layouts": {
      "get": {
        "tags": ["Layouts"],
        "summary": "List keyboard layouts",
        "operationId": "listKeyboardLayouts",
        "x-developer-group": "Layouts",
        "security": [{ "oauth2": ["layout:read"] }],
        "parameters": [{ "$ref": "#/components/parameters/KeyboardId" }],
        "responses": {
          "200": { "$ref": "#/components/responses/Json" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      }
    },
    "/api/v1/layout-variations/{id}": {
      "get": {
        "tags": ["Layouts"],
        "summary": "Read one layout variation",
        "operationId": "getLayoutVariation",
        "x-developer-group": "Layouts",
        "security": [{ "oauth2": ["layout:read"] }],
        "parameters": [{ "$ref": "#/components/parameters/Id" }],
        "responses": {
          "200": { "$ref": "#/components/responses/Json" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      }
    },
    "/api/v1/layout-versions/{id}": {
      "get": {
        "tags": ["Layouts"],
        "summary": "Read one layout version",
        "operationId": "getLayoutVersion",
        "x-developer-group": "Layouts",
        "security": [{ "oauth2": ["layout:read"] }],
        "parameters": [{ "$ref": "#/components/parameters/Id" }],
        "responses": {
          "200": { "$ref": "#/components/responses/Json" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      }
    },
    "/api/v1/layouts/resolve": {
      "post": {
        "tags": ["Layouts"],
        "summary": "Resolve an imported layout",
        "operationId": "resolveLayout",
        "x-developer-group": "Layouts",
        "security": [{ "oauth2": ["layout:read"] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ResolveLayoutRequest" }
            }
          }
        },
        "responses": {
          "200": { "$ref": "#/components/responses/Json" },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" }
        }
      }
    },
    "/api/v1/layouts/via-candidates": {
      "post": {
        "tags": ["Layouts"],
        "summary": "Find VIA layout candidates",
        "operationId": "findViaLayoutCandidates",
        "x-developer-group": "Layouts",
        "security": [{ "oauth2": ["layout:read"] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ViaLayoutCandidatesRequest"
              }
            }
          }
        },
        "responses": {
          "200": { "$ref": "#/components/responses/Json" },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" }
        }
      }
    },
    "/api/v1/keymap-conversion-rules": {
      "get": {
        "tags": ["Conversion rules"],
        "summary": "List keymap conversion rules",
        "operationId": "listConversionRules",
        "x-developer-group": "Conversion rules",
        "x-developer-scope": "public",
        "parameters": [
          {
            "name": "sourceLayoutVariationId",
            "in": "query",
            "schema": { "type": "string", "minLength": 1 }
          },
          {
            "name": "targetLayoutVariationId",
            "in": "query",
            "schema": { "type": "string", "minLength": 1 }
          },
          {
            "name": "sourceLayoutVersionId",
            "in": "query",
            "schema": { "type": "string", "minLength": 1 }
          },
          {
            "name": "targetLayoutVersionId",
            "in": "query",
            "schema": { "type": "string", "minLength": 1 }
          }
        ],
        "responses": { "200": { "$ref": "#/components/responses/Json" } }
      },
      "post": {
        "tags": ["Conversion rules"],
        "summary": "Create a keymap conversion rule",
        "operationId": "createConversionRule",
        "x-developer-group": "Conversion rules",
        "x-developer-scope": "signed-in user",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ConversionRuleRequest" }
            }
          }
        },
        "responses": {
          "201": { "$ref": "#/components/responses/Json" },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "409": { "$ref": "#/components/responses/ConflictError" }
        }
      }
    },
    "/api/v1/keymap-conversion-rules/{id}": {
      "get": {
        "tags": ["Conversion rules"],
        "summary": "Read one keymap conversion rule",
        "operationId": "getConversionRule",
        "x-developer-group": "Conversion rules",
        "x-developer-scope": "public",
        "parameters": [{ "$ref": "#/components/parameters/Id" }],
        "responses": {
          "200": { "$ref": "#/components/responses/Json" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      },
      "patch": {
        "tags": ["Conversion rules"],
        "summary": "Update an owned keymap conversion rule",
        "operationId": "patchConversionRule",
        "x-developer-group": "Conversion rules",
        "x-developer-scope": "rule owner",
        "parameters": [{ "$ref": "#/components/parameters/Id" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchConversionRuleRequest"
              }
            }
          }
        },
        "responses": {
          "200": { "$ref": "#/components/responses/Json" },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      }
    },
    "/api/v1/keymap-conversion-rules/{id}/official": {
      "patch": {
        "tags": ["Conversion rules"],
        "summary": "Update conversion rule official status",
        "operationId": "patchConversionRuleOfficialStatus",
        "x-developer-group": "Conversion rules",
        "x-developer-scope": "target maintainer",
        "parameters": [{ "$ref": "#/components/parameters/Id" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConversionRuleStatusRequest"
              }
            }
          }
        },
        "responses": {
          "200": { "$ref": "#/components/responses/Json" },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "401": { "$ref": "#/components/responses/UnauthorizedError" },
          "403": { "$ref": "#/components/responses/ForbiddenError" },
          "404": { "$ref": "#/components/responses/NotFoundError" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "oauth2": {
        "type": "oauth2",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "/oauth/authorize",
            "tokenUrl": "/oauth/token",
            "refreshUrl": "/oauth/token",
            "scopes": {
              "profile:read": "Read the authorized user's public profile metadata.",
              "keymap:read": "Read keymaps visible to the authorized user.",
              "keymap:write": "Create, update, delete, fork, and convert keymaps for the authorized user.",
              "layout:read": "Read layout metadata needed to import or convert keymaps."
            }
          }
        }
      }
    },
    "parameters": {
      "Id": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": { "type": "string", "minLength": 1 }
      },
      "KeymapId": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": { "$ref": "./db-schema.json#/$defs/Ulid" }
      },
      "KeyboardId": {
        "name": "keyboardId",
        "in": "path",
        "required": true,
        "schema": { "type": "string", "minLength": 1 }
      },
      "KeyboardSlug": {
        "name": "keyboardSlug",
        "in": "path",
        "required": true,
        "schema": { "type": "string", "minLength": 1 }
      },
      "Username": {
        "name": "username",
        "in": "path",
        "required": true,
        "schema": { "type": "string", "minLength": 1 }
      },
      "VariationId": {
        "name": "variationId",
        "in": "path",
        "required": true,
        "schema": { "$ref": "./db-schema.json#/$defs/Ulid" }
      },
      "VersionId": {
        "name": "versionId",
        "in": "path",
        "required": true,
        "schema": { "$ref": "./db-schema.json#/$defs/Ulid" }
      },
      "VersionNumber": {
        "name": "version",
        "in": "path",
        "required": true,
        "schema": { "type": "integer", "exclusiveMinimum": 0 }
      },
      "Page": {
        "name": "page",
        "in": "query",
        "schema": { "type": "integer", "minimum": 1, "default": 1 }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "schema": { "type": "integer", "minimum": 1, "maximum": 100 }
      }
    },
    "responses": {
      "Ok": {
        "description": "Boolean success response.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/OkResponse" }
          }
        }
      },
      "Json": {
        "description": "JSON response. See endpoint summary for the route-specific shape.",
        "content": { "application/json": { "schema": {} } }
      },
      "UnauthorizedError": {
        "description": "The request is missing valid authentication.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ApiError" }
          }
        }
      },
      "ForbiddenError": {
        "description": "The user or OAuth token does not have access.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ApiError" }
          }
        }
      },
      "NotFoundError": {
        "description": "The requested resource was not found.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ApiError" }
          }
        }
      },
      "ValidationError": {
        "description": "The request was invalid.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ApiError" }
          }
        }
      },
      "ConflictError": {
        "description": "The request conflicts with existing data.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ApiError" }
          }
        }
      }
    },
    "schemas": {
      "OAuthScope": {
        "type": "string",
        "enum": ["profile:read", "keymap:read", "keymap:write", "layout:read"],
        "x-zod-values-name": "oauthScopeValues"
      },
      "OkResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": ["ok"],
        "properties": { "ok": { "type": "boolean" } }
      },
      "OAuthTokenResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "access_token",
          "token_type",
          "expires_in",
          "refresh_token",
          "scope"
        ],
        "properties": {
          "access_token": { "type": "string", "minLength": 1 },
          "token_type": { "type": "string", "const": "Bearer" },
          "expires_in": { "type": "integer", "exclusiveMinimum": 0 },
          "refresh_token": { "type": "string", "minLength": 1 },
          "scope": { "type": "string", "minLength": 1 }
        }
      },
      "OAuthUserInfo": {
        "type": "object",
        "additionalProperties": false,
        "required": ["sub", "username"],
        "properties": {
          "sub": { "$ref": "./db-schema.json#/$defs/Ulid" },
          "username": { "type": "string", "minLength": 1 },
          "displayName": { "type": ["string", "null"] },
          "avatarUrl": { "type": ["string", "null"], "format": "uri" }
        }
      },
      "ApiErrorCode": {
        "type": "string",
        "enum": [
          "UNAUTHORIZED",
          "FORBIDDEN",
          "NOT_FOUND",
          "CONFLICT",
          "VALIDATION_ERROR",
          "DISABLED_VARIATION",
          "RATE_LIMITED"
        ],
        "x-zod-values-name": "apiErrorCodeValues"
      },
      "KeymapExportFormat": {
        "type": "string",
        "enum": ["json", "zmk", "qmk-json", "qmk-c", "via", "kle"],
        "x-zod-values-name": "keymapExportFormatValues"
      },
      "ApiError": {
        "description": "Standard API error response schema.",
        "type": "object",
        "additionalProperties": false,
        "required": ["error", "message"],
        "properties": {
          "error": { "$ref": "#/components/schemas/ApiErrorCode" },
          "message": { "type": "string", "minLength": 1 }
        }
      },
      "PatchMeRequest": {
        "description": "Account profile update request schema.",
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "displayName": { "type": "string", "minLength": 1 },
          "bio": { "type": ["string", "null"] },
          "websiteUrl": { "type": ["string", "null"], "format": "uri" },
          "locale": { "$ref": "./db-schema.json#/$defs/UserLocale" }
        }
      },
      "CreateKeyboardRequest": {
        "description": "Keyboard creation request schema.",
        "type": "object",
        "additionalProperties": false,
        "required": ["name", "slug"],
        "properties": {
          "name": { "type": "string", "minLength": 1 },
          "slug": { "type": "string", "minLength": 1 },
          "description": { "type": ["string", "null"] },
          "status": { "type": "string", "enum": ["draft", "published"] },
          "type": { "type": "string", "minLength": 1 },
          "firmware": {
            "type": "array",
            "items": { "type": "string", "minLength": 1 }
          },
          "links": {
            "type": "array",
            "maxItems": 6,
            "items": { "$ref": "./db-schema.json#/$defs/KeyboardLink" }
          },
          "hashtags": {
            "type": "array",
            "maxItems": 8,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 60,
              "pattern": "^[^\\s#]+$"
            }
          }
        }
      },
      "CreateKeyboardResponse": {
        "description": "Keyboard creation response schema.",
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "slug", "ownerCount", "maintainerCount"],
        "properties": {
          "id": { "$ref": "./db-schema.json#/$defs/Ulid" },
          "slug": { "type": "string", "minLength": 1 },
          "ownerCount": { "type": "integer", "minimum": 0 },
          "maintainerCount": { "type": "integer", "minimum": 0 }
        }
      },
      "LayoutVariationDefinition": {
        "description": "Layout variation definition schema used by API payloads.",
        "type": "object",
        "additionalProperties": false,
        "required": ["name", "positions"],
        "properties": {
          "name": { "type": "string", "minLength": 1 },
          "displayName": { "type": "string", "minLength": 1 },
          "positions": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "./db-schema.json#/$defs/KeyboardLayoutPosition"
            }
          },
          "matrix": { "$ref": "./db-schema.json#/$defs/KeyboardLayoutMatrix" },
          "modules": {
            "type": "array",
            "default": [],
            "items": { "$ref": "./db-schema.json#/$defs/KeyboardModule" }
          },
          "features": {
            "$ref": "./db-schema.json#/$defs/KeyboardLayoutFeature",
            "default": {}
          },
          "firmwareDialect": {
            "$ref": "./db-schema.json#/$defs/FirmwareDialect",
            "default": {}
          }
        }
      },
      "PositionMapping": {
        "description": "Conversion mapping from source position index to target position index or indexes.",
        "type": "object",
        "additionalProperties": {
          "oneOf": [
            { "type": "integer", "minimum": 0, "maximum": 399 },
            {
              "type": "array",
              "minItems": 1,
              "maxItems": 400,
              "items": { "type": "integer", "minimum": 0, "maximum": 399 }
            }
          ]
        },
        "default": {}
      },
      "ModuleMapping": {
        "description": "Conversion mapping between source and target layout module names.",
        "type": "object",
        "additionalProperties": false,
        "required": ["sourceModuleName", "targetModuleName"],
        "properties": {
          "sourceModuleName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "targetModuleName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          }
        }
      },
      "CreateLayoutVariationRequest": {
        "description": "Layout variation creation request schema.",
        "type": "object",
        "additionalProperties": false,
        "required": ["positions"],
        "properties": {
          "positions": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "./db-schema.json#/$defs/KeyboardLayoutPosition"
            }
          },
          "matrix": { "$ref": "./db-schema.json#/$defs/KeyboardLayoutMatrix" },
          "modules": {
            "type": "array",
            "default": [],
            "items": { "$ref": "./db-schema.json#/$defs/KeyboardModule" }
          },
          "features": {
            "$ref": "./db-schema.json#/$defs/KeyboardLayoutFeature",
            "default": {}
          },
          "firmwareDialect": {
            "$ref": "./db-schema.json#/$defs/FirmwareDialect",
            "default": {}
          },
          "changelog": { "type": ["string", "null"] },
          "status": {
            "$ref": "./db-schema.json#/$defs/LayoutVariationStatus",
            "default": "normal"
          }
        }
      },
      "CreateLayoutVersionRequest": {
        "description": "Layout version creation request schema.",
        "$ref": "#/components/schemas/CreateLayoutVariationRequest"
      },
      "CreateKeymapRequest": {
        "description": "Keymap creation request schema.",
        "type": "object",
        "additionalProperties": false,
        "required": ["name", "visibility", "data"],
        "properties": {
          "name": { "type": "string", "minLength": 1 },
          "description": { "type": ["string", "null"] },
          "firmwareUrl": {
            "type": ["string", "null"],
            "format": "uri",
            "maxLength": 500
          },
          "libraryEntryIds": {
            "type": "array",
            "maxItems": 20,
            "items": { "$ref": "./db-schema.json#/$defs/Ulid" }
          },
          "visibility": { "$ref": "./db-schema.json#/$defs/KeymapVisibility" },
          "data": { "$ref": "#/components/schemas/KeyboardHubKeymapV1" },
          "message": { "type": ["string", "null"] },
          "layout": { "$ref": "#/components/schemas/LayoutVariationDefinition" }
        }
      },
      "ImportKeymapRequest": {
        "description": "Keymap import request schema.",
        "type": "object",
        "additionalProperties": false,
        "required": ["name", "data"],
        "properties": {
          "layoutVariationId": { "$ref": "./db-schema.json#/$defs/Ulid" },
          "layoutVersionId": { "$ref": "./db-schema.json#/$defs/Ulid" },
          "layout": {
            "$ref": "#/components/schemas/LayoutVariationDefinition"
          },
          "name": { "type": "string", "minLength": 1 },
          "description": { "type": ["string", "null"] },
          "firmwareUrl": {
            "type": ["string", "null"],
            "format": "uri",
            "maxLength": 500
          },
          "libraryEntryIds": {
            "type": "array",
            "maxItems": 20,
            "items": { "$ref": "./db-schema.json#/$defs/Ulid" }
          },
          "visibility": {
            "$ref": "./db-schema.json#/$defs/KeymapVisibility",
            "default": "private"
          },
          "data": { "$ref": "#/components/schemas/KeyboardHubKeymapV1" },
          "keyboardType": { "type": "string", "minLength": 1 },
          "message": { "type": ["string", "null"] }
        }
      },
      "UpdateKeymapRequest": {
        "description": "Keymap data update request schema.",
        "type": "object",
        "additionalProperties": false,
        "required": ["data"],
        "properties": {
          "data": { "$ref": "#/components/schemas/KeyboardHubKeymapV1" },
          "layoutVariationId": { "$ref": "./db-schema.json#/$defs/Ulid" },
          "layoutVersionId": { "$ref": "./db-schema.json#/$defs/Ulid" },
          "layout": {
            "$ref": "#/components/schemas/LayoutVariationDefinition"
          },
          "description": { "type": ["string", "null"] },
          "firmwareUrl": {
            "type": ["string", "null"],
            "format": "uri",
            "maxLength": 500
          },
          "libraryEntryIds": {
            "type": "array",
            "maxItems": 20,
            "items": { "$ref": "./db-schema.json#/$defs/Ulid" }
          },
          "message": { "type": ["string", "null"] }
        }
      },
      "PatchKeymapRequest": {
        "description": "Keymap metadata patch request schema.",
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": { "type": "string", "minLength": 1 },
          "description": { "type": ["string", "null"] },
          "firmwareUrl": {
            "type": ["string", "null"],
            "format": "uri",
            "maxLength": 500
          },
          "libraryEntryIds": {
            "type": "array",
            "maxItems": 20,
            "items": { "$ref": "./db-schema.json#/$defs/Ulid" }
          },
          "visibility": { "$ref": "./db-schema.json#/$defs/KeymapVisibility" },
          "status": { "$ref": "./db-schema.json#/$defs/KeymapStatus" }
        }
      },
      "ForkKeymapRequest": {
        "description": "Keymap fork request schema.",
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": { "type": "string", "minLength": 1 },
          "layoutVariationId": { "$ref": "./db-schema.json#/$defs/Ulid" },
          "layoutVersionId": { "$ref": "./db-schema.json#/$defs/Ulid" }
        }
      },
      "CreateKeymapResponse": {
        "description": "Keymap creation response schema.",
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "version", "layoutVariationId"],
        "properties": {
          "id": { "$ref": "./db-schema.json#/$defs/Ulid" },
          "version": { "type": "integer", "exclusiveMinimum": 0 },
          "layoutVariationId": { "$ref": "./db-schema.json#/$defs/Ulid" },
          "layoutVersionId": { "$ref": "./db-schema.json#/$defs/Ulid" }
        }
      },
      "KeymapShareResponse": {
        "description": "Keymap share URL response schema.",
        "type": "object",
        "additionalProperties": false,
        "required": ["shortHash", "shareUrl", "imageUrl"],
        "properties": {
          "shortHash": { "type": "string", "pattern": "^[a-z0-9]{8}$" },
          "shareUrl": { "type": "string", "format": "uri" },
          "imageUrl": { "type": "string", "format": "uri" }
        }
      },
      "ResolveLayoutRequest": {
        "description": "Layout resolution request schema.",
        "type": "object",
        "additionalProperties": false,
        "required": ["keyboard", "layout"],
        "properties": {
          "keyboard": { "type": "string", "minLength": 1 },
          "layout": { "$ref": "#/components/schemas/LayoutVariationDefinition" }
        }
      },
      "ViaLayoutCandidatesRequest": {
        "description": "VIA layout candidate request schema.",
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "firmware": {
            "type": "string",
            "enum": ["via", "vial"],
            "default": "via"
          },
          "productName": { "type": "string", "minLength": 1, "maxLength": 160 },
          "vendorId": {
            "oneOf": [
              { "type": "string", "minLength": 1 },
              { "type": "integer", "minimum": 0 }
            ]
          },
          "productId": {
            "oneOf": [
              { "type": "string", "minLength": 1 },
              { "type": "integer", "minimum": 0 }
            ]
          }
        }
      },
      "ConversionRuleRequest": {
        "description": "Keymap conversion rule creation request schema.",
        "type": "object",
        "additionalProperties": false,
        "required": ["name"],
        "properties": {
          "name": { "type": "string", "minLength": 1 },
          "description": { "type": ["string", "null"] },
          "sourceLayoutVariationId": { "$ref": "./db-schema.json#/$defs/Ulid" },
          "targetLayoutVariationId": { "$ref": "./db-schema.json#/$defs/Ulid" },
          "sourceLayoutVersionId": { "$ref": "./db-schema.json#/$defs/Ulid" },
          "targetLayoutVersionId": { "$ref": "./db-schema.json#/$defs/Ulid" },
          "positionMapping": { "$ref": "#/components/schemas/PositionMapping" },
          "moduleMapping": {
            "type": "array",
            "maxItems": 50,
            "items": { "$ref": "#/components/schemas/ModuleMapping" },
            "default": []
          }
        }
      },
      "PatchConversionRuleRequest": {
        "description": "Keymap conversion rule patch request schema.",
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": { "type": "string", "minLength": 1 },
          "description": { "type": ["string", "null"] },
          "positionMapping": { "$ref": "#/components/schemas/PositionMapping" },
          "moduleMapping": {
            "type": "array",
            "maxItems": 50,
            "items": { "$ref": "#/components/schemas/ModuleMapping" }
          }
        }
      },
      "ConversionRuleStatusRequest": {
        "description": "Conversion rule status request schema.",
        "type": "object",
        "additionalProperties": false,
        "required": ["status"],
        "properties": {
          "status": {
            "type": "string",
            "enum": ["official", "normal", "not_suggested"]
          }
        }
      },
      "ConvertKeymapRequest": {
        "description": "Keymap conversion request schema.",
        "type": "object",
        "additionalProperties": false,
        "required": ["name"],
        "properties": {
          "targetLayoutVariationId": { "$ref": "./db-schema.json#/$defs/Ulid" },
          "targetLayoutVersionId": { "$ref": "./db-schema.json#/$defs/Ulid" },
          "ruleId": { "$ref": "./db-schema.json#/$defs/Ulid" },
          "rule": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "name": { "type": "string", "minLength": 1 },
              "description": { "type": ["string", "null"] },
              "positionMapping": {
                "$ref": "#/components/schemas/PositionMapping"
              },
              "moduleMapping": {
                "type": "array",
                "maxItems": 50,
                "items": { "$ref": "#/components/schemas/ModuleMapping" },
                "default": []
              }
            }
          },
          "name": { "type": "string", "minLength": 1 },
          "description": { "type": ["string", "null"] },
          "visibility": {
            "$ref": "./db-schema.json#/$defs/KeymapVisibility",
            "default": "private"
          },
          "saveRule": { "type": "boolean", "default": false }
        }
      },
      "KeymapExportRequestParams": {
        "description": "Keymap export route parameter schema.",
        "type": "object",
        "additionalProperties": false,
        "required": ["id", "format"],
        "properties": {
          "id": { "$ref": "./db-schema.json#/$defs/Ulid" },
          "format": { "$ref": "#/components/schemas/KeymapExportFormat" }
        }
      },
      "KeymapExportMetadata": {
        "description": "Keymap export metadata schema.",
        "type": "object",
        "additionalProperties": false,
        "required": ["filename", "mimeType"],
        "properties": {
          "filename": { "type": "string", "minLength": 1 },
          "mimeType": { "type": "string", "minLength": 1 }
        }
      },
      "KeyboardHubKeymapV1": { "x-zod-expression": "keyboardHubKeymapSchema" }
    }
  }
}
