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

# Token Endpoint

> API reference for Mubarokah ID OAuth 2.0 Token Endpoint (/oauth/token). Used to exchange authorization codes or refresh tokens for access tokens.

# Token Endpoint

The Token Endpoint is used to obtain access tokens (and optionally refresh tokens) by providing an authorization grant. Mubarokah ID supports several grant types on this endpoint: `authorization_code`, `refresh_token`, and `client_credentials`.

**Important requirements:**

* All requests to the token endpoint **MUST use the `POST` method**
* Request body **MUST use `application/x-www-form-urlencoded`**
* Endpoint: `https://accounts.mubarokah.com/oauth/token`

## Request Parameters

<ParamField body="grant_type" type="string" required initialValue="authorization_code" placeholder="authorization_code">
  Grant type to be used. Available options: `authorization_code`, `refresh_token`, or `client_credentials`
</ParamField>

<ParamField body="code" type="string" placeholder="def5020052a4b237f572e55dd3ff5428...">
  Authorization code received from the `/oauth/authorize` redirect (only for grant\_type: authorization\_code)
</ParamField>

<ParamField body="refresh_token" type="string" placeholder="def502007283433111c7d0723e7683fd...">
  Valid refresh token (only for grant\_type: refresh\_token)
</ParamField>

<ParamField body="redirect_uri" type="string" placeholder="http://127.0.0.1:3090/sso/auth/callback">
  Redirect URI that matches the one used in the initial authorization request (for authorization\_code grant)
</ParamField>

<ParamField body="client_id" type="string" required placeholder="0a9f8dd9-9f13-4138-abf7-566f30886cf1">
  Your application's Client ID
</ParamField>

<ParamField body="client_secret" type="string" required placeholder="ORgE1SbhnjX73A3NPk2zZjxN0fMJetKPxXsH7Hyu">
  Your application's Client Secret
</ParamField>

<ParamField body="scope" type="string" placeholder="view-user detail-user">
  Requested scope (optional for some grant types)
</ParamField>

<ParamField body="code_verifier" type="string" placeholder="">
  Code verifier for PKCE (optional, if using PKCE)
</ParamField>

## Response

<ResponseField name="access_token" type="string" required>
  Access token that can be used to access protected resources
</ResponseField>

<ResponseField name="token_type" type="string" required>
  Usually `Bearer`. How to use the token in API requests
</ResponseField>

<ResponseField name="expires_in" type="number" required>
  Access token lifetime in seconds (e.g., `86400` for 24 hours)
</ResponseField>

<ResponseField name="refresh_token" type="string">
  Token for obtaining new access tokens when expired
</ResponseField>

<ResponseField name="scope" type="string">
  Granted scope (if different from requested)
</ResponseField>

## How to Fill API Playground

Based on your successful Laravel OAuth flow, here's how to fill the fields in "Try It":

### **Option 1: Refresh Token Grant (RECOMMENDED)** ✅

**Fields to fill:**

* `grant_type`: `refresh_token`
* `refresh_token`: `def502007283433111c7d0723e7683fd204977ccb0f679666ccd96fbf9385cda625bfe318102cf78245d44c8cb85818bc30b29ba74c25ccf1e8c85c5acbefcea8ee25c7b0d3f86e56e979c4a684c7d3276393c154577276e724c5f8f7f2aae592827f455e689d3a422fa85ea74af66e6c5f6a71d9ef8fcd5d0ebe3615cb7efdaa1771e3512c7db0562d63ac9e1cd28d1ce1c7148d667efaaaef9d49774a913f88438a7d57681119cb01eff80b3ad90c003ecd751852ee447ef232ada4789d684f802eeaa29ec35d06b7dfb3b4993171550e3625ff2f56b9157d5b565845f99575e70abd8c9b6d4ddf9e85fdd909b1cda38278147a021e6e2e6e18f9fcb053cb116e62fb5a4a2db50d3640da8d1848e6ea8fae43d334dac942bb374ecb84e89d4b793f77208c9a56c1a3ec76352e14d93cb888482cc91984747dd5f988bc2c416b23f3ebc3495ec919f540968807fff982e1066eedfca74ec0edc423bb13b36ecde2d73f87e8fa83f4bc3f3da36eb210c4a4bf30731774eac51807ae0b4cbf3fa4864254898427ce35b07b281505555668a6c364b2a9cbdeb02f2f0186c`
* `client_id`: `0a9f8dd9-9f13-4138-abf7-566f30886cf1`
* `client_secret`: `ORgE1SbhnjX73A3NPk2zZjxN0fMJetKPxXsH7Hyu`

**Fields to leave empty:**

* `code` (leave empty)
* `redirect_uri` (leave empty)
* `scope` (optional)
* `code_verifier` (leave empty)

### **Option 2: Client Credentials Grant**

**Fields to fill:**

* `grant_type`: `client_credentials`
* `client_id`: `0a9f8dd9-9f13-4138-abf7-566f30886cf1`
* `client_secret`: `ORgE1SbhnjX73A3NPk2zZjxN0fMJetKPxXsH7Hyu`
* `scope`: `server-operations` (optional)

**Fields to leave empty:**

* `code` (leave empty)
* `refresh_token` (leave empty)
* `redirect_uri` (leave empty)
* `code_verifier` (leave empty)

### **⚠️ Authorization Code Grant (Not Recommended for Testing)**

The authorization code from your logs has already been used and will result in an `invalid_grant` error. For testing this, you need to perform a new OAuth flow:

* `grant_type`: `authorization_code`
* `code`: `[NEW_AUTHORIZATION_CODE]`
* `redirect_uri`: `http://127.0.0.1:3090/sso/auth/callback`
* `client_id`: `0a9f8dd9-9f13-4138-abf7-566f30886cf1`
* `client_secret`: `ORgE1SbhnjX73A3NPk2zZjxN0fMJetKPxXsH7Hyu`

## Supported Grant Types

### 1. Authorization Code Grant (Most Common)

Used after user authorizes your application. Exchanges authorization code for access token.

**Example Request:**

```javascript theme={null}
const response = await fetch('https://accounts.mubarokah.com/oauth/token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  body: new URLSearchParams({
    grant_type: 'authorization_code',
    code: 'authorization_code_from_callback',
    redirect_uri: 'http://127.0.0.1:3090/sso/auth/callback',
    client_id: '0a9f8dd9-9f13-4138-abf7-566f30886cf1',
    client_secret: 'ORgE1SbhnjX73A3NPk2zZjxN0fMJetKPxXsH7Hyu'
  })
});

const tokenData = await response.json();
console.log('Access token:', tokenData.access_token);
```

### 2. Refresh Token Grant

Used to obtain new access tokens when current token expires.

**Example Request:**

```javascript theme={null}
const response = await fetch('https://accounts.mubarokah.com/oauth/token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  body: new URLSearchParams({
    grant_type: 'refresh_token',
    refresh_token: 'def502007283433111c7d0723e7683fd204977ccb0f679666ccd96fbf9385cda625bfe318102cf78245d44c8cb85818bc30b29ba74c25ccf1e8c85c5acbefcea8ee25c7b0d3f86e56e979c4a684c7d3276393c154577276e724c5f8f7f2aae592827f455e689d3a422fa85ea74af66e6c5f6a71d9ef8fcd5d0ebe3615cb7efdaa1771e3512c7db0562d63ac9e1cd28d1ce1c7148d667efaaaef9d49774a913f88438a7d57681119cb01eff80b3ad90c003ecd751852ee447ef232ada4789d684f802eeaa29ec35d06b7dfb3b4993171550e3625ff2f56b9157d5b565845f99575e70abd8c9b6d4ddf9e85fdd909b1cda38278147a021e6e2e6e18f9fcb053cb116e62fb5a4a2db50d3640da8d1848e6ea8fae43d334dac942bb374ecb84e89d4b793f77208c9a56c1a3ec76352e14d93cb888482cc91984747dd5f988bc2c416b23f3ebc3495ec919f540968807fff982e1066eedfca74ec0edc423bb13b36ecde2d73f87e8fa83f4bc3f3da36eb210c4a4bf30731774eac51807ae0b4cbf3fa4864254898427ce35b07b281505555668a6c364b2a9cbdeb02f2f0186c',
    client_id: '0a9f8dd9-9f13-4138-abf7-566f30886cf1',
    client_secret: 'ORgE1SbhnjX73A3NPk2zZjxN0fMJetKPxXsH7Hyu'
  })
});

const newTokens = await response.json();
```

### 3. Client Credentials Grant

For machine-to-machine (M2M) authentication, without user involvement.

**Example Request:**

```javascript theme={null}
const response = await fetch('https://accounts.mubarokah.com/oauth/token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  body: new URLSearchParams({
    grant_type: 'client_credentials',
    client_id: '0a9f8dd9-9f13-4138-abf7-566f30886cf1',
    client_secret: 'ORgE1SbhnjX73A3NPk2zZjxN0fMJetKPxXsH7Hyu',
    scope: 'server-operations' // optional
  })
});

const appToken = await response.json();
```

## Example Success Response

```json theme={null}
{
  "token_type": "Bearer",
  "expires_in": 86400,
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "def5020023761949f076f069874c92d8...",
  "scope": "view-user detail-user"
}
```

## Error Response

If the request fails, it will return a JSON error response:

```json theme={null}
{
  "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.",
  "message": "The provided authorization grant is invalid or expired.",
  "hint": "Check the authorization code and try again."
}
```

## Common Error Codes

| Error Code               | Description                               | Solution                                                            |
| ------------------------ | ----------------------------------------- | ------------------------------------------------------------------- |
| `invalid_request`        | Missing or malformed parameters           | Check all required parameters                                       |
| `invalid_client`         | Client authentication failed              | Verify `client_id` and `client_secret`                              |
| `invalid_grant`          | Authorization grant invalid/expired       | Obtain new authorization code                                       |
| `unauthorized_client`    | Client not authorized for this grant type | Check client configuration                                          |
| `unsupported_grant_type` | Grant type not supported                  | Use: `authorization_code`, `refresh_token`, or `client_credentials` |
| `invalid_scope`          | Requested scope is invalid                | Check available scopes                                              |

## Security Best Practices

<Warning>
  **Never expose `client_secret` in client-side code!** `client_secret` must be stored securely on your server.
</Warning>

1. **Store credentials securely using environment variables**
2. **Use HTTPS for all OAuth communications**
3. **Implement proper error handling**
4. **Validate state parameter for CSRF protection**
5. **Rotate credentials regularly**
6. **Monitor token usage for suspicious activity**
7. **Implement token refresh logic**
8. **Use PKCE for public clients**
