{
  "components": {
    "schemas": {
      "DeviceAuthorizationResponse": {
        "properties": {
          "device_code": {
            "type": "string"
          },
          "expires_in": {
            "type": "integer"
          },
          "interval": {
            "type": "integer"
          },
          "user_code": {
            "type": "string"
          },
          "verification_uri": {
            "format": "uri",
            "type": "string"
          },
          "verification_uri_complete": {
            "format": "uri",
            "type": "string"
          }
        },
        "required": [
          "device_code",
          "user_code",
          "verification_uri",
          "expires_in",
          "interval"
        ],
        "type": "object"
      },
      "JsonWebKeySet": {
        "properties": {
          "keys": {
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "type": "array"
          }
        },
        "required": [
          "keys"
        ],
        "type": "object"
      },
      "OAuthTokenResponse": {
        "properties": {
          "access_token": {
            "type": "string"
          },
          "expires_in": {
            "type": "integer"
          },
          "id_token": {
            "type": "string"
          },
          "refresh_token": {
            "type": "string"
          },
          "scope": {
            "type": "string"
          },
          "token_type": {
            "example": "Bearer",
            "type": "string"
          }
        },
        "type": "object"
      },
      "OpenIdProviderMetadata": {
        "description": "OpenID Provider Metadata (abbreviated; see live discovery for the full document).",
        "properties": {
          "authorization_endpoint": {
            "format": "uri",
            "type": "string"
          },
          "device_authorization_endpoint": {
            "format": "uri",
            "type": "string"
          },
          "end_session_endpoint": {
            "format": "uri",
            "type": "string"
          },
          "grant_types_supported": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "id_token_signing_alg_values_supported": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "introspection_endpoint": {
            "format": "uri",
            "type": "string"
          },
          "issuer": {
            "format": "uri",
            "type": "string"
          },
          "jwks_uri": {
            "format": "uri",
            "type": "string"
          },
          "response_types_supported": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "revocation_endpoint": {
            "format": "uri",
            "type": "string"
          },
          "scopes_supported": {
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "token_endpoint": {
            "format": "uri",
            "type": "string"
          },
          "userinfo_endpoint": {
            "format": "uri",
            "type": "string"
          }
        },
        "type": "object"
      },
      "TokenIntrospectionResponse": {
        "properties": {
          "active": {
            "type": "boolean"
          },
          "client_id": {
            "type": "string"
          },
          "exp": {
            "type": "integer"
          },
          "scope": {
            "type": "string"
          },
          "sub": {
            "type": "string"
          }
        },
        "required": [
          "active"
        ],
        "type": "object"
      },
      "UserInfoClaims": {
        "additionalProperties": true,
        "description": "OpenID Connect claims available for the granted scopes.",
        "type": "object"
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "bearerFormat": "JWT",
        "description": "Access token from the token endpoint.",
        "scheme": "bearer",
        "type": "http"
      },
      "clientBasic": {
        "description": "HTTP Basic with client_id as username and client_secret as password.",
        "scheme": "basic",
        "type": "http"
      }
    }
  },
  "info": {
    "description": "OAuth 2.0 and OpenID Connect on accounts.yoursafe.com. This document is maintained for integrators alongside the product docs. The live discovery document at `/.well-known/openid-configuration` remains authoritative for endpoint URLs, supported scopes, and client authentication methods.",
    "title": "Yoursafe ID (OpenID Connect)",
    "version": "1.0.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/.well-known/openid-configuration": {
      "get": {
        "description": "Returns OpenID Provider Metadata. Use this document for authoritative URLs and supported values.",
        "operationId": "getOpenIdConfiguration",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenIdProviderMetadata"
                }
              }
            },
            "description": "Provider metadata JSON"
          }
        },
        "summary": "OpenID discovery metadata",
        "tags": [
          "Discovery"
        ]
      }
    },
    "/connect/logout": {
      "get": {
        "description": "Ends the session at Yoursafe and optionally redirects to `post_logout_redirect_uri`.",
        "operationId": "endSession",
        "parameters": [
          {
            "in": "query",
            "name": "id_token_hint",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "post_logout_redirect_uri",
            "schema": {
              "format": "uri",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "client_id",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "state",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect after logout or to an error page"
          }
        },
        "summary": "RP-initiated logout",
        "tags": [
          "Session"
        ]
      }
    },
    "/oauth2/authorize": {
      "get": {
        "description": "Redirects the user agent to authenticate and consent. On success, redirects to `redirect_uri` with `code` and `state`.",
        "operationId": "authorize",
        "parameters": [
          {
            "in": "query",
            "name": "response_type",
            "required": true,
            "schema": {
              "enum": [
                "code"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "client_id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "redirect_uri",
            "required": true,
            "schema": {
              "format": "uri",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "scope",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "state",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "nonce",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to login, consent, or back to the client with `code` or OAuth error parameters."
          }
        },
        "summary": "Start sign-in and consent",
        "tags": [
          "Authorization"
        ]
      }
    },
    "/oauth2/device_authorization": {
      "post": {
        "description": "Starts the device flow for clients without a browser or with limited input.",
        "operationId": "deviceAuthorization",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "properties": {
                  "client_id": {
                    "type": "string"
                  },
                  "client_secret": {
                    "type": "string"
                  },
                  "scope": {
                    "type": "string"
                  }
                },
                "required": [
                  "client_id",
                  "scope"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceAuthorizationResponse"
                }
              }
            },
            "description": "Device and user codes for verification and polling"
          }
        },
        "summary": "Device authorization grant (RFC 8628)",
        "tags": [
          "Authorization"
        ]
      }
    },
    "/oauth2/introspect": {
      "post": {
        "operationId": "introspect",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "properties": {
                  "token": {
                    "type": "string"
                  },
                  "token_type_hint": {
                    "enum": [
                      "access_token",
                      "refresh_token"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "token"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenIntrospectionResponse"
                }
              }
            },
            "description": "Introspection result"
          }
        },
        "security": [
          {
            "clientBasic": []
          }
        ],
        "summary": "Token introspection (RFC 7662)",
        "tags": [
          "Token"
        ]
      }
    },
    "/oauth2/jwks": {
      "get": {
        "description": "Public signing keys for verifying ID tokens and other JWTs from this issuer.",
        "operationId": "jwks",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonWebKeySet"
                }
              }
            },
            "description": "JWKS document"
          }
        },
        "summary": "JSON Web Key Set",
        "tags": [
          "Session"
        ]
      }
    },
    "/oauth2/revoke": {
      "post": {
        "operationId": "revoke",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "properties": {
                  "client_id": {
                    "type": "string"
                  },
                  "client_secret": {
                    "type": "string"
                  },
                  "token": {
                    "type": "string"
                  },
                  "token_type_hint": {
                    "enum": [
                      "access_token",
                      "refresh_token"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "token"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Token revoked (empty body)"
          }
        },
        "security": [
          {
            "clientBasic": []
          }
        ],
        "summary": "Token revocation (RFC 7009)",
        "tags": [
          "Token"
        ]
      }
    },
    "/oauth2/token": {
      "put": {
        "description": "Yoursafe documents token exchange with HTTP PUT (not POST). Supports the authorization code grant and the device code grant.",
        "operationId": "token",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "oneOf": [
                  {
                    "properties": {
                      "client_id": {
                        "type": "string"
                      },
                      "client_secret": {
                        "type": "string"
                      },
                      "code": {
                        "type": "string"
                      },
                      "grant_type": {
                        "enum": [
                          "authorization_code"
                        ],
                        "type": "string"
                      },
                      "redirect_uri": {
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "required": [
                      "grant_type",
                      "code",
                      "redirect_uri",
                      "client_id",
                      "client_secret"
                    ],
                    "type": "object"
                  },
                  {
                    "properties": {
                      "client_id": {
                        "type": "string"
                      },
                      "client_secret": {
                        "type": "string"
                      },
                      "device_code": {
                        "type": "string"
                      },
                      "grant_type": {
                        "enum": [
                          "urn:ietf:params:oauth:grant-type:device_code"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "grant_type",
                      "device_code",
                      "client_id"
                    ],
                    "type": "object"
                  }
                ]
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthTokenResponse"
                }
              }
            },
            "description": "Token response"
          }
        },
        "summary": "Exchange or refresh tokens",
        "tags": [
          "Token"
        ]
      }
    },
    "/userinfo": {
      "get": {
        "description": "Returns OpenID Connect claims for the subject associated with the access token.",
        "operationId": "userinfo",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserInfoClaims"
                }
              }
            },
            "description": "Claims JSON"
          },
          "401": {
            "description": "Invalid or missing access token"
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "UserInfo claims",
        "tags": [
          "UserInfo"
        ]
      }
    }
  },
  "servers": [
    {
      "description": "Yoursafe ID authorization server",
      "url": "https://accounts.yoursafe.com"
    }
  ],
  "tags": [
    {
      "description": "Provider metadata",
      "name": "Discovery"
    },
    {
      "description": "Browser-facing sign-in and consent",
      "name": "Authorization"
    },
    {
      "description": "Token issuance and validation",
      "name": "Token"
    },
    {
      "description": "Claims for an access token",
      "name": "UserInfo"
    },
    {
      "description": "Logout and key material",
      "name": "Session"
    }
  ]
}
