Contents
PlatformStableVersion 2026-10

OAuth & OpenID Connect API

Authorization server for apps and AI assistants that act on behalf of a Nucleo user.

Nucleo Core is the identity provider of the platform: every person signs in once at auth.nucleoplatform.com and every module (Brain, Catalog, Commerce, Intelligence) trusts the access tokens it issues.

External clients — MCP connectors in Claude or ChatGPT, partner tools, local scripts — use the standard OAuth 2.0 authorization code flow with PKCE (S256). They can discover the endpoints from the metadata documents (RFC 8414 / OpenID Connect Discovery) and register themselves with Dynamic Client Registration (RFC 7591), without asking Nucleo for credentials. With the scope openid the code exchange also returns a signed ID token (OpenID Connect Core).

Every token belongs to a person: there is no server-to-server (client_credentials) grant. A partner integration acts on behalf of the user who connected it.

Tokens issued to self-registered clients always carry the scope nucleo.ai_tools: they are valid for the Nucleo AI tools (the MCP connector and the modules' /api/v1/ai-tools), for userinfo and for revoking themselves — every other Nucleo API answers 403 insufficient_scope. The user always sees a consent screen before such a client receives a token.

Authentication

  • nucleoOAuthOAuth 2.0 · authorizationCode

    Authorization code with PKCE (S256). Register your client at /oauth/register (or ask Nucleo for a pre-registered one). Self-registered clients' tokens always carry nucleo.ai_tools.

    authorize: https://auth.nucleoplatform.com/oauth/authorize
    token: https://auth.nucleoplatform.com/oauth/token
    scopes: openid, profile, email, offline_access, nucleo.ai_tools
  • bearerTokenHTTP bearer (JWT)

    Authorization: Bearer <access_token> obtained from /oauth/token.

Base URL
https://auth.nucleoplatform.comProduction issuer (`iss`). All endpoints below are relative to it.
Who calls it
AI assistants, Partners
Endpoints
10
OpenAPI 3.1 specification
oauth.yaml

Discovery

Machine-readable metadata. Start here: a compliant client needs nothing else than the issuer URL https://auth.nucleoplatform.com.

get/.well-known/openid-configuration

Get OpenID Connect discovery document

OpenID Connect Discovery 1.0 document. Public, cacheable, served with Access-Control-Allow-Origin: * so browser-based clients can read it.

Notes on the current implementation:

  • response_types_supported is only code; implicit and hybrid flows are not available.
  • grant_types_supported is authorization_code and refresh_token: there is no client_credentials grant.
  • code_challenge_methods_supported is only S256.
  • ID tokens are signed with RS256 and returned by the code exchange when the scope includes openid; claims_supported lists every claim they can carry. The request, request_uri and claims authorization parameters are not supported.
  • For everything beyond the ID token claims (companies, module access) call userinfo with the access token.
GET https://auth.nucleoplatform.com/.well-known/openid-configuration
Authentication: None — public endpoint

Responses

  • 200Discovery document.
    Headers
    • Access-Control-Allow-Origin
    • issuerstring (uri)
    • authorization_endpointstring (uri)
    • token_endpointstring (uri)
    • userinfo_endpointstring (uri)
    • jwks_uristring (uri)
    • registration_endpointstring (uri)
    • scopes_supportedarray of string
    • response_types_supportedarray of string
    • grant_types_supportedarray of string
    • code_challenge_methods_supportedarray of string
    • token_endpoint_auth_methods_supportedarray of string
    • response_modes_supportedarray of string
    • service_documentationstring (uri)
    • subject_types_supportedarray of string
    • id_token_signing_alg_values_supportedarray of string
      One ofRS256
    • claims_supportedarray of string
    • request_parameter_supportedboolean
      One offalse
    • request_uri_parameter_supportedboolean
      One offalse
    • claims_parameter_supportedboolean
      One offalse
Request
curl -X GET https://auth.nucleoplatform.com/.well-known/openid-configuration \
  -H 'Accept: application/json'
Response
{
  "issuer": "https://auth.nucleoplatform.com",
  "authorization_endpoint": "https://auth.nucleoplatform.com/oauth/authorize",
  "token_endpoint": "https://auth.nucleoplatform.com/oauth/token",
  "userinfo_endpoint": "https://auth.nucleoplatform.com/api/oauth/userinfo",
  "jwks_uri": "https://auth.nucleoplatform.com/.well-known/jwks.json",
  "registration_endpoint": "https://auth.nucleoplatform.com/oauth/register",
  "scopes_supported": [
    "openid",
    "profile",
    "email",
    "offline_access",
    "nucleo.ai_tools"
  ],
  "response_types_supported": [
    "code"
  ],
  "response_modes_supported": [
    "query"
  ],
  "grant_types_supported": [
    "authorization_code",
    "refresh_token"
  ],
  "code_challenge_methods_supported": [
    "S256"
  ],
  "token_endpoint_auth_methods_supported": [
    "client_secret_post",
    "client_secret_basic",
    "none"
  ],
  "service_documentation": "https://nucleoplatform.com/developers",
  "subject_types_supported": [
    "public"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ],
  "claims_supported": [
    "iss",
    "sub",
    "aud",
    "azp",
    "exp",
    "iat",
    "jti",
    "auth_time",
    "nonce",
    "email",
    "email_verified",
    "name",
    "picture",
    "locale"
  ],
  "request_parameter_supported": false,
  "request_uri_parameter_supported": false,
  "claims_parameter_supported": false
}
get/.well-known/oauth-authorization-server

Get OAuth authorization server metadata

OAuth 2.0 Authorization Server Metadata (RFC 8414). This is the document MCP clients reach after reading the protected-resource metadata of the Nucleo MCP server (https://mcp.nucleoplatform.com/.well-known/oauth-protected-resource); from here they take registration_endpoint to register themselves. Public, with Access-Control-Allow-Origin: *.

GET https://auth.nucleoplatform.com/.well-known/oauth-authorization-server
Authentication: None — public endpoint

Responses

  • 200Authorization server metadata.
    Headers
    • Access-Control-Allow-Origin
    • issuerstring (uri)
    • authorization_endpointstring (uri)
    • token_endpointstring (uri)
    • registration_endpointstring (uri)
    • jwks_uristring (uri)
    • userinfo_endpointstring (uri)
    • scopes_supportedarray of string
    • response_types_supportedarray of string
    • response_modes_supportedarray of string
    • grant_types_supportedarray of string
    • code_challenge_methods_supportedarray of string
    • token_endpoint_auth_methods_supportedarray of string
    • service_documentationstring (uri)
Request
curl -X GET https://auth.nucleoplatform.com/.well-known/oauth-authorization-server \
  -H 'Accept: application/json'
Response
{
  "issuer": "https://auth.nucleoplatform.com",
  "authorization_endpoint": "https://auth.nucleoplatform.com/oauth/authorize",
  "token_endpoint": "https://auth.nucleoplatform.com/oauth/token",
  "registration_endpoint": "https://auth.nucleoplatform.com/oauth/register",
  "jwks_uri": "https://auth.nucleoplatform.com/.well-known/jwks.json",
  "userinfo_endpoint": "https://auth.nucleoplatform.com/api/oauth/userinfo",
  "scopes_supported": [
    "openid",
    "profile",
    "email",
    "offline_access",
    "nucleo.ai_tools"
  ],
  "response_types_supported": [
    "code"
  ],
  "response_modes_supported": [
    "query"
  ],
  "grant_types_supported": [
    "authorization_code",
    "refresh_token"
  ],
  "code_challenge_methods_supported": [
    "S256"
  ],
  "token_endpoint_auth_methods_supported": [
    "client_secret_post",
    "client_secret_basic",
    "none"
  ],
  "service_documentation": "https://nucleoplatform.com/developers"
}
get/.well-known/jwks.json

Get the token signing keys

JSON Web Key Set with the RSA public key that signs Nucleo access tokens and ID tokens (RS256). The kid is the base64url SHA-256 of the public key, so it changes only when the key is rotated; ID tokens carry it in their header. Use it to verify a token locally (signature, exp, aud = your client_id). Public, with Access-Control-Allow-Origin: *. Returns {"keys": []} only if the server has no key configured.

GET https://auth.nucleoplatform.com/.well-known/jwks.json
Authentication: None — public endpoint

Responses

  • 200Key set.
    • keysarray of objectrequired
      Attributes of each item
      • ktystring
        One ofRSA
      • usestring
        One ofsig
      • algstring
        One ofRS256
      • kidstring
      • nstring

        Modulus

      • estring

        Exponent

Request
curl -X GET https://auth.nucleoplatform.com/.well-known/jwks.json \
  -H 'Accept: application/json'
Response
{
  "keys": [
    {
      "kty": "RSA",
      "use": "sig",
      "alg": "RS256",
      "kid": "3rL1x0dXq6m0yBqH2l7xZr9n0bq8f4k1s2vJt8o5pWc",
      "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
      "e": "AQAB"
    }
  ]
}

Client registration

Dynamic Client Registration (RFC 7591). Anonymous by design (as required by the MCP authorization spec): the guard rails are on the metadata — https (or loopback) redirect URIs, authorization code grant only, a fixed set of scopes. Self-registered clients are always treated as third-party: the user approves them on a consent screen.

post/oauth/register

Register an OAuth client dynamically

RFC 7591 Dynamic Client Registration. No authentication: any client can register, the user's consent is what protects the account.

Rules applied to the metadata:

  • redirect_uris is required, 1 to 5 absolute URIs, https only — http is accepted only for loopback hosts (localhost, 127.0.0.1, [::1], RFC 8252). No fragment, no *. Duplicates are removed.
  • grant_types defaults to ["authorization_code"]; only authorization_code and refresh_token are accepted and authorization_code must be present. refresh_token is always added.
  • response_types may only contain code.
  • token_endpoint_auth_method defaults to none (public client + PKCE, as MCP connectors work). client_secret_post or client_secret_basic make it a confidential client and the response includes a client_secret that never expires — it is shown only once.
  • scope is filtered (not rejected) to the supported set; when nothing valid is requested you get all of them. nucleo.ai_tools is always added.
  • client_name is stripped of HTML and cut to 120 characters (default: the host of the first redirect URI); client_uri is cut to 250 characters. Other RFC 7591 fields are ignored.

Every call creates a new client (not idempotent). Clients registered here are third-party: the user always sees the consent screen, and their tokens are limited to the AI tools (nucleo.ai_tools).

Rate limit: 10 requests per minute per IP address.

POST https://auth.nucleoplatform.com/oauth/register
Authentication: None — public endpoint
Rate limit: 10 requests per 1m, per IP

Request bodyapplication/json

  • redirect_urisarray of string (uri)required

    https, or http on loopback only. No fragment, no wildcard.

    min items 1max items 5
  • client_namestring

    Shown on the consent screen. HTML is stripped.

    max length 120
  • client_uristring (uri)
    max length 250
  • grant_typesarray of string
    One ofauthorization_coderefresh_token
    default ["authorization_code"]
  • response_typesarray of string
    One ofcode
    default ["code"]
  • token_endpoint_auth_methodstring
    One ofnoneclient_secret_postclient_secret_basic
    default none
  • scopestring

    Space-separated; filtered to the supported scopes.

    default openid profile email

Responses

  • 201Client created.
    Headers
    • Access-Control-Allow-Origin
    • client_idstringrequired
    • client_id_issued_atintegerrequired

      Unix timestamp.

    • client_secretstring

      Confidential clients only. Shown once.

    • client_secret_expires_atinteger

      0 = never expires.

      One of0
    • client_namestring
    • redirect_urisarray of string (uri)required
    • grant_typesarray of stringrequired
    • response_typesarray of stringrequired
    • token_endpoint_auth_methodstringrequired
    • scopestringrequired
  • 400Invalid client metadata (RFC 7591 §3.2.2 error response).
    Headers
    • Access-Control-Allow-Origin
    • errorstringrequired
      One ofinvalid_redirect_uriinvalid_client_metadata
    • error_descriptionstring
  • 429Rate limit exceeded.
    Headers
    • Retry-After
    • X-RateLimit-Limit
    • X-RateLimit-Remaining
    • messagestring
Request
curl -X POST https://auth.nucleoplatform.com/oauth/register \
  -H 'Content-Type: application/json' \
  -d '{
  "client_name": "Acme Assistant",
  "redirect_uris": [
    "https://assistant.acme.example/oauth/callback"
  ],
  "grant_types": [
    "authorization_code",
    "refresh_token"
  ],
  "response_types": [
    "code"
  ],
  "token_endpoint_auth_method": "none",
  "scope": "openid profile email offline_access"
}'
Response
{
  "client_id": "9d3f2b1c-6a4e-4f7b-9c2d-1e8a7b6c5d4f",
  "client_id_issued_at": 1791100800,
  "client_name": "Acme Assistant",
  "redirect_uris": [
    "https://assistant.acme.example/oauth/callback"
  ],
  "grant_types": [
    "authorization_code",
    "refresh_token"
  ],
  "response_types": [
    "code"
  ],
  "token_endpoint_auth_method": "none",
  "scope": "openid profile email offline_access nucleo.ai_tools"
}
options/oauth/register

CORS preflight for client registration

Lets browser-based clients register themselves. Always answers 204 with permissive CORS headers.

OPTIONS https://auth.nucleoplatform.com/oauth/register
Authentication: None — public endpoint

Responses

  • 204Preflight accepted.
    Headers
    • Access-Control-Allow-Origin
    • Access-Control-Allow-Methods
    • Access-Control-Allow-Headers
Request
curl -X OPTIONS https://auth.nucleoplatform.com/oauth/register
Response
HTTP 204 — Preflight accepted.

Authorization

Browser-facing part of the authorization code flow: sign-in, consent, redirect back with a code.

get/oauth/authorize

Start the authorization code flow

Open this URL in the user's browser (not in an embedded web view). Nucleo:

  1. shows the Nucleo sign-in page (/login) if the user has no session;
  2. shows a consent screen naming your client and the requested scopes (self-registered clients always see it; Nucleo's own apps skip it);
  3. redirects to redirect_uri with code and state — or with error=access_denied if the user clicks Cancel.

PKCE is required for public clients (token_endpoint_auth_method: none) and only S256 is advertised. Authorization codes are single-use and short-lived (10 minutes): exchange them immediately at /oauth/token.

redirect_uri must match exactly one of the URIs registered for the client. Errors that make the redirect unsafe (unknown client, unregistered redirect_uri) are shown to the user instead of being redirected.

GET https://auth.nucleoplatform.com/oauth/authorize
Authentication: None — public endpoint

Query parameters

  • response_typestringrequired
    One ofcode
    Example: code
  • client_idstringrequired
    Example: 9d3f2b1c-6a4e-4f7b-9c2d-1e8a7b6c5d4f
  • redirect_uristring (uri)required
    Example: https://assistant.acme.example/oauth/callback
  • scopestring

    Space-separated. Unknown scopes are rejected with invalid_scope.

    Example: openid profile email offline_access
  • statestring

    Opaque value returned unchanged; strongly recommended against CSRF.

    Example: af0ifjsldkj
  • code_challengestring

    BASE64URL(SHA256(code_verifier)). Required for public clients.

    min length 43max length 128
    Example: E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  • code_challenge_methodstring
    One ofS256
    Example: S256
  • noncestring

    OpenID Connect nonce (up to 255 characters). Returned unchanged in the nonce claim of the ID token; check it there to bind the ID token to your sign-in request.

    max length 255
    Example: n-0S6_WzA2Mj
  • promptstring

    login forces a new sign-in, consent forces the consent screen, none fails with login_required / consent_required instead of showing UI.

    One ofnoneloginconsent
    Example: none

Responses

  • 200Sign-in page or consent screen (HTML).

    string

  • 302Redirect. Either to /login (no session), or back to the client: https://assistant.acme.example/oauth/callback?code=def502…&state=af0ifjsldkj on approval, …?error=access_denied&error_description=…&state=af0ifjsldkj on denial or invalid request.
    Headers
    • Location
Request
curl -X GET 'https://auth.nucleoplatform.com/oauth/authorize?response_type=code&client_id=9d3f2b1c-6a4e-4f7b-9c2d-1e8a7b6c5d4f&redirect_uri=https%3A%2F%2Fassistant.acme.example%2Foauth%2Fcallback&scope=openid%20profile%20email%20offline_access&state=af0ifjsldkj&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256&nonce=n-0S6_WzA2Mj&prompt=none' \
  -H 'Accept: text/html'
Response
string

Tokens

Token endpoint and token revocation. Access tokens and ID tokens are RS256 JWTs signed with the key published in the JWKS; access tokens last 8 hours, ID tokens 1 hour. Refresh tokens last 30 days.

post/oauth/token

Exchange a code or refresh a token

Standard OAuth 2.0 token endpoint (application/x-www-form-urlencoded or JSON).

  • authorization_code: send code, redirect_uri (same as in the authorize request), client_id, and code_verifier (PKCE). Confidential clients also authenticate with client_secret (body) or HTTP Basic.
  • refresh_token: send refresh_token and client_id (plus secret for confidential clients). A new refresh token is returned and the previous one is revoked — always store the latest one.
  • There is no client_credentials grant: every token acts for a person.

ID token. When the granted scope includes openid, the authorization_code exchange also returns id_token: an RS256 JWT signed with the JWKS key (kid in the header), valid for 1 hour. Claims: iss (https://auth.nucleoplatform.com), sub (same as userinfo), aud and azp (your client_id), iat, exp, jti, auth_time (when the person signed in to Nucleo), and nonce if you sent one to /oauth/authorize. With email: email, email_verified. With profile: name, locale, and picture when the person has an avatar. The refresh exchange does not return a new ID token: keep the one from sign-in. An ID token is not an access token — sending it as Bearer gets 401.

Lifetimes: access token 8 hours (expires_in: 28800), refresh token 30 days. For self-registered clients the granted scope always includes nucleo.ai_tools.

Rate limit: 60 requests per minute per IP address.

POST https://auth.nucleoplatform.com/oauth/token
Authentication: None — public endpoint
Rate limit: 60 requests per 1m, per IP

Request bodyapplication/x-www-form-urlencoded, application/json

  • grant_typestringrequired
    One ofauthorization_coderefresh_token
  • client_idstringrequired
  • client_secretstring

    Confidential clients using client_secret_post.

  • codestring

    authorization_code only.

  • redirect_uristring (uri)

    authorization_code only; must equal the one used at /oauth/authorize.

  • code_verifierstring

    PKCE verifier; required when a code_challenge was sent.

    min length 43max length 128
  • refresh_tokenstring

    refresh_token only.

  • scopestring

    Optional; on refresh it may only narrow the original scope.

Responses

  • 200Tokens issued.
    • token_typestringrequired
      One ofBearer
    • expires_inintegerrequired
      Example: 28800
    • access_tokenstringrequired

      RS256 JWT.

    • refresh_tokenstring
    • id_tokenstring

      RS256 JWT (OpenID Connect ID token). Only on the authorization_code exchange when the scope includes openid. Claims are described in IdTokenClaims.

  • 400Invalid request, grant or scope.
    • errorstringrequired
      One ofinvalid_requestinvalid_clientinvalid_grantunauthorized_clientunsupported_grant_typeinvalid_scopeaccess_denied
    • error_descriptionstring
    • hintstring
  • 401Client authentication failed.
    • errorstringrequired
      One ofinvalid_requestinvalid_clientinvalid_grantunauthorized_clientunsupported_grant_typeinvalid_scopeaccess_denied
    • error_descriptionstring
    • hintstring
  • 429Rate limit exceeded.
    Headers
    • Retry-After
    • X-RateLimit-Limit
    • X-RateLimit-Remaining
    • messagestring
Request
curl -X POST https://auth.nucleoplatform.com/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode grant_type=authorization_code \
  --data-urlencode client_id=9d3f2b1c-6a4e-4f7b-9c2d-1e8a7b6c5d4f \
  --data-urlencode redirect_uri=https://assistant.acme.example/oauth/callback \
  --data-urlencode code=def50200a1b2c3 \
  --data-urlencode code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
Response
{
  "token_type": "Bearer",
  "expires_in": 28800,
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiI5ZDNmMmIxYy02YTRlIiwic3ViIjoiNDIiLCJzY29wZXMiOlsib3BlbmlkIiwibnVjbGVvLmFpX3Rvb2xzIl19.signature",
  "refresh_token": "def50200f9e8d7c6b5a4",
  "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjNyTDF4MGRYcTZtMHlCcUgybDd4WnI5bjBicThmNGsxczJ2SnQ4bzVwV2MifQ.eyJpc3MiOiJodHRwczovL2F1dGgubnVjbGVvcGxhdGZvcm0uY29tIiwic3ViIjoiNDIiLCJhdWQiOiI5ZDNmMmIxYy02YTRlLTRmN2ItOWMyZC0xZThhN2I2YzVkNGYiLCJhenAiOiI5ZDNmMmIxYy02YTRlLTRmN2ItOWMyZC0xZThhN2I2YzVkNGYiLCJpYXQiOjE3OTExMDA4MDAsImV4cCI6MTc5MTEwNDQwMCwianRpIjoiMGI2ZjFkMmUtNGMzYS00ZThiLTlmN2QtMmExYzNlNWI3ZDlmIiwiYXV0aF90aW1lIjoxNzkxMTAwNzUwLCJub25jZSI6Im4tMFM2X1d6QTJNaiIsImVtYWlsIjoiZ2l1bGlhLnJvc3NpQGFjbWUuZXhhbXBsZSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlfQ.signature"
}
post/api/auth/revoke

Revoke the current access token

Revokes the access token sent in Authorization and every refresh token issued with it (sign-out / disconnect). Idempotent from the client's point of view: a revoked token then answers 401, on the MCP connector immediately as well. Available to self-registered clients' tokens. The confirmation message is currently returned in Italian.

POST https://auth.nucleoplatform.com/api/auth/revoke
Authentication: OAuth 2.0 access token or Bearer token

Responses

  • 200Token revoked.
    • messagestring
  • 401Missing, expired or revoked access token.
    • messagestring
Request
curl -X POST https://auth.nucleoplatform.com/api/auth/revoke \
  -H "Authorization: Bearer $NUCLEO_ACCESS_TOKEN" \
  -H 'Accept: application/json'
Response
{
  "message": "Token revocato."
}

Identity

The signed-in person, their companies and module access (OpenID Connect UserInfo).

get/api/oauth/userinfo

Get the signed-in user

OpenID Connect UserInfo. Returns who the token belongs to, the companies (organizations) they belong to and the Nucleo modules they can use, with their role.

  • sub is the stable user id: key your local records on it, never on email.
  • orgs[].id is the company id to pass as X-Nucleo-Company to the AI tools.
  • apps[] lists module access per company (org_id: null = global access for Nucleo staff). During the module migration legacy slugs may appear next to brain, catalog, commerce, intelligence: ignore slugs you do not know.
  • disabled_sections lists, per company id, the sub-modules switched off for that company.
  • scope is the effective scope of the token: nucleo.ai_tools marks a token of a self-registered (AI) client.
  • impersonator is non-null only when Nucleo staff is acting as the user.

Available to self-registered clients' tokens.

GET https://auth.nucleoplatform.com/api/oauth/userinfo
Authentication: OAuth 2.0 access token or Bearer token

Responses

  • 200The user.
    • substringrequired

      Stable user id.

    • namestring
    • emailstring (email)required
    • email_verifiedboolean
    • avatar_urlstring (uri) | null
    • languagestring
      Example: en
    • themestring
      One oflightdark
    • is_internalboolean

      True only for Nucleo staff with access to every company.

    • is_ownerboolean
    • org_idsarray of integer
    • orgsarray of object
      Attributes of each item
      • idinteger
      • slugstring
      • namestring
      • logo_urlstring (uri) | null
      • rolestring
        Example: admin
    • app_accessarray of string

      Module slugs the user can open.

    • appsarray of object
      Attributes of each item
      • slugstring
        Example: catalog
      • rolestring
        Example: editor
      • org_idinteger | null
    • disabled_sectionsobject

      Company id → list of disabled sub-module slugs.

    • client_idstring | null
    • scopestring

      Effective scopes of the token

    • impersonatorobject | null
      Child attributes
      • idinteger
      • namestring
      • emailstring (email)
      • expires_atstring (date-time)
  • 401Missing, expired or revoked access token.
    • messagestring
Request
curl -X GET https://auth.nucleoplatform.com/api/oauth/userinfo \
  -H "Authorization: Bearer $NUCLEO_ACCESS_TOKEN" \
  -H 'Accept: application/json'
Response
{
  "sub": "42",
  "name": "Giulia Rossi",
  "email": "giulia.rossi@acme.example",
  "email_verified": true,
  "avatar_url": "https://cdn.acme.example/avatars/42.png",
  "language": "it",
  "theme": "light",
  "is_internal": false,
  "is_owner": false,
  "org_ids": [
    7
  ],
  "orgs": [
    {
      "id": 7,
      "slug": "acme",
      "name": "Acme Apparel",
      "logo_url": "https://cdn.acme.example/logo.png",
      "role": "admin"
    }
  ],
  "app_access": [
    "catalog",
    "commerce"
  ],
  "apps": [
    {
      "slug": "catalog",
      "role": "editor",
      "org_id": 7
    },
    {
      "slug": "commerce",
      "role": "viewer",
      "org_id": 7
    }
  ],
  "disabled_sections": {
    "7": [
      "pos"
    ]
  },
  "client_id": "9d3f2b1c-6a4e-4f7b-9c2d-1e8a7b6c5d4f",
  "scope": "openid profile email offline_access nucleo.ai_tools",
  "impersonator": null
}

Organization branding

Public, unauthenticated branding of a company (name, logos, favicons), used by Nucleo's public pages (for example booking pages) that have no signed-in user but must carry the company's brand.

get/api/public/organizations/{slug}/branding

Get a company's public branding

Name, logos (light and dark) and favicons of a company, by slug. Only data that is public by nature (logo URLs point to public storage) — never members, domains or billing. Cached for 5 minutes on the server and sent with Cache-Control: public, max-age=300.

Rate limit: 120 requests per minute per IP address.

GET https://auth.nucleoplatform.com/api/public/organizations/{slug}/branding
Authentication: None — public endpoint
Rate limit: 120 requests per 1m, per IP

Path parameters

  • slugstringrequired

    Company slug, lowercase. Must match ^[a-z0-9][a-z0-9-]{0,63}$, otherwise 404.

    max length 64pattern ^[a-z0-9][a-z0-9-]{0,63}$
    Example: acme

Responses

  • 200Branding.
    Headers
    • Cache-Control
    • dataOrganizationBrandingrequired
      Child attributes
      • slugstring
      • namestring
      • logo_urlstring (uri) | null
      • logo_dark_urlstring (uri) | null
      • favicon_urlstring (uri) | null
      • favicon_light_urlstring (uri) | null
  • 404Unknown or invalid slug.
    • messagestring
  • 429Rate limit exceeded.
    Headers
    • Retry-After
    • X-RateLimit-Limit
    • X-RateLimit-Remaining
    • messagestring
Request
curl -X GET https://auth.nucleoplatform.com/api/public/organizations/acme/branding \
  -H 'Accept: application/json'
Response
{
  "data": {
    "slug": "acme",
    "name": "Acme Apparel",
    "logo_url": "https://cdn.acme.example/brand/logo.svg",
    "logo_dark_url": "https://cdn.acme.example/brand/logo-dark.svg",
    "favicon_url": "https://cdn.acme.example/brand/favicon.png",
    "favicon_light_url": null
  }
}