Benefits are perks automatically granted when customers purchase products or subscribe. Polar handles the complete lifecycle: granting access when purchases occur, managing ongoing access, and revoking when subscriptions end.
Overview
Benefits enable you to:
Grant access to GitHub repositories
Invite customers to Discord servers
Generate and distribute license keys
Provide file downloads
Issue usage credits for metered billing
Control feature flags
Trigger custom webhooks
Benefit Types
License Keys
File Downloads
GitHub Repository
Discord Access
Meter Credit
Feature Flag
Custom
Generate unique license keys for software activation. Use cases : Software licenses, API keys, activation codes
Provide access to downloadable files. Use cases : Digital products, documents, media files
Auto-invite to private GitHub repositories. Use cases : Private code access, early access repos
Auto-invite to Discord servers with role assignment. Use cases : Community access, premium channels
Grant credits for usage-based billing. Use cases : API call credits, resource allowances
Control feature access in your application. Use cases : Premium features, beta access
Trigger webhooks for custom fulfillment. Use cases : Custom integrations, third-party services
Creating Benefits
Create benefits through the API:
License Keys
File Downloads
GitHub Repository
Discord Access
Meter Credit
Feature Flag
Custom Webhook
const benefit = await polar . benefits . create ({
organization_id: orgId ,
description: "Pro License Key" ,
type: "license_keys" ,
properties: {
prefix: "PRO" , // Optional: PRO-XXXX-XXXX
expires: {
ttl: 1 ,
timeframe: "year" // year, month, or day
},
activations: {
limit: 3 , // Max devices
enable_customer_admin: true // Allow customer to manage
},
limit_usage: 1000 // Max uses (optional)
}
});
Attaching Benefits to Products
Benefits are granted by attaching them to products:
await polar . products . updateBenefits ( productId , {
benefits: [ benefitId1 , benefitId2 , benefitId3 ]
});
When a customer purchases or subscribes:
Order/subscription is created
Benefits are automatically granted
Customer receives confirmation with benefit details
Benefit Grants
Benefit grants track individual customer access.
Viewing Grants
List grants for a benefit:
const { items : grants } = await polar . benefits . grants ( benefitId , {
is_granted: true , // Active grants only
customer_id: [ customerId ]
});
grants . forEach ( grant => {
console . log ( grant . customer . email );
console . log ( grant . properties ); // Type-specific properties
console . log ( grant . granted_at );
});
Grant Properties
Each grant type has specific properties:
License Keys
File Downloads
GitHub Repository
Discord Access
{
license_key : "PRO-1A2B-3C4D-5E6F" ,
display_key : "PRO-••••-••••-5E6F" ,
activation_url : "https://app.com/activate?key=..." ,
expires_at : "2025-01-01T00:00:00Z"
}
{
files : [
{
id: "file_xxx" ,
name: "premium-pack.zip" ,
url: "https://..."
}
]
}
{
repository_owner : "your-org" ,
repository_name : "private-repo" ,
invitation_url : "https://github.com/..."
}
{
guild_id : "123456789" ,
invitation_url : "https://discord.gg/..."
}
Benefit Lifecycle
Product Purchase
Customer purchases a product with benefits attached.
Grant Created
Benefit grants are created for the customer.
Status: is_granted: true
Access Provided
License keys generated
GitHub invitations sent
Discord roles assigned
Files made available
Active Use
Customer uses the benefit. Polar tracks usage and status.
Revocation
When subscription ends or is canceled:
is_granted: false
Access removed
Keys deactivated
License Keys
Configuration
License keys support several configuration options:
Optional prefix for generated keys (e.g., “PRO-XXXX-XXXX-XXXX”).
Set automatic expiration:
ttl: Number of time units
timeframe: year, month, or day
Limit how many devices can use a key:
limit: Max simultaneous activations (1-50)
enable_customer_admin: Allow customers to manage activations
Limit total number of uses (validations) across all activations.
Customer Management
With enable_customer_admin, customers can:
View active devices
Deactivate devices
See remaining activations
Access via customer portal
Key Validation
Validate license keys via API:
const validation = await polar . licenses . validate ({
key: "PRO-1A2B-3C4D-5E6F" ,
organization_id: orgId ,
benefit_id: benefitId ,
activation_id: deviceId // Optional: track device
});
if ( validation . valid ) {
console . log ( 'Activations:' , validation . activations );
console . log ( 'Limit:' , validation . limit );
}
File Downloads
Upload Files
Upload files through the dashboard or API:
// 1. Create upload URL
const upload = await polar . files . create ({
organization_id: orgId ,
name: "premium-pack.zip" ,
mime_type: "application/zip" ,
size: 1024000 ,
service: "downloadable"
});
// 2. Upload to signed URL
await fetch ( upload . upload_url , {
method: 'PUT' ,
body: fileData
});
// 3. Complete upload
await polar . files . complete ( upload . id );
Manage Files
Update benefit to add/remove files:
await polar . benefits . update ( benefitId , {
properties: {
files: [ fileId1 , fileId2 , newFileId ],
archived: {
[oldFileId]: true // Archive file
}
}
});
GitHub Repository Access
Setup
Install GitHub App
Install the Polar GitHub App on your organization.
Grant Repository Access
Give the app access to private repositories.
Create Benefit
Create a GitHub repository benefit with desired permission level.
Permission Levels
pull : Read-only access
triage : Read + manage issues/PRs
push : Read + write access
maintain : Push + manage settings
admin : Full control
See GitHub documentation for details.
How It Works
Customer purchases product
Polar sends GitHub invitation
Customer accepts invitation via email
Access granted with specified permission
On cancellation, access is revoked
Discord Access
Setup
Connect Discord Server
Connect your Discord server through the Polar dashboard.
Select Role
Choose which role to assign to customers.
Configure Removal
Set whether to kick members on revocation or just remove role.
How It Works
Customer purchases product
Polar generates Discord invitation
Customer joins via invitation link
Role automatically assigned
On cancellation:
Role removed
Optionally kicked from server
Meter Credits
Grant usage credits as a benefit:
const benefit = await polar . benefits . create ({
description: "1000 API Calls" ,
type: "meter_credit" ,
properties: {
meter_id: apiCallMeterId ,
credits: 1000
}
});
Credits are:
Granted when subscription starts
Replenished each billing cycle
Consumed by usage events
See Usage-Based Billing for details.
Feature Flags
Control feature access in your application:
// Check if customer has feature access
const customer = await polar . customers . get ( customerId );
const hasFeature = customer . benefits . some (
b => b . type === "feature_flag" && b . properties . key === "premium_features"
);
if ( hasFeature ) {
// Enable premium features
}
Custom Webhooks
Custom benefits trigger webhooks for your own fulfillment:
// benefit.granted webhook
{
"type" : "benefit.granted" ,
"data" : {
"customer" : { /* ... */ },
"benefit" : {
"type" : "custom" ,
"description" : "Custom Integration" ,
"properties" : {
"note" : "Trigger custom logic"
}
},
"properties" : {} // Your custom grant data
}
}
Implement your fulfillment logic in the webhook handler.
Webhooks
Listen for benefit events:
benefit.granted Benefit granted to customer
benefit.revoked Benefit revoked from customer
benefit.updated Benefit configuration updated
Updating Benefits
Update benefit configuration:
await polar . benefits . update ( benefitId , {
description: "Updated Description" ,
properties: {
// Type-specific properties
}
});
Changing properties may affect existing grants. For example, changing a license key expiration affects all issued keys.
Deleting Benefits
Delete benefits to revoke all grants:
await polar . benefits . delete ( benefitId );
All grants are immediately revoked
Access removed for all customers
Cannot be undone
Remove from products first to prevent new grants
Best Practices
Set reasonable activation limits (3-5 for most software)
Enable customer admin for better experience
Use prefixes to identify product tiers
Set expiration for time-limited licenses
Use versioning in file names
Archive old files instead of deleting
Keep file sizes reasonable (under 100MB)
Provide multiple formats when possible
Use minimum required permission level
Create dedicated repos for customers
Document access in README
Monitor repository access logs
Create dedicated customer roles
Set up proper channel permissions
Choose kick settings carefully
Welcome new members automatically
Keep benefit names clear and descriptive
Test fulfillment before attaching to products
Group related benefits on the same product
Document benefit usage for customers
API Reference
Create Benefit Create a new benefit
List Benefits Query benefits with filters
Update Benefit Modify benefit configuration
Delete Benefit Remove benefit and revoke grants
List Grants View benefit grants