UGM ID — OAuth 2.0 / OpenID Connect Authorization Server

Universitas Gadjah Mada's own identity API, operated by the Directorate of Information Technology (DTI) at oauth.simaster.ugm.ac.id, in front of SIMASTER, the university's integrated academic information system. UGM publishes an OpenAPI 3.1.0 document for it at /openapi.json (retrieved 2026-09-01, 200, 19677 bytes) and serves Swagger UI from /docs. Twenty operations across five tags: the OAuth2 core (authorize, token, introspect, revoke, logout, userinfo), Discovery (OIDC configuration, RFC 8414 metadata, JWKS), three read-only resource endpoints (/api/me, /user/me, /user/username/{username}), social login initiation for Google, Microsoft 365, Facebook, LinkedIn and Apple, and a public /health check that reports the status of its database, Redis and SIMASTER dependencies. Six grant types including PKCE-protected authorization_code and RFC 8693 token exchange. Five scopes, all read-only. The specification is written by UGM in Indonesian. Two real defects are recorded rather than smoothed over: both discovery documents emit scheme-less URLs, breaking OIDC Discovery and RFC 8414 conformance, and the JWKS endpoint returns an empty key set while advertising RS256 id_tokens.

Operations 19

GET /.well-known/jwks.json JSON Web Key Set (JWKS) #
GET /.well-known/oauth-authorization-server OAuth 2.0 Authorization Server Metadata (RFC 8414) #
GET /.well-known/openid-configuration OpenID Connect Discovery #
GET /api/me Data User — Profil Dasar #
GET /authorize/apple Login dengan Apple #
GET /authorize/facebook Login dengan Facebook #
GET /authorize/google Login dengan Google #
GET /authorize/linkedin Login dengan LinkedIn #
GET /authorize/microsoft Login dengan Microsoft 365 UGM #
POST /callback/apple Callback Apple Sign In #
GET /health Health Check #
GET /oauth/authorize Otorisasi Pengguna (Authorization Code + PKCE) #
POST /oauth/introspect Introspeksi Token (RFC 7662) #
GET /oauth/logout RP-Initiated Logout (OIDC) #
POST /oauth/revoke Cabut Token OAuth2 (RFC 7009) #
POST /oauth/token Terbitkan Token OAuth2 #
GET /user/me Data User — Profil Lengkap (Simaster) #
GET /user/username/{username} Data User by Username #
GET /userinfo OIDC UserInfo Endpoint #

Documentation

Specifications

Schemas & Data

Other Resources

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/ugm-id"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

gadjah-mada-university-ugm-id-openapi.yml Raw ↑
# UGM ID — OAuth 2.0 / OpenID Connect Authorization Server
# Universitas Gadjah Mada's own, first-party OpenAPI 3.1.0 document.
# generated: '2026-09-01'
# method: searched
# source: >-
#   Retrieved verbatim on 2026-09-01 from https://oauth.simaster.ugm.ac.id/openapi.json (HTTP 200,
#   19677 bytes, application/json) — the document the institution's own Swagger UI at
#   https://oauth.simaster.ugm.ac.id/docs loads. Written by UGM (descriptions are in Indonesian).
#   x-operator: institution — servers[] are https://oauth.simaster.ugm.ac.id (Production) and
#   https://oauth.dev.ugm.ac.id (Development), both under the institution's own registrable domain
#   ugm.ac.id; info.title is "UGM ID". No vendor is named anywhere in the document.
# x-operator: institution
# original: openapi/_original/gadjah-mada-university-ugm-id-openapi.json
components:
  parameters:
    OAuthClientId:
      in: query
      name: client_id
      required: true
      schema:
        type: string
    OAuthRedirectUri:
      in: query
      name: redirect_uri
      required: true
      schema:
        type: string
    OAuthScope:
      in: query
      name: scope
      required: false
      schema:
        type: string
    OAuthState:
      in: query
      name: state
      required: false
      schema:
        type: string
  responses:
    BadRequest:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: Permintaan tidak valid
    Forbidden:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: Scope tidak mencukupi atau akses ditolak
    OAuth2Error:
      content:
        application/json:
          schema:
            properties:
              error:
                example: invalid_grant
                type: string
              error_description:
                type: string
            type: object
      description: OAuth2 error response
    Unauthorized:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: Token tidak valid atau tidak disertakan
  schemas:
    ErrorResponse:
      properties:
        error:
          type: string
        error_description:
          type: string
        message:
          type: string
      type: object
    HealthResponse:
      properties:
        services:
          properties:
            database:
              properties:
                status:
                  enum:
                  - ok
                  - error
                  type: string
              type: object
            redis:
              properties:
                status:
                  enum:
                  - ok
                  - error
                  - disabled
                  type: string
              type: object
            simaster:
              properties:
                status:
                  enum:
                  - ok
                  - error
                  - disabled
                  type: string
              type: object
          type: object
        status:
          enum:
          - ok
          - degraded
          - error
          type: string
        timestamp:
          format: date-time
          type: string
        version:
          type: string
      type: object
    IntrospectResponse:
      properties:
        active:
          description: True jika token valid dan belum expired
          type: boolean
        client_id:
          type: string
        data:
          description: Data user (hanya untuk user-based grants)
          properties:
            attributes:
              items:
                type: object
              type: array
            client_id:
              type: string
            email:
              type: string
            unit_id:
              type: integer
            username:
              type: string
          type: object
        exp:
          type: integer
        grant_type:
          type: string
        iat:
          type: integer
        iss:
          type: string
        scope:
          type: string
        sub:
          description: Username (untuk user-based grants)
          type: string
        token_type:
          example: Bearer
          type: string
      type: object
    ServerMetadata:
      description: RFC 8414 / OIDC Discovery metadata
      properties:
        authorization_endpoint:
          type: string
        end_session_endpoint:
          type: string
        grant_types_supported:
          items:
            type: string
          type: array
        id_token_signing_alg_values_supported:
          items:
            type: string
          type: array
        introspection_endpoint:
          type: string
        issuer:
          type: string
        jwks_uri:
          type: string
        response_types_supported:
          items:
            type: string
          type: array
        revocation_endpoint:
          type: string
        scopes_supported:
          items:
            type: string
          type: array
        token_endpoint:
          type: string
        token_endpoint_auth_methods_supported:
          items:
            type: string
          type: array
        userinfo_endpoint:
          type: string
      type: object
    TokenResponse:
      description: Respons token OAuth2
      example:
        access_token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
        expires_in: 3600
        refresh_token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
        scope: openid user.read
        token_type: Bearer
      properties:
        access_token:
          description: JWT access token
          type: string
        expires_in:
          description: Masa berlaku dalam detik
          example: 3600
          type: integer
        id_token:
          description: OIDC ID Token (hanya jika scope openid)
          type: string
        refresh_token:
          description: JWT refresh token (tidak selalu ada)
          type: string
        scope:
          type: string
        token_type:
          example: Bearer
          type: string
      type: object
    UserData:
      description: Profil dasar user dari /api/me
      properties:
        email:
          example: johndoe@ugm.ac.id
          type: string
        family_name:
          type: string
        given_name:
          type: string
        name:
          type: string
        picture:
          type: string
        provider:
          enum:
          - cas_sso
          - google
          - microsoft
          - facebook
          - linkedin
          - apple
          type: string
        username:
          example: johndoe
          type: string
      type: object
    UserDetailData:
      description: Profil lengkap user dari Simaster (/user/me, /user/username/:username)
      properties:
        attributes:
          items:
            properties:
              id:
                type: integer
              is_default:
                type: integer
              user_identitas:
                type: string
              user_identitas_id:
                type: integer
              user_identitas_nomor:
                type: string
              user_tipe:
                type: string
              user_tipe_id:
                type: integer
            type: object
          type: array
        email:
          example: johndoe@ugm.ac.id
          type: string
        is_blacklist:
          example: false
          type: boolean
        nama_lengkap:
          example: John Doe
          type: string
        total_attributes:
          example: 3
          type: integer
        user_id:
          example: 123456
          type: integer
        user_identitas:
          example: ID STAFF
          type: string
        user_identitas_id:
          example: 8
          type: integer
        user_identitas_nomor:
          example: '12345'
          type: string
        user_tipe:
          example: Karyawan
          type: string
        user_tipe_id:
          example: 2
          type: integer
        username:
          example: johndoe
          type: string
      type: object
    UserInfoResponse:
      description: OIDC UserInfo claims
      properties:
        email:
          type: string
        email_verified:
          type: boolean
        family_name:
          type: string
        given_name:
          type: string
        name:
          type: string
        picture:
          type: string
        preferred_username:
          type: string
        sub:
          description: Username
          type: string
      type: object
  securitySchemes:
    BasicAuth:
      description: client_id:client_secret via Basic Auth header
      scheme: basic
      type: http
    BearerAuth:
      bearerFormat: JWT
      description: Access token JWT dari /oauth/token
      scheme: bearer
      type: http
info:
  description: 'Layanan OAuth 2.0 / OIDC Authorization Server untuk mengakses UGM API.


    **Grant Types yang didukung:**

    - Authorization Code + PKCE (`authorization_code`)

    - Resource Owner Password (`password`)

    - Client Credentials (`client_credentials`)

    - Refresh Token (`refresh_token`)

    - Google ID Token Exchange (`urn:ietf:params:oauth:grant-type:google_id_token`)

    - RFC 8693 Token Exchange (`urn:ietf:params:oauth:grant-type:token-exchange`)


    **Autentikasi client:**

    - `client_secret_basic` — Basic Auth header

    - `client_secret_post` — form body

    - `none` — untuk legacy client (akan dihapus di masa depan)

    '
  title: UGM ID
  version: '2.0'
openapi: 3.1.0
paths:
  /.well-known/jwks.json:
    get:
      description: Public keys untuk verifikasi JWT RS256. Di-cache 5 menit.
      operationId: getJwks
      responses:
        '200':
          content:
            application/json:
              schema:
                properties:
                  keys:
                    items:
                      properties:
                        alg:
                          example: RS256
                          type: string
                        e:
                          type: string
                        kid:
                          type: string
                        kty:
                          example: RSA
                          type: string
                        n:
                          type: string
                        use:
                          example: sig
                          type: string
                      type: object
                    type: array
                type: object
          description: JWKS berhasil
      summary: JSON Web Key Set (JWKS)
      tags:
      - Discovery
  /.well-known/oauth-authorization-server:
    get:
      operationId: getOAuthMetadata
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServerMetadata'
          description: Metadata server otorisasi OAuth 2.0
      summary: OAuth 2.0 Authorization Server Metadata (RFC 8414)
      tags:
      - Discovery
  /.well-known/openid-configuration:
    get:
      operationId: getOidcConfiguration
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServerMetadata'
          description: Konfigurasi OIDC
      summary: OpenID Connect Discovery
      tags:
      - Discovery
  /api/me:
    get:
      description: Mengambil username, email, nama, picture, provider. Scope `user.read` diperlukan.
      operationId: getMe
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserData'
          description: Data user berhasil
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      security:
      - BearerAuth: []
      summary: Data User — Profil Dasar
      tags:
      - API
  /authorize/apple:
    get:
      description: 'Redirect ke Apple Sign In. Apple menggunakan `response_mode=form_post`,

        sehingga callback diterima sebagai POST ke `/callback/apple`.

        '
      operationId: authorizeApple
      parameters:
      - $ref: '#/components/parameters/OAuthClientId'
      - $ref: '#/components/parameters/OAuthRedirectUri'
      - $ref: '#/components/parameters/OAuthScope'
      - $ref: '#/components/parameters/OAuthState'
      responses:
        '302':
          description: Redirect ke Apple Sign In
      summary: Login dengan Apple
      tags:
      - Social Login
  /authorize/facebook:
    get:
      operationId: authorizeFacebook
      parameters:
      - $ref: '#/components/parameters/OAuthClientId'
      - $ref: '#/components/parameters/OAuthRedirectUri'
      - $ref: '#/components/parameters/OAuthScope'
      - $ref: '#/components/parameters/OAuthState'
      responses:
        '302':
          description: Redirect ke Facebook OAuth
      summary: Login dengan Facebook
      tags:
      - Social Login
  /authorize/google:
    get:
      description: Redirect ke Google OAuth. State dienkripsi AES-GCM.
      operationId: authorizeGoogle
      parameters:
      - $ref: '#/components/parameters/OAuthClientId'
      - $ref: '#/components/parameters/OAuthRedirectUri'
      - $ref: '#/components/parameters/OAuthScope'
      - $ref: '#/components/parameters/OAuthState'
      responses:
        '302':
          description: Redirect ke Google OAuth
      summary: Login dengan Google
      tags:
      - Social Login
  /authorize/linkedin:
    get:
      operationId: authorizeLinkedin
      parameters:
      - $ref: '#/components/parameters/OAuthClientId'
      - $ref: '#/components/parameters/OAuthRedirectUri'
      - $ref: '#/components/parameters/OAuthScope'
      - $ref: '#/components/parameters/OAuthState'
      responses:
        '302':
          description: Redirect ke LinkedIn OAuth
      summary: Login dengan LinkedIn
      tags:
      - Social Login
  /authorize/microsoft:
    get:
      description: Redirect ke Microsoft OAuth. Tenant dan domain email divalidasi.
      operationId: authorizeMicrosoft
      parameters:
      - $ref: '#/components/parameters/OAuthClientId'
      - $ref: '#/components/parameters/OAuthRedirectUri'
      - $ref: '#/components/parameters/OAuthScope'
      - $ref: '#/components/parameters/OAuthState'
      responses:
        '302':
          description: Redirect ke Microsoft OAuth
      summary: Login dengan Microsoft 365 UGM
      tags:
      - Social Login
  /callback/apple:
    post:
      description: 'Apple mengirim data via HTTP POST (form_post mode).

        Menerima `id_token`, `code`, `state`, dan `user` (hanya first-time login).

        '
      operationId: callbackApple
      requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              properties:
                code:
                  type: string
                id_token:
                  description: Apple signed JWT
                  type: string
                state:
                  type: string
                user:
                  description: JSON string (hanya first-time login)
                  type: string
              type: object
        required: true
      responses:
        '302':
          description: Redirect ke client redirect_uri dengan authorization code
        '403':
          $ref: '#/components/responses/Forbidden'
      summary: Callback Apple Sign In
      tags:
      - Social Login
  /health:
    get:
      description: 'Cek status semua layanan. Tidak terkena rate limit.

        - `ok` — semua layanan normal

        - `degraded` — Simaster tidak terjangkau (non-fatal)

        - `error` — primary DB atau Redis down

        '
      operationId: healthCheck
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HealthResponse'
          description: Server sehat
        '503':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HealthResponse'
          description: Server tidak sehat
      summary: Health Check
      tags:
      - Infra
  /oauth/authorize:
    get:
      description: 'Memulai Authorization Code flow. Redirect ke CAS SSO UGM, kemudian tampilkan

        consent screen. PKCE (`code_challenge`) **wajib** disertakan.

        '
      operationId: authorizeUser
      parameters:
      - in: query
        name: response_type
        required: true
        schema:
          enum:
          - code
          type: string
      - in: query
        name: client_id
        required: true
        schema:
          type: string
      - in: query
        name: redirect_uri
        required: true
        schema:
          type: string
      - in: query
        name: scope
        required: false
        schema:
          example: openid user.read userDetail.read
          type: string
      - in: query
        name: state
        required: false
        schema:
          type: string
      - description: PKCE code challenge (disarankan S256)
        in: query
        name: code_challenge
        required: false
        schema:
          type: string
      - in: query
        name: code_challenge_method
        required: false
        schema:
          enum:
          - S256
          - plain
          type: string
      responses:
        '200':
          description: Halaman consent ditampilkan
        '302':
          description: Redirect ke CAS SSO atau redirect_uri dengan code
        '400':
          $ref: '#/components/responses/BadRequest'
      summary: Otorisasi Pengguna (Authorization Code + PKCE)
      tags:
      - OAuth2
  /oauth/introspect:
    post:
      description: 'Cek validitas dan metadata token. Hanya client yang memiliki token tersebut

        yang bisa mengintrospeksi (token.client_id harus sama dengan client yang request).

        '
      operationId: introspectToken
      requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              properties:
                token:
                  type: string
                token_type_hint:
                  enum:
                  - access_token
                  - refresh_token
                  type: string
              required:
              - token
              type: object
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntrospectResponse'
          description: Hasil introspeksi
        '401':
          $ref: '#/components/responses/Unauthorized'
      security:
      - BasicAuth: []
      summary: Introspeksi Token (RFC 7662)
      tags:
      - OAuth2
  /oauth/logout:
    get:
      description: Logout dari sesi OIDC. Opsional redirect ke `post_logout_redirect_uri`.
      operationId: logoutUser
      parameters:
      - in: query
        name: id_token_hint
        required: false
        schema:
          type: string
      - in: query
        name: post_logout_redirect_uri
        required: false
        schema:
          type: string
      - in: query
        name: state
        required: false
        schema:
          type: string
      responses:
        '200':
          description: Halaman logout berhasil ditampilkan
        '302':
          description: Redirect ke post_logout_redirect_uri
      summary: RP-Initiated Logout (OIDC)
      tags:
      - OAuth2
  /oauth/revoke:
    post:
      description: Mencabut access token atau refresh token. Harus menggunakan Basic Auth.
      operationId: revokeToken
      requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              properties:
                token:
                  type: string
                token_type_hint:
                  enum:
                  - access_token
                  - refresh_token
                  type: string
              required:
              - token
              type: object
        required: true
      responses:
        '200':
          description: Token berhasil dicabut (atau tidak ditemukan — keduanya mengembalikan 200)
        '401':
          $ref: '#/components/responses/Unauthorized'
      security:
      - BasicAuth: []
      summary: Cabut Token OAuth2 (RFC 7009)
      tags:
      - OAuth2
  /oauth/token:
    post:
      description: 'Mendukung semua grant types. Autentikasi client via Basic Auth atau form body.


        **grant_type yang didukung:**

        - `authorization_code` — tukar code dengan token (wajib `code_verifier` jika pakai PKCE)

        - `password` — LDAP credentials langsung

        - `client_credentials` — service-to-service

        - `refresh_token` — perbarui access token

        - `urn:ietf:params:oauth:grant-type:google_id_token` — tukar Google ID Token

        - `urn:ietf:params:oauth:grant-type:token-exchange` — RFC 8693 token exchange

        '
      operationId: getToken
      requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              properties:
                apple_user_payload:
                  description: JSON string user data Apple (hanya first-time login via Apple)
                  type: string
                client_id:
                  type: string
                client_secret:
                  type: string
                code:
                  description: Authorization code (grant authorization_code)
                  type: string
                code_verifier:
                  description: PKCE verifier (wajib jika menggunakan code_challenge)
                  type: string
                grant_type:
                  enum:
                  - authorization_code
                  - password
                  - client_credentials
                  - refresh_token
                  - urn:ietf:params:oauth:grant-type:google_id_token
                  - urn:ietf:params:oauth:grant-type:token-exchange
                  type: string
                id_token:
                  description: Google ID Token (grant google_id_token)
                  type: string
                password:
                  description: Hanya untuk grant password
                  type: string
                redirect_uri:
                  type: string
                refresh_token:
                  description: Hanya untuk grant refresh_token
                  type: string
                scope:
                  type: string
                subject_issuer:
                  description: Issuer dari subject_token (e.g. https://appleid.apple.com)
                  example: https://appleid.apple.com
                  type: string
                subject_token:
                  description: Token untuk ditukar (grant token-exchange)
                  type: string
                subject_token_type:
                  description: Tipe subject_token
                  example: urn:ietf:params:oauth:token-type:id_token
                  type: string
                username:
                  description: Hanya untuk grant password
                  type: string
              required:
              - grant_type
              type: object
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
          description: Token berhasil diterbitkan
        '400':
          $ref: '#/components/responses/OAuth2Error'
        '401':
          $ref: '#/components/responses/Unauthorized'
      security:
      - BasicAuth: []
      - {}
      summary: Terbitkan Token OAuth2
      tags:
      - OAuth2
  /user/me:
    get:
      description: 'Mengambil data lengkap user dari Simaster termasuk `user_tipe`, `identitas`,

        dan `attributes`. Scope `userDetail.read` diperlukan.

        '
      operationId: getUserMe
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserDetailData'
          description: Data user lengkap berhasil
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      security:
      - BearerAuth: []
      summary: Data User — Profil Lengkap (Simaster)
      tags:
      - API
  /user/username/{username}:
    get:
      description: 'Mengambil data user berdasarkan username. Scope `user.read` diperlukan.

        Mengembalikan 404 jika tidak ditemukan.

        '
      operationId: getUserByUsername
      parameters:
      - example: johndoe
        in: path
        name: username
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserDetailData'
          description: Data user berhasil
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: User tidak ditemukan
      security:
      - BearerAuth: []
      summary: Data User by Username
      tags:
      - API
  /userinfo:
    get:
      description: Mengambil klaim user. Memerlukan scope `openid`.
      operationId: getUserInfo
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserInfoResponse'
          description: Data user berhasil
        '401':
          $ref: '#/components/responses/Unauthorized'
      security:
      - BearerAuth: []
      summary: OIDC UserInfo Endpoint
      tags:
      - OAuth2
servers:
- description: Production Server
  url: https://oauth.simaster.ugm.ac.id
- description: Development Server
  url: https://oauth.dev.ugm.ac.id
tags:
- description: Endpoint inti OAuth2/OIDC
  name: OAuth2
- description: RFC 8414 & OIDC Discovery
  name: Discovery
- description: Resource API (butuh Bearer token)
  name: API
- description: Social provider login (Google, Microsoft, Facebook, LinkedIn)
  name: Social Login
- description: Health check & infrastruktur
  name: Infra