> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Cabut Sesi (Keluar) | API Autentikasi Didit

> Di Didit API, DELETE /session/ mengakhiri sesi dari token akses dan mengembalikan 204. Refresh token dicabut; pemeriksaan sesi langsung gagal.

> [!WARNING]
>
> Autentikasi adalah fitur baru. Endpoint-endpoint ini dilayani oleh penerbit aplikasi Anda, misalnya `https://<name>.auth.didit.me`, dan tidak pernah menggunakan kunci API Didit Anda.

Kirimkan token akses pengguna yang berlaku saat ini: token yang belum kedaluwarsa dan belum diganti melalui penyegaran. Respons `401` berarti sesi belum berakhir, sehingga lakukan penyegaran lalu keluar lagi dengan token akses yang baru.

Token akses yang Anda verifikasi secara offline tetap valid sampai kedaluwarsa, dalam waktu paling lama 5 menit. Setelah keluar, arahkan pengguna ke `post_logout_redirect_uri` Anda, jika Anda telah mengaturnya. Lihat [Keluar](https://docs.didit.me/id/authentication/tokens-and-jwks.md#keluar).


## OpenAPI

````yaml id/openapi-authentication.json DELETE /session/
openapi: 3.0.3
info:
  title: Didit Authentication API
  version: 1.0.0
  description: >-
    Endpoint yang menghadap ke server dari Didit Authentication, produk masuk
    (sign-in) untuk pengguna akhir aplikasi Anda. Authentication adalah fitur
    **baru** dan akan tersedia di lingkungan produksi pada rilis 2026-11-01.


    ## Base URL


    Setiap aplikasi adalah penerbit (issuer) OpenID Connect miliknya sendiri,
    dan setiap endpoint di bawah ini dilayani di root dari penerbit tersebut:


    - `https://<name>.auth.didit.me` untuk aplikasi live, atau
    `https://<name>.sandbox.auth.didit.me` untuk aplikasi sandbox.

    - Domain kustom Anda sendiri, setelah aktif. Domain tersebut kemudian
    menggantikan host default sebagai penerbit: token baru mencantumkannya di
    `iss`, discovery mengarah ke sana, dan kunci yang dapat dipublikasikan
    berubah. Token akses yang diterbitkan di bawah host default akan gagal di
    `/session/`, `/step-up/`, dan `/monitoring-token/` hingga token tersebut
    diperbarui.


    Lingkungan live dan sandbox adalah aplikasi terpisah, sehingga keduanya
    merupakan penerbit terpisah dengan kunci terpisah. Kunci yang dapat
    dipublikasikan adalah `pk_live_` (live) atau `pk_test_` (sandbox) diikuti
    oleh encoding base64url tanpa padding dari penerbit, tanpa garis miring
    penutup: lakukan decode untuk menemukan penerbitnya. Kunci ini adalah
    pengidentifikasi publik, bukan kredensial.


    Endpoint JSON yang sama juga dilayani di bawah
    `https://apx.didit.me/auth/v2/authentication/{application_id}/`. Token
    selalu mencantumkan penerbit di atas, alamat mana pun yang menerbitkannya.


    ## Kredensial


    Endpoint ini tidak pernah menerima kunci API Didit Anda atau token konsol.


    - Discovery, JWKS, dan `POST /token/` tidak memerlukan kredensial. Klien
    bersifat publik: tidak ada client secret, dan kode otorisasi terikat pada
    verifier PKCE-nya (`S256`). `client_id` adalah ID aplikasi Anda.

    - `/session/`, `/step-up/`, dan `/monitoring-token/` menerima token akses
    pengguna: `Authorization: Bearer <access_token>`. Setiap panggilan yang
    berhasil dihitung sebagai aktivitas pada sesi, sehingga memulai ulang batas
    waktu tidak aktif (idle timeout) sesi tersebut.


    ## Body permintaan


    Setiap endpoint yang menerima body mendukung format JSON, form-encoded, dan
    multipart. Dokumen ini mencantumkan JSON, ditambah form-encoded untuk `POST
    /token/` sebagaimana yang dikirimkan oleh klien OAuth. Kolom yang tidak
    diterima oleh endpoint akan menghasilkan `400 {"<field>": "unknown_field"}`.


    ## Token


    - **Token akses**: JWT ES256 dengan header `typ: at+jwt`, berlaku paling
    lama 5 menit dan tidak pernah lebih lama dari sesinya. Klaim:
    `AccessTokenClaims`.

    - **Token ID**: JWT ES256 dengan header `typ: JWT`. Klaim: `IDTokenClaims`.
    Token ini tidak pernah diterima sebagai token akses.

    - **Token pembaruan**: string acak yang dirotasi pada setiap penggunaan.
    Mengirimkan token pembaruan yang sudah digunakan kembali akan mencabut sesi.


    Verifikasi token dengan kunci dari `GET /.well-known/jwks.json`: algoritma
    harus berupa `ES256`, `typ` harus cocok dengan tipe token, `iss` harus sama
    dengan penerbit yang Anda konfigurasikan, dan `aud` harus sama dengan ID
    aplikasi Anda. Verifikasi offline hanya melihat sesi yang dicabut setelah
    token aksesnya kedaluwarsa; `GET /session/` adalah pemeriksaan instan.


    ## Error


    | Body | Kapan |

    | --- | --- |

    | `{"error": "<code>"}` | Error dari `POST /token/`, semuanya dengan status
    `400`, dalam bentuk body [RFC 6749 bagian
    5.2](https://www.rfc-editor.org/rfc/rfc6749#section-5.2): `invalid_grant`,
    `invalid_client`, dan `mfa_required` dari Didit. Error layanan:
    `temporarily_unavailable`, `monitoring_unavailable`, `monitoring_disabled`.
    |

    | `{"<field>": ["<message>"]}` atau `{"<field>": "<code>"}` | Kolom
    permintaan gagal divalidasi. `non_field_errors` menunjukkan aturan lintas
    kolom, dan `unknown_field` menunjukkan kolom yang tidak diterima oleh
    endpoint. |

    | `{"detail": "<message>"}` | `401` (`invalid_token`), `403`
    (`origin_not_allowed`), `404` (aplikasi atau step-up tidak dikenal), dan
    `429` (batas laju). Juga `400` untuk body yang tidak dapat di-parse (`JSON
    parse error - ...`), `405` untuk metode yang tidak dilayani oleh endpoint,
    dan `415` untuk `Content-Type` yang tidak didukung. |


    Status `401` juga membawa `WWW-Authenticate: Bearer`, dan `429` membawa
    `Retry-After` dalam detik.


    Ada dua penolakan yang bukan berupa JSON. Alamat yang bukan merupakan
    penerbit akan ditolak sebelum mencapai endpoint ini, misalnya dengan `404`
    kosong untuk nama `*.auth.didit.me` yang tidak digunakan. `step_up_id` yang
    bukan merupakan UUID akan menghasilkan halaman `404`.


    ## Batas laju


    Sebuah permintaan harus melewati dua lapisan.


    **Batas endpoint**, dihitung per alamat IP klien, per aplikasi, dan per
    endpoint:


    - Discovery dan JWKS: 1,200 permintaan per menit dan 12,000 per jam.

    - Setiap endpoint lainnya: 30 permintaan per menit dan 300 per jam. `GET`
    dan `DELETE /session/` berbagi satu hitungan.


    Melebihi batas: `429 {"detail": "Too many requests from this IP address.
    Please wait before trying again. Expected available in 60 seconds."}`, atau
    `3600 seconds` untuk batas per jam.


    **Proteksi bot**, pada setiap `POST` dan `DELETE`. Bucket-nya digunakan
    bersama oleh semua permintaan `POST` dan `DELETE` aplikasi, termasuk langkah
    masuk yang di-hosting, dan diisi ulang terus-menerus:


    - 60 permintaan per menit per alamat IP klien.

    - 30 permintaan per menit per perangkat, untuk permintaan yang
    mengidentifikasi perangkatnya, seperti yang dilakukan oleh SDK browser dan
    native.

    - 3,000 permintaan per menit untuk seluruh aplikasi, di seluruh alamat IP.
    Pembaruan token (`POST /token/` dengan `grant_type=refresh_token`)
    menggunakan bucket tersendiri: 6,000 per menit untuk seluruh aplikasi.


    Melebihi bucket: `429 {"detail": "rate_limited Expected available in N
    seconds."}` (`1 second.` jika N bernilai 1). Bucket per IP mencakup seluruh
    endpoint, sehingga satu alamat yang mencampur panggilan token, step-up, dan
    keluar (sign-out) dapat mengosongkannya sebelum mencapai batas endpoint apa
    pun. Bucket aplikasi menghitung setiap klien dari aplikasi tersebut,
    termasuk browser.


    Kedua lapisan merespons sebelum endpoint dijalankan, sehingga permintaan
    yang mendapatkan `429` tidak dijalankan: coba lagi setelah `Retry-After`,
    termasuk pembaruan.


    ## Permintaan browser


    Permintaan yang membawa header `Origin` harus berasal dari salah satu origin
    milik aplikasi itu sendiri atau origin yang diizinkan, atau akan mendapatkan
    `403 origin_not_allowed`. Permintaan server-ke-server tidak mengirimkan
    `Origin`.


    ## Tidak dibahas di sini


    Rute-rute ini melayani halaman yang di-hosting, SDK browser dan native,
    serta agen AI. Rute ini bukan bagian dari kontrak server, dan SDK server
    tidak memanggilnya:


    - Langkah masuk: `POST /authorize/`, `POST /password/`, `/email/*`,
    `/phone/*`, `/password-reset/*`, `/passkeys/*`, `/mfa/*`, `/social/*`, dan
    `/protection/complete/`.

    - Halaman yang di-hosting dan callback: `/sign-in`, `/magic`, `/invite`,
    `/reset`, `/verify/`, `/sso/*`, `/wallet/callback/`, `/logo/`, serta file
    asosiasi aplikasi native di bawah `/.well-known/`.

    - Akses agen: `/agents/*` dan `/grants/`, termasuk `GET /agents/session/`,
    pemeriksaan live untuk token akses agen AI. Akses agen bukan bagian dari
    versi kontrak ini.

    - API manajemen konsol untuk Authentication, yang menggunakan sesi konsol.


    Event Authentication belum dikirimkan sebagai webhook, sehingga dokumen ini
    tidak mendefinisikan webhook apa pun.
servers:
  - url: https://{issuer}
    description: 'Penerbit aplikasi Anda: asal proses masuknya.'
    variables:
      issuer:
        default: your-app.auth.didit.me
        description: >-
          Host penerbit: `<name>.auth.didit.me` (produksi),
          `<name>.sandbox.auth.didit.me` (sandbox), atau domain kustom aktif
          Anda.
security: []
tags:
  - name: Issuer
    description: Kunci penemuan dan penandatanganan, untuk memverifikasi token.
  - name: Tokens
    description: Grant untuk kode otorisasi dan refresh.
  - name: Sessions
    description: Periksa dan akhiri sesi yang terkait dengan token akses.
  - name: Step-ups
    description: Verifikasi sebelum tindakan sensitif.
  - name: Monitoring
    description: Kredensial perangkat untuk event pemantauan transaksi.
paths:
  /session/:
    delete:
      tags:
        - Sessions
      summary: Cabut sesi
      description: >-
        Mengeluarkan pengguna: mengakhiri sesi di balik token akses. Token
        aksesnya langsung gagal pada `GET /session/`, dan token refresh-nya
        berhenti berfungsi.


        Kirim token akses saat ini: yang belum kedaluwarsa dan belum digantikan
        oleh token refresh. Token lain mana pun akan menerima `401` dan sesi
        tidak berakhir, jadi refresh dan keluar lagi dengan token akses baru.
        Token pemantauan yang diterbitkan sebelumnya tidak terikat pada sesi dan
        tetap dapat digunakan hingga kedaluwarsa, dalam 15 menit. Token yang
        Anda verifikasi secara offline tetap valid hingga kedaluwarsa, dalam 5
        menit. Kemudian arahkan pengguna ke `post_logout_redirect_uri` Anda,
        jika Anda mengaturnya.
      operationId: authentication_revoke_session
      responses:
        '204':
          description: Sesi telah berakhir.
          headers:
            Cache-Control:
              description: >-
                Selalu `no-store`: jangan pernah menyimpan respons ini dalam
                cache.
              schema:
                type: string
                example: no-store
            Pragma:
              description: Selalu `no-cache`.
              schema:
                type: string
                example: no-cache
        '401':
          $ref: '#/components/responses/InvalidToken'
        '403':
          $ref: '#/components/responses/OriginNotAllowed'
        '404':
          $ref: '#/components/responses/ApplicationNotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/TemporarilyUnavailable'
      security:
        - AccessToken: []
components:
  responses:
    InvalidToken:
      description: >-
        Token akses tidak ada, salah format, kedaluwarsa, ditandatangani oleh
        penerbit atau kunci lain, merupakan token ID, token agen, atau
        digantikan oleh token refresh; atau sesinya telah dicabut, habis karena
        tidak aktif, melewati masa berlakunya atau tidak lagi memenuhi kebijakan
        MFA Anda, atau orang tersebut diblokir atau email mereka tidak lagi
        terverifikasi. Arahkan orang tersebut untuk masuk lagi.
      headers:
        WWW-Authenticate:
          description: '`Bearer`.'
          schema:
            type: string
            example: Bearer
        Cache-Control:
          description: 'Selalu `no-store`: jangan pernah menyimpan respons ini dalam cache.'
          schema:
            type: string
            example: no-store
        Pragma:
          description: Selalu `no-cache`.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Detail'
          examples:
            InvalidToken:
              summary: Token akses ditolak
              value:
                detail: invalid_token
    OriginNotAllowed:
      description: >-
        Permintaan membawa `Origin` yang bukan milik aplikasi dan tidak terdapat
        dalam daftar origin yang diizinkan. Permintaan server tidak mengirimkan
        `Origin`.
      headers:
        Cache-Control:
          description: 'Selalu `no-store`: jangan pernah menyimpan respons ini dalam cache.'
          schema:
            type: string
            example: no-store
        Pragma:
          description: Selalu `no-cache`.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Detail'
          examples:
            OriginNotAllowed:
              summary: Asal tidak diizinkan
              value:
                detail: origin_not_allowed
    ApplicationNotFound:
      description: >-
        Alamat milik suatu aplikasi, tetapi Autentikasi tidak aktif untuk
        aplikasi tersebut; pada alamat `apx.didit.me`, ID aplikasi tidak
        diketahui. Alamat yang bukan milik aplikasi mana pun ditolak sebelum
        mencapai endpoint, dan respons tersebut bukan JSON.
      headers:
        Cache-Control:
          description: 'Selalu `no-store`: jangan pernah menyimpan respons ini dalam cache.'
          schema:
            type: string
            example: no-store
        Pragma:
          description: Selalu `no-cache`.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Detail'
          examples:
            ApplicationNotFound:
              summary: Aplikasi tidak dikenal
              value:
                detail: No Configuration matches the given query.
    RateLimited:
      description: >-
        Terlalu banyak permintaan dari alamat ini untuk endpoint ini, atau, pada
        `POST` atau `DELETE`, bucket perlindungan bot kosong. Tidak ada yang
        dijalankan: tunggu selama `Retry-After` detik, lalu coba lagi.
      headers:
        Retry-After:
          description: Detik untuk menunggu sebelum mencoba lagi.
          schema:
            type: integer
            example: 60
        Cache-Control:
          description: 'Selalu `no-store`: jangan pernah menyimpan respons ini dalam cache.'
          schema:
            type: string
            example: no-store
        Pragma:
          description: Selalu `no-cache`.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Detail'
          examples:
            RateLimited:
              summary: Batas endpoint
              value:
                detail: >-
                  Too many requests from this IP address. Please wait before
                  trying again. Expected available in 60 seconds.
            BotProtection:
              summary: Batas perlindungan bot (POST dan DELETE)
              value:
                detail: rate_limited Expected available in 2 seconds.
    TemporarilyUnavailable:
      description: >-
        Layanan yang dibutuhkan permintaan sedang tidak tersedia untuk
        sementara. Coba lagi dengan backoff.
      headers:
        Cache-Control:
          description: 'Selalu `no-store`: jangan pernah menyimpan respons ini dalam cache.'
          schema:
            type: string
            example: no-store
        Pragma:
          description: Selalu `no-cache`.
          schema:
            type: string
            example: no-cache
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/OAuthError'
          examples:
            TemporarilyUnavailable:
              summary: Coba lagi nanti
              value:
                error: temporarily_unavailable
  schemas:
    Detail:
      type: object
      required:
        - detail
      properties:
        detail:
          type: string
          example: invalid_token
    OAuthError:
      title: OAuth error
      type: object
      description: Error OAuth (RFC 6749 bagian 5.2) atau error layanan.
      required:
        - error
      properties:
        error:
          type: string
          example: invalid_grant
  securitySchemes:
    AccessToken:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Token akses orang tersebut dari `POST /token/`: JWT ES256 dengan header
        `typ: at+jwt`, berlaku paling lama 5 menit. Bukan kunci API Didit Anda.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.