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

# OAuth Apps

> Register an OAuth app to build integrations that act on behalf of Essal users with scoped access.

**OAuth Apps** allow third-party applications to access the Essal API on behalf of users. Users grant permission to specific scopes, and your app receives short-lived access tokens scoped to exactly what was requested.

## Registering an OAuth App

1. Go to **Settings → Developer → OAuth Apps**
2. Click **Register New App**
3. Enter your app name, homepage URL, and redirect URIs
4. Copy the `client_id` and `client_secret`

Or register via API:

```bash theme={null}
POST /v1/access/oauth-apps
{
  "name": "MyIntegration",
  "homepage_url": "https://myapp.example.com",
  "redirect_uris": ["https://myapp.example.com/oauth/callback"],
  "scopes": ["office:read", "project:read", "project:write"]
}
```

## Authorization Flow (PKCE)

```
1. Generate code_verifier and code_challenge
2. Redirect user to:
   https://access.essal.cloud/oauth/authorize
     ?client_id=YOUR_CLIENT_ID
     &redirect_uri=https://myapp.example.com/oauth/callback
     &response_type=code
     &scope=office:read project:write
     &code_challenge=BASE64URL(SHA256(verifier))
     &code_challenge_method=S256

3. User approves → redirect to your callback with ?code=AUTH_CODE

4. Exchange for tokens:
   POST https://access.essal.cloud/oauth/token
   {
     "grant_type": "authorization_code",
     "code": "AUTH_CODE",
     "redirect_uri": "https://myapp.example.com/oauth/callback",
     "client_id": "YOUR_CLIENT_ID",
     "code_verifier": "VERIFIER"
   }
```

## Token Lifetimes

| Token         | Lifetime          |
| ------------- | ----------------- |
| Access Token  | 1 hour            |
| Refresh Token | 30 days (rolling) |

## Refreshing Tokens

```bash theme={null}
POST https://access.essal.cloud/oauth/token
{
  "grant_type": "refresh_token",
  "refresh_token": "YOUR_REFRESH_TOKEN",
  "client_id": "YOUR_CLIENT_ID"
}
```

<Warning>
  Refresh tokens are rotated on each use. Store the new refresh token from every token response. Using an old refresh token will invalidate the entire session.
</Warning>

## Revoking Access

Users can revoke your app's access at any time from **Settings → Connected Apps**. Your app will receive a `401` on the next API request when access has been revoked.
