{
  "components": {
    "securitySchemes": {
      "clientBasic": {
        "description": "Client authentication with the client ID and client secret (HTTP Basic).",
        "scheme": "basic",
        "type": "http"
      },
      "oauth2": {
        "description": "OAuth2 tokens issued by this server. Signed-in Reserva users use the authorization code flow, server-side integrations the client credentials flow, and partner applications acting for their own end users use token exchange (RFC 8693) on the token endpoint.",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://reserva.bojanlab.com/auth/oauth2/authorize",
            "scopes": {
              "openid": "OpenID Connect",
              "profile": "Profile",
              "read": "Read access",
              "reservation:create": "Create reservations on behalf of a partner's end user",
              "reservation:read:own": "Read the reservations a partner made for the calling end user",
              "write": "Write access"
            },
            "tokenUrl": "https://reserva.bojanlab.com/auth/oauth2/token"
          },
          "clientCredentials": {
            "scopes": {
              "openid": "OpenID Connect",
              "profile": "Profile",
              "read": "Read access",
              "reservation:create": "Create reservations on behalf of a partner's end user",
              "reservation:read:own": "Read the reservations a partner made for the calling end user",
              "write": "Write access"
            },
            "tokenUrl": "https://reserva.bojanlab.com/auth/oauth2/token"
          }
        },
        "type": "oauth2"
      }
    }
  },
  "info": {
    "contact": {
      "name": "Reserva API support",
      "url": "https://reserva.rs"
    },
    "description": "OAuth2 authorization server of Reserva. Issues the access tokens used to call the Reserva Resource API: authorization code, client credentials and token exchange (RFC 8693) for partner applications, plus the OpenID Connect discovery and key (JWKS) endpoints.",
    "license": {
      "name": "Apache-2.0",
      "url": "https://www.apache.org/licenses/LICENSE-2.0.html"
    },
    "title": "Reserva Auth API",
    "version": "0.1.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/.well-known/oauth-authorization-server": {
      "get": {
        "description": "Returns the authorization server metadata defined by RFC 8414.",
        "operationId": "getAuthorizationServerMetadata",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\"issuer\":\"https://auth.example.com/auth\",\"token_endpoint\":\"https://auth.example.com/auth/oauth2/token\",\"jwks_uri\":\"https://auth.example.com/auth/oauth2/jwks\"}",
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "OK"
          }
        },
        "security": [],
        "summary": "Get the OAuth2 authorization server metadata",
        "tags": [
          "Discovery"
        ]
      }
    },
    "/.well-known/openid-configuration": {
      "get": {
        "description": "Returns the issuer, endpoint URLs and supported capabilities of the authorization server.",
        "operationId": "getOpenIdConfiguration",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\"issuer\":\"https://auth.example.com/auth\",\"token_endpoint\":\"https://auth.example.com/auth/oauth2/token\",\"jwks_uri\":\"https://auth.example.com/auth/oauth2/jwks\"}",
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "OK"
          }
        },
        "security": [],
        "summary": "Get the OpenID Connect discovery document",
        "tags": [
          "Discovery"
        ]
      }
    },
    "/oauth2/jwks": {
      "get": {
        "description": "Returns the public keys (JWKS) used to verify the signature of access tokens.",
        "operationId": "getJwks",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\"keys\":[{\"kty\":\"RSA\",\"e\":\"AQAB\",\"use\":\"sig\",\"kid\":\"3b1c7f0e\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx...\"}]}",
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "OK"
          }
        },
        "security": [],
        "summary": "Get the JSON Web Key Set",
        "tags": [
          "Discovery"
        ]
      }
    },
    "/oauth2/token": {
      "post": {
        "description": "OAuth2 token endpoint. Supports the authorization code, client credentials and refresh token grants and token exchange (RFC 8693) for partner applications. Confidential clients authenticate with HTTP Basic; public token exchange clients send client_id only.",
        "operationId": "issueToken",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "examples": {
                "tokenExchange": {
                  "summary": "Token exchange",
                  "value": "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange&client_id=partner-client-id&subject_token=eyJhbGciOi...&subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aid_token&scope=reservation%3Acreate%20reservation%3Aread%3Aown"
                }
              },
              "schema": {
                "properties": {
                  "client_id": {
                    "description": "Client ID; required for public (token exchange) clients",
                    "example": "partner-client-id",
                    "type": "string"
                  },
                  "code": {
                    "description": "Authorization code (authorization_code grant)",
                    "type": "string"
                  },
                  "grant_type": {
                    "description": "authorization_code, client_credentials, refresh_token or urn:ietf:params:oauth:grant-type:token-exchange",
                    "example": "urn:ietf:params:oauth:grant-type:token-exchange",
                    "type": "string"
                  },
                  "redirect_uri": {
                    "description": "Redirect URI used in the authorization request (authorization_code grant)",
                    "type": "string"
                  },
                  "refresh_token": {
                    "description": "Refresh token (refresh_token grant)",
                    "type": "string"
                  },
                  "scope": {
                    "description": "Space-separated scopes requested",
                    "example": "reservation:create reservation:read:own",
                    "type": "string"
                  },
                  "subject_token": {
                    "description": "Token exchange: ID token of the partner's end user, or a signed partner assertion",
                    "type": "string"
                  },
                  "subject_token_type": {
                    "description": "Token exchange: type of the subject token",
                    "example": "urn:ietf:params:oauth:token-type:id_token",
                    "type": "string"
                  }
                },
                "required": [
                  "grant_type"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\"access_token\":\"eyJhbGciOi...\",\"token_type\":\"Bearer\",\"expires_in\":3600,\"scope\":\"reservation:create reservation:read:own\"}",
                "schema": {
                  "properties": {
                    "access_token": {
                      "description": "The access token (JWT)",
                      "type": "string"
                    },
                    "expires_in": {
                      "description": "Lifetime in seconds",
                      "example": 3600,
                      "format": "int64"
                    },
                    "id_token": {
                      "description": "OpenID Connect ID token, when requested",
                      "type": "string"
                    },
                    "issued_token_type": {
                      "description": "Token exchange: type of the issued token",
                      "type": "string"
                    },
                    "refresh_token": {
                      "description": "Refresh token, when issued",
                      "type": "string"
                    },
                    "scope": {
                      "description": "Granted scopes",
                      "type": "string"
                    },
                    "token_type": {
                      "description": "Always Bearer",
                      "example": "Bearer",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Token issued"
          },
          "400": {
            "description": "Invalid request or grant (OAuth2 error response)"
          },
          "401": {
            "description": "Client authentication failed"
          }
        },
        "security": [
          {
            "clientBasic": []
          },
          {}
        ],
        "summary": "Request an access token",
        "tags": [
          "OAuth2 Token"
        ]
      }
    }
  },
  "security": [
    {
      "oauth2": [
        "openid",
        "profile"
      ]
    }
  ]
}
