Developer documentation

Add one secure NeonLogin account to your application.

NeonLogin uses a browser redirect, a consent screen, and a signed callback. Register your application to receive its own signing secret and allowlist its callback domains.

Request SSO access

  1. Create or sign in to your NeonLogin account.
  2. Open the Developer Portal and register your app name, type, primary domain, and any callback subdomains.
  3. Copy the one-time app secret and store it only on your server.

Your registered domain is used for callback allowlisting and to select the correct app secret.

Continue to SSO access

What your app receives

After the user approves access, NeonLogin redirects to your callback with:

state     Your original anti-forgery value
neon_id   Stable NeonLogin user ID
username  NeonLogin username
email     User email address
ts        Unix timestamp
sig       HMAC-SHA256 signature
flow      login or link
scope     Requested scope

Only request and retain user data your application actually needs.

Signed callback integration

1. Send the user to NeonLogin

Create a cryptographically random state, save it in the user's server-side session, and redirect the browser:

https://teammidnite.tv/NeonLogin/?return_to=https%3A%2F%2Fexample.com%2Fauth%2Fneonlogin%2Fcallback&state=RANDOM_VALUE&flow=login&scope=basic

2. Verify the callback on your server

Reject the callback unless state exactly matches the unused value in the user's session, the timestamp is recent, and the signature matches.

<?php
$payload = implode('|', [
    $_GET['neon_id'],
    $_GET['username'],
    $_GET['email'],
    $_GET['ts'],
    $_GET['state'],
]);

$expected = hash_hmac('sha256', $payload, getenv('NEONLOGIN_APP_SECRET'));
if (!hash_equals($expected, (string) $_GET['sig'])) {
    http_response_code(401);
    exit('Invalid NeonLogin signature');
}

if (abs(time() - (int) $_GET['ts']) > 300) {
    http_response_code(401);
    exit('Expired NeonLogin callback');
}

3. Create your local session

Look up the account by neon_id, link or provision it according to your application's policy, rotate the local session ID, and mark the saved state value as consumed.

Production security checklist

  • Keep the app secret server-side; never put it in JavaScript, mobile binaries, logs, or source control.
  • Require HTTPS for production callback URLs.
  • Use a new, unpredictable state value for every attempt and consume it once.
  • Use hash_equals for constant-time signature comparison.
  • Reject stale timestamps and callbacks with missing fields.
  • Rotate a secret immediately if it may have been exposed.

Scopes and flows

flow=login signs a user into your app. Use flow=link when attaching NeonLogin to an account that is already authenticated.

scope=basic is the standard signed-callback profile. The callback currently includes the stable user ID, username, and email shown on the consent screen.

Need API keys or webhooks? Create them under the registered app in the Developer Portal. Available API scopes include users:read_basic, users:read_email, and accounts:read.