{
  "openapi": "3.0.0",
  "info": {
    "title": "Authentication API",
    "version": "1.0.0",
    "description": "Zesty.io platform service for issuing, verifying and ending user sessions."
  },
  "x-readme": {
    "explorer-enabled": false
  },
  "servers": [
    {
      "url": "https://auth.api.zesty.io",
      "description": "Production server"
    },
    {
      "url": "https://auth.api.dev.zesty.io",
      "description": "Development server"
    },
    {
      "url": "https://auth.api.stage.zesty.io",
      "description": "Staging server"
    }
  ],
  "paths": {
    "/azure/login": {
      "get": {
        "summary": "Microsoft Azure SSO Login",
        "operationId": "azure-sso-login",
        "tags": ["/azure"],
        "description": "Authenticate a user using Azure SSO",
        "responses": {
          "302": {
            "description": "Redirect to Azure OAuth2 Authorization Endpoint",
            "headers": {
              "Location": {
                "description": "URI where the user can authorize the SSO using Azure",
                "schema": {
                  "type": "string"
                },
                "example": {
                  "value": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?tenant=common&client_id=XXXXX&response_type=code&redirect_uri=https://auth.api.zesty.io/azure/reply&scope=openid email profile offline_access&state=XXXXX"
                }
              }
            }
          }
        }
      }
    },
    "/azure/reply": {
      "get": {
        "summary": "Microsoft SSO redirect URI",
        "operationId": "azure-sso-reply",
        "tags": ["/azure"],
        "description": "Get the access token, refresh token and id_token of a user authenticating to Azure SSO",
        "parameters": [
          {
            "in": "query",
            "name": "state",
            "required": true,
            "description": "the state from the /azure/reply endpoint passed from the redirect",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "code",
            "required": true,
            "description": "the authorization code from the /authorize endpoint of Azure SSO",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to Zesty.io Auth API /finished endpoint",
            "headers": {
              "Location": {
                "description": "URI where the authentication status and error message is passed",
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "200": {
                    "value": "https://auth.api.zesty.io/finished?status=200"
                  },
                  "400": {
                    "value": "https://auth.api.zesty.io/finished?status=400&error_message=Microsoft SSO access was not granted"
                  },
                  "401": {
                    "value": "https://auth.api.zesty.io/finished?status=400&error_message=Invalid auth state"
                  },
                  "403": {
                    "value": "https://auth.api.zesty.io/finished?status=400&error_message=Login unsuccessful. You have selected an incorrect login method for your account. Please double-check your selected login method and attempt to log in again."
                  },
                  "500": {
                    "value": "https://auth.api.zesty.io/finished?status=400&error_message=Failed adding SSO"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/github/login": {
      "get": {
        "summary": "Github SSO Login",
        "operationId": "github-sso-login",
        "tags": ["/github"],
        "description": "Authenticate a user using Github SSO",
        "responses": {
          "302": {
            "description": "Redirect to Github OAuth2 Authorization Endpoint",
            "headers": {
              "Location": {
                "description": "URI where the user can authorize the SSO using Github",
                "schema": {
                  "type": "string"
                },
                "example": {
                  "value": "https://github.com/login/oauth/authorize?scope=read:user%20user:email&redirect_uri=https://auth.api.zesty.io/github/reply&client_id=XXXXX&state=XXXXX"
                }
              }
            }
          }
        }
      }
    },
    "/github/reply": {
      "get": {
        "summary": "Github SSO redirect URI",
        "operationId": "github-sso-reply",
        "tags": ["/github"],
        "description": "Get the access token of a user authenticating to Github SSO",
        "parameters": [
          {
            "in": "query",
            "name": "state",
            "required": true,
            "description": "the state from the /github/reply endpoint passed from the redirect",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "code",
            "required": true,
            "description": "the authorization code from the /authorize endpoint of Github SSO",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to Zesty.io Auth API /finished endpoint",
            "headers": {
              "Location": {
                "description": "URI where the authentication status and error message is passed",
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "200": {
                    "value": "https://auth.api.zesty.io/finished?status=200"
                  },
                  "400": {
                    "value": "https://auth.api.zesty.io/finished?status=400&error_message=Github SSO access was not granted"
                  },
                  "401": {
                    "value": "https://auth.api.zesty.io/finished?status=400&error_message=Invalid auth state"
                  },
                  "403": {
                    "value": "https://auth.api.zesty.io/finished?status=400&error_message=Login unsuccessful. You have selected an incorrect login method for your account. Please double-check your selected login method and attempt to log in again."
                  },
                  "500": {
                    "value": "https://auth.api.zesty.io/finished?status=400&error_message=Failed adding SSO"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/google/login": {
      "get": {
        "summary": "Google SSO Login",
        "operationId": "google-sso-login",
        "tags": ["/google"],
        "description": "Authenticate a user using Google SSO",
        "responses": {
          "302": {
            "description": "Redirect to Google OAuth2 Authorization Endpoint",
            "headers": {
              "Location": {
                "description": "URI where the user can authorize the SSO using Google",
                "schema": {
                  "type": "string"
                },
                "example": {
                  "value": "https://accounts.google.com/o/oauth2/v2/auth?prompt=consent&access_type=offline&response_type=code&client_id=XXXXX&redirect_uri=https://auth.api.zesty.io/google/reply&scope=https://www.googleapis.com/auth/userinfo.email+https://www.googleapis.com/auth/userinfo.profile+openid&state=XXXXX"
                }
              }
            }
          }
        }
      }
    },
    "/google/reply": {
      "get": {
        "summary": "Google SSO redirect URI",
        "operationId": "google-sso-reply",
        "tags": ["/google"],
        "description": "Get the access token, refresh token and id_token of a user authenticating to Google SSO",
        "parameters": [
          {
            "in": "query",
            "name": "state",
            "required": true,
            "description": "the state from the /google/reply endpoint passed from the redirect",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "code",
            "required": true,
            "description": "the authorization code from the /authorize endpoint of Google SSO",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to Zesty.io Auth API /finished endpoint",
            "headers": {
              "Location": {
                "description": "URI where the authentication status and error message is passed",
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "200": {
                    "value": "https://auth.api.zesty.io/finished?status=200"
                  },
                  "400": {
                    "value": "https://auth.api.zesty.io/finished?status=400&error_message=Google SSO access was not granted"
                  },
                  "401": {
                    "value": "https://auth.api.zesty.io/finished?status=400&error_message=Invalid auth state"
                  },
                  "403": {
                    "value": "https://auth.api.zesty.io/finished?status=400&error_message=Login unsuccessful. You have selected an incorrect login method for your account. Please double-check your selected login method and attempt to log in again."
                  },
                  "500": {
                    "value": "https://auth.api.zesty.io/finished?status=400&error_message=Failed adding SSO"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/login": {
      "post": {
        "summary": "Login",
        "operationId": "login",
        "description": "Authenticate a user with an email and password",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful (200)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "message": "Logged in successfully.",
                  "status": "OK",
                  "data": {
                    "data": "XXXXXXXXXXXXX"
                  },
                  "meta": {
                    "userZuid": "5-xyzxyz-xy4zxy4z",
                    "token": "XXXXXXXXXXXXX"
                  },
                  "code": 200
                }
              }
            }
          },
          "404": {
            "description": "Unauthorized (404)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "message": "Your reset authorization code is invalid.",
                  "status": "Unauthorized",
                  "data": null,
                  "meta": {},
                  "code": null
                }
              }
            }
          }
        }
      }
    },
    "/logout": {
      "post": {
        "summary": "Logout",
        "operationId": "logout",
        "description": "Sending a session token to this API will invalidate the provided token.",
        "security": [
          {
            "Bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful (200)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "message": "",
                  "status": "OK",
                  "meta": {},
                  "code": 200
                }
              }
            }
          }
        }
      }
    },
    "/okta/login": {
      "get": {
        "summary": "Okta SSO Login",
        "operationId": "okta-sso-login",
        "tags": ["/okta"],
        "description": "Authenticate a user using Okta SSO",
        "parameters": [
          {
            "in": "query",
            "name": "iss",
            "required": true,
            "description": "the client domain (issuer) where the /okta/login is triggered",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to Okta OAuth2 Authorization Endpoint",
            "headers": {
              "Location": {
                "description": "URI where the user can authorize the SSO using Okta",
                "schema": {
                  "type": "string"
                },
                "example": {
                  "value": "https://dev-46725118.okta.com/oauth2/v1/authorize?scope=openid%20profile%20email&response_type=code&client_id=XXXXX&redirect_uri=https://auth.api.zesty.io/okta/reply&state=XXXXX,YYYY"
                }
              }
            }
          }
        }
      }
    },
    "/okta/reply": {
      "get": {
        "summary": "Okta SSO redirect URI",
        "operationId": "okta-sso-reply",
        "tags": ["/okta"],
        "description": "Get the access token, refresh token and id_token of a user authenticating to Okta SSO",
        "parameters": [
          {
            "in": "query",
            "name": "state",
            "required": true,
            "description": "the state from the /okta/reply endpoint passed from the redirect and the client domain of the issuer, the state and client domain are separated by a comma",
            "schema": {
              "type": "string"
            },
            "example": {
              "value": "XXXXX,https://okta-dev.com"
            }
          },
          {
            "in": "query",
            "name": "code",
            "required": true,
            "description": "the authorization code from the /authorize endpoint of Okta SSO",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to Zesty.io Auth API /finished endpoint",
            "headers": {
              "Location": {
                "description": "URI where the authentication status and error message is passed",
                "schema": {
                  "type": "string"
                },
                "examples": {
                  "200": {
                    "value": "https://auth.api.zesty.io/finished?status=200"
                  },
                  "400": {
                    "value": "https://auth.api.zesty.io/finished?status=400&error_message=Okta SSO access was not granted"
                  },
                  "401": {
                    "value": "https://auth.api.zesty.io/finished?status=400&error_message=Invalid auth state"
                  },
                  "403": {
                    "value": "https://auth.api.zesty.io/finished?status=400&error_message=Login unsuccessful. You have selected an incorrect login method for your account. Please double-check your selected login method and attempt to log in again."
                  },
                  "500": {
                    "value": "https://auth.api.zesty.io/finished?status=400&error_message=Failed adding SSO"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/password-reset": {
      "post": {
        "summary": "Password Reset",
        "operationId": "password-reset",
        "description": "Reset a password of a user",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string"
                  },
                  "email": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful (200)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "message": "Password reset",
                  "status": "OK",
                  "data": null,
                  "meta": {},
                  "code": 200
                }
              }
            }
          },
          "400": {
            "description": "Bad Request (400)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "message": "Your password must be at least 8 characters long.",
                  "status": "Bad request",
                  "data": null,
                  "meta": {},
                  "code": 400
                }
              }
            }
          },
          "404": {
            "description": "Not Found (404)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "message": "Your reset authorization code is invalid.",
                  "status": "Bad request",
                  "data": null,
                  "meta": {},
                  "code": 404
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error (500)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "message": "Error with password reset code. Contact support@zesty.io",
                  "status": "Internal Server Error",
                  "data": null,
                  "meta": {},
                  "code": 500
                }
              }
            }
          }
        }
      }
    },
    "/verify-2fa": {
      "get": {
        "summary": "Verify 2FA using One Touch",
        "operationId": "verify-2fa-one-touch",
        "tags": ["/verify"],
        "description": "Verify two factor authentication (2FA) using One Touch",
        "security": [
          {
            "Bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful (200)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "message": "Authorized",
                  "status": "OK",
                  "data": {},
                  "meta": {
                    "userZuid": "5-xyzxyz-xy4zxy4",
                    "token": "XXXXXXXXXXXXX"
                  },
                  "code": 200
                }
              }
            }
          },
          "202": {
            "description": "2FA Pending (202)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "message": "2FA pending",
                  "status": "Accepted",
                  "data": {},
                  "meta": {},
                  "code": 202
                }
              }
            }
          },
          "401": {
            "description": "Unathorized (401)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "message": "This 2FA request was denied",
                  "status": "Unauthorized",
                  "meta": {},
                  "code": 401
                }
              }
            }
          },
          "404": {
            "description": "Not Found (404)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "message": "This 2FA request has expired",
                  "status": "Not Found",
                  "meta": {},
                  "code": 404
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Verify 2FA using Authy",
        "operationId": "verify-2fa-authy",
        "tags": ["/verify"],
        "description": "Verify two factor authentication (2FA) using Authy",
        "security": [
          {
            "Bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "properties": {
                  "token": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful (200)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "message": "Authorized",
                  "status": "OK",
                  "data": {},
                  "meta": {
                    "userZuid": "5-xyzxyz-xy4zxy4"
                  },
                  "code": 200
                }
              }
            }
          },
          "400": {
            "description": "Bad Request (400)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "message": "Invalid two factor user. Please contact support@zesty.io",
                  "status": "Bad Request",
                  "meta": {},
                  "code": 400
                }
              }
            }
          },
          "401": {
            "description": "Unathorized (401)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "message": "Invalid two factor authorization. Please contact support@zesty.io",
                  "status": "Unauthorized",
                  "meta": {},
                  "code": 401
                }
              }
            }
          }
        }
      }
    },
    "/verify": {
      "get": {
        "summary": "Verify Session",
        "operationId": "verify-session",
        "tags": ["/verify"],
        "description": "Verify if session token is valid and extend a user session. Tokens expire 20 minutes from last login or API usage. Everytime an API call is run the session extends 20 minutes.",
        "security": [
          {
            "Bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful (200)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "message": "Session valid",
                  "status": "OK",
                  "data": "XXXXXXXXXXXXX",
                  "meta": {
                    "userZuid": "5-xyzxyz-xy4zxy4"
                  },
                  "code": 200
                }
              }
            }
          },
          "401": {
            "description": "Unathorized (401)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "message": "No Session",
                  "status": "Unauthorized",
                  "meta": {},
                  "code": 401
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {},
  "tags": []
}
