Referencia

OAuth

Emitir, inspeccionar y revocar access tokens, más la metadata de descubrimiento.

Emitir un access token

POSTapi.niucore.com/api/oauth/token

Sin bearer

Intercambia client_id y client_secret por un access token de vida corta. Es el único grant admitido: client_credentials (RFC 6749 §4.4).

Las credenciales se mandan por Authorization: Basic (client_secret_basic) o en el cuerpo (client_secret_post), pero nunca por las dos a la vez: enviarlas por ambos canales devuelve invalid_request, porque deja ambiguo cuál gana.

El parámetro scope es opcional y solo sirve para recortar: pedir un scope que la credencial no tiene devuelve invalid_scope. Sin scope, el token se emite con todos los scopes vigentes de la credencial.

No hay refresh token

Client Credentials no lo usa: cuando el access token vence, se pide otro con las mismas credenciales. Guardá el token en memoria y renovalo un poco antes de expires_in.

Cuerpo

grant_typestringobligatorio

Único grant admitido. Cualquier otro valor devuelve unsupported_grant_type.

client_credentials

client_idstring

Identificador público de la credencial (nc_…). Obligatorio si no se usa Authorization: Basic.

client_secretstring

Secreto de la credencial (ncs_…). Obligatorio si no se usa Authorization: Basic.

scopestring

Subconjunto de scopes separados por espacios. Omitirlo pide todos los vigentes.

Devuelve

access_tokenstring

JWT firmado. Se usa como Bearer.

token_typestring

Siempre Bearer.

expires_ininteger

Segundos de vida. Nunca supera lo que le queda a la credencial.

scopestring

Scopes realmente concedidos, separados por espacios. Puede ser menor a lo pedido si el rol del usuario cambió.

Errores

  • 400unsupported_grant_typegrant_type no es client_credentials.
  • 400invalid_scopeSe pidió un scope inexistente, o uno que la credencial ya no tiene vigente.
  • 400invalid_requestLas credenciales viajaron por Basic y por el cuerpo a la vez.
  • 401invalid_clientCredencial inexistente, secreto incorrecto, credencial revocada o vencida, usuario inactivo o empresa inhabilitada. Un solo error para todos los casos, a propósito.
  • 413invalid_requestEl formulario supera los 8 KB.
  • 429rate_limit_exceededSe superó la cubeta por IP o la del client_id.
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'
Respuesta
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "chat:read chat:write"
}

Inspeccionar un token

POSTapi.niucore.com/api/oauth/introspect

Sin bearer

Devuelve el estado y los claims de un access token (RFC 7662). Requiere autenticar la credencial, no el token: se inspecciona lo propio.

Nota

Responde 200 siempre que el cliente se autentique. Un token vencido, revocado, ilegible o de otra credencial devuelve {"active": false} — sin distinguir el motivo, para que el endpoint no sea un oráculo.

Cuerpo

tokenstringobligatorio

El access token a inspeccionar.

Devuelve

activeboolean

false cuando el token no sirve. Es el único campo garantizado.

scopestring

Scopes del token.

client_idstring

Credencial emisora.

usernamestring

Email del usuario titular.

expinteger

Vencimiento (epoch).

iatinteger

Emisión (epoch).

jtistring

Identificador del token.

company_idinteger

Empresa de la credencial.

Errores

  • 401invalid_clientEl cliente no se autenticó. Es el único error posible.
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"
Respuesta
{
  "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
}

Revocar un access token

POSTapi.niucore.com/api/oauth/revoke

Sin bearer

Invalida el access token presentado (RFC 7009). No revoca la credencial: para eso hay que revocarla desde la aplicación.

Nota

Responde 200 siempre —incluso con un token desconocido o ya vencido— como pide el RFC, y para que no sirva para averiguar si un token existe. Solo el dueño puede revocar su token: un token de otra credencial se ignora en silencio.

Cuerpo

tokenstringobligatorio

El access token a revocar.

Errores

  • 401invalid_clientEl cliente no se autenticó.
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"
Respuesta
HTTP/1.1 200 OK
Cache-Control: no-store

Metadata del servidor

GETapi.niucore.com/.well-known/oauth-authorization-server

Sin bearer

Descubrimiento RFC 8414: endpoints, grants, métodos de autenticación y catálogo de scopes. Un cliente OAuth genérico se configura solo con esto.

Sugerencia

Es público y cacheable (max-age=3600). No requiere credenciales.

curl -sS 'https://api.niucore.com/.well-known/oauth-authorization-server'
Respuesta
{
  "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"
}