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

# OAuth Apps

> Register OAuth applications to build third-party integrations with the Mavio platform.

Register an OAuth application to let users authorize your third-party integration to access their Mavio data. Mavio implements the OAuth 2.0 authorization code flow, enabling secure delegated access without users sharing their credentials.

## Registering an OAuth app

<Steps>
  <Step title="Open developer settings">
    Navigate to **Settings > Developer > OAuth Apps** and click **Register New App**.
  </Step>

  <Step title="Fill in app details">
    Provide the following information:

    * **App name** — displayed to users during authorization
    * **Description** — brief explanation of what your app does
    * **Homepage URL** — your application's public homepage
    * **Redirect URIs** — one or more callback URLs where Mavio sends the authorization code after user consent (must use HTTPS in production)
    * **Logo** — optional app icon displayed on the consent screen
  </Step>

  <Step title="Receive credentials">
    After registration, you receive:

    * **Client ID** — a public identifier for your app (`mavio_client_xxxxxxxxxxxx`)
    * **Client Secret** — a confidential key used to exchange codes for tokens
  </Step>

  <Step title="Store credentials securely">
    Save the client secret immediately. It is shown only once. Store it in your server's environment variables or a secrets manager.
  </Step>
</Steps>

<Warning>
  Never expose your client secret in client-side code (browser JavaScript, mobile apps). Use a backend server to handle the token exchange.
</Warning>

## Authorization flow

Mavio uses the standard OAuth 2.0 authorization code flow:

```
Your App                        Mavio
  |                               |
  |-- 1. Redirect user ---------->|
  |   GET /oauth/authorize        |
  |   ?client_id=...              |
  |   &redirect_uri=...           |
  |   &scope=...                  |
  |   &state=...                  |
  |                               |
  |   2. User grants consent      |
  |                               |
  |<- 3. Redirect with code ------|
  |   GET /callback               |
  |   ?code=...&state=...         |
  |                               |
  |-- 4. Exchange code ---------->|
  |   POST /oauth/token           |
  |   code=...                    |
  |   &client_id=...              |
  |   &client_secret=...          |
  |                               |
  |<- 5. Access + refresh token --|
  |                               |
  |-- 6. API requests ----------->|
  |   Authorization: Bearer ...   |
```

### Step 1: Redirect the user

Direct the user to the Mavio authorization endpoint:

```
https://api.mavioapp.com/oauth/authorize
  ?client_id=mavio_client_xxxxxxxxxxxx
  &redirect_uri=https://yourapp.com/callback
  &scope=meetings:read+transcripts:read
  &state=random_csrf_token
  &response_type=code
```

### Step 2: User grants consent

Mavio displays a consent screen showing your app name, logo, and requested permissions. The user clicks **Authorize** or **Deny**.

### Step 3: Handle the callback

On approval, Mavio redirects to your `redirect_uri` with an authorization code:

```
https://yourapp.com/callback?code=AUTH_CODE_HERE&state=random_csrf_token
```

Always validate that the `state` parameter matches what you sent in step 1.

### Step 4: Exchange the code

Make a server-side POST request to exchange the code for tokens:

```bash theme={null}
curl -X POST https://api.mavioapp.com/oauth/token \
  -d "grant_type=authorization_code" \
  -d "code=AUTH_CODE_HERE" \
  -d "client_id=mavio_client_xxxxxxxxxxxx" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "redirect_uri=https://yourapp.com/callback"
```

### Step 5: Receive tokens

```json theme={null}
{
  "access_token": "mavio_at_xxxxxxxxxxxx",
  "refresh_token": "mavio_rt_xxxxxxxxxxxx",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "meetings:read transcripts:read"
}
```

## Scopes

Request only the scopes your application needs. See the full scope reference in [API Keys](/documentation/developer/api-keys).

## Refreshing tokens

Access tokens expire after 1 hour. Use the refresh token to obtain a new access token:

```bash theme={null}
curl -X POST https://api.mavioapp.com/oauth/token \
  -d "grant_type=refresh_token" \
  -d "refresh_token=mavio_rt_xxxxxxxxxxxx" \
  -d "client_id=mavio_client_xxxxxxxxxxxx" \
  -d "client_secret=YOUR_CLIENT_SECRET"
```

Refresh tokens are valid for 30 days. If a refresh token expires, the user must re-authorize your application.

## Managing your OAuth app

From **Settings > Developer > OAuth Apps**, you can:

* **Edit** app details, redirect URIs, and logo
* **View stats** — active authorizations count, API calls made
* **Regenerate client secret** — invalidates the current secret (update your server immediately)
* **Revoke all tokens** — immediately invalidates all user authorizations
* **Delete app** — permanently removes the app and revokes all tokens

## Troubleshooting

<AccordionGroup>
  <Accordion title="Redirect URI mismatch error">
    The `redirect_uri` in your authorization request must exactly match one of the URIs registered for your app, including protocol, host, port, and path. Check for trailing slashes and query parameters.
  </Accordion>

  <Accordion title="Invalid client secret">
    Client secrets are shown only once. If lost, regenerate the secret from the OAuth app settings. Update your server configuration immediately after regeneration.
  </Accordion>

  <Accordion title="Token expired errors">
    Access tokens expire after 1 hour. Implement automatic token refresh in your integration. If the refresh token is also expired (after 30 days of inactivity), prompt the user to re-authorize.
  </Accordion>

  <Accordion title="User denied authorization">
    If the user clicks **Deny**, Mavio redirects to your callback with `error=access_denied`. Handle this gracefully in your app with a clear message.
  </Accordion>

  <Accordion title="Scope not authorized">
    If your app requests scopes that were not approved during registration or that the user's plan does not support, the authorization fails. Request only necessary scopes and handle partial grants.
  </Accordion>
</AccordionGroup>
