# Scopes and permissions

Ask only for the permission areas your product uses, see what each account was actually granted, and handle missing permissions.

When a user connects an account, the platform asks them to approve a list of permissions. By default Pozy asks for everything it supports on that platform, so the account can post, read analytics, answer comments and handle messages. If your product only publishes, you can ask for less. A shorter consent screen is easier to approve, and some platforms review apps by what they request.

Two different things are called permissions in Pozy:

| | Controls | Set by |
| --- | --- | --- |
| Platform scopes | What Pozy may do on the connected account (post, read insights, reply). | The user, on the platform's consent screen, from the areas you request. |
| API key permissions | What your key may do in Pozy (read only, which resource groups). | You, when you create the key. See [Authentication](https://pozy.ai/docs/getting-started/authentication). |

This page is about the first.

## Request fewer areas

Pass `scopes` with a comma-separated list of areas on the connect call:

```bash cURL
curl "https://api.pozy.ai/v1/connect/linkedin?profileId=6650c1f2a9e4b7d3c8a1f0e2&scopes=posting,analytics&redirect_url=https://app.example.com/connected" \
  -H "Authorization: Bearer $POZY_API_KEY"
```
```ts Node
const res = await fetch("https://api.pozy.ai/v1/connect/linkedin?profileId=6650c1f2a9e4b7d3c8a1f0e2&scopes=posting,analytics&redirect_url=https:%2F%2Fapp.example.com%2Fconnected", {
  headers: { Authorization: `Bearer ${process.env.POZY_API_KEY}` },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);
```
```python Python
resp = requests.get(
    "https://api.pozy.ai/v1/connect/linkedin",
    headers={"Authorization": f"Bearer {os.environ['POZY_API_KEY']}"},
    params={
        "profileId": "6650c1f2a9e4b7d3c8a1f0e2",
        "scopes": "posting,analytics",
        "redirect_url": "https://app.example.com/connected",
    },
    timeout=30,
)
```

The consent screen then lists only those areas, plus what every connection needs: the user's identity, token refresh, and the list of Pages, organizations or channels to pick from.

## Areas

| Area | What it allows |
| --- | --- |
| `posting` | Publishing, editing and deleting posts. |
| `analytics` | Post and account insights, follower counts. |
| `comments` | Reading and replying to comments, and [first comments](https://pozy.ai/docs/publishing/first-comments) on your own posts. |
| `messaging` | Reading and sending DMs in the [inbox](https://pozy.ai/docs/inbox). |
| `ads` | Ad accounts, campaigns and audiences. |

The exact platform scopes behind each area are listed per platform in the `platforms` field of [`GET /v1/connect/oauth-apps`](https://pozy.ai/docs/api/listOAuthApps).

### Which platforms accept `scopes`

| Accepts `scopes` | Rejects it (the consent screen cannot be reduced) |
| --- | --- |
| Facebook, Instagram (both login methods), LinkedIn, X, TikTok, YouTube, Threads, Pinterest, Google Business Profile, Reddit, Slack | Bluesky, Telegram, Discord, Snapchat, WhatsApp |

Sending `scopes` to a platform that rejects it, or an unknown area, returns `400 invalid_field_value` with `param: scopes`.

### Google and Microsoft

Google and Microsoft accounts require `scopes`, with their own areas:

| Area | Google | Microsoft |
| --- | --- | --- |
| `email` | Read, search, send, label and trash Gmail | Read, send, move and trash Outlook mail |
| `calendar` | Read and write events, free/busy | Read and write events, free/busy |
| `files` | Files Pozy created or the user picked in Drive | The user's OneDrive files |
| `contacts` | Read-only sync of Google Contacts | Read-only sync of Outlook contacts |

```bash
curl "https://api.pozy.ai/v1/connect/google?profileId=6650c1f2a9e4b7d3c8a1f0e2&scopes=email,calendar&loginHint=ana@acme.com" \
  -H "Authorization: Bearer $POZY_API_KEY"
```

Areas only accumulate. Connecting the same mailbox again with more areas widens the same account and keeps its `accountId`. Leaving an area out of a reconnect does not remove it: to drop one, disconnect the account and connect it again. See [Email, calendar & files](https://pozy.ai/docs/productivity).

## Ask for less, carefully

> **A posting-only account is posting-only:**
> 
> An account connected with `scopes=posting` cannot read analytics or the inbox, and first comments are skipped because they need `comments`. Adding an area later means the user connects again.

Ask for the areas you will use in the next few months, not just today. A second consent screen is a point where users drop off.

## See what was granted

Users can untick permissions on some consent screens. What you asked for and what you got can differ. [Account health](https://pozy.ai/docs/connect/account-health) shows the result:

```json
{
  "permissions": {
    "posting": [{ "scope": "w_member_social", "granted": true, "required": true }],
    "analytics": [{ "scope": "r_organization_social", "granted": false, "required": true }],
    "canPost": true,
    "canFetchAnalytics": false,
    "missingRequired": ["r_organization_social"]
  }
}
```

`canPost` and `canFetchAnalytics` are the two flags to check before you offer a feature for an account. `GET /v1/accounts/health` returns them for every account at once.

## When a permission is missing

| Signal | Platform | Fix |
| --- | --- | --- |
| `canPost` or `canFetchAnalytics` is `false` in health | Any | Reconnect with `reconnectAccountId` and the areas you need. |
| `412 account_scope_missing` on a call | Google, Microsoft | Reconnect with that area in `scopes`. |
| `412 admin_consent_required` | Microsoft work and school accounts | The organization only lets admins approve apps. `details.adminConsentUrl` is a link for their administrator; [`GET /v1/connect/microsoft/admin-consent`](https://pozy.ai/docs/api/startMicrosoftAdminConsent) creates a fresh one. |
| `missing_tiktok_permissions` on the redirect | TikTok | The user left out a permission the account needs, and nothing changed. Connect again and accept every permission. |
| `account.permissions_changed` webhook | Accounts on [your own platform app](https://pozy.ai/docs/connect/own-apps) | Your app lost one or more areas (`missingScopeAreas`), for example after a platform review. `reason` explains why. |

## Webhook events

| Event | When it fires |
| --- | --- |
| [`account.disconnected`](https://pozy.ai/docs/webhooks/events#account-disconnected) | Account disconnected. |
| [`account.permissions_changed`](https://pozy.ai/docs/webhooks/events#account-permissions-changed) | Account permissions changed. |

## Endpoints

| Endpoint | What it does |
| --- | --- |
| [`GET /v1/connect/{platform}`](https://pozy.ai/docs/api/getConnectUrl) | Get OAuth connect URL |
| [`GET /v1/accounts/{accountId}/health`](https://pozy.ai/docs/api/getAccountHealth) | Check account health |
| [`GET /v1/accounts/health`](https://pozy.ai/docs/api/getAllAccountsHealth) | Check accounts health |
| [`GET /v1/connect/oauth-apps`](https://pozy.ai/docs/api/listOAuthApps) | List your OAuth apps |
| [`GET /v1/connect/microsoft/admin-consent`](https://pozy.ai/docs/api/startMicrosoftAdminConsent) | Admin-consent link for a Microsoft tenant |
