API Reference

Base URLs

Production

Base URL: https://account.oten.com

Sandbox

Base URL: https://account.sbx.oten.dev

Authentication Endpoints

1. Authorization Endpoint

Endpoint: GET /v1/oauth/authorize

Description: Initiates the OAuth 2.0 authorization flow. REQUIRES JAR (JWT-Secured Authorization Request).

URL: {base_url}/v1/oauth/authorize

Parameters

Parameter
Type
Required
Description

client_id

string

Your application's client ID

request

string

JAR token containing all OAuth parameters

JAR Token Requirements

The request parameter must contain a signed JWT with these claims:

Required JWT Claims:

{
  "iss": "your_client_id",
  "aud": "https://account.oten.com",
  "iat": 1640995200,
  "exp": 1640995500,
  "jti": "unique-request-id",
  
  "client_id": "your_client_id",
  "redirect_uri": "https://yourapp.com/callback",
  "response_type": "code",
  "scope": "openid profile email",
  "state": "random_state_string",
  "code_challenge": "base64url_encoded_challenge",
  "code_challenge_method": "S256"
}

Optional Claims:

{
  "nonce": "random_nonce_string",
  "max_age": 3600,
  "prompt": "login",
  "ui_locales": "en-US"
}

Example Request

GET /v1/oauth/authorize?client_id=your_client_id&request=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Host: account.oten.com

Success Response

Status: 302 Found Location: https://yourapp.com/callback?code=abc123&state=xyz789

Error Responses

Authorization endpoint errors are returned as URL parameters in the redirect URI (if valid) or as an error page.

📖 Complete Error Reference: See Error Codes Reference for comprehensive error documentation.

Error Response Format:

HTTP/1.1 302 Found
Location: https://yourapp.com/callback?
  error=invalid_request&
  error_description=The%20request%20is%20missing%20a%20required%20parameter&
  state=xyz789

Common Error Codes:

Error Code
Description
HTTP Status
Retryable

invalid_request

Missing request parameter or other required parameters

400

No*

invalid_request_object

Invalid JAR token

400

No

invalid_client

Client auth failed or IP not whitelisted

401

No

unauthorized_client

Client not authorized for grant type

403

No

access_denied

User denied authorization

400

Yes

server_error

Internal server error

500

Yes

*Note: invalid_request is retryable only for JAR expiration scenarios

Error Response Examples:

# Missing Request Parameter
GET /v1/oauth/authorize?client_id=123&response_type=code&redirect_uri=https://app.com/callback

Response:
HTTP/1.1 302 Found
Location: https://app.com/callback?error=invalid_request&error_description=Request%20parameter%20is%20required

# Invalid JAR Signature
GET /v1/oauth/authorize?client_id=123&request=invalid.jwt.token

Response:
HTTP/1.1 302 Found
Location: https://app.com/callback?error=invalid_request_object&error_description=Invalid%20JAR%20signature

# JAR Token Expired
GET /v1/oauth/authorize?client_id=123&request=expired.jwt.token

Response:
HTTP/1.1 302 Found
Location: https://app.com/callback?error=invalid_request&error_description=JAR%20token%20has%20expired

# Missing JAR Request Parameter
GET /v1/oauth/authorize?client_id=123&redirect_uri=https://app.com/callback

Response:
HTTP/1.1 302 Found
Location: https://app.com/callback?error=invalid_request&error_description=Request%20parameter%20is%20required

# Both request and request_uri provided (Invalid)
GET /v1/oauth/authorize?client_id=123&request=jwt.token&request_uri=https://example.com/request.jwt

Response:
HTTP/1.1 302 Found
Location: https://app.com/callback?error=invalid_request&error_description=Only%20one%20of%20request%20or%20request_uri%20parameters%20is%20allowed

2. Token Endpoint

Endpoint: POST /v1/oauth/token

Description: Exchanges authorization code for access tokens.

URL: {base_url}/v1/oauth/token

Headers

Content-Type: application/x-www-form-urlencoded

Parameters

For Authorization Code Grant:

Parameter
Type
Required
Description

grant_type

string

Must be authorization_code

code

string

Authorization code from callback

redirect_uri

string

Must match authorization request

client_id

string

Your application's client ID

code_verifier

string

PKCE code verifier

client_secret

string

⚠️

Required for confidential clients

For Refresh Token Grant:

Parameter
Type
Required
Description

grant_type

string

Must be refresh_token

refresh_token

string

Valid refresh token

client_id

string

Your application's client ID

client_secret

string

⚠️

Required for confidential clients

Example Request

POST /v1/oauth/token
Host: account.oten.com
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=abc123&redirect_uri=https://yourapp.com/callback&client_id=your_client_id&code_verifier=xyz789

Success Response

Status: 200 OK Content-Type: application/json

{
  "status": "OK",
  "data": [{
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
    "token_type": "Bearer",
    "expires_in": 3600,
    "refresh_token": "def456...",
    "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
    "scope": "openid profile email"
  }],
  "message": "Tokens issued successfully"
}

Error Responses

Token endpoint errors are returned as JSON in the response body.

📖 Complete Error Reference: See Error Codes Reference for comprehensive error documentation.

Error Response Format:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": "invalid_grant",
  "error_description": "The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client"
}

Common Error Codes:

Error Code
Description
HTTP Status
Retryable

invalid_request

Missing required parameter

400

No

invalid_client

Client authentication failed

401

No

invalid_grant

Authorization code/refresh token invalid

400

No

unauthorized_client

Client not authorized for grant type

403

No

unsupported_grant_type

Grant type not supported

400

No

server_error

Internal server error

500

Yes

Error Response Examples:

# Invalid Authorization Code
POST /v1/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=invalid_code&client_id=123&client_secret=secret

Response:
HTTP/1.1 400 Bad Request
{
  "error": "invalid_grant",
  "error_description": "Invalid authorization code: code not found"
}

# PKCE Verification Failed
POST /v1/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=valid_code&client_id=123&code_verifier=wrong_verifier

Response:
HTTP/1.1 400 Bad Request
{
  "error": "invalid_grant",
  "error_description": "Invalid code verifier"
}

# IP Address Not Whitelisted (Client Credentials)
POST /v1/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=123&client_secret=secret

Response:
HTTP/1.1 401 Unauthorized
{
  "error": "invalid_client",
  "error_description": "Invalid client IP: 192.168.1.100 is not in whitelist"
}

# Public Client Using Client Credentials
POST /v1/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=public_client_123

Response:
HTTP/1.1 403 Forbidden
{
  "error": "unauthorized_client",
  "error_description": "Public clients are not authorized for client credentials grant"
}

# Client Not Confidential
POST /v1/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=123&client_secret=secret

Response:
HTTP/1.1 401 Unauthorized
{
  "error": "invalid_client",
  "error_description": "Client is not confidential"
}

# Missing IP Address in Client Credentials Request
POST /v1/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=123&client_secret=secret

Response:
HTTP/1.1 401 Unauthorized
{
  "error": "invalid_client",
  "error_description": "Missing IP address in client credentials request"
}

3. Token Validation Endpoint

Endpoint: POST /v1/token/validate

Description: Validates an access token and returns token information.

URL: {base_url}/v1/token/validate

Headers

Content-Type: application/json

Parameters

Parameter
Type
Required
Description

token

string

Access token to validate

Example Request

POST /v1/token/validate
Host: account.oten.com
Content-Type: application/json

{
  "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Success Response

Status: 200 OK Content-Type: application/json

{
  "status": "OK",
  "data": [{
    "active": true,
    "client_id": "your_client_id",
    "username": "[email protected]",
    "scope": "openid profile email",
    "exp": 1640998800,
    "iat": 1640995200,
    "sub": "user-uuid-123",
    "aud": "your_client_id"
  }],
  "message": "Token is valid"
}

Error Responses

Error
Description
HTTP Status

invalid_token

Token is invalid or expired

401

invalid_request

Missing token parameter

400

4. User Info Endpoint

Endpoint: GET /v1/userinfo

Description: Returns user information for a valid access token.

URL: {base_url}/v1/userinfo

Headers

Authorization: Bearer {access_token}

Example Request

GET /v1/userinfo
Host: account.oten.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

Success Response

Status: 200 OK Content-Type: application/json

{
  "sub": "user-uuid-123",
  "email": "[email protected]",
  "email_verified": true,
  "name": "John Doe",
  "given_name": "John",
  "family_name": "Doe",
  "picture": "https://example.com/avatar.jpg",
  "locale": "en-US",
  "updated_at": 1640995200
}

Error Responses

Error
Description
HTTP Status

invalid_token

Token is invalid or expired

401

insufficient_scope

Token lacks required scope

403

Discovery Endpoints

5. OpenID Connect Discovery

Endpoint: GET /.well-known/openid_configuration

Description: Returns OpenID Connect configuration metadata.

URL: {base_url}/.well-known/openid_configuration

Example Request

GET /.well-known/openid_configuration
Host: account.oten.com

Success Response

Status: 200 OK Content-Type: application/json

{
  "issuer": "https://account.oten.com",
  "authorization_endpoint": "https://account.oten.com/v1/oauth/authorize",
  "token_endpoint": "https://account.oten.com/v1/oauth/token",
  "userinfo_endpoint": "https://account.oten.com/v1/userinfo",
  "jwks_uri": "https://account.oten.com/.well-known/jwks.json",
  "scopes_supported": ["openid", "profile", "email", "phone", "offline_access"],
  "response_types_supported": ["code"],
  "grant_types_supported": ["authorization_code", "refresh_token"],
  "subject_types_supported": ["public"],
  "id_token_signing_alg_values_supported": ["RS256", "EdDSA"],
  "request_object_signing_alg_values_supported": ["HS256", "EdDSA"],
  "token_endpoint_auth_methods_supported": ["client_secret_post", "private_key_jwt"],
  "claims_supported": ["sub", "email", "email_verified", "name", "given_name", "family_name", "picture", "locale"]
}

6. JWKS Endpoint

Endpoint: GET /.well-known/jwks.json

Description: Returns JSON Web Key Set for token verification.

URL: {base_url}/.well-known/jwks.json

Example Request

GET /.well-known/jwks.json
Host: account.oten.com

Success Response

Status: 200 OK Content-Type: application/json

{
  "keys": [
    {
      "kty": "RSA",
      "use": "sig",
      "kid": "key-1",
      "alg": "RS256",
      "n": "base64url_encoded_modulus",
      "e": "AQAB"
    },
    {
      "kty": "OKP",
      "use": "sig",
      "kid": "key-2",
      "alg": "EdDSA",
      "crv": "Ed25519",
      "x": "base64url_encoded_public_key"
    }
  ]
}

Rate Limits

All endpoints are subject to rate limiting:

Production Environment

Endpoint
Rate Limit
Window

/v1/oauth/authorize

10 requests

per minute per IP

/v1/oauth/token

60 requests

per minute per client

/v1/token/validate

1000 requests

per minute per client

/v1/userinfo

100 requests

per minute per token

Discovery endpoints

100 requests

per minute per IP

Development Environment

Endpoint
Rate Limit
Window

/v1/oauth/authorize

20 requests

per minute per IP

/v1/oauth/token

120 requests

per minute per client

/v1/token/validate

2000 requests

per minute per client

/v1/userinfo

200 requests

per minute per token

Discovery endpoints

200 requests

per minute per IP

Rate Limit Headers

When rate limits are exceeded, the following headers are returned:

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640995260
Retry-After: 60

{
  "status": "ERROR",
  "message": "Rate limit exceeded",
  "error_code": "rate_limit_exceeded"
}

Error Response Format

All error responses follow this standard format:

{
  "status": "ERROR",
  "message": "Human-readable error description",
  "error_code": "machine_readable_error_code",
  "data": null
}

Common Error Codes

Error Code
Description
HTTP Status

invalid_request

Request is missing required parameters or malformed

400

invalid_client

Client authentication failed

401

invalid_grant

Authorization grant is invalid, expired, or revoked

400

unauthorized_client

Client is not authorized for this grant type

400

unsupported_grant_type

Grant type is not supported

400

invalid_scope

Requested scope is invalid or unknown

400

access_denied

User denied the authorization request

400

server_error

Internal server error

500

temporarily_unavailable

Service temporarily unavailable

503

invalid_request

JAR required, JAR expired, or missing parameters

400

invalid_request_object

JAR signature verification failed

400

rate_limit_exceeded

Rate limit exceeded

429

Note: Oten IDP uses standard OAuth 2.0 error codes. Specific scenarios like JAR requirements, workspace selection, or MFA requirements are indicated through the error_description parameter.

Supported Scopes

OpenID Connect Scopes

Scope
Description
Claims Returned

openid

Required for OIDC flow

sub

profile

Basic profile information

name, given_name, family_name, picture, locale, updated_at

email

Email address

email, email_verified

phone

Phone number

phone_number, phone_number_verified

OAuth 2.0 Scopes

Scope
Description

offline_access

Request refresh token

read

Read access to resources

write

Write access to resources

Custom Scopes

Custom scopes can be defined per application. Contact support for custom scope configuration.

Token Formats

Access Token

Access tokens are JWTs signed with RS256 or EdDSA:

{
  "iss": "https://account.oten.com",
  "sub": "user-uuid-123",
  "aud": "your_client_id",
  "exp": 1640998800,
  "iat": 1640995200,
  "scope": "openid profile email",
  "client_id": "your_client_id"
}

ID Token

ID tokens are JWTs signed with RS256:

{
  "iss": "https://account.oten.com",
  "sub": "user-uuid-123",
  "aud": "your_client_id",
  "exp": 1640998800,
  "iat": 1640995200,
  "nonce": "random_nonce_string",
  "email": "[email protected]",
  "email_verified": true,
  "name": "John Doe",
  "given_name": "John",
  "family_name": "Doe",
  "picture": "https://example.com/avatar.jpg",
  "locale": "en-US"
}

Refresh Token

Refresh tokens are opaque strings that can be used to obtain new access tokens.

Security Considerations

HTTPS Required

All endpoints MUST be accessed over HTTPS. HTTP requests will be rejected.

JAR Requirement

All authorization requests MUST use JAR (JWT-Secured Authorization Request). Traditional OAuth query parameters will be rejected.

PKCE Required

PKCE (Proof Key for Code Exchange) is required for all public clients and recommended for confidential clients.

Token Validation

Always validate tokens before use:

  1. Verify signature using JWKS

  2. Check expiration (exp claim)

  3. Verify audience (aud claim)

  4. Verify issuer (iss claim)

SDK and Libraries

Official Libraries

  • Go: gitlab.oten.com/go-sdk/go-oauth/client

  • JavaScript/Node.js: Coming soon

  • Python: Coming soon

Community Libraries

See Step 1: Choose OAuth Library for recommended third-party libraries.

Support

For API support and questions:

  • Configuration Reference - Endpoints and settings

  • JAR Complete Implementation Guide - JAR implementation examples

  • Developer Integration Guide - Complete integration process

Last updated