{
  "openapi": "3.1.0",
  "info": {
    "title": "MIX ID public protocol surface — source profile",
    "version": "0.1.0",
    "description": "Source-reviewed integration profile, not a certification of standards compliance or full live authenticated verification. No internal admin or native session routes. Closed source licensing is separate.",
    "contact": {
      "name": "Ivan Zorin",
      "email": "creator@localzet.com"
    }
  },
  "servers": [
    {
      "url": "https://id.zorin.cloud"
    }
  ],
  "paths": {
    "/.well-known/openid-configuration": {
      "get": {
        "operationId": "discover",
        "summary": "OIDC discovery",
        "security": [],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Discovery"
                }
              }
            }
          }
        }
      }
    },
    "/oauth2/jwks": {
      "get": {
        "operationId": "jwks",
        "summary": "Public signing keys",
        "security": [],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "keys": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "description": "Public JWK, no private key material."
                      }
                    }
                  },
                  "required": [
                    "keys"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/oauth2/authorize": {
      "get": {
        "operationId": "authorize",
        "summary": "Authorization Code + PKCE or a single-use PAR request_uri",
        "security": [],
        "parameters": [
          {
            "name": "response_type",
            "in": "query",
            "required": false,
            "schema": {
              "const": "code"
            }
          },
          {
            "name": "client_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "redirect_uri",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Requires openid; third-party clients are limited to openid/profile/email/offline_access."
            }
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "nonce",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "code_challenge",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "code_challenge_method",
            "in": "query",
            "required": false,
            "schema": {
              "const": "S256"
            }
          },
          {
            "name": "request_uri",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "description": "Direct request requires AuthorizationRequest fields. PAR form requires client_id + request_uri. state/nonce are required by integration security guidance even though current handler stores missing values as null. Redirect URI must match registration; HTTPS except loopback.",
        "responses": {
          "302": {
            "description": "Hosted interaction redirect",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid client, credentials, token or grant",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          }
        }
      }
    },
    "/oauth2/par": {
      "post": {
        "operationId": "pushAuthorizationRequest",
        "summary": "Pushed Authorization Request",
        "description": "Public clients are accepted in this source profile; confidential clients authenticate. request_uri is single-use, bound to client, TTL 90 seconds. Current source uses Nest default HTTP 201 for successful POST. This is a compatibility finding, not a statement of OAuth compliance.",
        "security": [
          {},
          {
            "clientBasic": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/AuthorizationRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Authorization request stored",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ParResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid client, credentials, token or grant",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          }
        }
      }
    },
    "/oauth2/token": {
      "post": {
        "operationId": "exchangeToken",
        "summary": "Token endpoint",
        "description": "Grant must be allowed for the client. THIRD_PARTY machine grants disabled. Refresh tokens rotate; reuse revokes family and session. id_token applies to user grants, refresh_token only offline_access. client_id body required unless derived from Basic auth. Current source uses Nest default HTTP 201 for successful POST. This is a compatibility finding, not a statement of OAuth compliance.",
        "security": [
          {},
          {
            "clientBasic": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/TokenRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Token issued",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid client, credentials, token or grant",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          }
        }
      }
    },
    "/oauth2/device/authorize": {
      "post": {
        "operationId": "deviceAuthorize",
        "summary": "Device Authorization",
        "description": "Restricted to FIRST_PARTY, MIX Account mode, and explicitly enabled device grant. Not available to general third-party apps. Current source uses Nest default HTTP 201 for successful POST. This is a compatibility finding, not a statement of OAuth compliance.",
        "security": [
          {},
          {
            "clientBasic": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "client_id": {
                    "type": "string"
                  },
                  "client_secret": {
                    "type": "string"
                  },
                  "scope": {
                    "type": "string"
                  }
                },
                "required": []
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Device authorization created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid client, credentials, token or grant",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          }
        }
      }
    },
    "/oauth2/userinfo": {
      "get": {
        "operationId": "userinfo",
        "summary": "Profile from a user access token and its scopes",
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserInfo"
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid client, credentials, token or grant",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          }
        }
      }
    },
    "/oauth2/introspect": {
      "post": {
        "operationId": "introspect",
        "summary": "Introspection",
        "description": "Confidential client required. Non-first-party caller must match token audience. Invalid/expired/inactive token returns active:false. Current source uses Nest default HTTP 201 for successful POST. This is a compatibility finding, not a statement of OAuth compliance. client_secret_post is represented by client_id/client_secret form fields; HTTP Basic alternative is described by security scheme. The empty security alternative is valid only with authenticated client_id/client_secret form fields; anonymous requests are rejected.",
        "security": [
          {
            "clientBasic": []
          },
          {}
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "client_id": {
                    "type": "string"
                  },
                  "client_secret": {
                    "type": "string"
                  },
                  "token": {
                    "type": "string"
                  }
                },
                "required": [
                  "token"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Token introspection result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Introspection"
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid client, credentials, token or grant",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          }
        },
        "x-client-auth-methods": [
          "client_secret_basic",
          "client_secret_post"
        ]
      }
    },
    "/oauth2/revoke": {
      "post": {
        "operationId": "revoke",
        "summary": "Token revocation",
        "description": "Confidential client required in current source. Unknown token is handled idempotently; this profile is not a generic revocation route for public clients. Current source uses Nest default HTTP 201 for successful POST. This is a compatibility finding, not a statement of OAuth compliance. client_secret_post is represented by client_id/client_secret form fields; HTTP Basic alternative is described by security scheme. The empty security alternative is valid only with authenticated client_id/client_secret form fields; anonymous requests are rejected.",
        "security": [
          {
            "clientBasic": []
          },
          {}
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "client_id": {
                    "type": "string"
                  },
                  "client_secret": {
                    "type": "string"
                  },
                  "token": {
                    "type": "string"
                  }
                },
                "required": [
                  "token"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Token revoked",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "maxProperties": 0
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid client, credentials, token or grant",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          }
        },
        "x-client-auth-methods": [
          "client_secret_basic",
          "client_secret_post"
        ]
      }
    },
    "/oauth2/logout": {
      "get": {
        "operationId": "logout",
        "summary": "Logout using an ID token hint",
        "security": [],
        "parameters": [
          {
            "name": "id_token_hint",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "post_logout_redirect_uri",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Session revoked without a redirect"
          },
          "302": {
            "description": "Redirect to a registered URI",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid client, credentials, token or grant",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HttpError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "HttpError": {
        "type": "object",
        "properties": {
          "statusCode": {
            "type": "integer"
          },
          "message": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          },
          "error": {
            "type": "string"
          }
        },
        "required": [
          "statusCode",
          "message"
        ]
      },
      "TokenResponse": {
        "type": "object",
        "properties": {
          "access_token": {
            "type": "string"
          },
          "token_type": {
            "const": "Bearer"
          },
          "expires_in": {
            "type": "integer",
            "minimum": 1
          },
          "scope": {
            "type": "string"
          },
          "id_token": {
            "type": "string"
          },
          "refresh_token": {
            "type": "string"
          }
        },
        "required": [
          "access_token",
          "token_type",
          "expires_in",
          "scope"
        ]
      },
      "TokenRequest": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "client_id": {
                "type": "string"
              },
              "client_secret": {
                "type": "string"
              },
              "grant_type": {
                "const": "authorization_code"
              },
              "code": {
                "type": "string"
              },
              "redirect_uri": {
                "type": "string",
                "format": "uri"
              },
              "code_verifier": {
                "type": "string"
              }
            },
            "required": [
              "grant_type",
              "code",
              "redirect_uri",
              "code_verifier"
            ]
          },
          {
            "type": "object",
            "properties": {
              "client_id": {
                "type": "string"
              },
              "client_secret": {
                "type": "string"
              },
              "grant_type": {
                "const": "refresh_token"
              },
              "refresh_token": {
                "type": "string"
              }
            },
            "required": [
              "grant_type",
              "refresh_token"
            ]
          },
          {
            "type": "object",
            "properties": {
              "client_id": {
                "type": "string"
              },
              "client_secret": {
                "type": "string"
              },
              "grant_type": {
                "const": "client_credentials"
              },
              "scope": {
                "type": "string"
              }
            },
            "required": [
              "grant_type"
            ]
          },
          {
            "type": "object",
            "properties": {
              "client_id": {
                "type": "string"
              },
              "client_secret": {
                "type": "string"
              },
              "grant_type": {
                "const": "urn:ietf:params:oauth:grant-type:device_code"
              },
              "device_code": {
                "type": "string"
              }
            },
            "required": [
              "grant_type",
              "device_code"
            ]
          }
        ]
      },
      "AuthorizationRequest": {
        "type": "object",
        "properties": {
          "response_type": {
            "const": "code"
          },
          "client_id": {
            "type": "string"
          },
          "redirect_uri": {
            "type": "string",
            "format": "uri"
          },
          "scope": {
            "type": "string",
            "description": "Requires openid; third-party clients are limited to openid/profile/email/offline_access."
          },
          "state": {
            "type": "string"
          },
          "nonce": {
            "type": "string"
          },
          "code_challenge": {
            "type": "string"
          },
          "code_challenge_method": {
            "const": "S256"
          },
          "client_secret": {
            "type": "string"
          }
        },
        "required": [
          "response_type",
          "client_id",
          "redirect_uri",
          "scope",
          "code_challenge",
          "code_challenge_method"
        ]
      },
      "ParResponse": {
        "type": "object",
        "properties": {
          "request_uri": {
            "type": "string"
          },
          "expires_in": {
            "type": "integer",
            "const": 90
          }
        },
        "required": [
          "request_uri",
          "expires_in"
        ]
      },
      "DeviceResponse": {
        "type": "object",
        "properties": {
          "device_code": {
            "type": "string"
          },
          "user_code": {
            "type": "string"
          },
          "verification_uri": {
            "type": "string",
            "format": "uri"
          },
          "verification_uri_complete": {
            "type": "string",
            "format": "uri"
          },
          "expires_in": {
            "const": 600
          },
          "interval": {
            "const": 5
          }
        },
        "required": [
          "device_code",
          "user_code",
          "verification_uri",
          "verification_uri_complete",
          "expires_in",
          "interval"
        ]
      },
      "UserInfo": {
        "type": "object",
        "properties": {
          "sub": {
            "type": "string"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": "string"
          },
          "email_verified": {
            "type": "boolean"
          }
        },
        "required": [
          "sub"
        ]
      },
      "Introspection": {
        "type": "object",
        "properties": {
          "active": {
            "type": "boolean"
          },
          "sub": {
            "type": "string"
          },
          "aud": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          },
          "scope": {
            "type": "string"
          },
          "exp": {
            "type": "integer"
          },
          "iat": {
            "type": "integer"
          },
          "token_type": {
            "const": "Bearer"
          },
          "token_use": {
            "type": "string"
          }
        },
        "required": [
          "active"
        ]
      },
      "Discovery": {
        "type": "object",
        "properties": {
          "issuer": {
            "type": "string",
            "format": "uri"
          },
          "authorization_endpoint": {
            "type": "string",
            "format": "uri"
          },
          "pushed_authorization_request_endpoint": {
            "type": "string",
            "format": "uri"
          },
          "token_endpoint": {
            "type": "string",
            "format": "uri"
          },
          "device_authorization_endpoint": {
            "type": "string",
            "format": "uri"
          },
          "userinfo_endpoint": {
            "type": "string",
            "format": "uri"
          },
          "jwks_uri": {
            "type": "string",
            "format": "uri"
          },
          "revocation_endpoint": {
            "type": "string",
            "format": "uri"
          },
          "introspection_endpoint": {
            "type": "string",
            "format": "uri"
          },
          "end_session_endpoint": {
            "type": "string",
            "format": "uri"
          },
          "response_types_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "grant_types_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "subject_types_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "id_token_signing_alg_values_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "code_challenge_methods_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "scopes_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "token_endpoint_auth_methods_supported": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "issuer",
          "authorization_endpoint",
          "pushed_authorization_request_endpoint",
          "token_endpoint",
          "device_authorization_endpoint",
          "userinfo_endpoint",
          "jwks_uri",
          "revocation_endpoint",
          "introspection_endpoint",
          "end_session_endpoint",
          "response_types_supported",
          "grant_types_supported",
          "subject_types_supported",
          "id_token_signing_alg_values_supported",
          "code_challenge_methods_supported",
          "scopes_supported",
          "token_endpoint_auth_methods_supported"
        ]
      }
    },
    "securitySchemes": {
      "clientBasic": {
        "type": "http",
        "scheme": "basic"
      },
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  },
  "x-source-review-date": "2026-10-16"
}
