> ## Documentation Index
> Fetch the complete documentation index at: https://humanity-eaeda8f6.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# OAuth Scopes

> Scope-based authorization model for accessing user data

Humanity Protocol uses a granular scope model to control access to user data. Apps request scopes during OAuth authorization, and users grant or deny access. Scopes determine which presets and data fields your application can access.

## Scope Hierarchy

Scopes are organized into two levels:

1. **Category scopes** - Grant access to low/medium sensitivity fields in a category
2. **Field-level scopes** - Required for high/critical sensitivity fields

```
identity:read          → Basic identity (email, phone, country, wallet)
├── identity:date_of_birth  → DOB, age, age verification
├── identity:legal_name     → Full legal name
├── identity:address_postal_code → Postal/ZIP code
└── identity:address_full   → Complete address
```

## Available Scopes

### Category Scopes

| Scope            | Description             | Fields Included                                                                                        |
| ---------------- | ----------------------- | ------------------------------------------------------------------------------------------------------ |
| `identity:read`  | Basic identity data     | `humanity_uuid`, `is_human`, `country_of_residence`, `email`, `phone`, `wallet_address`, `nationality` |
| `kyc:read`       | KYC verification status | `kyc_passed`, `kyc_last_updated_at`, `document_country`, `document_expiry_date`                        |
| `financial:read` | General financial data  | Trading frequency, exchange balances                                                                   |

### Field-Level Scopes (High Sensitivity)

| Scope                          | Description                      | Fields Included                                                  |
| ------------------------------ | -------------------------------- | ---------------------------------------------------------------- |
| `identity:date_of_birth`       | Date of birth and derived fields | `date_of_birth`, `age`, `age_over_18`, `age_over_21`             |
| `identity:legal_name`          | Legal name from ID verification  | `legal_name`                                                     |
| `identity:address_postal_code` | Postal/ZIP code                  | `address_postal_code`                                            |
| `identity:address_full`        | Complete verified address        | `address_full`                                                   |
| `kyc:document_number`          | ID document number               | `document_number`                                                |
| `financial:net_worth`          | Total net worth                  | `net_worth_total`, `net_worth_above_10k`, `net_worth_above_100k` |
| `financial:bank_balance`       | Bank account balances            | `bank_balance_total`                                             |
| `financial:loan_balance`       | Outstanding loans                | `loan_balance_total`                                             |

### Profile Scopes

| Scope          | Description                           |
| -------------- | ------------------------------------- |
| `openid`       | Required for OpenID Connect ID tokens |
| `profile.full` | Complete user profile access          |
| `data.read`    | Raw data record access                |

## Preset to Scope Mapping

Each preset requires a specific scope. Here's the mapping:

### Identity Presets

| Preset                                                    | Required Scope                 |
| --------------------------------------------------------- | ------------------------------ |
| `humanity_uuid`, `humanity_score`, `is_human`             | `identity:read`                |
| `country_of_residence`, `residency_region`, `nationality` | `identity:read`                |
| `email`, `phone`, `wallet_address`                        | `identity:read`                |
| `palm_verified`, `social_accounts`                        | `identity:read`                |
| `date_of_birth`, `age`, `age_over_18`, `age_over_21`      | `identity:date_of_birth`       |
| `legal_name`                                              | `identity:legal_name`          |
| `address_postal_code`                                     | `identity:address_postal_code` |
| `address_full`                                            | `identity:address_full`        |

### KYC Presets

| Preset                                     | Required Scope        |
| ------------------------------------------ | --------------------- |
| `kyc_passed`, `kyc_last_updated_at`        | `kyc:read`            |
| `document_country`, `document_expiry_date` | `kyc:read`            |
| `document_number`                          | `kyc:document_number` |

### Financial Presets

| Preset                                                           | Required Scope           |
| ---------------------------------------------------------------- | ------------------------ |
| `net_worth_above_10k`, `net_worth_above_100k`, `net_worth_total` | `financial:net_worth`    |
| `bank_balance_total`                                             | `financial:bank_balance` |
| `loan_balance_total`                                             | `financial:loan_balance` |

## Requesting Scopes

Request scopes during OAuth authorization:

```ts theme={null}
const { url } = sdk.buildAuthUrl({
  scopes: ['identity:read', 'identity:date_of_birth', 'kyc:read'],
  prompt: 'consent',
});
```

Or in the raw authorization URL:

```
GET /oauth/authorize?
  client_id=your_client_id&
  redirect_uri=https://yourapp.com/callback&
  response_type=code&
  scope=identity:read%20identity:date_of_birth%20kyc:read&
  code_challenge=...&
  code_challenge_method=S256
```

## Scope Validation

When accessing presets or using the query engine, the API validates that:

1. The access token has the required scope for the requested data
2. The user has consented to share that data
3. The credential is valid and not expired

If validation fails, you'll receive an `E4003` error:

```json theme={null}
{
  "error": "insufficient_scope",
  "error_code": "E4003",
  "error_description": "Token does not have the required scope: identity:date_of_birth"
}
```

## Sensitivity Levels

Scopes align with data sensitivity levels:

| Sensitivity | Description            | Example Scopes                                                 |
| ----------- | ---------------------- | -------------------------------------------------------------- |
| `low`       | Minimal privacy impact | Derived fields like `age`, `residency_region`                  |
| `medium`    | Standard PII           | `identity:read`, `kyc:read`                                    |
| `high`      | Sensitive PII          | `identity:date_of_birth`, `identity:legal_name`, `financial:*` |
| `critical`  | Highly sensitive       | Tax IDs, SSN (restricted access)                               |

## Best Practices

1. **Request minimal scopes** - Only request what you need
2. **Explain why** - Use clear consent text explaining data usage
3. **Handle scope downgrade** - Users may grant fewer scopes than requested
4. **Check granted\_scopes** - The token response includes actual granted scopes

```ts theme={null}
const token = await sdk.exchangeCodeForToken({ code, codeVerifier });

// Check what was actually granted
if (!token.granted_scopes.includes('identity:date_of_birth')) {
  // Handle case where age verification isn't available
}
```

## Discovery

Fetch available scopes from the discovery endpoint:

```bash theme={null}
curl https://api.humanity.org/v2/.well-known/hp-configuration
```

The response includes `scopes_supported` and `scopes_catalog` with detailed metadata for each scope.
