How to set up Custom SSO
Custom SSO lets members sign in to your app with the username and password they already use on your website, so they do not have to create a second account.
How to set up Custom SSO
Preview
Members sign in with their existing website credentials. The login screen looks the same as before, and accounts are created in your app automatically the first time someone signs in.
Overview
Custom SSO replaces the app's standard email-and-password sign-in. Instead of checking credentials against the app's own member list, the app sends them to your website to be verified. Your website remains the single place where accounts are created, changed, and removed.
Requirements
Custom SSO is only available on select plans. If you do not see this option in your Control Panel, contact your account administrator.
Username and Password Sign In must be enabled, because Custom SSO changes how that sign-in works.
Custom SSO connects your app to your existing login system, and that connection must be built on your website's side. You will not write any code, but someone technical must set it up and provide the values you enter in the Control Panel.
Before you begin, ask whoever manages your website for the following. Forward them the Information for your web team section at the bottom of this article.
-
Login API — the web address the app sends the username and password to for verification
-
Access Token Validator API — the web address the app uses to look up a member's name and email after sign-in
-
Client ID and Client Secret — two codes that identify your app to your website
-
Content Type — how the information is packaged. Your web team will know which of the three options to select
-
Register Url — optional. Your website's own sign-up page, if members should register there rather than in the app
-
Reset Password API — optional. The web address that sends a member a password reset email
How to set up Custom SSO
-
Log in, go to User Access, then select Login Screen from the left side menu.
-
Click the Settings tab.
-
Under Sign In Options, make sure Username and Password Sign In is enabled.
-
Select Custom SSO
-
Click the arrow to the right of SSO Settings to open the settings.
-
Enter the required values your web team provided.
-
Enter the Login API
-
Enter the Access Token Validator API
-
Enter the Client ID
-
Enter the Client Secret if your web team says one is needed
-
Select the Content Type your web team specified
-
-
Enter the optional values you want to use.
-
Enter a Register Url to open your website's sign-up page instead of the built-in registration form
-
Enter a Reset Password API to enable Forgot password
-
Enter a Reset Password Message, or leave it blank to use the default message
-
-
Click Save
-
Scroll to SSO Testing, which becomes available once the required web addresses are saved.
-
Click Test Login to attempt a real sign-in
-
Click Test Forget Password to attempt a password reset
-
Review the results in the box above the buttons. A successful test ends with "Succeed..."
-
-
Sign in through the emulator using a real account from your website.
-
Confirm the member appears in your app's member list.
Pro tips
-
Members do not need to update the app. Your change takes effect immediately, including for members who already have it installed.
-
Test with a spare account rather than your own. Test Login performs a genuine sign-in against your live website.
-
Custom SSO disables Custom Registration fields. Since your website owns member accounts, collect any additional profile information on your website's sign-up form instead.
-
If all your members share an email domain, set a Default Domain on the Settings tab so members only enter the part before the @.
-
While working in the Control Panel, the emulator displays a live preview of the screen you are editing. Changes appear in the emulator immediately but are not visible to members until you save them.
Troubleshooting tips
-
If you do not see the Custom SSO option, confirm Username and Password Sign In is enabled. If it is still missing, your plan does not include this feature.
-
If SSO Testing shows "SSO Not Available," enter both the Login API and the Access Token Validator API, then click Save.
-
If a test fails, copy the text from the results box and send it to your web team along with the Information for your web team section below.
-
If members can sign in but their names are blank, your website is not returning the name fields. Your web team can add them.
-
If members are repeatedly asked to sign in again, your website is rejecting sign-ins that should still be valid. This is a website-side fix.
-
If sign-in worked and then stopped, check with your web team first. A change to your website's login system is the most common cause.
Information for your web team
Forward this section to whoever manages your website. Two endpoints are required, and both must be reachable over HTTPS from the public internet.
1. Login API
Receives an OAuth 2.0 password-grant style request by HTTP POST. The body format depends on the Content Type selected in the Control Panel.
application/x-www-form-urlencoded — the only option that sends the Client Secret:
grant_type=password&username=<USERNAME>&password=<PASSWORD>&client_id=<CLIENT_ID>&client_secret=<CLIENT_SECRET>
multipart/form-data — sends the credentials only:
username=<USERNAME>
password=<PASSWORD>
Content Type not selected — sends JSON:
{
"grant_type": "password",
"username": "<USERNAME>",
"password": "<PASSWORD>",
"client_id": "<CLIENT_ID>"
}
On success, return JSON containing an access token:
{
"access_token": "I6daIgMSiUgYX1K2qgQWPi37ztS6",
"token_type": "BearerToken",
"expires_in": "1799",
"issued_at": "<EPOCH TIMESTAMP>"
}
Only access_token is required, and only Bearer tokens are supported. expires_in and issued_at are used together to determine when to re-prompt for sign-in. If either is missing, the token is treated as long-lived and revocation is detected through the profile endpoint instead.
On failure, return HTTP 400 with a standard OAuth 2.0 error body so an incorrect password can be distinguished from an outage:
{ "error": "invalid_grant", "error_description": "The username or password is incorrect." }
2. Access Token Validator API
Receives an HTTP GET. Accept the token both as a header and as a query parameter, because the presentation varies by content type:
Authorization: Bearer <ACCESS_TOKEN>
?access_token=<ACCESS_TOKEN>
Return the member's profile as JSON:
{
"user_name": "jsmith",
"email": "jsmith@example.com",
"first_name": "Jordan",
"last_name": "Smith",
"display_name": "Jordan Smith",
"profile_pic": "https://example.com/avatars/jsmith.png"
}
user_name is the only required field, and sign-in fails without it. If email is omitted, the username entered at sign-in is used. firstname and lastname are accepted as alternatives to first_name and last_name. Return a non-200 status for invalid or expired tokens. This endpoint is also polled to detect revocation, and a failure re-prompts the member to sign in.
With application/x-www-form-urlencoded or multipart/form-data, requests are routed through a secure proxy and no CORS headers are needed. With Content Type left unselected, requests are made directly from the app and both endpoints must return permissive CORS headers.
Optional endpoints
Reset Password API — receives an HTTP GET with the member's email appended as a query parameter, using & if the URL already has a query string:
https://your-domain.com/reset-password?email=person@example.com
Register Url — opened inside a frame in the app. To create the account and sign the member in directly, post a message back once registration completes:
<script>
function afterRegister(username, access_token) {
window.parent.postMessage(JSON.stringify({
status: "success",
user: { username: username, access_token: access_token }
}), "*");
}
</script>
Send status: "success" to close the page and sign the member in. Send status: "close" to dismiss without signing in.
Access from plugins
The access token is exposed to plugins through the platform's authentication API as an SSO object, so plugins and the Webview feature can call your other APIs as the signed-in member.
A note on security
Passwords members enter in the app are passed straight to your website and are never stored by the app. Your Client Secret is stored with your app's settings and is only sent to the Login API address you entered, so make sure that address is one you control and that it begins with https://.
Related articles
How to configure SAML Single Sign-On (SSO) — use this instead if your members sign in through a company system such as Microsoft Entra ID, Okta, or Google Workspace
How to set up an OAuth 2 sign-in integration — use this instead to add a "Sign in with…" button for another service alongside your existing sign-in options