All products
Create accountSign in

Developers

Sign in with NullDaily

NullDaily accounts are an OAuth 2.1 authorization server and an OpenID Connect provider. Any standard OIDC client library works. Read the discovery document and you are most of the way there.

Third-party app registration is not open yet. NullDaily products use it today; if you want to build on it, write to [email protected]. Self-hosted NullDaily products can register themselves (see below).

Endpoints

The issuer below is where the account service runs. Always read the endpoints from discovery rather than hard-coding them.

Discoveryhttps://nulldaily.com/.well-known/openid-configuration
Authorizehttps://nulldaily.com/oauth/authorize
Tokenhttps://nulldaily.com/oauth/token
User infohttps://nulldaily.com/oauth/userinfo
Keys (JWKS)https://nulldaily.com/.well-known/jwks.json
Revokehttps://nulldaily.com/oauth/revoke (RFC 7009)
Introspecthttps://nulldaily.com/oauth/introspect (RFC 7662, confidential clients)
Registerhttps://nulldaily.com/oauth/register (RFC 7591, self-hosted instances)
Sign outhttps://nulldaily.com/oauth/logout (RP-initiated logout)

The flow

  1. Make a random code_verifier and its S256 code_challenge. PKCE is required for every client, and plain is refused.
  2. Send the person to the authorize endpoint. They sign in if needed and see your consent screen once.
  3. You get code, your state and iss back on your registered redirect URI. Check both.
  4. Exchange the code at the token endpoint within five minutes. Codes work once; a replayed code revokes what it minted.
GET https://nulldaily.com/oauth/authorize
  ?response_type=code
  &client_id=YOUR_CLIENT_ID
  &redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback
  &scope=openid%20profile%20email%20offline_access
  &state=RANDOM_STATE
  &nonce=RANDOM_NONCE
  &code_challenge=BASE64URL_SHA256_OF_VERIFIER
  &code_challenge_method=S256
curl -u "$CLIENT_ID:$CLIENT_SECRET" https://nulldaily.com/oauth/token \
  -d grant_type=authorization_code \
  -d code="$CODE" \
  -d redirect_uri=https://app.example.com/callback \
  -d code_verifier="$VERIFIER"

{
  "access_token": "nda_...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "openid profile email offline_access",
  "refresh_token": "ndr_...",
  "id_token": "eyJ..."
}

ID tokens are RS256 JWTs signed with a key from the JWKS. They carry sub, auth_time, nonce, amr, sid and the claims your scopes allow. Access tokens are opaque: call user info or introspection, do not parse them.

Scopes

ScopeWhat the person seesWhat you get
openidSign you in with your NullDaily accountsub, a stable account ID
profileSee your name and profile picturename, picture, updated_at
emailSee your email addressemail, email_verified
rolesSee your roles for this approles in the ID token and user info: only roles NullDaily lets this app see (first-party apps)
licenses:readSee your NullDaily licenseslicenses in user info: product, plan, status, major version
offline_accessStay connected while you are awayA refresh token

Refresh tokens

Refresh tokens rotate on every use: each refresh returns a new one and retires the old one. If a retired token is ever used again, we assume it leaked and revoke the whole chain, so store the newest token and use each one once. Removing your app from Connected apps revokes everything at once.

Self-hosted instances

Self-hosted products (a Stavo server, a Servio panel) each run on their own domain, so each install registers itself as its own client with dynamic client registration. These clients are not verified, and the consent screen shows the address they will send people back to, so nobody can pose as a NullDaily product.

curl https://nulldaily.com/oauth/register -H 'content-type: application/json' -d '{
  "client_name": "Stavo on cloud.example.org",
  "redirect_uris": ["https://cloud.example.org/auth/nulldaily/callback"],
  "token_endpoint_auth_method": "client_secret_basic",
  "scope": "openid profile email offline_access licenses:read"
}'

Rules for redirect URIs

  • Exact match against what is registered. Use https, or http on a loopback address (127.0.0.1 or [::1]) for local tools; loopback may use any port.
  • Native apps may use a reverse-domain scheme, such as com.example.app:/callback.
  • A redirect URI we do not recognize stops at our own error page; we never forward people to it.

The verified badge

NullDaily staff mark an app as verified after checking who runs it and that its redirect URIs belong to them. The badge says who is asking. It does not mean we vouch for everything the app does with what you share.