> For the complete documentation index, see [llms.txt](https://developer.paddle.com/llms.txt).

# Permissions

Limit an API key's access to specific entities and actions in Paddle.

---

Permissions grant an API key access to specific entities or allow it to take specific actions in Paddle.

You can assign permissions to a key when creating or updating it.

If your key doesn't have the correct permissions, it returns a [`forbidden`](https://developer.paddle.com/errors/shared/forbidden.md) error (403).

## Permission types

Each permission targets an entity, like [products](https://developer.paddle.com/api-reference/products.md), [customers](https://developer.paddle.com/api-reference/customers.md), or [transactions](https://developer.paddle.com/api-reference/transactions.md), and is one of two types:

- `entity.read`  
  Read and list the entity, or use it with the [`include` parameter](https://developer.paddle.com/api-reference/about/include-entities#use-include-parameter.md). Applies to `GET` requests and preview requests (`POST` or `PATCH`).
- `entity.write`  
  Create, update, archive, and delete the entity. Applies to `POST`, `PATCH`, and `DELETE` requests. Write permission automatically includes read.

## When permissions are required

Your API key needs permissions when working with:

- **Operations that access entities**  
  Your key needs permission for any entity an operation returns or acts on. For example, [listing adjustments](https://developer.paddle.com/api-reference/adjustments/list-adjustments.md) requires the `adjustment.read` permission.
- **Responses that use the `include` parameter**  
  Your key needs read permission for any entity added via the [`include` parameter](https://developer.paddle.com/api-reference/about/include-entities#use-include-parameter.md). For example, [listing prices](https://developer.paddle.com/api-reference/prices/list-prices.md) with `include=product` requires both `price.read` and `product.read` permissions.
- **Entities that return customer portal URLs**  
  Authenticated [customer portal](https://developer.paddle.com/concepts/customer-portal.md) URLs are only returned if the key has `customer_portal_session.write`. For example, without the `customer_portal_session.write` permission, [listing subscriptions](https://developer.paddle.com/api-reference/subscriptions/list-subscriptions.md) doesn't return the `management_urls` object containing authenticated links.
- **Entities populated in simulated webhooks**  
  When simulating webhooks using real data, your API key needs permission to read the entity and any related entities included in webhook payloads but not nested in the parent. For example, [creating a notification simulation](https://developer.paddle.com/api-reference/notification-simulations/create-simulation.md) with `config.entities.subscription_id` requires the `subscription.read` permission or the request fails.
  
{% callout type="info" %}
When using real data in simulated webhooks, permissions are also required for related entities to the parent entity. For example, without the `transaction.read` permission, related transactions for a real subscription fall back to static examples in simulated payloads.
{% /callout %}

## When permissions aren't required

Your API key doesn't need permissions when working with:

- **Nested entities in responses**  
  Entities nested within a response are included regardless of permissions. For example, a [transaction response](https://developer.paddle.com/api-reference/transactions/get-transaction.md) contains [prices](https://developer.paddle.com/api-reference/prices.md) in the `items` array. These are included even if you only have `transaction.read` permission and not `price.read`.
- **Indirectly created or updated entities**  
  Operations that indirectly create or update entities don't require write permission for those entities. For example, [creating an adjustment](https://developer.paddle.com/api-reference/adjustments/create-adjustment.md) that updates a [transaction](https://developer.paddle.com/api-reference/transactions.md) only requires `adjustment.write`, not `transaction.write`.
- **Parent entities**  
  You don't need permissions for a parent entity to access its child. For example, [retrieving an address for a customer](https://developer.paddle.com/api-reference/addresses/get-address.md) uses both `address` and `customer` path parameters, but only requires `address.read`, not `customer.read`.

## Available permissions

| Entity | Permission |
|---|---|
| [**Products**](https://developer.paddle.com/api-reference/products.md) | `product.read` |
| [**Products**](https://developer.paddle.com/api-reference/products.md) | `product.write` |
| [**Prices**](https://developer.paddle.com/api-reference/prices.md) | `price.read` |
| [**Prices**](https://developer.paddle.com/api-reference/prices.md) | `price.write` |
| [**Discounts**](https://developer.paddle.com/api-reference/discounts.md) | `discount.read` |
| [**Discounts**](https://developer.paddle.com/api-reference/discounts.md) | `discount.write` |
| [**Customers**](https://developer.paddle.com/api-reference/customers.md) | `customer.read` |
| [**Customers**](https://developer.paddle.com/api-reference/customers.md) | `customer.write` |
| [**Addresses**](https://developer.paddle.com/api-reference/addresses.md) | `address.read` |
| [**Addresses**](https://developer.paddle.com/api-reference/addresses.md) | `address.write` |
| [**Businesses**](https://developer.paddle.com/api-reference/businesses.md) | `business.read` |
| [**Businesses**](https://developer.paddle.com/api-reference/businesses.md) | `business.write` |
| [**Payment methods**](https://developer.paddle.com/api-reference/payment-methods.md) | `payment_method.read` |
| [**Payment methods**](https://developer.paddle.com/api-reference/payment-methods.md) | `payment_method.write` |
| [**Customer authentication tokens**](https://developer.paddle.com/api-reference/customers/generate-customer-authentication-token.md) | `customer_auth_token.write` |
| [**Customer portal sessions**](https://developer.paddle.com/api-reference/customer-portal-sessions.md) | `customer_portal_session.write` |
| [**Transactions**](https://developer.paddle.com/api-reference/transactions.md) | `transaction.read` |
| [**Transactions**](https://developer.paddle.com/api-reference/transactions.md) | `transaction.write` |
| [**Subscriptions**](https://developer.paddle.com/api-reference/subscriptions.md) | `subscription.read` |
| [**Subscriptions**](https://developer.paddle.com/api-reference/subscriptions.md) | `subscription.write` |
| [**Adjustments**](https://developer.paddle.com/api-reference/adjustments.md) | `adjustment.read` |
| [**Adjustments**](https://developer.paddle.com/api-reference/adjustments.md) | `adjustment.write` |
| [**Pricing preview**](https://developer.paddle.com/api-reference/pricing-preview.md) | `transaction.read` |
| [**Reports**](https://developer.paddle.com/api-reference/reports.md) | `report.read` |
| [**Reports**](https://developer.paddle.com/api-reference/reports.md) | `report.write` |
| [**Metrics**](https://developer.paddle.com/api-reference/metrics.md) | `metrics.read` |
| [**Events**](https://developer.paddle.com/api-reference/events.md) | `notification.read` |
| [**Notification settings**](https://developer.paddle.com/api-reference/notification-settings.md) | `notification_setting.read` |
| [**Notification settings**](https://developer.paddle.com/api-reference/notification-settings.md) | `notification_setting.write` |
| [**Notifications**](https://developer.paddle.com/api-reference/notifications.md) | `notification.read` |
| [**Notifications**](https://developer.paddle.com/api-reference/notifications.md) | `notification.write` |
| [**Notification logs**](https://developer.paddle.com/api-reference/notification-logs.md) | `notification.read` |
| [**Simulations**](https://developer.paddle.com/api-reference/notification-simulations.md) | `notification_simulation.read` |
| [**Simulations**](https://developer.paddle.com/api-reference/notification-simulations.md) | `notification_simulation.write` |
| [**Simulation runs**](https://developer.paddle.com/api-reference/notification-simulation-runs.md) | `notification_simulation.read` |
| [**Simulation runs**](https://developer.paddle.com/api-reference/notification-simulation-runs.md) | `notification_simulation.write` |
| [**Simulation run events**](https://developer.paddle.com/api-reference/notification-simulation-events.md) | `notification_simulation.read` |
| [**Simulation run events**](https://developer.paddle.com/api-reference/notification-simulation-events.md) | `notification_simulation.write` |
| [**Client-side tokens**](https://developer.paddle.com/api-reference/client-side-tokens.md) | `client_tokens.read` |
| [**Client-side tokens**](https://developer.paddle.com/api-reference/client-side-tokens.md) | `client_tokens.write` |

## Best practices

- **Follow the principle of least privilege.**  
  Only assign the permissions a key actually needs. A key used to sync product catalog data doesn't need `transaction.write`.
- **Create separate keys per integration or team.**  
  Issue a distinct key per system or team so you can revoke access without affecting others.
- **Review and rotate keys when access requirements change.**  
  When access requirements change, update the key rather than leaving unused permissions in place.