Permissions
Limit an API key's access to specific entities and actions in Paddle.
Permissions control what API keys can do. They help you keep data secure by limiting each key to only the access it needs. You can create different keys with tailored permissions for different users, teams, or systems. This acts as a guardrail, preventing unauthorized access to your entire account.
When creating or updating an API key, you can assign it specific permissions.
Permissions are scoped to specific entities in Paddle, such as products, customers, or transactions. You can select two types of permission to determine what the key can do with an entity:
Read -
Entity (Read)or{entity}.readRead, list, and use the
includeparameter to include the entity in a response. Works forGETrequests and preview requests (usingPOSTorPATCH).Write -
Entity (Write)or{entity}.writeCreate, update, archive, and delete the entity. Works for
POST,PATCH, andDELETErequests. Having write permission for an entity automatically includes read permission for that entity.
Select the correct permissions
The permissions a key needs depend on the operation being performed and what entities it's accessing.
Permissions required
You do need permissions when working with:
Operations that access entities
For operations that return or take action on an entity, your API key needs permission for that entity.
Example: Listing adjustments requires the
adjustment.readpermission.Responses enriched with entities
When using the
includeparameter to enrich a response, your API key needs permission for any included entities.Example: Listing prices with
include=productrequires bothprice.readandproduct.readpermissions.Entities that return customer portal URLs
When a response can include authenticated URLs linking to the customer portal, your API key needs the
customer_portal_session.writepermission or they are not returned.Example: Without the
customer_portal_session.writepermission, listing subscriptions doesn't return themanagement_urlsobject containing authenticated links.Entities to populate in simulated webhooks
When providing an entity ID in
config.entities, your API key needs permission to read that entity and any related entities included in webhook payloads but not nested in the parent. For the entity you're attempting to populate, the request fails without the read permission. For related entities, static examples are used if the key has no read permissions.Example: Creating a notification simulation with
config.entities.subscription_idrequires thesubscription.readpermission or the request fails. Without thetransaction.readpermission, related transactions will fall back to static examples in simulated payloads. Transactions aren't nested in subscriptions by default.
Permissions not required
You don't need permissions when working with:
Nested entities in responses
When an operation returns different entities within the primary entity's response, these nested entities are included even without specific permissions for them.
Example: A transaction response contains prices in the
itemsarray. These are included even if you only havetransaction.readpermission and notprice.read.Indirectly created or updated entities
Operations that indirectly create or update entities don't require additional write permissions for those generated entities.
Example: Creating an adjustment that updates a transaction only requires
adjustment.write, nottransaction.write.Parent entities
If an entity has a parent entity, it isn't a prerequisite that the permissions for the parent entities are needed.
Example: Retrieving an address for a customer uses both
addressandcustomerpath parameters, but only requiresaddress.read, notcustomer.read.
Requests made with API keys that don't have the required permissions return a
forbiddenerror (403).
Available permissions
| Entity | Permission | Operations |
|---|---|---|
| Products | product.read | |
product.write | ||
| Prices | price.read | |
price.write | ||
| Discounts | discount.read | |
discount.write | ||
| Customers | customer.read | |
customer.write | ||
| Addresses | address.read | |
address.write | ||
| Businesses | business.read | |
business.write | ||
| Payment methods | payment_method.read | |
payment_method.write | ||
| Customer authentication tokens | customer_auth_token.write | |
| Customer portal sessions | customer_portal_session.write | |
| Transactions | transaction.read | |
transaction.write | ||
| Subscriptions | subscription.read | |
subscription.write | ||
| Adjustments | adjustment.read | |
adjustment.write | ||
| Pricing preview | transaction.read | |
| Reports | report.read | |
report.write | ||
| Events | notification.read | |
| Notification settings | notification_setting.read | |
notification_setting.write | ||
| Notifications | notification.read | |
notification.write | ||
| Notification logs | notification.read | |
| Simulations | notification_simulation.read | |
notification_simulation.write | ||
| Simulation runs | notification_simulation.read | |
notification_simulation.write | ||
| Simulation run events | notification_simulation.read | |
notification_simulation.write | ||
| Client-side tokens | client_tokens.read | |
client_tokens.write |