API reference
OAuth
Issue, introspect and revoke access tokens, plus discovery metadata.
Issue an access token
api.niucore.com/api /oauth /tokenNo bearer
Exchanges client_id and client_secret for a short-lived access token. It is the only supported grant: client_credentials (RFC 6749 §4.4).
Credentials go in Authorization: Basic (client_secret_basic) or in the body (client_secret_post), but never both at once: sending them through both channels returns invalid_request, because it leaves ambiguous which one wins.
The scope parameter is optional and only narrows: asking for a scope the credential does not hold returns invalid_scope. Without scope, the token is issued with every scope the credential currently holds.
There is no refresh token
Client Credentials does not use one: when the access token expires, you request another with the same credentials. Keep the token in memory and refresh it slightly before expires_in.
Request body
grant_typestringrequiredThe only supported grant. Any other value returns unsupported_grant_type.
client_credentials
client_idstringPublic identifier of the credential (nc_…). Required unless you use Authorization: Basic.
client_secretstringCredential secret (ncs_…). Required unless you use Authorization: Basic.
scopestringSpace-separated subset of scopes. Omitting it requests every scope currently in force.
Returns
access_tokenstringSigned JWT. Used as Bearer.
token_typestringAlways Bearer.
expires_inintegerLifetime in seconds. Never exceeds the credential's remaining lifetime.
scopestringScopes actually granted, space separated. It may be narrower than requested if the user's role changed.
Errors
- 400
unsupported_grant_typegrant_typeis notclient_credentials. - 400
invalid_scopeA nonexistent scope was requested, or one the credential no longer holds. - 400
invalid_requestCredentials were sent through Basic and the body at the same time. - 401
invalid_clientNonexistent credential, wrong secret, revoked or expired credential, inactive user or disabled company. One single error for every case, by design. - 413
invalid_requestThe form exceeds 8 KB. - 429
rate_limit_exceededThe per-IP or per-client_idbucket was exceeded.
curl -sS -X POST 'https://api.niucore.com/api/oauth/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-u "$NIUCORE_CLIENT_ID:$NIUCORE_CLIENT_SECRET" \
-d 'grant_type=client_credentials' \
-d 'scope=chat:read chat:write'{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "chat:read chat:write"
}Introspect a token
api.niucore.com/api /oauth /introspectNo bearer
Returns the state and claims of an access token (RFC 7662). It authenticates the credential, not the token: you introspect your own.
Note
It answers 200 whenever the client authenticates. An expired, revoked, unreadable, or foreign token returns {"active": false} — without telling which, so the endpoint is not an oracle.
Request body
tokenstringrequiredThe access token to introspect.
Returns
activebooleanfalse when the token is unusable. It is the only guaranteed field.
scopestringToken scopes.
client_idstringIssuing credential.
usernamestringEmail of the owning user.
expintegerExpiry (epoch).
iatintegerIssued at (epoch).
jtistringToken identifier.
company_idintegerCompany of the credential.
Errors
- 401
invalid_clientThe client did not authenticate. It is the only possible error.
curl -sS -X POST 'https://api.niucore.com/api/oauth/introspect' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-u "$NIUCORE_CLIENT_ID:$NIUCORE_CLIENT_SECRET" \
-d "token=$NIUCORE_ACCESS_TOKEN"{
"active": true,
"scope": "chat:read chat:write",
"client_id": "nc_7f3c1a9b8e2d4056",
"username": "integraciones@acme.com",
"token_type": "Bearer",
"exp": 1767225600,
"iat": 1767222000,
"nbf": 1767222000,
"sub": "integraciones@acme.com",
"aud": "niucore-public-api",
"iss": "https://api.niucore.com",
"jti": "0f2f5a52-9c1e-4f7a-9c3e-1c2b3d4e5f60",
"tid": 412,
"company_id": 2149
}Revoke an access token
api.niucore.com/api /oauth /revokeNo bearer
Invalidates the presented access token (RFC 7009). It does not revoke the credential: for that, revoke it from the application.
Note
It always answers 200 — even for an unknown or already expired token — as the RFC requires, and so it cannot be used to learn whether a token exists. Only the owner can revoke its token: one from another credential is silently ignored.
Request body
tokenstringrequiredThe access token to revoke.
Errors
- 401
invalid_clientThe client did not authenticate.
curl -sS -X POST 'https://api.niucore.com/api/oauth/revoke' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-u "$NIUCORE_CLIENT_ID:$NIUCORE_CLIENT_SECRET" \
-d "token=$NIUCORE_ACCESS_TOKEN"HTTP/1.1 200 OK
Cache-Control: no-storeAuthorization server metadata
api.niucore.com/.well-known /oauth-authorization-serverNo bearer
RFC 8414 discovery: endpoints, grants, authentication methods and the scope catalog. A generic OAuth client can configure itself from this alone.
Tip
It is public and cacheable (max-age=3600). No credentials required.
curl -sS 'https://api.niucore.com/.well-known/oauth-authorization-server'{
"issuer": "https://api.niucore.com",
"token_endpoint": "https://api.niucore.com/api/oauth/token",
"introspection_endpoint": "https://api.niucore.com/api/oauth/introspect",
"revocation_endpoint": "https://api.niucore.com/api/oauth/revoke",
"grant_types_supported": ["client_credentials"],
"token_endpoint_auth_methods_supported": [
"client_secret_basic",
"client_secret_post"
],
"scopes_supported": [
"chat:read", "chat:write", "areas:read", "skills:read", "skills:write",
"rules:read", "rules:write", "permissions:read", "libraries:read",
"libraries:write", "connectors:use", "profile:read", "profile:write",
"analytics:read"
],
"response_types_supported": [],
"service_documentation": "https://api.niucore.com/api/v1/docs"
}