# Polar
> ## Documentation Index
---
# Source: https://polar.sh/docs/merchant-of-record/acceptable-use.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# null
As your Merchant of Record (MoR), we are the reseller of all digital goods and
services and focus exclusively on digital products. Therefore we cannot support
physical goods or entirely human services, e.g consultation or support. In
addition to not accepting the sale of anything illegal, harmful, abusive,
deceptive or sketchy.
## Acceptable Products & Businesses
* Software & SaaS
* Digital products: Templates, eBooks, PDFs, code, icons, fonts, design assets, photos, videos, audio etc
* Premium content & access: Discord server, GitHub repositories, courses and content requiring a subscription.
**General rule of acceptable services**
Digital goods, software or services that can be fulfilled by…
1. Polar on your behalf (License Keys, File Downloads, GitHub- or Discord invites or private links, e.g premium YouTube videos etc)
2. Your site/service using our APIs to grant immediate access to digital assets
or services for customers with a one-time purchase or subscriptions
Combined with being something you’d proudly boast about in public, i.e nothing illegal, unfair, deceptive, abusive, harmful or shady.
Don’t hesitate to [reach out to us](/support) in advance in case you’re unsure if your use case would be approved.
## Prohibited Businesses
**Not an exhaustive list**
We reserve the right to add to it at any time. Combined with placing your
account under further review or suspend it in case we consider the usage
deceptive, fraudulent, high-risk or of low quality for consumers with high
refund/chargeback risks.
* Illegal or age restricted, e.g drugs, alcohol, tobacco or vaping products
* Violates laws in the jurisdictions where your business is located or to which your business is targeted
* Violates any rules or regulations from payment processors & credit card networks, e.g [Stripe](https://stripe.com/en-se/legal/restricted-businesses)
* Reselling or distributing customer data to other parties for commercial, promotional or any other reason (disclosed service providers are accepted).
* Threatens reputation of Polar or any of our partners and payment providers
* Causes or has a significant risk of refunds, chargebacks, fines, damages, or harm and liability
* Services used by-, intended for or advertised towards minors
* Physical goods of any kind. Including SaaS services offering or requiring fulfilment via physical delivery or human services.
* Human services, e.g marketing, design, web development and consulting in general.
* Donations or charity, i.e price is greater than product value or there is no exchange at all (pure money transfer). Open source maintainers with sponsorship can be supported - reach out.
* Marketplaces. Selling others’ products or services using Polar against an upfront payment or with an agreed upon revenue share.
* Adult services or content. Including by AI or proxy, e.g
* AI Girlfriend/Boyfriend services.
* OnlyFans related services.
* Explicit/NSFW content generated with AI
* Low-quality products, services or sites, e.g
* E-books generated with AI or 4 pages sold for \$50
* Quickly & poorly executed websites, products or services
* Services with a lot of bugs and issues
* Products, services or websites we determine to have a low trust score
* Fake testimonials, reviews, social proof, and review inflation platforms. It's deceptive to consumers which is behaviour we do not tolerate.
* Trademark violations
* "Get rich" schemes or content
* Gambling & betting services (including lootboxes, mystery boxes and pack openings of random nature)
* Regulated services or products
* Counterfeit goods
* Job boards
* NFT & Crypto assets.
* Cheating: Utilizing macros, cheat codes, hacks, or any unauthorized modifications that alter gameplay or provide an unfair advantage.
* Reselling Licenses: Selling, distributing, or otherwise transferring software licenses at reduced prices or without proper authorization.
* Services to circumvent rules or terms of other services: Attempting to bypass, manipulate, or undermine any established rules, gameplay mechanics, or pricing structures of other vendors/games.
* Financial services, e.g facilitating transactions, investments or balances for customers.
* Financial trading, trading bots, brokerage, or investment advisory services (including insights platforms).
* Financial advice, e.g content or services related to tax guidance, wealth management, trading signals, investment strategies etc.
* IPTV services
* Virus & Spyware
* Telecommunication & eSIM Services
* Products you don’t own the IP of or have the required licenses to resell
* Advertising & unsolicited marketing services. Including services to:
* Generate, scrape or sell leads
* Send SMS/WhatsApp messages in bulk
* Automate outreach (spam risks)
* Automate mass content generation & submission across sites
* API & IP cloaking services, e.g services to circumvent IP bans, API rate limits etc.
* Products or services associated with pseudo-science; clairvoyance, horoscopes, fortune-telling etc.
* Travel services, reservation services, travel clubs and timeshares
* Medical advice services or products, e.g. pharmaceutical, weight loss, muscle building
* Watermark removal services
* Third-party content downloaders (e.g., YouTube, Instagram, Snapchat, etc.)
## Restricted Businesses
Requires closer review and a higher bar of quality, execution, trust and compliance
standards to be accepted.
* Directories & boards
* Marketing services
* Pre-orders & Paid waitlist
* Ticket sales
* eBooks
## FAQ
**Why do directories & boards require closer review?**
They often sell premium placement, i.e ads, without meeting compliance
requirements for advertising. Or even where it's their sole purpose to sell
placement.
**Why do marketing services require closer review?**
Too many services offer sketchy marketing tactics and mass outreach
(unsolicited) features. There is no short-cut to sales beyond offering a great
product & service. We love marketing services that reflect that and focus on the
long game vs. shortcuts and hacks.
**Can I sell pre-orders or use paid waitlists for my service to validate demand
before build?**
Generally, no. It's a high risk category for us as the Merchant of Record.
Sellers could withdraw funds and never deliver the service or not as promised.
Causing consumers to demand refunds or dispute the sale against us at a later
date.
For high-trust cases from developers with a track record, we're able to make
exceptions, but simultaneously need to adapt our payout process to withhold all
funds until verified fulfilment.
**Why are marketplaces or human services (consultancy) not allowed?**
We hope to change this status quo amongst Merchants of Record long-term, but
both come with additional compliance and risk challenges. Since fulfilment is
not digital, immediate or between known parties to us, we cannot fulfil our
compliance & risk requirements or effectively mitigate potential disputes.
**Why are OnlyFans services not allowed?**
Close & blurred lines between the service and the content & service provided on
OnlyFans, i.e often adult content. In addition to us having seen
fraudulent & deceptive behavior in the category. We're simply not comfortable
acting as the Merchant of Record here.
---
# Source: https://polar.sh/docs/merchant-of-record/account-reviews.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# null
As a Merchant of Record (MoR), we act as the reseller of digital goods and services. Therefore, we need to make sure that businesses using Polar complies with our [acceptable products & use](/merchant-of-record/acceptable-use) policies. Combined with continuously monitoring, reviewing and preventing fraud, unacceptable use, bad actors and high risk accounts.
Account reviews are typically completed within a week on average. However, sometimes it can take longer due to weekends, holidays etc. We process them as quickly as possible and resolve every single one.
### First payout review
You will need to go through our main review ahead of the initial payout. We’ll reach out over email for:
1. A quick survey about your business, products and intended use case with Polar.
2. Identity verification (KYC) using Passport/ID Card/Driver License and a selfie. It’s secure, easy and quick to submit using Stripe Identity.
We need to perform this review to ensure compliance with our [acceptable products & use](/merchant-of-record/acceptable-use) policy. Combined with meeting our own KYC/AML requirements as a billing platform.
**Submit upfront (Soon)**
We’ll soon offer the ability to submit all of this information in advance to speed up the initial payout even further and without concern of any issues or delays.
### Continuous reviews (Async)
We continuously monitor all transactions across our platform to proactively prevent fraud. In addition to performing asynchronous reviews of accounts at certain sale thresholds. These reviews are often completed within a day or two and without any additional information required from you.
You’ll get notified over email that a review is taking place. Payouts will be paused during this time, but it has no impact on your customers’ experience or ability to purchase, subscribe or checkout at any time.
We look at:
* Risk scores across historic transactions
* Refunds & Chargebacks ratio
* Appropriate next sales threshold for a review given the above
**High chargeback ratios**
Credit card networks, e.g Visa/Mastercard, consider 0.7% of sales in chargebacks excessive. Exceeding it can lead to monitoring programs with high costs, penalties and ultimately termination.
We therefore reach out proactively to collaborate on maintaining a low chargeback ratio and reducing it ahead of getting close to these thresholds.
## Operational Guidelines
To maintain platform integrity and ensure smooth operations, we have established clear guidelines for merchants using Polar.
#### Expected Responsiveness
We expect merchants to maintain high standards of customer support and responsiveness to their customers:
* **Support Ticket Management**: Maintain a low rate of support tickets from customers
* **Merchant Communication**: When we include you in customer support communications, we require a response within 48 hours
* If no response is received within 48 hours, we may issue refunds to affected customers and a warning to merchants
* In case of repeated issues, we'll have to offboard unresponsive merchants
* **Customer Service Quality**: We evaluate your customer service history and approach when determining appropriate actions
#### Test Transactions
To maintain platform security and prevent abuse:
* **Use Sandbox Environment or 100% Discounts**: All testing must be conducted using our sandbox environment. Want to test in production? Use a Free Product or a 100% Discount code to avoid using real money.
* **No Real Money Testing**: Any such transactions are prohibited and will be refunded. It's against the terms of payment service providers, triggers our account reviews and can potentially lead to the card or account getting blocked since it can be flagged as "card testing".
#### Chargeback Management
We monitor chargeback rates closely to protect both merchants and customers:
* **Acceptable Threshold**: We maintain a chargeback rate threshold of 0.4% for merchants
* **Timeframe**: Chargebacks can be filed up to 120 days from the original transaction date
* **Consequences of High Chargeback Rates**:
We work proactively to maintain a low chargeback rate throughout the platform and strive to collaborate with merchants at risk of exceeding our thresholds to reverse the trend. However, we reserve the right to (in order of severity):
* Refund transactions as needed
* Pause payouts pending review – up until the timeframe for chargebacks have been surpassed
* Pause future payments
* Block accounts and refund customers
We don't take this responsibility or actions lightly, and always strive to mitigate and avoid them, but have to take appropriate and proactive actions in case of issues.
We also have integrations with credit card networks to receive early chargeback signals before they're officially filed. We automatically refund such transactions under a certain value and cancel any subscriptions associated with the customer to reduce chargebacks proactively.
#### Policy Violations
For merchants who violate our [acceptable use policies](/merchant-of-record/acceptable-use) (and don't have high chargeback rates):
* **Immediate Action**: We will offboard merchants who violate our policies
* **Payment Processing**: All payment processing will be blocked
* **Payout Management**: Payouts will be paused pending review
* **Resolution Process**:
* We may conduct test transactions to verify account status
* In case of strong suspicion of fraud or intentional abuse, we block the account immediately
* We reach out merchants about the issue and give them 48 hours to respond
* Failure to respond may result in refunds to affected customers
* We pause future payments in the meantime if deemed necessary
* We pause payouts during the resolution process
* We strive to collaborate with merchants on the best possible path forward. Clear fraud or abuse, however, is immediately blocked.
* We have to cancel subscriptions and refund payments made in violation of our acceptable use policies for compliance and risk, and strive to do so in collaboration with the merchant.
## Frequently Asked Questions
### Why is my account under review again?
Your account may go through multiple reviews as your business grows. We perform [continuous reviews](#continuous-reviews-async) at certain sales thresholds to maintain platform integrity and prevent fraud. This is a standard practice across payment platforms and is part of our ongoing risk management process.
### Why do you need my social media in settings?
We request social media information as part of our identity verification and fraud prevention processes. This helps us:
* Verify that you're a real business or creator with an online presence
* Understand your products and services better
* Ensure compliance with our [acceptable use policies](/merchant-of-record/acceptable-use)
Providing accurate social media information helps speed up the review process and demonstrates the legitimacy of your business.
### Are social media settings visible publicly?
No, your social media settings are not publicly visible. This information is used internally for verification and compliance purposes only. We treat all merchant information with strict confidentiality and use it solely for risk assessment and account review processes.
### Why do I need to share a video recording showing the product working?
To help us verify that everything is working correctly in line with our acceptable use policy, our team would ask you to share a 100% discount code by email. This is our preferred method, as it allows the team to go through the full journey themselves and confirm the automated fulfillment from an unpaid user to a paid user.
Alternatively, you can provide a video recording that clearly shows the complete flow from an unpaid user to a paid user, including how the product is automatically accessible after purchase.
### How does changing the admin of an organization work?
To change the admin of an organization:
1. Invite the new admin to the team via `Settings` > `Members` in the Polar dashboard
2. Ask that new admin to complete identity verification under `Finance` > `Account` after logging in via that email in the Polar dashboard
3. Make sure no payout is pending
4. Send an email from the current admin email to our support confirming the transfer to the new admin
If you need assistance with changing organization ownership or have special circumstances, please contact [support@polar.sh](mailto:support@polar.sh).
---
# Source: https://polar.sh/docs/features/finance/accounts.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Setup a Payout Account
## Connect Payout Account
You need to setup an account so that we can issue [payouts](/features/finance/payouts).
1. Go to the `Finance` page in your Polar dashboard
2. Click `Setup` in the card shown above in your dashboard
3. Choose account type & follow their setup instructions
*This is only required the first time and you can do this proactively too in order - recommended to avoid any additional delays.*
### Stripe Connect Express
Stripe is the default and recommended option since it enables instant transfers.
---
# Source: https://polar.sh/docs/api-reference/license-keys/activate.md
# Source: https://polar.sh/docs/api-reference/customer-portal/license-keys/activate.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Activate License Key
> Activate a license key instance.
> This endpoint doesn't require authentication and can be safely used on a public
> client, like a desktop application or a mobile app.
> If you plan to validate a license key on a server, use the `/v1/license-keys/activate`
> endpoint instead.
You only need to use this endpoint if you have device **activations** enabled on the license key benefit. You then use this endpoint to reserve an allocation for a specific device. Storing the unique activation ID from the response on the device and using it as extra validation in the [/validate](/api-reference/customer-portal/license-keys/validate) endpoint.
Not using **activations**? Just use the [/validate](/api-reference/customer-portal/license-keys/validate) endpoint directly instead.
## OpenAPI
````yaml post /v1/customer-portal/license-keys/activate
openapi: 3.1.0
info:
title: Polar API
summary: Polar HTTP and Webhooks API
description: Read the docs at https://polar.sh/docs/api-reference
version: 0.1.0
servers:
- url: https://api.polar.sh
description: Production environment
x-speakeasy-server-id: production
- url: https://sandbox-api.polar.sh
description: Sandbox environment
x-speakeasy-server-id: sandbox
security:
- access_token: []
tags:
- name: public
description: >-
Endpoints shown and documented in the Polar API documentation and
available in our SDKs.
- name: private
description: >-
Endpoints that should appear in the schema only in development to generate
our internal JS SDK.
- name: mcp
description: Endpoints enabled in the MCP server.
paths:
/v1/customer-portal/license-keys/activate:
post:
tags:
- customer_portal
- license_keys
- public
summary: Activate License Key
description: >-
Activate a license key instance.
> This endpoint doesn't require authentication and can be safely used on
a public
> client, like a desktop application or a mobile app.
> If you plan to validate a license key on a server, use the
`/v1/license-keys/activate`
> endpoint instead.
operationId: customer_portal:license_keys:activate
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/LicenseKeyActivate'
required: true
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/LicenseKeyActivationRead'
'403':
description: >-
License key activation not supported or limit reached. Use /validate
endpoint for licenses without activations.
content:
application/json:
schema:
$ref: '#/components/schemas/NotPermitted'
'404':
description: License key not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ResourceNotFound'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
security:
- {}
components:
schemas:
LicenseKeyActivate:
properties:
key:
type: string
title: Key
organization_id:
type: string
format: uuid4
title: Organization Id
label:
type: string
title: Label
conditions:
additionalProperties:
anyOf:
- type: string
maxLength: 500
minLength: 1
- type: integer
- type: number
- type: boolean
propertyNames:
maxLength: 40
minLength: 1
type: object
maxProperties: 50
title: Conditions
description: >-
Key-value object allowing you to set conditions that must match when
validating the license key.
The key must be a string with a maximum length of **40 characters**.
The value must be either:
* A string with a maximum length of **500 characters**
* An integer
* A floating-point number
* A boolean
You can store up to **50 key-value pairs**.
meta:
additionalProperties:
anyOf:
- type: string
maxLength: 500
minLength: 1
- type: integer
- type: number
- type: boolean
propertyNames:
maxLength: 40
minLength: 1
type: object
maxProperties: 50
title: Meta
description: >-
Key-value object allowing you to store additional information about
the activation
The key must be a string with a maximum length of **40 characters**.
The value must be either:
* A string with a maximum length of **500 characters**
* An integer
* A floating-point number
* A boolean
You can store up to **50 key-value pairs**.
type: object
required:
- key
- organization_id
- label
title: LicenseKeyActivate
LicenseKeyActivationRead:
properties:
id:
type: string
format: uuid4
title: Id
license_key_id:
type: string
format: uuid4
title: License Key Id
label:
type: string
title: Label
meta:
additionalProperties:
anyOf:
- type: string
- type: integer
- type: number
- type: boolean
type: object
title: Meta
created_at:
type: string
format: date-time
title: Created At
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
license_key:
$ref: '#/components/schemas/LicenseKeyRead'
type: object
required:
- id
- license_key_id
- label
- meta
- created_at
- modified_at
- license_key
title: LicenseKeyActivationRead
NotPermitted:
properties:
error:
type: string
const: NotPermitted
title: Error
examples:
- NotPermitted
detail:
type: string
title: Detail
type: object
required:
- error
- detail
title: NotPermitted
ResourceNotFound:
properties:
error:
type: string
const: ResourceNotFound
title: Error
examples:
- ResourceNotFound
detail:
type: string
title: Detail
type: object
required:
- error
- detail
title: ResourceNotFound
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
type: object
title: HTTPValidationError
LicenseKeyRead:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
organization_id:
type: string
format: uuid4
title: Organization Id
customer_id:
type: string
format: uuid4
title: Customer Id
customer:
$ref: '#/components/schemas/LicenseKeyCustomer'
benefit_id:
type: string
format: uuid4
title: Benefit Id
description: The benefit ID.
x-polar-selector-widget:
displayProperty: description
resourceName: Benefit
resourceRoot: /v1/benefits
key:
type: string
title: Key
display_key:
type: string
title: Display Key
status:
$ref: '#/components/schemas/LicenseKeyStatus'
limit_activations:
anyOf:
- type: integer
- type: 'null'
title: Limit Activations
usage:
type: integer
title: Usage
limit_usage:
anyOf:
- type: integer
- type: 'null'
title: Limit Usage
validations:
type: integer
title: Validations
last_validated_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Last Validated At
expires_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Expires At
type: object
required:
- id
- created_at
- modified_at
- organization_id
- customer_id
- customer
- benefit_id
- key
- display_key
- status
- limit_activations
- usage
- limit_usage
- validations
- last_validated_at
- expires_at
title: LicenseKeyRead
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
msg:
type: string
title: Message
type:
type: string
title: Error Type
type: object
required:
- loc
- msg
- type
title: ValidationError
LicenseKeyCustomer:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the customer.
examples:
- 992fae2a-2a17-4b7a-8d9e-e287cf90131b
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
metadata:
$ref: '#/components/schemas/MetadataOutputType'
external_id:
anyOf:
- type: string
- type: 'null'
title: External Id
description: >-
The ID of the customer in your system. This must be unique within
the organization. Once set, it can't be updated.
examples:
- usr_1337
email:
type: string
title: Email
description: >-
The email address of the customer. This must be unique within the
organization.
examples:
- customer@example.com
email_verified:
type: boolean
title: Email Verified
description: >-
Whether the customer email address is verified. The address is
automatically verified when the customer accesses the customer
portal using their email address.
examples:
- true
type:
anyOf:
- $ref: '#/components/schemas/CustomerType'
- type: 'null'
description: >-
The type of customer: 'individual' for single users, 'team' for
customers with multiple members. Legacy customers may have NULL type
which is treated as 'individual'.
examples:
- individual
name:
anyOf:
- type: string
- type: 'null'
title: Name
description: The name of the customer.
examples:
- John Doe
billing_address:
anyOf:
- $ref: '#/components/schemas/Address'
- type: 'null'
tax_id:
anyOf:
- prefixItems:
- type: string
- $ref: '#/components/schemas/TaxIDFormat'
type: array
maxItems: 2
minItems: 2
examples:
- - '911144442'
- us_ein
- - FR61954506077
- eu_vat
- type: 'null'
title: Tax Id
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the customer.
examples:
- 1dbfc517-0bbf-4301-9ba8-555ca42b9737
deleted_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Deleted At
description: Timestamp for when the customer was soft deleted.
avatar_url:
type: string
title: Avatar Url
examples:
- https://www.gravatar.com/avatar/xxx?d=404
type: object
required:
- id
- created_at
- modified_at
- metadata
- external_id
- email
- email_verified
- name
- billing_address
- tax_id
- organization_id
- deleted_at
- avatar_url
title: LicenseKeyCustomer
LicenseKeyStatus:
type: string
enum:
- granted
- revoked
- disabled
title: LicenseKeyStatus
MetadataOutputType:
additionalProperties:
anyOf:
- type: string
- type: integer
- type: number
- type: boolean
type: object
CustomerType:
type: string
enum:
- individual
- team
title: CustomerType
Address:
properties:
line1:
anyOf:
- type: string
- type: 'null'
title: Line1
line2:
anyOf:
- type: string
- type: 'null'
title: Line2
postal_code:
anyOf:
- type: string
- type: 'null'
title: Postal Code
city:
anyOf:
- type: string
- type: 'null'
title: City
state:
anyOf:
- type: string
- type: 'null'
title: State
country:
type: string
enum:
- AD
- AE
- AF
- AG
- AI
- AL
- AM
- AO
- AQ
- AR
- AS
- AT
- AU
- AW
- AX
- AZ
- BA
- BB
- BD
- BE
- BF
- BG
- BH
- BI
- BJ
- BL
- BM
- BN
- BO
- BQ
- BR
- BS
- BT
- BV
- BW
- BY
- BZ
- CA
- CC
- CD
- CF
- CG
- CH
- CI
- CK
- CL
- CM
- CN
- CO
- CR
- CU
- CV
- CW
- CX
- CY
- CZ
- DE
- DJ
- DK
- DM
- DO
- DZ
- EC
- EE
- EG
- EH
- ER
- ES
- ET
- FI
- FJ
- FK
- FM
- FO
- FR
- GA
- GB
- GD
- GE
- GF
- GG
- GH
- GI
- GL
- GM
- GN
- GP
- GQ
- GR
- GS
- GT
- GU
- GW
- GY
- HK
- HM
- HN
- HR
- HT
- HU
- ID
- IE
- IL
- IM
- IN
- IO
- IQ
- IR
- IS
- IT
- JE
- JM
- JO
- JP
- KE
- KG
- KH
- KI
- KM
- KN
- KP
- KR
- KW
- KY
- KZ
- LA
- LB
- LC
- LI
- LK
- LR
- LS
- LT
- LU
- LV
- LY
- MA
- MC
- MD
- ME
- MF
- MG
- MH
- MK
- ML
- MM
- MN
- MO
- MP
- MQ
- MR
- MS
- MT
- MU
- MV
- MW
- MX
- MY
- MZ
- NA
- NC
- NE
- NF
- NG
- NI
- NL
- 'NO'
- NP
- NR
- NU
- NZ
- OM
- PA
- PE
- PF
- PG
- PH
- PK
- PL
- PM
- PN
- PR
- PS
- PT
- PW
- PY
- QA
- RE
- RO
- RS
- RU
- RW
- SA
- SB
- SC
- SD
- SE
- SG
- SH
- SI
- SJ
- SK
- SL
- SM
- SN
- SO
- SR
- SS
- ST
- SV
- SX
- SY
- SZ
- TC
- TD
- TF
- TG
- TH
- TJ
- TK
- TL
- TM
- TN
- TO
- TR
- TT
- TV
- TW
- TZ
- UA
- UG
- UM
- US
- UY
- UZ
- VA
- VC
- VE
- VG
- VI
- VN
- VU
- WF
- WS
- YE
- YT
- ZA
- ZM
- ZW
title: CountryAlpha2
examples:
- US
- SE
- FR
x-speakeasy-enums:
- AD
- AE
- AF
- AG
- AI
- AL
- AM
- AO
- AQ
- AR
- AS
- AT
- AU
- AW
- AX
- AZ
- BA
- BB
- BD
- BE
- BF
- BG
- BH
- BI
- BJ
- BL
- BM
- BN
- BO
- BQ
- BR
- BS
- BT
- BV
- BW
- BY
- BZ
- CA
- CC
- CD
- CF
- CG
- CH
- CI
- CK
- CL
- CM
- CN
- CO
- CR
- CU
- CV
- CW
- CX
- CY
- CZ
- DE
- DJ
- DK
- DM
- DO
- DZ
- EC
- EE
- EG
- EH
- ER
- ES
- ET
- FI
- FJ
- FK
- FM
- FO
- FR
- GA
- GB
- GD
- GE
- GF
- GG
- GH
- GI
- GL
- GM
- GN
- GP
- GQ
- GR
- GS
- GT
- GU
- GW
- GY
- HK
- HM
- HN
- HR
- HT
- HU
- ID
- IE
- IL
- IM
- IN
- IO
- IQ
- IR
- IS
- IT
- JE
- JM
- JO
- JP
- KE
- KG
- KH
- KI
- KM
- KN
- KP
- KR
- KW
- KY
- KZ
- LA
- LB
- LC
- LI
- LK
- LR
- LS
- LT
- LU
- LV
- LY
- MA
- MC
- MD
- ME
- MF
- MG
- MH
- MK
- ML
- MM
- MN
- MO
- MP
- MQ
- MR
- MS
- MT
- MU
- MV
- MW
- MX
- MY
- MZ
- NA
- NC
- NE
- NF
- NG
- NI
- NL
- 'NO'
- NP
- NR
- NU
- NZ
- OM
- PA
- PE
- PF
- PG
- PH
- PK
- PL
- PM
- PN
- PR
- PS
- PT
- PW
- PY
- QA
- RE
- RO
- RS
- RU
- RW
- SA
- SB
- SC
- SD
- SE
- SG
- SH
- SI
- SJ
- SK
- SL
- SM
- SN
- SO
- SR
- SS
- ST
- SV
- SX
- SY
- SZ
- TC
- TD
- TF
- TG
- TH
- TJ
- TK
- TL
- TM
- TN
- TO
- TR
- TT
- TV
- TW
- TZ
- UA
- UG
- UM
- US
- UY
- UZ
- VA
- VC
- VE
- VG
- VI
- VN
- VU
- WF
- WS
- YE
- YT
- ZA
- ZM
- ZW
type: object
required:
- country
title: Address
securitySchemes:
access_token:
type: http
scheme: bearer
description: >-
You can generate an **Organization Access Token** from your
organization's settings.
````
---
# Source: https://polar.sh/docs/features/integrations/affonso.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Affonso Affiliates with Polar
This guide explains how to integrate
[Affonso](https://affonso.io)'s affiliate marketing software with your Polar
account to track and manage affiliate-driven sales for your SaaS business.
## What is Affonso?
[Affonso](https://affonso.io) is an affiliate marketing software that enables SaaS businesses to launch, manage, and scale their own affiliate programs. With Affonso, you can:
* Set up flexible commission structures
* Manage multiple affiliate programs from one dashboard
* Provide your affiliates with real-time tracking and marketing resources
* Automate affiliate payments and commission calculations
## Integration Steps
### 1. Create a Polar Access Token for Affonso
First, you'll need to create an API token in Polar that Affonso can use to communicate with your account:
1. Login to your **Polar Dashboard**
2. Navigate to **Settings** in the main menu
3. Scroll down to the **Developers** section on the Settings page
4. Click the **New token** button
5. Give your token a name (e.g., "Affonso Integration")
6. Set token expiration to **No expiration**
Important: If you set an expiration date, you'll need to manually update the token in Affonso when it expires. Tracking will stop working if the token expires.
7. Enable all the following scopes:
* discounts:read
* discounts:write
* events:read
* subscriptions:read
* customers:read
* customers:write
* orders:read
* refunds:read
* webhooks:read
* webhooks:write
8. Click **Create token** and copy the generated token
9. Provide this token to Affonso by entering it [in their integration settings](https://affonso.io/app/affiliate-program/connect)
### 2. Set Up Webhooks in Polar
After connecting your Polar account with Affonso, you'll [receive a webhook URL and secret from Affonso](https://affonso.io/app/affiliate-program/connect). Add these to your Polar account:
1. Go to **Settings** → **Developers** → **Webhooks** in your Polar Dashboard
2. Click the **"Add Endpoint"** button
3. In the URL field, paste the webhook URL provided by Affonso
4. For Format, select **RAW** from the dropdown
5. In the Secret field, paste the webhook secret provided by Affonso
6. Under Events, enable all of the following:
* `order.created`
* `order.refunded`
* `subscription.canceled`
7. Click **Save** to complete the webhook setup
### 3. Add the Affonso Tracking Script to Your Website
Add Affonso's tracking script to the `
` tag of your website:
```html theme={null}
```
Replace `YOUR_AFFONSO_PROGRAM_ID` with the unique program ID provided by Affonso.
This script should be placed on all pages of your website, including:
* Your main marketing website
* Your application domain
* Any subdomains where users might land or make purchases
### 4. Track User Signups (Optional)
For better conversion insights, you can track when users sign up through an affiliate link:
```javascript theme={null}
// After successful registration
window.Affonso.signup(userEmail);
```
### 5. Pass Referral Data to Polar Checkout
To ensure proper commission attribution, pass the referral data when creating checkout sessions:
```javascript theme={null}
// Get the referral ID from the Affonso global variable
const referralId = window.affonso_referral;
// Create checkout session with Polar
const checkout = await polar.checkouts.create({
products: ["your_product_id"],
success_url: "https://your-app.com/success",
metadata: {
affonso_referral: referralId, // Include referral ID from Affonso
}
});
// Redirect to checkout
window.location.href = checkout.url;
```
## How It Works
1. When a user visits your site through an affiliate link, Affonso's script stores a unique identifier in a cookie
2. If you've implemented signup tracking, Affonso records when the user creates an account
3. When the user makes a purchase, the referral ID is passed to Polar as metadata
4. Polar's webhook notifies Affonso about the purchase
5. Affonso attributes the sale to the correct affiliate and calculates the commission
## Benefits of the Integration
* **Automated Tracking**: No manual work required to track affiliate-driven sales
* **Real-Time Analytics**: Both you and your affiliates get immediate insights into performance
* **Seamless User Experience**: The integration works behind the scenes without affecting your checkout flow
* **Flexible Commission Structures**: Set up complex commission rules based on product, subscription duration, etc.
## Getting Help
More details about the integration: [Polar Affiliate Program](https://affonso.io/polar-affiliate-program)
If you need assistance with your Affonso integration, contact Affonso's support team:
* Email: [hello@affonso.io](mailto:hello@affonso.io)
* Live chat: Available directly in the Affonso dashboard
---
# Source: https://polar.sh/docs/guides/allow-multiple-subscriptions-per-customer.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# How to allow multiple subscriptions per customer
> Learn how to allow multiple subscriptions per customer in Polar.
In the Polar dashboard sidebar, click on **Settings**.
You can also go directly to:\
`https://polar.sh/dashboard/${org_slug}/settings`\
Scroll down to **Subscriptions** section.
**Toggle ON** Allow multiple subscriptions to allow multiple subscriptions per customer.
Click **Save** in the **Subscriptions** section to save the changed settings.
---
# Source: https://polar.sh/docs/features/analytics.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Analytics
## Sales Metrics
Polar offers a professional metrics dashboard out of the box. So you can stay focused on increasing revenue vs. how to measure it.
**Missing any metrics?** [Let us know so we can add it.](https://github.com/orgs/polarsource/discussions/categories/feature-requests)
### Filters
You can easily slice and dice metrics with the filters below.
### Period
Change the time period in the X-axis to one of:
* Yearly
* Monthly
* Weekly
* Daily
* Hourly
### Timeframe
You can choose a date range to view all metrics for.
### Product
By default metrics reflect the total across all products. However, you can specify individual products or subscription tiers to filter metrics by.
## Metrics
* **Revenue**: How much revenue you've earned before fees.
* **Orders**: How many product sales and subscription payments have been made.
* **Average Order Value (AOV)**: The average earning per order, i.e. revenue / orders.
* **One-Time Products**: Amount of products sold.
* **One-Time Products Revenue**: Amount of revenue earned from products.
* **New Subscriptions**: Amount of new subscriptions.
* **New Subscription Revenue**: Amount of revenue earned from new subscriptions.
* **Renewed Subscriptions**: Amount of renewed subscriptions.
* **Renewed Subscription Revenue**: Amount of revenue earned from renewed subscriptions.
* **Active Subscriptions**: Amount of active subscriptions (new + renewed).
* **Monthly Recurring Revenue (MRR)**: Amount of revenue earned from active subscriptions.
* **Checkouts**: Number of created checkouts.
* **Succeeded Checkouts**: Number of successful checkouts, i.e. checkouts that lead to a new order or subscription.
* **Checkouts Conversion Rate**: The percentage of successful checkouts out of all created checkouts.
## Cost Metrics
* **Costs**: How much costs you've incurred.
* **Cumulative Costs**: How much costs you've incurred over time.
* **Cost Per User**: The average cost per active user.
* **Gross Margin**: The gross margin, i.e. revenue - costs.
* **Gross Margin Percentage**: The gross margin percentage, i.e. gross margin / revenue.
* **Net Cashflow**: The net cashflow, i.e. revenue - costs.
* **Monthly Recurring Cost (MRC)**: The monthly recurring cost, i.e. costs / active subscriptions.
* **Return on Investment (ROI)**: The return on investment, i.e. (revenue - costs) / costs.
---
# Source: https://polar.sh/docs/changelog/api.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# API Changelog
> Stay up to date with the latest changes, improvements and deprecations to the Polar API.
## Checkout API and Customer Session API changes
To be more consistent across our API, we've renamed `customer_external_id` field to `external_customer_id` in the Checkout API and Customer Session API.
* **Deprecated**:
`customer_external_id` field in the Checkout API and Customer Session API. Use
`external_customer_id` instead.
## Benefit metadata in Customer State
The customer state now includes the [benefit metadata](/api-reference/customers/state#response-benefit-metadata) in the `granted_benefits` list.
## Webhook API endpoints are now documented
The API endpoints for managing webhooks are now documented in the API reference, and fully supported in our SDK.
[Read more](/api-reference/webhooks/endpoints/create)
## Rate limits
To ensure fair usage and maintain performance, we've introduced rate limits for the API. The limits are as follows:
* **100 requests per second** per IP address.
## Order invoice generation and retrieval
Until now, the invoice was generated automatically when the order was created, allowing you to call [`GET /v1/orders/{id}/invoice`](/api-reference/orders/get-invoice) and [`GET /v1/customer-portal/orders/{id}/invoice`](/api-reference/customer-portal/orders/get-invoice) endpoints without any prior action.
We now require you to explicitly generate the invoice by calling the [`POST /v1/orders/{id}/invoice`](/api-reference/orders/post-invoice) or [`POST /v1/customer-portal/orders/{id}/invoice`](/api-reference/customer-portal/orders/post-invoice) endpoints.
This change allows us to better handle the invoice generation process, and to allow the customer to change the billing details (name and address) before generating the invoice. This can be done through the [`PATCH /v1/orders/{id}`](/api-reference/orders/patch) or [`PATCH /v1/customer-portal/orders/{id}`](/api-reference/customer-portal/orders/patch) endpoints.
## Benefit metadata support and floating point numbers in metadata
* **Added**: Benefits now support
[metadata](/api-reference/benefits/create#body-metadata).
* **Added**: Metadata values now
support floating-point numbers. Before, only strings, integers and booleans
were supported.
## Checkout amount fields changes and depreciations
To be more consistent with the [Order schema changes](#2025-03-14), we've made some changes to the field related to amounts in the Checkout schema.
* **Added**:
[`checkout.discount_amount`](/api-reference/checkouts/get-session#response-discount-amount).
* **Added**:
[`checkout.net_amount`](/api-reference/checkouts/get-session#response-net-amount).
* **Deprecated**:
`checkout.subtotal_amount`, use
[`checkout.net_amount`](/api-reference/checkouts/get-session#response-net-amount)
instead.
## New order status and webhooks
Until now, Polar only kept track of fully processed, **paid** orders. To help you keep track of the order lifecycle, we've added a new status `pending`, which is a transitive state meaning the order is created but not paid yet. In most cases, the order will transition from `pending` to `paid` in a short time.
* When receiving
`order.created` event, the order status might not be `paid`.
* **Added**:
[`order.updated`](/api-reference/webhooks/order.updated) webhook, sent when
the order status changes or when it's partially or fully refunded.
* **Added**:
[`order.paid`](/api-reference/webhooks/order.paid) webhook, sent when the
order is fully processed and paid.
* **Added**:
[`Order.paid`](/api-reference/orders/get#response-paid) property to the order
schema.
If you were relying on the `order.created` webhook to keep track of succesful
orders, we recommend you to switch to `order.paid`.
## Subscriptions and Orders schema changes
To prepare our next move to support usage-based billing, we've made some changes to the [`Subscription`](/api-reference/subscriptions/get) and [`Order`](/api-reference/orders/get) schemas. The main reason behind those is that we need to support multiple prices and items in a single subscription or order.
* **Deprecated**:
`Subscription.price_id` and `Subscription.price`. Use the
`Subscription.prices` array instead.
* **Deprecated**:
`Order.product_price_id` and `Order.product_price`. Use the `Order.items`
array instead.
* **Deprecated**:
`Order.amount`. Use the `Order.net_amount` instead. It has the same value and
meaning, but the new name is more explicit.
* **Added**:
`Order.subtotal_amount`, `Order.discount_amount`, and `Order.total_amount`
fields to provide a more detailed breakdown of the order amount.
---
# Source: https://polar.sh/docs/api-reference/customer-seats/assign.md
# Source: https://polar.sh/docs/api-reference/customer-portal/seats/assign.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Assign Seat
## OpenAPI
````yaml post /v1/customer-portal/seats
openapi: 3.1.0
info:
title: Polar API
summary: Polar HTTP and Webhooks API
description: Read the docs at https://polar.sh/docs/api-reference
version: 0.1.0
servers:
- url: https://api.polar.sh
description: Production environment
x-speakeasy-server-id: production
- url: https://sandbox-api.polar.sh
description: Sandbox environment
x-speakeasy-server-id: sandbox
security:
- access_token: []
tags:
- name: public
description: >-
Endpoints shown and documented in the Polar API documentation and
available in our SDKs.
- name: private
description: >-
Endpoints that should appear in the schema only in development to generate
our internal JS SDK.
- name: mcp
description: Endpoints enabled in the MCP server.
paths:
/v1/customer-portal/seats:
post:
tags:
- customer_portal
- seats
- public
summary: Assign Seat
operationId: customer_portal:seats:assign_seat
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SeatAssign'
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/CustomerSeat'
'400':
description: No available seats or customer already has a seat
'401':
description: Authentication required
'403':
description: Not permitted or seat-based pricing not enabled
'404':
description: Subscription, order, or customer not found
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
security:
- customer_session:
- customer_portal:write
- member_session:
- customer_portal:write
components:
schemas:
SeatAssign:
properties:
subscription_id:
anyOf:
- type: string
format: uuid
- type: 'null'
title: Subscription Id
description: >-
Subscription ID. Required if checkout_id and order_id are not
provided.
checkout_id:
anyOf:
- type: string
format: uuid
- type: 'null'
title: Checkout Id
description: >-
Checkout ID. Used to look up subscription or order from the checkout
page.
order_id:
anyOf:
- type: string
format: uuid
- type: 'null'
title: Order Id
description: >-
Order ID for one-time purchases. Required if subscription_id and
checkout_id are not provided.
email:
anyOf:
- type: string
format: email
- type: 'null'
title: Email
description: Email of the customer to assign the seat to
external_customer_id:
anyOf:
- type: string
- type: 'null'
title: External Customer Id
description: External customer ID for the seat assignment
customer_id:
anyOf:
- type: string
format: uuid
- type: 'null'
title: Customer Id
description: Customer ID for the seat assignment
metadata:
anyOf:
- additionalProperties: true
type: object
- type: 'null'
title: Metadata
description: Additional metadata for the seat (max 10 keys, 1KB total)
immediate_claim:
type: boolean
title: Immediate Claim
description: >-
If true, the seat will be immediately claimed without sending an
invitation email. API-only feature.
default: false
type: object
title: SeatAssign
CustomerSeat:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid
title: Id
description: The seat ID
subscription_id:
anyOf:
- type: string
format: uuid
- type: 'null'
title: Subscription Id
description: The subscription ID (for recurring seats)
order_id:
anyOf:
- type: string
format: uuid
- type: 'null'
title: Order Id
description: The order ID (for one-time purchase seats)
status:
$ref: '#/components/schemas/SeatStatus'
description: Status of the seat
customer_id:
anyOf:
- type: string
format: uuid
- type: 'null'
title: Customer Id
description: >-
The customer ID. When member_model_enabled is true, this is the
billing customer (purchaser). When false, this is the seat member
customer.
member_id:
anyOf:
- type: string
format: uuid
- type: 'null'
title: Member Id
description: The member ID of the seat occupant
email:
anyOf:
- type: string
- type: 'null'
title: Email
description: Email of the seat member (set when member_model_enabled is true)
customer_email:
anyOf:
- type: string
- type: 'null'
title: Customer Email
description: The assigned customer email
invitation_token_expires_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Invitation Token Expires At
description: When the invitation token expires
claimed_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Claimed At
description: When the seat was claimed
revoked_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Revoked At
description: When the seat was revoked
seat_metadata:
anyOf:
- additionalProperties: true
type: object
- type: 'null'
title: Seat Metadata
description: Additional metadata for the seat
type: object
required:
- created_at
- modified_at
- id
- status
title: CustomerSeat
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
type: object
title: HTTPValidationError
SeatStatus:
type: string
enum:
- pending
- claimed
- revoked
title: SeatStatus
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
msg:
type: string
title: Message
type:
type: string
title: Error Type
type: object
required:
- loc
- msg
- type
title: ValidationError
securitySchemes:
access_token:
type: http
scheme: bearer
description: >-
You can generate an **Organization Access Token** from your
organization's settings.
customer_session:
type: http
description: >-
Customer session tokens are specific tokens that are used to
authenticate customers on your organization. You can create those
sessions programmatically using the [Create Customer Session
endpoint](/api-reference/customer-portal/sessions/create).
scheme: bearer
member_session:
type: http
description: >-
Member session tokens are specific tokens that are used to authenticate
members on your organization. You can create those sessions
programmatically using the [Create Member Session
endpoint](/api-reference/member-portal/sessions/create).
scheme: bearer
````
---
# Source: https://polar.sh/docs/integrate/sdk/adapters/astro.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Astro
> Payments and Checkouts made dead simple with Astro
## Examples
* [With Astro](https://github.com/polarsource/examples/tree/main/with-astro)
* [With Astro and Cloudflare Workers](https://github.com/polarsource/examples/tree/main/with-astro-cloudflare-workers)
## Installation
Install the required Polar packages using the following command:
```bash Terminal theme={null}
npm install zod @polar-sh/astro
```
```bash Terminal theme={null}
yarn add zod @polar-sh/astro
```
```bash Terminal theme={null}
pnpm add zod @polar-sh/astro
```
```bash Terminal theme={null}
bun add zod @polar-sh/astro
```
## Checkout
Create a Checkout handler which takes care of redirections.
```typescript icon="square-js" theme={null}
import { Checkout } from "@polar-sh/astro";
import { POLAR_ACCESS_TOKEN, POLAR_SUCCESS_URL } from "astro:env/server";
export const GET = Checkout({
accessToken: POLAR_ACCESS_TOKEN,
successUrl: POLAR_SUCCESS_URL,
returnUrl: "https://myapp.com", // An optional URL which renders a back-button in the Checkout
server: "sandbox", // Use sandbox if you're testing Polar - omit the parameter or pass 'production' otherwise
theme: "dark", // Enforces the theme - System-preferred theme will be set if left omitted
});
```
### Query Params
Pass query params to this route.
* products `?products=123`
* customerId (optional) `?products=123&customerId=xxx`
* customerExternalId (optional) `?products=123&customerExternalId=xxx`
* customerEmail (optional) `?products=123&customerEmail=janedoe@gmail.com`
* customerName (optional) `?products=123&customerName=Jane`
* metadata (optional) `URL-Encoded JSON string`
## Customer Portal
Create a customer portal where your customer can view orders and subscriptions.
```typescript icon="square-js" theme={null}
import { CustomerPortal } from "@polar-sh/astro";
import { POLAR_ACCESS_TOKEN } from "astro:env/server";
export const GET = CustomerPortal({
accessToken: POLAR_ACCESS_TOKEN,
getCustomerId: (event) => "", // Function to resolve a Polar Customer ID
returnUrl: "https://myapp.com", // An optional URL which renders a back-button in the Customer Portal
server: "sandbox", // Use sandbox if you're testing Polar - omit the parameter or pass 'production' otherwise
});
```
## Webhooks
A simple utility which resolves incoming webhook payloads by signing the webhook secret properly.
```typescript icon="square-js" theme={null}
import { Webhooks } from '@polar-sh/astro';
import { POLAR_WEBHOOK_SECRET } from "astro:env/server"
export const POST = Webhooks({
webhookSecret: POLAR_WEBHOOK_SECRET,
onPayload: async (payload) => /** Handle payload */,
})
```
### Payload Handlers
The Webhook handler also supports granular handlers for easy integration.
* `onPayload` - Catch-all handler for any incoming Webhook event
* `onCheckoutCreated` - Triggered when a checkout is created
* `onCheckoutUpdated` - Triggered when a checkout is updated
* `onOrderCreated` - Triggered when an order is created
* `onOrderPaid` - Triggered when an order is paid
* `onOrderRefunded` - Triggered when an order is refunded
* `onRefundCreated` - Triggered when a refund is created
* `onRefundUpdated` - Triggered when a refund is updated
* `onSubscriptionCreated` - Triggered when a subscription is created
* `onSubscriptionUpdated` - Triggered when a subscription is updated
* `onSubscriptionActive` - Triggered when a subscription becomes active
* `onSubscriptionCanceled` - Triggered when a subscription is canceled
* `onSubscriptionRevoked` - Triggered when a subscription is revoked
* `onSubscriptionUncanceled` - Triggered when a subscription cancellation is reversed
* `onProductCreated` - Triggered when a product is created
* `onProductUpdated` - Triggered when a product is updated
* `onOrganizationUpdated` - Triggered when an organization is updated
* `onBenefitCreated` - Triggered when a benefit is created
* `onBenefitUpdated` - Triggered when a benefit is updated
* `onBenefitGrantCreated` - Triggered when a benefit grant is created
* `onBenefitGrantUpdated` - Triggered when a benefit grant is updated
* `onBenefitGrantRevoked` - Triggered when a benefit grant is revoked
* `onCustomerCreated` - Triggered when a customer is created
* `onCustomerUpdated` - Triggered when a customer is updated
* `onCustomerDeleted` - Triggered when a customer is deleted
* `onCustomerStateChanged` - Triggered when a customer state changes
---
# Source: https://polar.sh/docs/integrate/authentication.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Authentication
All bearer tokens should be kept private and never shared or exposed in client-side code.
To authenticate requests, Polar API has two mechanisms.
1. [Organization Access Tokens (OAT)](/integrate/oat) - Recommended
2. [OAuth 2.0 Provider](/integrate/oauth2/introduction) (Partner Integrations)
## Organization Access Tokens (OAT)
They are tied to **one** of your organization. You can create them from your organization settings.
## Security
To protect your data and ensure the security of Polar, we've several mechanisms in place to automatically revoke tokens that may have been leaked publicly on the web.
In particular, we're part of the [GitHub Secret Scanning Program](https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning). If GitHub systems detect a Polar token in a code repository or public discussion, our systems are notified and the tokens are immediately revoked.
If you received an email about one of your token being leaked, it means that we were notified of such situation. The email contains the details about the nature of the token and the source of the leak.
In the future, it's crucial that you remain extra cautious about not leaking your tokens publicly online. You can read more about the good practices to manage secrets in the [OWASP Secrets Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html).
---
# Source: https://polar.sh/docs/api-reference/oauth2/connect/authorize.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Authorize
## OpenAPI
````yaml get /v1/oauth2/authorize
openapi: 3.1.0
info:
title: Polar API
summary: Polar HTTP and Webhooks API
description: Read the docs at https://polar.sh/docs/api-reference
version: 0.1.0
servers:
- url: https://api.polar.sh
description: Production environment
x-speakeasy-server-id: production
- url: https://sandbox-api.polar.sh
description: Sandbox environment
x-speakeasy-server-id: sandbox
security:
- access_token: []
tags:
- name: public
description: >-
Endpoints shown and documented in the Polar API documentation and
available in our SDKs.
- name: private
description: >-
Endpoints that should appear in the schema only in development to generate
our internal JS SDK.
- name: mcp
description: Endpoints enabled in the MCP server.
paths:
/v1/oauth2/authorize:
get:
tags:
- oauth2
- public
summary: Authorize
operationId: oauth2:authorize
responses:
'200':
description: Successful Response
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/AuthorizeResponseUser'
- $ref: '#/components/schemas/AuthorizeResponseOrganization'
title: Response Oauth2:Authorize
discriminator:
propertyName: sub_type
mapping:
user: '#/components/schemas/AuthorizeResponseUser'
organization: '#/components/schemas/AuthorizeResponseOrganization'
components:
schemas:
AuthorizeResponseUser:
properties:
client:
$ref: '#/components/schemas/OAuth2ClientPublic'
sub_type:
type: string
const: user
title: Sub Type
sub:
anyOf:
- $ref: '#/components/schemas/AuthorizeUser'
- type: 'null'
scopes:
items:
$ref: '#/components/schemas/Scope'
type: array
title: Scopes
scope_display_names:
additionalProperties:
type: string
type: object
title: Scope Display Names
default:
openid: OpenID
profile: Read your profile
email: Read your email address
web:read: Web Read Access
web:write: Web Write Access
user:read: User Read
user:write: Delete your user account
organizations:read: Read your organizations
organizations:write: Create or modify organizations
custom_fields:read: Read custom fields
custom_fields:write: Create or modify custom fields
discounts:read: Read discounts
discounts:write: Create or modify discounts
checkout_links:read: Read checkout links
checkout_links:write: Create or modify checkout links
checkouts:read: Read checkout sessions
checkouts:write: Create or modify checkout sessions
transactions:read: Read transactions
transactions:write: Create or modify transactions
payouts:read: Read payouts
payouts:write: Create or modify payouts
products:read: Read products
products:write: Create or modify products
benefits:read: Read benefits
benefits:write: Create or modify benefits
events:read: Read events
events:write: Create events
meters:read: Read meters
meters:write: Create or modify meters
files:read: Read file uploads
files:write: Create or modify file uploads
subscriptions:read: Read subscriptions made on your organizations
subscriptions:write: Create or modify subscriptions made on your organizations
customers:read: Read customers
customers:write: Create or modify customers
members:read: Read members
members:write: Create or modify members
wallets:read: Read wallets
wallets:write: Create or modify wallets
disputes:read: Read disputes
customer_meters:read: Read customer meters
customer_sessions:write: Create or modify customer sessions
member_sessions:write: Create or modify member sessions
customer_seats:read: Read customer seats
customer_seats:write: Create or modify customer seats
orders:read: Read orders made on your organizations
orders:write: Modify orders made on your organizations
refunds:read: Read refunds made on your organizations
refunds:write: Create or modify refunds
payments:read: Read payments made on your organizations
metrics:read: Read metrics
webhooks:read: Read webhooks
webhooks:write: Create or modify webhooks
external_organizations:read: Read external organizations
license_keys:read: Read license keys
license_keys:write: Modify license keys
customer_portal:read: Read your orders, subscriptions and benefits
customer_portal:write: Create or modify your orders, subscriptions and benefits
notifications:read: Read notifications
notifications:write: Mark notifications as read
notification_recipients:read: Read notification recipients
notification_recipients:write: Create or modify notification recipients
organization_access_tokens:read: Read organization access tokens
organization_access_tokens:write: Create or modify organization access tokens
type: object
required:
- client
- sub_type
- sub
- scopes
title: AuthorizeResponseUser
AuthorizeResponseOrganization:
properties:
client:
$ref: '#/components/schemas/OAuth2ClientPublic'
sub_type:
type: string
const: organization
title: Sub Type
sub:
anyOf:
- $ref: '#/components/schemas/AuthorizeOrganization'
- type: 'null'
scopes:
items:
$ref: '#/components/schemas/Scope'
type: array
title: Scopes
scope_display_names:
additionalProperties:
type: string
type: object
title: Scope Display Names
default:
openid: OpenID
profile: Read your profile
email: Read your email address
web:read: Web Read Access
web:write: Web Write Access
user:read: User Read
user:write: Delete your user account
organizations:read: Read your organizations
organizations:write: Create or modify organizations
custom_fields:read: Read custom fields
custom_fields:write: Create or modify custom fields
discounts:read: Read discounts
discounts:write: Create or modify discounts
checkout_links:read: Read checkout links
checkout_links:write: Create or modify checkout links
checkouts:read: Read checkout sessions
checkouts:write: Create or modify checkout sessions
transactions:read: Read transactions
transactions:write: Create or modify transactions
payouts:read: Read payouts
payouts:write: Create or modify payouts
products:read: Read products
products:write: Create or modify products
benefits:read: Read benefits
benefits:write: Create or modify benefits
events:read: Read events
events:write: Create events
meters:read: Read meters
meters:write: Create or modify meters
files:read: Read file uploads
files:write: Create or modify file uploads
subscriptions:read: Read subscriptions made on your organizations
subscriptions:write: Create or modify subscriptions made on your organizations
customers:read: Read customers
customers:write: Create or modify customers
members:read: Read members
members:write: Create or modify members
wallets:read: Read wallets
wallets:write: Create or modify wallets
disputes:read: Read disputes
customer_meters:read: Read customer meters
customer_sessions:write: Create or modify customer sessions
member_sessions:write: Create or modify member sessions
customer_seats:read: Read customer seats
customer_seats:write: Create or modify customer seats
orders:read: Read orders made on your organizations
orders:write: Modify orders made on your organizations
refunds:read: Read refunds made on your organizations
refunds:write: Create or modify refunds
payments:read: Read payments made on your organizations
metrics:read: Read metrics
webhooks:read: Read webhooks
webhooks:write: Create or modify webhooks
external_organizations:read: Read external organizations
license_keys:read: Read license keys
license_keys:write: Modify license keys
customer_portal:read: Read your orders, subscriptions and benefits
customer_portal:write: Create or modify your orders, subscriptions and benefits
notifications:read: Read notifications
notifications:write: Mark notifications as read
notification_recipients:read: Read notification recipients
notification_recipients:write: Create or modify notification recipients
organization_access_tokens:read: Read organization access tokens
organization_access_tokens:write: Create or modify organization access tokens
organizations:
items:
$ref: '#/components/schemas/AuthorizeOrganization'
type: array
title: Organizations
type: object
required:
- client
- sub_type
- sub
- scopes
- organizations
title: AuthorizeResponseOrganization
OAuth2ClientPublic:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
client_id:
type: string
title: Client Id
client_name:
anyOf:
- type: string
- type: 'null'
title: Client Name
client_uri:
anyOf:
- type: string
- type: 'null'
title: Client Uri
logo_uri:
anyOf:
- type: string
- type: 'null'
title: Logo Uri
tos_uri:
anyOf:
- type: string
- type: 'null'
title: Tos Uri
policy_uri:
anyOf:
- type: string
- type: 'null'
title: Policy Uri
type: object
required:
- created_at
- modified_at
- client_id
- client_name
- client_uri
- logo_uri
- tos_uri
- policy_uri
title: OAuth2ClientPublic
AuthorizeUser:
properties:
id:
type: string
format: uuid4
title: Id
email:
type: string
format: email
title: Email
avatar_url:
anyOf:
- type: string
- type: 'null'
title: Avatar Url
type: object
required:
- id
- email
- avatar_url
title: AuthorizeUser
Scope:
type: string
enum:
- openid
- profile
- email
- user:read
- user:write
- web:read
- web:write
- organizations:read
- organizations:write
- custom_fields:read
- custom_fields:write
- discounts:read
- discounts:write
- checkout_links:read
- checkout_links:write
- checkouts:read
- checkouts:write
- transactions:read
- transactions:write
- payouts:read
- payouts:write
- products:read
- products:write
- benefits:read
- benefits:write
- events:read
- events:write
- meters:read
- meters:write
- files:read
- files:write
- subscriptions:read
- subscriptions:write
- customers:read
- customers:write
- members:read
- members:write
- wallets:read
- wallets:write
- disputes:read
- customer_meters:read
- customer_sessions:write
- member_sessions:write
- customer_seats:read
- customer_seats:write
- orders:read
- orders:write
- refunds:read
- refunds:write
- payments:read
- metrics:read
- webhooks:read
- webhooks:write
- external_organizations:read
- license_keys:read
- license_keys:write
- repositories:read
- repositories:write
- issues:read
- issues:write
- customer_portal:read
- customer_portal:write
- notifications:read
- notifications:write
- notification_recipients:read
- notification_recipients:write
- organization_access_tokens:read
- organization_access_tokens:write
title: Scope
enumNames:
benefits:read: Read benefits
benefits:write: Create or modify benefits
checkout_links:read: Read checkout links
checkout_links:write: Create or modify checkout links
checkouts:read: Read checkout sessions
checkouts:write: Create or modify checkout sessions
custom_fields:read: Read custom fields
custom_fields:write: Create or modify custom fields
customer_meters:read: Read customer meters
customer_portal:read: Read your orders, subscriptions and benefits
customer_portal:write: Create or modify your orders, subscriptions and benefits
customer_seats:read: Read customer seats
customer_seats:write: Create or modify customer seats
customer_sessions:write: Create or modify customer sessions
customers:read: Read customers
customers:write: Create or modify customers
discounts:read: Read discounts
discounts:write: Create or modify discounts
disputes:read: Read disputes
email: Read your email address
events:read: Read events
events:write: Create events
external_organizations:read: Read external organizations
files:read: Read file uploads
files:write: Create or modify file uploads
license_keys:read: Read license keys
license_keys:write: Modify license keys
member_sessions:write: Create or modify member sessions
members:read: Read members
members:write: Create or modify members
meters:read: Read meters
meters:write: Create or modify meters
metrics:read: Read metrics
notification_recipients:read: Read notification recipients
notification_recipients:write: Create or modify notification recipients
notifications:read: Read notifications
notifications:write: Mark notifications as read
openid: OpenID
orders:read: Read orders made on your organizations
orders:write: Modify orders made on your organizations
organization_access_tokens:read: Read organization access tokens
organization_access_tokens:write: Create or modify organization access tokens
organizations:read: Read your organizations
organizations:write: Create or modify organizations
payments:read: Read payments made on your organizations
payouts:read: Read payouts
payouts:write: Create or modify payouts
products:read: Read products
products:write: Create or modify products
profile: Read your profile
refunds:read: Read refunds made on your organizations
refunds:write: Create or modify refunds
subscriptions:read: Read subscriptions made on your organizations
subscriptions:write: Create or modify subscriptions made on your organizations
transactions:read: Read transactions
transactions:write: Create or modify transactions
user:read: User Read
user:write: Delete your user account
wallets:read: Read wallets
wallets:write: Create or modify wallets
web:read: Web Read Access
web:write: Web Write Access
webhooks:read: Read webhooks
webhooks:write: Create or modify webhooks
AuthorizeOrganization:
properties:
id:
type: string
format: uuid4
title: Id
slug:
type: string
title: Slug
avatar_url:
anyOf:
- type: string
- type: 'null'
title: Avatar Url
type: object
required:
- id
- slug
- avatar_url
title: AuthorizeOrganization
securitySchemes:
access_token:
type: http
scheme: bearer
description: >-
You can generate an **Organization Access Token** from your
organization's settings.
````
---
# Source: https://polar.sh/docs/guides/automate-post-purchase-link-sharing.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# How to automatically share links to customers after purchase
> Learn how to use the Custom Benefit to automatically share links with customers after purchase.
## Create a Custom Benefit
In the Polar dashboard sidebar, click on **Benefits**.
You can also go directly to `https://polar.sh/dashboard/${org_slug}/products/benefits`.
Click on **Create Benefit**. You’ll see three configuration fields as shown in the image below: **Description**, **Type**, and **Private note**.
The **Type** field is set to Custom by default (which is what we need).
The **Private note** field is specific to the Custom **Type**. If you select a different **Type**, you’ll see configuration options specific to that type instead.
Fill the **Description** and **Private note** fields where:
* **Description** accepts regular text and is the title of the link that you want to share with the customer.
* **Private note** uses the [Markdown format](https://www.markdownguide.org/basic-syntax/) so you can format text, add links, or lists.
Make sure to add your link inside the **Private note** section so that it's only accessible post a payment.
Then, click the **Create** button to save the configuration.
## Create a product using the Custom Benefit
In the Polar dashboard sidebar, navigate to **Products** > **Catalogue** for your organization.
You can also go directly to `https://polar.sh/dashboard/${org_slug}/products`.
Click on **New Product**. Fill out the Product information.
On the product creation page, scroll to the bottom to find the **Automated Benefits** section.
Click on Custom to see all the custom benefits you’ve created, and then toggle ON the one you want to enable.
If you don’t want to use an existing Custom benefit, you can create a new one by clicking **Create new**.
Enter the configuration details, following the [Step 3](#configuration-fill) of [Create a Custom Benefit](#create-a-custom-benefit) section.
Click on **Create Product** button in the product creation form.
Your product is successfully created along with the Custom benefit that allows you to share the links automatically to customers after purchase.
## How the Custom Benefit Appears During Checkout
Your Custom Benefit is visible to customers at multiple stages of their purchase journey:
### Checkout Page
When a customer opens the checkout session, they’ll see the **Description of your Custom Benefit** listed under **Included**.
### After Purchase
Once the customer completes their purchase, the **Description**, the **Benefit Type** (in this case, **Custom**), and the **rendered Markdown content** from the **Private note** of the **Custom Benefit** are displayed, allowing them to access any links or formatted text you’ve added.
### Purchase Confirmation Email
The **Description** and the rendered Markdown content of the **Custom Benefit** also appear in the purchase confirmation email sent to the customer, as shown below.
### Customer Portal
When the customer opens the [Customer Portal](/features/customer-portal) through the link in their confirmation email, the **Custom Benefit** is displayed there as well.
---
# Source: https://polar.sh/docs/features/finance/balance.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Account Balance & Transparent Fees
> Monitor your Polar balance without hidden fees
You can see your available balance for payout at any time under your `Finance` page.
## Polar Balance
Your balance is all the earnings minus:
1. Any VAT we've captured for remittance, i.e balance is excluding VAT
2. Our revenue share (4% + 40¢)
All historic transactions are available in chronological order along with their associated fees that have been deducted.
Note: Upon [payout (withdrawal)](/features/finance/payouts), Stripe incurs additional fees that will be deducted before the final payout of the balance.
---
# Source: https://polar.sh/docs/api-reference/webhooks/benefit.created.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# benefit.created
---
# Source: https://polar.sh/docs/api-reference/webhooks/benefit.updated.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# benefit.updated
---
# Source: https://polar.sh/docs/api-reference/webhooks/benefit_grant.created.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# benefit_grant.created
---
# Source: https://polar.sh/docs/api-reference/webhooks/benefit_grant.cycled.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# benefit_grant.cycled
---
# Source: https://polar.sh/docs/api-reference/webhooks/benefit_grant.revoked.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# benefit_grant.revoked
---
# Source: https://polar.sh/docs/api-reference/webhooks/benefit_grant.updated.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# benefit_grant.updated
---
# Source: https://polar.sh/docs/integrate/sdk/adapters/better-auth.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# BetterAuth
> Payments and Checkouts made dead simple with BetterAuth
## @polar-sh/better-auth
A [Better Auth](https://github.com/better-auth/better-auth) plugin for integrating [Polar](https://polar.sh) payments and subscriptions into your authentication flow.
### Features
* [Automatic Customer creation on signup](#automatic-customer-creation-on-signup)
* [Sync customer deletion](#sync-customer-deletion)
* [Reference System to associate purchases with organizations](#3-2-orders)
* [Checkout Integration](#checkout-plugin)
* [Event Ingestion & Customer Meters for flexible Usage Based Billing](#usage-plugin)
* [Handle Polar Webhooks securely with signature verification](#webhooks-plugin)
* [Customer Portal](#portal-plugin)
## Examples
* [With Next.js, Better Auth and Cloudflare Workers](https://github.com/polarsource/examples/tree/main/with-nextjs-better-auth-cloudflare-workers)
## Installation
Install the required Better Auth and Polar packages using the following command:
```bash Terminal theme={null}
npm install better-auth @polar-sh/better-auth @polar-sh/sdk
```
```bash Terminal theme={null}
yarn add better-auth @polar-sh/better-auth @polar-sh/sdk
```
```bash Terminal theme={null}
pnpm add better-auth @polar-sh/better-auth @polar-sh/sdk
```
```bash Terminal theme={null}
bun add better-auth @polar-sh/better-auth @polar-sh/sdk
```
## Integrate Polar with BetterAuth
Go to your Polar Organization Settings, create an Organization Access Token, and add it to the environment variables of your application.
```bash .env theme={null}
POLAR_ACCESS_TOKEN=...
```
The Polar plugin comes with it's own set of plugins to add functionality to your stack:
* **checkout** - Enable seamless checkout integration
* **portal** - Make it possible for your customers to manage their orders, subscriptions & benefits
* **usage** - List customer meters & ingest events for Usage Based Billing
* **webhooks** - Listen for relevant Polar webhooks
```typescript icon="square-js" BetterAuth Server with Polar Example theme={null}
import { betterAuth } from "better-auth";
import { polar, checkout, portal, usage, webhooks } from "@polar-sh/better-auth"; // [!code ++]
import { Polar } from "@polar-sh/sdk"; // [!code ++]
const polarClient = new Polar({ // [!code ++]
accessToken: process.env.POLAR_ACCESS_TOKEN, // [!code ++]
// Use 'sandbox' if you're using the Polar Sandbox environment
// Remember that access tokens, products, etc. are completely separated between environments.
// Access tokens obtained in Production are for instance not usable in the Sandbox environment.
server: 'sandbox' // [!code ++]
}); // [!code ++]
const auth = betterAuth({
// ... Better Auth config
plugins: [
polar({ // [!code ++]
client: polarClient, // [!code ++]
createCustomerOnSignUp: true, // [!code ++]
use: [ // [!code ++]
checkout({ // [!code ++]
products: [ // [!code ++]
{ // [!code ++]
productId: "123-456-789", // ID of Product from Polar Dashboard // [!code ++]
slug: "pro" // Custom slug for easy reference in Checkout URL, e.g. /checkout/pro // [!code ++]
} // [!code ++]
], // [!code ++]
successUrl: "/success?checkout_id={CHECKOUT_ID}", // [!code ++]
authenticatedUsersOnly: true // [!code ++]
}), // [!code ++]
portal(), // [!code ++]
usage(), // [!code ++]
webhooks({ // [!code ++]
secret: process.env.POLAR_WEBHOOK_SECRET, // [!code ++]
onCustomerStateChanged: (payload) => // Triggered when anything regarding a customer changes // [!code ++]
onOrderPaid: (payload) => // Triggered when an order was paid (purchase, subscription renewal, etc.) // [!code ++]
... // Over 25 granular webhook handlers // [!code ++]
onPayload: (payload) => // Catch-all for all events // [!code ++]
}) // [!code ++]
], // [!code ++]
}) // [!code ++]
]
});
```
#### Polar Plugin Configuration Options
```typescript theme={null}
// ...
const auth = betterAuth({
// ... Better Auth config
plugins: [
polar({
client: polarClient, // [!code ++]
createCustomerOnSignUp: true, // [!code ++]
getCustomerCreateParams: ({ user }, request) => ({ // [!code ++]
metadata: { // [!code ++]
myCustomProperty: 123, // [!code ++]
}, // [!code ++]
}), // [!code ++]
use: [ // [!code ++]
// This is where you add Polar plugins // [!code ++]
], // [!code ++]
}),
],
});
```
* `client` (required): Polar SDK client instance
* `createCustomerOnSignUp` (optional): Automatically create a Polar customer when a user signs up
* `getCustomerCreateParams` (optional): Custom function to provide additional customer creation metadata
* `use` (optional): Array of Polar plugins to enable specific functionality (checkout, portal, usage, and webhooks)
You will be using the BetterAuth Client to interact with the Polar functionalities.
```typescript icon="square-js" BetterAuth Client with Polar Example theme={null}
import { createAuthClient } from "better-auth/react";
import { polarClient } from "@polar-sh/better-auth"; // [!code ++]
import { organizationClient } from "better-auth/client/plugins"; // [!code ++]
// All Polar plugins, etc. should be attached to BetterAuth server
export const authClient = createAuthClient({ // [!code ++]
plugins: [polarClient()], // [!code ++]
}); // [!code ++]
```
## Automatic Customer creation on signup
Enable the `createCustomerOnSignUp` [Polar plugin configuration option](#polar-plugin-configuration-options) to automatically create a new Polar Customer when a new User is added in the BetterAuth database.
All new customers are created with an associated `externalId`, i.e. the ID of your User in the Database. This skips any Polar to User mapping in your database.
## Sync Customer deletion
To add user deletion logic with external Polar customer deletion in BetterAuth, extend the user config of your betterAuth setup with the deleteUser option and an afterDelete hook. Here’s how to integrate this alongside your Polar plugin and automatic customer creation:
```typescript icon="square-js" Customer Deletion Example theme={null}
const auth = betterAuth({
user: {
// [!code ++]
deleteUser: {
// [!code ++]
enabled: true, // [!code ++]
afterDelete: async (user, request) => {
// [!code ++]
await polar.customers.deleteExternal({
// [!code ++]
externalId: user.id, // [!code ++]
}); // [!code ++]
}, // [!code ++]
}, // [!code ++]
}, // [!code ++]
});
```
## Checkout Plugin
[Source code](https://github.com/polarsource/polar-adapters/blob/main/packages/polar-betterauth/src/plugins/checkout.ts)
To support [checkouts](/features/checkout/links) in your app, you would pass the `checkout` plugin in the `use` property.
The checkout plugin accepts the following configuration options:
* **`products`** (optional): An array of product mappings or a function that returns them asynchronously. Each mapping contains a `productId` and a `slug` that allows you to reference products by a friendly slug instead of their full ID.
* **`successUrl`** (optional): The relative path or absolute URL where customers will be redirected after a successful checkout completion. You can use the `{CHECKOUT_ID}` placeholder in the URL to include the checkout session ID in the redirect.
* **`returnUrl`** (optional): An optional URL which renders a back-button in the Checkout.
* **`authenticatedUsersOnly`** (optional): A boolean flag that controls whether checkout sessions require user authentication. When set to `true`, only authenticated users can initiate checkouts and the customer information will be automatically associated with the authenticated user. When `false`, anonymous checkouts are allowed.
* **`theme`** (optional): A string that can be used to enforce the theme of the checkout page. Can be either `light` or `dark`.
Update the `use` property of the Polar plugin for BetterAuth client to have the `checkout` plugin.
```typescript icon="square-js" Checkout Plugin Example theme={null}
import {
polar,
checkout // [!code ++]
} from "@polar-sh/better-auth";
const auth = betterAuth({
// ... Better Auth config
plugins: [
polar({
...
use: [
checkout({ // [!code ++]
// Optional field - will make it possible to pass a slug to checkout instead of Product ID
products: [ { productId: "123-456-789", slug: "pro" } ], // [!code ++]
// Relative path or absolute URL to redirect to when checkout is successfully completed
successUrl: "/success?checkout_id={CHECKOUT_ID}", // [!code ++]
// Whether you want to allow unauthenticated checkout sessions or not
authenticatedUsersOnly: true, // [!code ++]
// An optional URL which renders a back-button in the Checkout
returnUrl: "https://myapp.com" // [!code ++]
}) // [!code ++]
],
})
]
});
```
When the `checkout` plugin is passed, you are then able to initialize Checkout Sessions using the `checkout` method on the BetterAuth client. This will redirect the user to the product's checkout link.
The `checkout` method accepts the following properties:
* **`products`** (optional): An array of Polar Product IDs.
* **`slug`** (optional): A string that can be used as a reference to the `products` defined in the Checkout config
* **`referenceId`** (optional): An identifier that will be saved in the metadata of the checkout, order & subscription object
```typescript icon="square-js" BetterAuth Checkout with Polar Example theme={null}
await authClient.checkout({
// Polar Product IDs
products: ["e651f46d-ac20-4f26-b769-ad088b123df2"], // [!code ++]
// OR
// if "products" in passed in the checkout plugin's config, you may pass the slug
// slug: "pro", // [!code ++]
});
```
This plugin supports the Organization plugin. If you pass the organization ID to the Checkout referenceId, you will be able to keep track of purchases made from organization members.
```typescript icon="square-js" BetterAuth Checkout with Polar Organization Example theme={null}
const organizationId = (await authClient.organization.list())?.data?.[0]?.id,
await authClient.checkout({
// Any Polar Product ID can be passed here
products: ["e651f46d-ac20-4f26-b769-ad088b123df2"],
// Or, if you setup "products" in the Checkout Config, you can pass the slug
slug: 'pro',
// Reference ID will be saved as `referenceId` in the metadata of the checkout, order & subscription object
referenceId: organizationId
});
```
## Usage Plugin
[Source code](https://github.com/polarsource/polar-adapters/blob/main/packages/polar-betterauth/src/plugins/usage.ts)
A plugin for Usage Based Billing that allows you to [ingest events](#event-ingestion) from your application and list the [authenticated user's Usage Meter](#customer-meters).
To enable [usage based billing](/integrate/sdk/adapters/better-auth) in your app, you would pass the `usage` plugin in the `use` property.
```typescript icon="square-js" Usage Plugin Example theme={null}
import {
polar, checkout, portal,
usage // [!code ++]
} from "@polar-sh/better-auth";
const auth = betterAuth({
// ... Better Auth config
plugins: [
polar({
...
use: [
checkout(...),
portal(),
usage() // [!code ++]
],
})
]
});
```
### 1. Event Ingestion
Polar's Usage Based Billing builds entirely on event ingestion. Ingest events from your application, create Meters to represent that usage, and add metered prices to Products to charge for it.
The `ingestion` method of the `usage` plugin accepts the following parameters:
* `event` (string): The name of the event to ingest. For example, `ai_usage`, `video_streamed` or `file_uploaded`.
* `metadata` (object): A record containing key-value pairs that provide additional context about the event. Values can be strings, numbers, or booleans. This is useful for storing information that can be used to filter the events or compute the actual usage. For example, you can store the duration of the video streamed or the size of the file uploaded.
The authenticated user is automatically associated with the ingested event.
```typescript icon="square-js" Event Ingestion with Usage Plugin Example theme={null}
const { data: ingested } = await authClient.usage.ingestion({
event: "file-uploads",
metadata: {
uploadedFiles: 12,
},
});
```
### 2. Customer Meters
A method to list the authenticated user's Usage Meters (aka Customer Meters). A Customer Meter contains all the information about their consumption on your defined meters.
The `meters` method of the `usage` plugin accepts the following parameters:
* `page` (number): The page number for pagination (starts from 1).
* `limit` (number): The maximum number of meters to return per page.
```typescript icon="square-js" Customer Meters with Usage Plugin Example theme={null}
const { data: customerMeters } = await authClient.usage.meters.list({
query: {
page: 1,
limit: 10,
},
});
```
The `meters` method returns the following fields in the response object:
* **Customer Information**: Details about the authenticated customer
* **Meter Information**: Configuration and settings of the usage meter
* **Customer Meter Information**:
* **Consumed Units**: Total units consumed by the customer
* **Credited Units**: Total units credited to the customer
* **Balance**: The balance of the meter, i.e. the difference between credited and consumed units.
## Webhooks Plugin
[Source code](https://github.com/polarsource/polar-adapters/blob/main/packages/polar-betterauth/src/plugins/webhooks.ts)
The `webhooks` plugin can be used to capture incoming events from your Polar organization.
To set up the Polar `webhooks` plugin with the BetterAuth client, follow the steps below:
Configure a Webhook endpoint in your Polar Organization Settings page by following [this guide](/integrate/webhooks/endpoints). Webhook endpoint is configured at `/api/auth/polar/webhooks`.
Add the obtained webhook secret to your application environment as an environment variable (to be used as `process.env.POLAR_WEBHOOK_SECRET`):
```bash .env theme={null}
POLAR_WEBHOOK_SECRET="..."
```
Pass the `webhooks` plugin in the `use` property.
```typescript icon="square-js" Webhooks Plugin Example theme={null}
import {
polar,
webhooks // [!code ++]
} from "@polar-sh/better-auth";
const auth = betterAuth({
// ... Better Auth config
plugins: [
polar({
...
use: [
webhooks({ // [!code ++]
secret: process.env.POLAR_WEBHOOK_SECRET, // [!code ++]
onCustomerStateChanged: (payload) => // Triggered when anything regarding a customer changes // [!code ++]
onOrderPaid: (payload) => // Triggered when an order was paid (purchase, subscription renewal, etc.) // [!code ++]
... // Over 25 granular webhook handlers // [!code ++]
onPayload: (payload) => // Catch-all for all events // [!code ++]
}) // [!code ++]
],
})
]
});
```
The `webhooks` plugin allows you to invoke handlers for all Polar webhook events:
* `onPayload` - Catch-all handler for any incoming Webhook event
* `onCheckoutCreated` - Triggered when a checkout is created
* `onCheckoutUpdated` - Triggered when a checkout is updated
* `onOrderCreated` - Triggered when an order is created
* `onOrderPaid` - Triggered when an order is paid
* `onOrderRefunded` - Triggered when an order is refunded
* `onRefundCreated` - Triggered when a refund is created
* `onRefundUpdated` - Triggered when a refund is updated
* `onSubscriptionCreated` - Triggered when a subscription is created
* `onSubscriptionUpdated` - Triggered when a subscription is updated
* `onSubscriptionActive` - Triggered when a subscription becomes active
* `onSubscriptionCanceled` - Triggered when a subscription is canceled
* `onSubscriptionRevoked` - Triggered when a subscription is revoked
* `onSubscriptionUncanceled` - Triggered when a subscription cancellation is reversed
* `onProductCreated` - Triggered when a product is created
* `onProductUpdated` - Triggered when a product is updated
* `onOrganizationUpdated` - Triggered when an organization is updated
* `onBenefitCreated` - Triggered when a benefit is created
* `onBenefitUpdated` - Triggered when a benefit is updated
* `onBenefitGrantCreated` - Triggered when a benefit grant is created
* `onBenefitGrantUpdated` - Triggered when a benefit grant is updated
* `onBenefitGrantRevoked` - Triggered when a benefit grant is revoked
* `onCustomerCreated` - Triggered when a customer is created
* `onCustomerUpdated` - Triggered when a customer is updated
* `onCustomerDeleted` - Triggered when a customer is deleted
* `onCustomerStateChanged` - Triggered when a customer state changes
## Portal Plugin
[Source code](https://github.com/polarsource/polar-adapters/blob/main/packages/polar-betterauth/src/plugins/portal.ts)
A plugin which enables customer management of their purchases, orders and subscriptions.
```typescript icon="square-js" Portal Plugin Example theme={null}
import {
polar, checkout,
portal // [!code ++]
} from "@polar-sh/better-auth";
const auth = betterAuth({
// ... Better Auth config
plugins: [
polar({
...
use: [
checkout(...),
portal({
returnUrl: "https://myapp.com", // An optional URL which renders a back-button in the Customer Portal
}) // [!code ++]
],
})
]
});
```
The `portal` plugin gives the BetterAuth Client a set of customer management methods, scoped under `authClient.customer` object.
### 1. Customer Portal Management
The following method will redirect the user to the Polar Customer Portal, where they can see their orders, purchases, subscriptions, benefits, etc.
```typescript icon="square-js" Open Customer Portal Example theme={null}
await authClient.customer.portal();
```
### 2. Customer State
The portal plugin also adds a convenient method to retrieve the Customer State.
```typescript icon="square-js" Retrieve Customer State Example theme={null}
const { data: customerState } = await authClient.customer.state();
```
The customer state object contains:
* All the data about the customer.
* The list of their active subscriptions.
This does not include subscriptions done by a parent organization. See the
subscription list-method below for more information.
* The list of their granted benefits.
* The list of their active meters, with their current balance.
Using the customer state object, you can determine whether to provision access for the user to your service.
Learn more about the Polar Customer State [in the Polar Docs](https://polar.sh/docs/integrate/customer-state).
### 3. Benefits, Orders & Subscriptions
The portal plugin adds the following 3 convenient methods for listing benefits, orders & subscriptions relevant to the authenticated user/customer.
#### 3.1 Benefits
This method only lists granted benefits for the authenticated user/customer.
```typescript icon="square-js" List User Benefits Example theme={null}
const { data: benefits } = await authClient.customer.benefits.list({
query: {
page: 1,
limit: 10,
},
});
```
#### 3.2 Orders
This method lists orders like purchases and subscription renewals for the authenticated user/customer.
```typescript icon="square-js" List User Orders Example theme={null}
const { data: orders } = await authClient.customer.orders.list({
query: {
page: 1,
limit: 10,
productBillingType: "one_time", // or 'recurring'
},
});
```
Using the Organization ID as the `referenceId` you can retrieve all the subscriptions associated with that organization (instead of the user).
To figure out if a user should have access, pass the user's organization ID to see if there is an active subscription for that organization.
```typescript icon="square-js" List Organization Subscriptions Example theme={null}
const organizationId = (await authClient.organization.list())?.data?.[0]?.id,
const { data: subscriptions } = await authClient.customer.orders.list({
query: {
page: 1,
limit: 10,
active: true,
referenceId: organizationId
},
});
const userShouldHaveAccess = subscriptions.some(
sub => // Your logic to check subscription product or whatever.
)
```
#### 3.3 Subscriptions
This method lists the subscriptions associated with authenticated user/customer.
```typescript icon="square-js" List User Subscriptions Example theme={null}
const { data: subscriptions } = await authClient.customer.subscriptions.list({
query: {
page: 1,
limit: 10,
active: true,
},
});
```
This will not return subscriptions made by a parent organization to the
authenticated user.
---
# Source: https://polar.sh/docs/features/usage-based-billing/billing.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Billing
> How billing works with Usage Based
## Metered Pricing
Metered Pricing is a pricing model where you charge your customers based on the usage of your application.
There are a few different pricing models unique to Usage Based Billing:
* Unit Pricing
* Volume Pricing *(coming soon)*
### Unit Pricing
Unit pricing is a simple pricing model where you charge a fixed amount for each unit of usage.
For example:
| Product Meter | Price per unit |
| ------------------- | -------------- |
| `prompt-tokens` | \$0.10 |
| `completion-tokens` | \$0.18 |
This means that every unit of `prompt-tokens` consumed by a customer will be charged at \$0.10 and every unit of `completion-tokens` will be charged at \$0.18.
It's a linear pricing model, where the price per unit is fixed.
### Volume Pricing *(coming soon)*
Volume pricing is a pricing model where you charge a fixed amount for a certain volume of usage. Volume pricing is not yet available, but will be coming soon.
## Invoicing Customers for Usage
Our Usage Based Billing infrastructure is built to work with Subscription products out of the box.
### Add a metered price to your product
To charge your customers for usage, you need to add a metered price to your product. You'll need the select the **Meter** and the **amount per unit**.
Optionally, you can set a **cap**. The customer will be charged the cap amount if they exceed it, regardless of the usage.
### Monthly Invoicing
If a customer has a subscription with a monthly billing period, usage is aggregated monthly and invoiced at the end of the month with the rest of the subscription.
### Yearly Invoicing
If a customer has a subscription with a yearly billing period, usage is aggregated yearly and invoiced at the end of the year with the rest of the subscription.
### Usage Charges and Subscription Cancellation
When a subscription is canceled, it generally remains active until the end of the current billing period (known as the grace period). During this grace period, all accumulated usage-based charges continue to be tracked. A final invoice will be issued at the end of that period to cover the consumed usage, even if the subscription will not be renewed. This ensures no pending usage charges are lost.
If a [discount](/features/discounts) is applied on the subscription, it'll be
applied on the **whole invoice**, including metered usage.
## Customer Portal
Customers can view their estimated charges for each meter in the Customer Portal.
---
# Source: https://polar.sh/docs/api-reference/customer-portal/subscriptions/cancel.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Cancel Subscription
> Cancel a subscription of the authenticated customer.
## OpenAPI
````yaml delete /v1/customer-portal/subscriptions/{id}
openapi: 3.1.0
info:
title: Polar API
summary: Polar HTTP and Webhooks API
description: Read the docs at https://polar.sh/docs/api-reference
version: 0.1.0
servers:
- url: https://api.polar.sh
description: Production environment
x-speakeasy-server-id: production
- url: https://sandbox-api.polar.sh
description: Sandbox environment
x-speakeasy-server-id: sandbox
security:
- access_token: []
tags:
- name: public
description: >-
Endpoints shown and documented in the Polar API documentation and
available in our SDKs.
- name: private
description: >-
Endpoints that should appear in the schema only in development to generate
our internal JS SDK.
- name: mcp
description: Endpoints enabled in the MCP server.
paths:
/v1/customer-portal/subscriptions/{id}:
delete:
tags:
- customer_portal
- subscriptions
- public
summary: Cancel Subscription
description: Cancel a subscription of the authenticated customer.
operationId: customer_portal:subscriptions:cancel
parameters:
- name: id
in: path
required: true
schema:
type: string
format: uuid4
description: The subscription ID.
title: Id
description: The subscription ID.
responses:
'200':
description: Customer subscription is canceled.
content:
application/json:
schema:
$ref: '#/components/schemas/CustomerSubscription'
'403':
description: >-
Customer subscription is already canceled or will be at the end of
the period, or the user lacks billing permissions.
content:
application/json:
schema:
$ref: '#/components/schemas/AlreadyCanceledSubscription'
'404':
description: Customer subscription was not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ResourceNotFound'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
security:
- customer_session:
- customer_portal:write
- member_session:
- customer_portal:write
components:
schemas:
CustomerSubscription:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
amount:
type: integer
title: Amount
description: The amount of the subscription.
examples:
- 10000
currency:
type: string
title: Currency
description: The currency of the subscription.
examples:
- usd
recurring_interval:
$ref: '#/components/schemas/SubscriptionRecurringInterval'
description: The interval at which the subscription recurs.
examples:
- month
recurring_interval_count:
type: integer
title: Recurring Interval Count
description: >-
Number of interval units of the subscription. If this is set to 1
the charge will happen every interval (e.g. every month), if set to
2 it will be every other month, and so on.
status:
$ref: '#/components/schemas/SubscriptionStatus'
description: The status of the subscription.
examples:
- active
current_period_start:
type: string
format: date-time
title: Current Period Start
description: The start timestamp of the current billing period.
current_period_end:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Current Period End
description: The end timestamp of the current billing period.
trial_start:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Trial Start
description: The start timestamp of the trial period, if any.
trial_end:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Trial End
description: The end timestamp of the trial period, if any.
cancel_at_period_end:
type: boolean
title: Cancel At Period End
description: >-
Whether the subscription will be canceled at the end of the current
period.
canceled_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Canceled At
description: >-
The timestamp when the subscription was canceled. The subscription
might still be active if `cancel_at_period_end` is `true`.
started_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Started At
description: The timestamp when the subscription started.
ends_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Ends At
description: The timestamp when the subscription will end.
ended_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Ended At
description: The timestamp when the subscription ended.
customer_id:
type: string
format: uuid4
title: Customer Id
description: The ID of the subscribed customer.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the subscribed product.
discount_id:
anyOf:
- type: string
format: uuid4
- type: 'null'
title: Discount Id
description: The ID of the applied discount, if any.
checkout_id:
anyOf:
- type: string
format: uuid4
- type: 'null'
title: Checkout Id
seats:
anyOf:
- type: integer
- type: 'null'
title: Seats
description: >-
The number of seats for seat-based subscriptions. None for non-seat
subscriptions.
customer_cancellation_reason:
anyOf:
- $ref: '#/components/schemas/CustomerCancellationReason'
- type: 'null'
customer_cancellation_comment:
anyOf:
- type: string
- type: 'null'
title: Customer Cancellation Comment
product:
$ref: '#/components/schemas/CustomerSubscriptionProduct'
prices:
items:
oneOf:
- $ref: '#/components/schemas/LegacyRecurringProductPrice'
- $ref: '#/components/schemas/ProductPrice'
type: array
title: Prices
description: List of enabled prices for the subscription.
meters:
items:
$ref: '#/components/schemas/CustomerSubscriptionMeter'
type: array
title: Meters
description: List of meters associated with the subscription.
type: object
required:
- created_at
- modified_at
- id
- amount
- currency
- recurring_interval
- recurring_interval_count
- status
- current_period_start
- current_period_end
- trial_start
- trial_end
- cancel_at_period_end
- canceled_at
- started_at
- ends_at
- ended_at
- customer_id
- product_id
- discount_id
- checkout_id
- customer_cancellation_reason
- customer_cancellation_comment
- product
- prices
- meters
title: CustomerSubscription
AlreadyCanceledSubscription:
properties:
error:
type: string
const: AlreadyCanceledSubscription
title: Error
examples:
- AlreadyCanceledSubscription
detail:
type: string
title: Detail
type: object
required:
- error
- detail
title: AlreadyCanceledSubscription
ResourceNotFound:
properties:
error:
type: string
const: ResourceNotFound
title: Error
examples:
- ResourceNotFound
detail:
type: string
title: Detail
type: object
required:
- error
- detail
title: ResourceNotFound
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
type: object
title: HTTPValidationError
SubscriptionRecurringInterval:
type: string
enum:
- day
- week
- month
- year
title: SubscriptionRecurringInterval
SubscriptionStatus:
type: string
enum:
- incomplete
- incomplete_expired
- trialing
- active
- past_due
- canceled
- unpaid
title: SubscriptionStatus
CustomerCancellationReason:
type: string
enum:
- customer_service
- low_quality
- missing_features
- switched_service
- too_complex
- too_expensive
- unused
- other
title: CustomerCancellationReason
CustomerSubscriptionProduct:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
trial_interval:
anyOf:
- $ref: '#/components/schemas/TrialInterval'
- type: 'null'
description: The interval unit for the trial period.
trial_interval_count:
anyOf:
- type: integer
- type: 'null'
title: Trial Interval Count
description: The number of interval units for the trial period.
name:
type: string
title: Name
description: The name of the product.
description:
anyOf:
- type: string
- type: 'null'
title: Description
description: The description of the product.
recurring_interval:
anyOf:
- $ref: '#/components/schemas/SubscriptionRecurringInterval'
- type: 'null'
description: >-
The recurring interval of the product. If `None`, the product is a
one-time purchase.
recurring_interval_count:
anyOf:
- type: integer
- type: 'null'
title: Recurring Interval Count
description: >-
Number of interval units of the subscription. If this is set to 1
the charge will happen every interval (e.g. every month), if set to
2 it will be every other month, and so on. None for one-time
products.
is_recurring:
type: boolean
title: Is Recurring
description: Whether the product is a subscription.
is_archived:
type: boolean
title: Is Archived
description: Whether the product is archived and no longer available.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the product.
prices:
items:
oneOf:
- $ref: '#/components/schemas/LegacyRecurringProductPrice'
- $ref: '#/components/schemas/ProductPrice'
type: array
title: Prices
description: List of prices for this product.
benefits:
items:
$ref: '#/components/schemas/BenefitPublic'
type: array
title: BenefitPublic
description: List of benefits granted by the product.
medias:
items:
$ref: '#/components/schemas/ProductMediaFileRead'
type: array
title: Medias
description: List of medias associated to the product.
organization:
$ref: '#/components/schemas/CustomerOrganization'
type: object
required:
- id
- created_at
- modified_at
- trial_interval
- trial_interval_count
- name
- description
- recurring_interval
- recurring_interval_count
- is_recurring
- is_archived
- organization_id
- prices
- benefits
- medias
- organization
title: CustomerSubscriptionProduct
LegacyRecurringProductPrice:
oneOf:
- $ref: '#/components/schemas/LegacyRecurringProductPriceFixed'
- $ref: '#/components/schemas/LegacyRecurringProductPriceCustom'
- $ref: '#/components/schemas/LegacyRecurringProductPriceFree'
discriminator:
propertyName: amount_type
mapping:
custom: '#/components/schemas/LegacyRecurringProductPriceCustom'
fixed: '#/components/schemas/LegacyRecurringProductPriceFixed'
free: '#/components/schemas/LegacyRecurringProductPriceFree'
ProductPrice:
oneOf:
- $ref: '#/components/schemas/ProductPriceFixed'
- $ref: '#/components/schemas/ProductPriceCustom'
- $ref: '#/components/schemas/ProductPriceFree'
- $ref: '#/components/schemas/ProductPriceSeatBased'
- $ref: '#/components/schemas/ProductPriceMeteredUnit'
discriminator:
propertyName: amount_type
mapping:
custom: '#/components/schemas/ProductPriceCustom'
fixed: '#/components/schemas/ProductPriceFixed'
free: '#/components/schemas/ProductPriceFree'
metered_unit: '#/components/schemas/ProductPriceMeteredUnit'
seat_based: '#/components/schemas/ProductPriceSeatBased'
CustomerSubscriptionMeter:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
consumed_units:
type: number
title: Consumed Units
description: The number of consumed units so far in this billing period.
examples:
- 25
credited_units:
type: integer
title: Credited Units
description: The number of credited units so far in this billing period.
examples:
- 100
amount:
type: integer
title: Amount
description: The amount due in cents so far in this billing period.
examples:
- 0
meter_id:
type: string
format: uuid4
title: Meter Id
description: The ID of the meter.
examples:
- d498a884-e2cd-4d3e-8002-f536468a8b22
meter:
$ref: '#/components/schemas/CustomerSubscriptionMeterMeter'
type: object
required:
- created_at
- modified_at
- id
- consumed_units
- credited_units
- amount
- meter_id
- meter
title: CustomerSubscriptionMeter
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
msg:
type: string
title: Message
type:
type: string
title: Error Type
type: object
required:
- loc
- msg
- type
title: ValidationError
TrialInterval:
type: string
enum:
- day
- week
- month
- year
title: TrialInterval
BenefitPublic:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the benefit.
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
type:
$ref: '#/components/schemas/BenefitType'
description: The type of the benefit.
description:
type: string
title: Description
description: The description of the benefit.
selectable:
type: boolean
title: Selectable
description: Whether the benefit is selectable when creating a product.
deletable:
type: boolean
title: Deletable
description: Whether the benefit is deletable.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the benefit.
type: object
required:
- id
- created_at
- modified_at
- type
- description
- selectable
- deletable
- organization_id
title: BenefitPublic
ProductMediaFileRead:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
organization_id:
type: string
format: uuid4
title: Organization Id
name:
type: string
title: Name
path:
type: string
title: Path
mime_type:
type: string
title: Mime Type
size:
type: integer
title: Size
storage_version:
anyOf:
- type: string
- type: 'null'
title: Storage Version
checksum_etag:
anyOf:
- type: string
- type: 'null'
title: Checksum Etag
checksum_sha256_base64:
anyOf:
- type: string
- type: 'null'
title: Checksum Sha256 Base64
checksum_sha256_hex:
anyOf:
- type: string
- type: 'null'
title: Checksum Sha256 Hex
last_modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Last Modified At
version:
anyOf:
- type: string
- type: 'null'
title: Version
service:
type: string
const: product_media
title: Service
is_uploaded:
type: boolean
title: Is Uploaded
created_at:
type: string
format: date-time
title: Created At
size_readable:
type: string
title: Size Readable
public_url:
type: string
title: Public Url
type: object
required:
- id
- organization_id
- name
- path
- mime_type
- size
- storage_version
- checksum_etag
- checksum_sha256_base64
- checksum_sha256_hex
- last_modified_at
- version
- service
- is_uploaded
- created_at
- size_readable
- public_url
title: ProductMediaFileRead
description: File to be used as a product media file.
CustomerOrganization:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
name:
type: string
title: Name
description: Organization name shown in checkout, customer portal, emails etc.
slug:
type: string
title: Slug
description: >-
Unique organization slug in checkout, customer portal and credit
card statements.
avatar_url:
anyOf:
- type: string
- type: 'null'
title: Avatar Url
description: Avatar URL shown in checkout, customer portal, emails etc.
proration_behavior:
$ref: '#/components/schemas/SubscriptionProrationBehavior'
description: >-
Proration behavior applied when customer updates their subscription
from the portal.
allow_customer_updates:
type: boolean
title: Allow Customer Updates
description: >-
Whether customers can update their subscriptions from the customer
portal.
customer_portal_settings:
$ref: '#/components/schemas/OrganizationCustomerPortalSettings'
description: Settings related to the customer portal
type: object
required:
- created_at
- modified_at
- id
- name
- slug
- avatar_url
- proration_behavior
- allow_customer_updates
- customer_portal_settings
title: CustomerOrganization
LegacyRecurringProductPriceFixed:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: fixed
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
type: string
const: recurring
title: Type
description: The type of the price.
recurring_interval:
$ref: '#/components/schemas/SubscriptionRecurringInterval'
description: The recurring interval of the price.
price_currency:
type: string
title: Price Currency
description: The currency.
price_amount:
type: integer
title: Price Amount
description: The price in cents.
legacy:
type: boolean
const: true
title: Legacy
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- price_currency
- price_amount
- legacy
title: LegacyRecurringProductPriceFixed
description: >-
A recurring price for a product, i.e. a subscription.
**Deprecated**: The recurring interval should be set on the product
itself.
LegacyRecurringProductPriceCustom:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: custom
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
type: string
const: recurring
title: Type
description: The type of the price.
recurring_interval:
$ref: '#/components/schemas/SubscriptionRecurringInterval'
description: The recurring interval of the price.
price_currency:
type: string
title: Price Currency
description: The currency.
minimum_amount:
type: integer
title: Minimum Amount
description: >-
The minimum amount the customer can pay. If 0, the price is 'free or
pay what you want'. Defaults to 50 cents.
maximum_amount:
anyOf:
- type: integer
- type: 'null'
title: Maximum Amount
description: The maximum amount the customer can pay.
preset_amount:
anyOf:
- type: integer
- type: 'null'
title: Preset Amount
description: The initial amount shown to the customer.
legacy:
type: boolean
const: true
title: Legacy
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- price_currency
- minimum_amount
- maximum_amount
- preset_amount
- legacy
title: LegacyRecurringProductPriceCustom
description: >-
A pay-what-you-want recurring price for a product, i.e. a subscription.
**Deprecated**: The recurring interval should be set on the product
itself.
LegacyRecurringProductPriceFree:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: free
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
type: string
const: recurring
title: Type
description: The type of the price.
recurring_interval:
$ref: '#/components/schemas/SubscriptionRecurringInterval'
description: The recurring interval of the price.
legacy:
type: boolean
const: true
title: Legacy
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- legacy
title: LegacyRecurringProductPriceFree
description: >-
A free recurring price for a product, i.e. a subscription.
**Deprecated**: The recurring interval should be set on the product
itself.
ProductPriceFixed:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: fixed
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
$ref: '#/components/schemas/ProductPriceType'
deprecated: true
recurring_interval:
anyOf:
- $ref: '#/components/schemas/SubscriptionRecurringInterval'
- type: 'null'
deprecated: true
price_currency:
type: string
title: Price Currency
description: The currency.
price_amount:
type: integer
title: Price Amount
description: The price in cents.
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- price_currency
- price_amount
title: ProductPriceFixed
description: A fixed price for a product.
ProductPriceCustom:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: custom
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
$ref: '#/components/schemas/ProductPriceType'
deprecated: true
recurring_interval:
anyOf:
- $ref: '#/components/schemas/SubscriptionRecurringInterval'
- type: 'null'
deprecated: true
price_currency:
type: string
title: Price Currency
description: The currency.
minimum_amount:
type: integer
title: Minimum Amount
description: >-
The minimum amount the customer can pay. If 0, the price is 'free or
pay what you want'. Defaults to 50 cents.
maximum_amount:
anyOf:
- type: integer
- type: 'null'
title: Maximum Amount
description: The maximum amount the customer can pay.
preset_amount:
anyOf:
- type: integer
- type: 'null'
title: Preset Amount
description: The initial amount shown to the customer.
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- price_currency
- minimum_amount
- maximum_amount
- preset_amount
title: ProductPriceCustom
description: A pay-what-you-want price for a product.
ProductPriceFree:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: free
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
$ref: '#/components/schemas/ProductPriceType'
deprecated: true
recurring_interval:
anyOf:
- $ref: '#/components/schemas/SubscriptionRecurringInterval'
- type: 'null'
deprecated: true
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
title: ProductPriceFree
description: A free price for a product.
ProductPriceSeatBased:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: seat_based
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
$ref: '#/components/schemas/ProductPriceType'
deprecated: true
recurring_interval:
anyOf:
- $ref: '#/components/schemas/SubscriptionRecurringInterval'
- type: 'null'
deprecated: true
price_currency:
type: string
title: Price Currency
description: The currency.
seat_tiers:
$ref: '#/components/schemas/ProductPriceSeatTiers-Output'
description: Tiered pricing based on seat quantity
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- price_currency
- seat_tiers
title: ProductPriceSeatBased
description: A seat-based price for a product.
ProductPriceMeteredUnit:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: metered_unit
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
$ref: '#/components/schemas/ProductPriceType'
deprecated: true
recurring_interval:
anyOf:
- $ref: '#/components/schemas/SubscriptionRecurringInterval'
- type: 'null'
deprecated: true
price_currency:
type: string
title: Price Currency
description: The currency.
unit_amount:
type: string
pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
title: Unit Amount
description: The price per unit in cents.
cap_amount:
anyOf:
- type: integer
- type: 'null'
title: Cap Amount
description: >-
The maximum amount in cents that can be charged, regardless of the
number of units consumed.
meter_id:
type: string
format: uuid4
title: Meter Id
description: The ID of the meter associated to the price.
meter:
$ref: '#/components/schemas/ProductPriceMeter'
description: The meter associated to the price.
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- price_currency
- unit_amount
- cap_amount
- meter_id
- meter
title: ProductPriceMeteredUnit
description: A metered, usage-based, price for a product, with a fixed unit price.
CustomerSubscriptionMeterMeter:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
name:
type: string
title: Name
description: >-
The name of the meter. Will be shown on customer's invoices and
usage.
type: object
required:
- created_at
- modified_at
- id
- name
title: CustomerSubscriptionMeterMeter
BenefitType:
type: string
enum:
- custom
- discord
- github_repository
- downloadables
- license_keys
- meter_credit
title: BenefitType
SubscriptionProrationBehavior:
type: string
enum:
- invoice
- prorate
title: SubscriptionProrationBehavior
OrganizationCustomerPortalSettings:
properties:
usage:
$ref: '#/components/schemas/CustomerPortalUsageSettings'
subscription:
$ref: '#/components/schemas/CustomerPortalSubscriptionSettings'
type: object
required:
- usage
- subscription
title: OrganizationCustomerPortalSettings
ProductPriceSource:
type: string
enum:
- catalog
- ad_hoc
title: ProductPriceSource
ProductPriceType:
type: string
enum:
- one_time
- recurring
title: ProductPriceType
ProductPriceSeatTiers-Output:
properties:
tiers:
items:
$ref: '#/components/schemas/ProductPriceSeatTier'
type: array
minItems: 1
title: Tiers
description: List of pricing tiers
minimum_seats:
type: integer
title: Minimum Seats
description: >-
Minimum number of seats required for purchase, derived from first
tier.
maximum_seats:
anyOf:
- type: integer
- type: 'null'
title: Maximum Seats
description: >-
Maximum number of seats allowed for purchase, derived from last
tier. None for unlimited.
type: object
required:
- tiers
- minimum_seats
- maximum_seats
title: ProductPriceSeatTiers
description: |-
List of pricing tiers for seat-based pricing.
The minimum and maximum seat limits are derived from the tiers:
- minimum_seats = first tier's min_seats
- maximum_seats = last tier's max_seats (None for unlimited)
ProductPriceMeter:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
name:
type: string
title: Name
description: The name of the meter.
type: object
required:
- id
- name
title: ProductPriceMeter
description: A meter associated to a metered price.
CustomerPortalUsageSettings:
properties:
show:
type: boolean
title: Show
type: object
required:
- show
title: CustomerPortalUsageSettings
CustomerPortalSubscriptionSettings:
properties:
update_seats:
type: boolean
title: Update Seats
update_plan:
type: boolean
title: Update Plan
type: object
required:
- update_seats
- update_plan
title: CustomerPortalSubscriptionSettings
ProductPriceSeatTier:
properties:
min_seats:
type: integer
minimum: 1
title: Min Seats
description: Minimum number of seats (inclusive)
max_seats:
anyOf:
- type: integer
minimum: 1
- type: 'null'
title: Max Seats
description: Maximum number of seats (inclusive). None for unlimited.
price_per_seat:
type: integer
maximum: 99999999
minimum: 0
title: Price Per Seat
description: Price per seat in cents for this tier
type: object
required:
- min_seats
- price_per_seat
title: ProductPriceSeatTier
description: A pricing tier for seat-based pricing.
securitySchemes:
access_token:
type: http
scheme: bearer
description: >-
You can generate an **Organization Access Token** from your
organization's settings.
customer_session:
type: http
description: >-
Customer session tokens are specific tokens that are used to
authenticate customers on your organization. You can create those
sessions programmatically using the [Create Customer Session
endpoint](/api-reference/customer-portal/sessions/create).
scheme: bearer
member_session:
type: http
description: >-
Member session tokens are specific tokens that are used to authenticate
members on your organization. You can create those sessions
programmatically using the [Create Member Session
endpoint](/api-reference/member-portal/sessions/create).
scheme: bearer
````
---
# Source: https://polar.sh/docs/guides/change-email-as-merchant.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# How to Change Account Email (as a Merchant)
> Learn how to change your account email on Polar as a Merchant.
To access account settings, open the menu in the bottom left corner in the dashboard and click `Account Settings`.
Click `Change Email` button in the `Account Connections` section to start changing your email.
Enter the new email in the input box that appears.
Polar would send an email to the new email that is entered in the previous step. Click the `Update my email` button in the email.
Confirm the email change by pressing the `Update the email` button.
---
# Source: https://polar.sh/docs/api-reference/webhooks/checkout.created.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# checkout.created
---
# Source: https://polar.sh/docs/api-reference/webhooks/checkout.updated.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# checkout.updated
---
# Source: https://polar.sh/docs/api-reference/customer-seats/claim.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Claim Seat
## OpenAPI
````yaml post /v1/customer-seats/claim
openapi: 3.1.0
info:
title: Polar API
summary: Polar HTTP and Webhooks API
description: Read the docs at https://polar.sh/docs/api-reference
version: 0.1.0
servers:
- url: https://api.polar.sh
description: Production environment
x-speakeasy-server-id: production
- url: https://sandbox-api.polar.sh
description: Sandbox environment
x-speakeasy-server-id: sandbox
security:
- access_token: []
tags:
- name: public
description: >-
Endpoints shown and documented in the Polar API documentation and
available in our SDKs.
- name: private
description: >-
Endpoints that should appear in the schema only in development to generate
our internal JS SDK.
- name: mcp
description: Endpoints enabled in the MCP server.
paths:
/v1/customer-seats/claim:
post:
tags:
- customer-seats
- public
summary: Claim Seat
operationId: customer-seats:claim_seat
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SeatClaim'
required: true
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/CustomerSeatClaimResponse'
'400':
description: Invalid, expired, or already claimed token
'403':
description: Seat-based pricing not enabled for organization
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
security:
- {}
components:
schemas:
SeatClaim:
properties:
invitation_token:
type: string
title: Invitation Token
description: Invitation token to claim the seat
type: object
required:
- invitation_token
title: SeatClaim
CustomerSeatClaimResponse:
properties:
seat:
$ref: '#/components/schemas/CustomerSeat'
description: The claimed seat
customer_session_token:
type: string
title: Customer Session Token
description: Session token for immediate customer portal access
type: object
required:
- seat
- customer_session_token
title: CustomerSeatClaimResponse
description: Response after successfully claiming a seat.
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
type: object
title: HTTPValidationError
CustomerSeat:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid
title: Id
description: The seat ID
subscription_id:
anyOf:
- type: string
format: uuid
- type: 'null'
title: Subscription Id
description: The subscription ID (for recurring seats)
order_id:
anyOf:
- type: string
format: uuid
- type: 'null'
title: Order Id
description: The order ID (for one-time purchase seats)
status:
$ref: '#/components/schemas/SeatStatus'
description: Status of the seat
customer_id:
anyOf:
- type: string
format: uuid
- type: 'null'
title: Customer Id
description: >-
The customer ID. When member_model_enabled is true, this is the
billing customer (purchaser). When false, this is the seat member
customer.
member_id:
anyOf:
- type: string
format: uuid
- type: 'null'
title: Member Id
description: The member ID of the seat occupant
email:
anyOf:
- type: string
- type: 'null'
title: Email
description: Email of the seat member (set when member_model_enabled is true)
customer_email:
anyOf:
- type: string
- type: 'null'
title: Customer Email
description: The assigned customer email
invitation_token_expires_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Invitation Token Expires At
description: When the invitation token expires
claimed_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Claimed At
description: When the seat was claimed
revoked_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Revoked At
description: When the seat was revoked
seat_metadata:
anyOf:
- additionalProperties: true
type: object
- type: 'null'
title: Seat Metadata
description: Additional metadata for the seat
type: object
required:
- created_at
- modified_at
- id
- status
title: CustomerSeat
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
msg:
type: string
title: Message
type:
type: string
title: Error Type
type: object
required:
- loc
- msg
- type
title: ValidationError
SeatStatus:
type: string
enum:
- pending
- claimed
- revoked
title: SeatStatus
securitySchemes:
access_token:
type: http
scheme: bearer
description: >-
You can generate an **Organization Access Token** from your
organization's settings.
````
---
# Source: https://polar.sh/docs/api-reference/files/complete-upload.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Complete File Upload
> Complete a file upload.
**Scopes**: `files:write`
## OpenAPI
````yaml post /v1/files/{id}/uploaded
openapi: 3.1.0
info:
title: Polar API
summary: Polar HTTP and Webhooks API
description: Read the docs at https://polar.sh/docs/api-reference
version: 0.1.0
servers:
- url: https://api.polar.sh
description: Production environment
x-speakeasy-server-id: production
- url: https://sandbox-api.polar.sh
description: Sandbox environment
x-speakeasy-server-id: sandbox
security:
- access_token: []
tags:
- name: public
description: >-
Endpoints shown and documented in the Polar API documentation and
available in our SDKs.
- name: private
description: >-
Endpoints that should appear in the schema only in development to generate
our internal JS SDK.
- name: mcp
description: Endpoints enabled in the MCP server.
paths:
/v1/files/{id}/uploaded:
post:
tags:
- files
- public
summary: Complete File Upload
description: |-
Complete a file upload.
**Scopes**: `files:write`
operationId: files:uploaded
parameters:
- name: id
in: path
required: true
schema:
type: string
format: uuid4
description: The file ID.
title: Id
description: The file ID.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/FileUploadCompleted'
responses:
'200':
description: File upload completed.
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/DownloadableFileRead'
- $ref: '#/components/schemas/ProductMediaFileRead'
- $ref: '#/components/schemas/OrganizationAvatarFileRead'
discriminator:
propertyName: service
mapping:
downloadable: '#/components/schemas/DownloadableFileRead'
product_media: '#/components/schemas/ProductMediaFileRead'
organization_avatar: '#/components/schemas/OrganizationAvatarFileRead'
title: Response Files:Uploaded
'403':
description: You don't have the permission to update this file.
content:
application/json:
schema:
$ref: '#/components/schemas/NotPermitted'
'404':
description: File not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ResourceNotFound'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
components:
schemas:
FileUploadCompleted:
properties:
id:
type: string
title: Id
path:
type: string
title: Path
parts:
items:
$ref: '#/components/schemas/S3FileUploadCompletedPart'
type: array
title: Parts
type: object
required:
- id
- path
- parts
title: FileUploadCompleted
DownloadableFileRead:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
organization_id:
type: string
format: uuid4
title: Organization Id
name:
type: string
title: Name
path:
type: string
title: Path
mime_type:
type: string
title: Mime Type
size:
type: integer
title: Size
storage_version:
anyOf:
- type: string
- type: 'null'
title: Storage Version
checksum_etag:
anyOf:
- type: string
- type: 'null'
title: Checksum Etag
checksum_sha256_base64:
anyOf:
- type: string
- type: 'null'
title: Checksum Sha256 Base64
checksum_sha256_hex:
anyOf:
- type: string
- type: 'null'
title: Checksum Sha256 Hex
last_modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Last Modified At
version:
anyOf:
- type: string
- type: 'null'
title: Version
service:
type: string
const: downloadable
title: Service
is_uploaded:
type: boolean
title: Is Uploaded
created_at:
type: string
format: date-time
title: Created At
size_readable:
type: string
title: Size Readable
type: object
required:
- id
- organization_id
- name
- path
- mime_type
- size
- storage_version
- checksum_etag
- checksum_sha256_base64
- checksum_sha256_hex
- last_modified_at
- version
- service
- is_uploaded
- created_at
- size_readable
title: DownloadableFileRead
description: File to be associated with the downloadables benefit.
ProductMediaFileRead:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
organization_id:
type: string
format: uuid4
title: Organization Id
name:
type: string
title: Name
path:
type: string
title: Path
mime_type:
type: string
title: Mime Type
size:
type: integer
title: Size
storage_version:
anyOf:
- type: string
- type: 'null'
title: Storage Version
checksum_etag:
anyOf:
- type: string
- type: 'null'
title: Checksum Etag
checksum_sha256_base64:
anyOf:
- type: string
- type: 'null'
title: Checksum Sha256 Base64
checksum_sha256_hex:
anyOf:
- type: string
- type: 'null'
title: Checksum Sha256 Hex
last_modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Last Modified At
version:
anyOf:
- type: string
- type: 'null'
title: Version
service:
type: string
const: product_media
title: Service
is_uploaded:
type: boolean
title: Is Uploaded
created_at:
type: string
format: date-time
title: Created At
size_readable:
type: string
title: Size Readable
public_url:
type: string
title: Public Url
type: object
required:
- id
- organization_id
- name
- path
- mime_type
- size
- storage_version
- checksum_etag
- checksum_sha256_base64
- checksum_sha256_hex
- last_modified_at
- version
- service
- is_uploaded
- created_at
- size_readable
- public_url
title: ProductMediaFileRead
description: File to be used as a product media file.
OrganizationAvatarFileRead:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
organization_id:
type: string
format: uuid4
title: Organization Id
name:
type: string
title: Name
path:
type: string
title: Path
mime_type:
type: string
title: Mime Type
size:
type: integer
title: Size
storage_version:
anyOf:
- type: string
- type: 'null'
title: Storage Version
checksum_etag:
anyOf:
- type: string
- type: 'null'
title: Checksum Etag
checksum_sha256_base64:
anyOf:
- type: string
- type: 'null'
title: Checksum Sha256 Base64
checksum_sha256_hex:
anyOf:
- type: string
- type: 'null'
title: Checksum Sha256 Hex
last_modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Last Modified At
version:
anyOf:
- type: string
- type: 'null'
title: Version
service:
type: string
const: organization_avatar
title: Service
is_uploaded:
type: boolean
title: Is Uploaded
created_at:
type: string
format: date-time
title: Created At
size_readable:
type: string
title: Size Readable
public_url:
type: string
title: Public Url
type: object
required:
- id
- organization_id
- name
- path
- mime_type
- size
- storage_version
- checksum_etag
- checksum_sha256_base64
- checksum_sha256_hex
- last_modified_at
- version
- service
- is_uploaded
- created_at
- size_readable
- public_url
title: OrganizationAvatarFileRead
description: File to be used as an organization avatar.
NotPermitted:
properties:
error:
type: string
const: NotPermitted
title: Error
examples:
- NotPermitted
detail:
type: string
title: Detail
type: object
required:
- error
- detail
title: NotPermitted
ResourceNotFound:
properties:
error:
type: string
const: ResourceNotFound
title: Error
examples:
- ResourceNotFound
detail:
type: string
title: Detail
type: object
required:
- error
- detail
title: ResourceNotFound
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
type: object
title: HTTPValidationError
S3FileUploadCompletedPart:
properties:
number:
type: integer
title: Number
checksum_etag:
type: string
title: Checksum Etag
checksum_sha256_base64:
anyOf:
- type: string
- type: 'null'
title: Checksum Sha256 Base64
type: object
required:
- number
- checksum_etag
- checksum_sha256_base64
title: S3FileUploadCompletedPart
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
msg:
type: string
title: Message
type:
type: string
title: Error Type
type: object
required:
- loc
- msg
- type
title: ValidationError
securitySchemes:
access_token:
type: http
scheme: bearer
description: >-
You can generate an **Organization Access Token** from your
organization's settings.
````
---
# Source: https://polar.sh/docs/api-reference/checkouts/confirm-session-from-client.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Confirm Checkout Session from Client
> Confirm a checkout session by client secret.
Orders and subscriptions will be processed.
## OpenAPI
````yaml post /v1/checkouts/client/{client_secret}/confirm
openapi: 3.1.0
info:
title: Polar API
summary: Polar HTTP and Webhooks API
description: Read the docs at https://polar.sh/docs/api-reference
version: 0.1.0
servers:
- url: https://api.polar.sh
description: Production environment
x-speakeasy-server-id: production
- url: https://sandbox-api.polar.sh
description: Sandbox environment
x-speakeasy-server-id: sandbox
security:
- access_token: []
tags:
- name: public
description: >-
Endpoints shown and documented in the Polar API documentation and
available in our SDKs.
- name: private
description: >-
Endpoints that should appear in the schema only in development to generate
our internal JS SDK.
- name: mcp
description: Endpoints enabled in the MCP server.
paths:
/v1/checkouts/client/{client_secret}/confirm:
post:
tags:
- checkouts
- public
summary: Confirm Checkout Session from Client
description: |-
Confirm a checkout session by client secret.
Orders and subscriptions will be processed.
operationId: checkouts:client_confirm
parameters:
- name: client_secret
in: path
required: true
schema:
type: string
description: The checkout session client secret.
title: Client Secret
description: The checkout session client secret.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CheckoutConfirmStripe'
responses:
'200':
description: Checkout session confirmed.
content:
application/json:
schema:
$ref: '#/components/schemas/CheckoutPublicConfirmed'
'400':
description: The payment failed.
content:
application/json:
schema:
$ref: '#/components/schemas/PaymentError'
'403':
description: >-
The checkout is expired, the customer already has an active
subscription, or the organization is not ready to accept payments.
content:
application/json:
schema:
$ref: '#/components/schemas/CheckoutForbiddenError'
'404':
description: Checkout session not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ResourceNotFound'
'410':
description: The checkout session is expired.
content:
application/json:
schema:
$ref: '#/components/schemas/ExpiredCheckoutError'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
components:
schemas:
CheckoutConfirmStripe:
properties:
custom_field_data:
additionalProperties:
anyOf:
- type: string
- type: integer
- type: boolean
- type: string
format: date-time
- type: 'null'
type: object
title: Custom Field Data
description: Key-value object storing custom field values.
product_id:
anyOf:
- type: string
format: uuid4
- type: 'null'
title: Product Id
description: >-
ID of the product to checkout. Must be present in the checkout's
product list.
product_price_id:
anyOf:
- type: string
format: uuid4
- type: 'null'
title: Product Price Id
description: >-
ID of the product price to checkout. Must correspond to a price
present in the checkout's product list.
deprecated: true
amount:
anyOf:
- type: integer
maximum: 99999999
minimum: 0
description: >-
Amount in cents, before discounts and taxes. Only useful for
custom prices, it'll be ignored for fixed and free prices.
- type: 'null'
title: Amount
seats:
anyOf:
- type: integer
maximum: 1000
minimum: 1
- type: 'null'
title: Seats
description: Number of seats for seat-based pricing.
is_business_customer:
anyOf:
- type: boolean
- type: 'null'
title: Is Business Customer
customer_name:
anyOf:
- type: string
maxLength: 256
description: The name of the customer.
examples:
- John Doe
- type: 'null'
title: Customer Name
customer_email:
anyOf:
- type: string
format: email
description: Email address of the customer.
- type: 'null'
title: Customer Email
customer_billing_name:
anyOf:
- type: string
- type: 'null'
title: Customer Billing Name
customer_billing_address:
anyOf:
- $ref: '#/components/schemas/AddressInput'
description: Billing address of the customer.
- type: 'null'
customer_tax_id:
anyOf:
- type: string
- type: 'null'
title: Customer Tax Id
discount_code:
anyOf:
- type: string
- type: 'null'
title: Discount Code
description: Discount code to apply to the checkout.
allow_trial:
anyOf:
- type: boolean
const: false
- type: 'null'
title: Allow Trial
description: >-
Disable the trial period for the checkout session. It's mainly
useful when the trial is blocked because the customer already
redeemed one.
confirmation_token_id:
anyOf:
- type: string
- type: 'null'
title: Confirmation Token Id
description: >-
ID of the Stripe confirmation token. Required for fixed prices and
custom prices.
type: object
title: CheckoutConfirmStripe
description: Confirm a checkout session using a Stripe confirmation token.
CheckoutPublicConfirmed:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
custom_field_data:
additionalProperties:
anyOf:
- type: string
- type: integer
- type: boolean
- type: string
format: date-time
- type: 'null'
type: object
title: Custom Field Data
description: Key-value object storing custom field values.
payment_processor:
$ref: '#/components/schemas/PaymentProcessor'
description: Payment processor used.
status:
type: string
const: confirmed
title: Status
client_secret:
type: string
title: Client Secret
description: >-
Client secret used to update and complete the checkout session from
the client.
url:
type: string
title: Url
description: URL where the customer can access the checkout session.
expires_at:
type: string
format: date-time
title: Expires At
description: Expiration date and time of the checkout session.
success_url:
type: string
title: Success Url
description: >-
URL where the customer will be redirected after a successful
payment.
return_url:
anyOf:
- type: string
- type: 'null'
title: Return Url
description: >-
When set, a back button will be shown in the checkout to return to
this URL.
embed_origin:
anyOf:
- type: string
- type: 'null'
title: Embed Origin
description: >-
When checkout is embedded, represents the Origin of the page
embedding the checkout. Used as a security measure to send messages
only to the embedding page.
amount:
type: integer
title: Amount
description: Amount in cents, before discounts and taxes.
seats:
anyOf:
- type: integer
- type: 'null'
title: Seats
description: Number of seats for seat-based pricing.
price_per_seat:
anyOf:
- type: integer
- type: 'null'
title: Price Per Seat
description: >-
Price per seat in cents for the current seat count, based on the
applicable tier. Only relevant for seat-based pricing.
discount_amount:
type: integer
title: Discount Amount
description: Discount amount in cents.
net_amount:
type: integer
title: Net Amount
description: Amount in cents, after discounts but before taxes.
tax_amount:
anyOf:
- type: integer
- type: 'null'
title: Tax Amount
description: >-
Sales tax amount in cents. If `null`, it means there is no enough
information yet to calculate it.
total_amount:
type: integer
title: Total Amount
description: Amount in cents, after discounts and taxes.
currency:
type: string
title: Currency
description: Currency code of the checkout session.
allow_trial:
anyOf:
- type: boolean
- type: 'null'
title: Allow Trial
description: >-
Whether to enable the trial period for the checkout session. If
`false`, the trial period will be disabled, even if the selected
product has a trial configured.
active_trial_interval:
anyOf:
- $ref: '#/components/schemas/TrialInterval'
- type: 'null'
description: >-
Interval unit of the trial period, if any. This value is either set
from the checkout, if `trial_interval` is set, or from the selected
product.
active_trial_interval_count:
anyOf:
- type: integer
- type: 'null'
title: Active Trial Interval Count
description: >-
Number of interval units of the trial period, if any. This value is
either set from the checkout, if `trial_interval_count` is set, or
from the selected product.
trial_end:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Trial End
description: End date and time of the trial period, if any.
organization_id:
type: string
format: uuid4
title: Organization Id
description: ID of the organization owning the checkout session.
product_id:
anyOf:
- type: string
format: uuid4
- type: 'null'
title: Product Id
description: ID of the product to checkout.
product_price_id:
anyOf:
- type: string
format: uuid4
- type: 'null'
title: Product Price Id
description: ID of the product price to checkout.
deprecated: true
discount_id:
anyOf:
- type: string
format: uuid4
- type: 'null'
title: Discount Id
description: ID of the discount applied to the checkout.
allow_discount_codes:
type: boolean
title: Allow Discount Codes
description: >-
Whether to allow the customer to apply discount codes. If you apply
a discount through `discount_id`, it'll still be applied, but the
customer won't be able to change it.
require_billing_address:
type: boolean
title: Require Billing Address
description: >-
Whether to require the customer to fill their full billing address,
instead of just the country. Customers in the US will always be
required to fill their full address, regardless of this setting. If
you preset the billing address, this setting will be automatically
set to `true`.
is_discount_applicable:
type: boolean
title: Is Discount Applicable
description: >-
Whether the discount is applicable to the checkout. Typically, free
and custom prices are not discountable.
is_free_product_price:
type: boolean
title: Is Free Product Price
description: Whether the product price is free, regardless of discounts.
is_payment_required:
type: boolean
title: Is Payment Required
description: >-
Whether the checkout requires payment, e.g. in case of free products
or discounts that cover the total amount.
is_payment_setup_required:
type: boolean
title: Is Payment Setup Required
description: >-
Whether the checkout requires setting up a payment method,
regardless of the amount, e.g. subscriptions that have first free
cycles.
is_payment_form_required:
type: boolean
title: Is Payment Form Required
description: >-
Whether the checkout requires a payment form, whether because of a
payment or payment method setup.
customer_id:
anyOf:
- type: string
format: uuid4
- type: 'null'
title: Customer Id
is_business_customer:
type: boolean
title: Is Business Customer
description: >-
Whether the customer is a business or an individual. If `true`, the
customer will be required to fill their full billing address and
billing name.
customer_name:
anyOf:
- type: string
- type: 'null'
title: Customer Name
description: Name of the customer.
customer_email:
anyOf:
- type: string
- type: 'null'
title: Customer Email
description: Email address of the customer.
customer_ip_address:
anyOf:
- type: string
format: ipvanyaddress
- type: 'null'
title: Customer Ip Address
customer_billing_name:
anyOf:
- type: string
- type: 'null'
title: Customer Billing Name
customer_billing_address:
anyOf:
- $ref: '#/components/schemas/Address'
description: Billing address of the customer.
- type: 'null'
customer_tax_id:
anyOf:
- type: string
- type: 'null'
title: Customer Tax Id
payment_processor_metadata:
additionalProperties:
type: string
type: object
title: Payment Processor Metadata
billing_address_fields:
$ref: '#/components/schemas/CheckoutBillingAddressFields'
description: >-
Determine which billing address fields should be disabled, optional
or required in the checkout form.
products:
items:
$ref: '#/components/schemas/CheckoutProduct'
type: array
title: Products
description: List of products available to select.
product:
anyOf:
- $ref: '#/components/schemas/CheckoutProduct'
- type: 'null'
description: Product selected to checkout.
product_price:
anyOf:
- oneOf:
- $ref: '#/components/schemas/LegacyRecurringProductPrice'
- $ref: '#/components/schemas/ProductPrice'
- type: 'null'
title: Product Price
description: Price of the selected product.
deprecated: true
prices:
anyOf:
- additionalProperties:
items:
oneOf:
- $ref: '#/components/schemas/LegacyRecurringProductPrice'
- $ref: '#/components/schemas/ProductPrice'
type: array
description: List of prices for this product.
propertyNames:
format: uuid4
type: object
- type: 'null'
title: Prices
description: Mapping of product IDs to their list of prices.
discount:
anyOf:
- oneOf:
- $ref: >-
#/components/schemas/CheckoutDiscountFixedOnceForeverDuration
- $ref: '#/components/schemas/CheckoutDiscountFixedRepeatDuration'
- $ref: >-
#/components/schemas/CheckoutDiscountPercentageOnceForeverDuration
- $ref: >-
#/components/schemas/CheckoutDiscountPercentageRepeatDuration
- type: 'null'
title: Discount
organization:
$ref: '#/components/schemas/CheckoutOrganization'
attached_custom_fields:
anyOf:
- items:
$ref: '#/components/schemas/AttachedCustomField'
type: array
- type: 'null'
title: Attached Custom Fields
customer_session_token:
type: string
title: Customer Session Token
type: object
required:
- id
- created_at
- modified_at
- payment_processor
- status
- client_secret
- url
- expires_at
- success_url
- return_url
- embed_origin
- amount
- discount_amount
- net_amount
- tax_amount
- total_amount
- currency
- allow_trial
- active_trial_interval
- active_trial_interval_count
- trial_end
- organization_id
- product_id
- product_price_id
- discount_id
- allow_discount_codes
- require_billing_address
- is_discount_applicable
- is_free_product_price
- is_payment_required
- is_payment_setup_required
- is_payment_form_required
- customer_id
- is_business_customer
- customer_name
- customer_email
- customer_ip_address
- customer_billing_name
- customer_billing_address
- customer_tax_id
- payment_processor_metadata
- billing_address_fields
- products
- product
- product_price
- prices
- discount
- organization
- attached_custom_fields
- customer_session_token
title: CheckoutPublicConfirmed
description: >-
Checkout session data retrieved using the client secret after
confirmation.
It contains a customer session token to retrieve order information
right after the checkout.
PaymentError:
properties:
error:
type: string
const: PaymentError
title: Error
examples:
- PaymentError
detail:
type: string
title: Detail
type: object
required:
- error
- detail
title: PaymentError
CheckoutForbiddenError:
anyOf:
- $ref: '#/components/schemas/AlreadyActiveSubscriptionError'
- $ref: '#/components/schemas/NotOpenCheckout'
- $ref: '#/components/schemas/PaymentNotReady'
- $ref: '#/components/schemas/TrialAlreadyRedeemed'
ResourceNotFound:
properties:
error:
type: string
const: ResourceNotFound
title: Error
examples:
- ResourceNotFound
detail:
type: string
title: Detail
type: object
required:
- error
- detail
title: ResourceNotFound
ExpiredCheckoutError:
properties:
error:
type: string
const: ExpiredCheckoutError
title: Error
examples:
- ExpiredCheckoutError
detail:
type: string
title: Detail
type: object
required:
- error
- detail
title: ExpiredCheckoutError
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
type: object
title: HTTPValidationError
AddressInput:
properties:
line1:
anyOf:
- type: string
- type: 'null'
title: Line1
line2:
anyOf:
- type: string
- type: 'null'
title: Line2
postal_code:
anyOf:
- type: string
- type: 'null'
title: Postal Code
city:
anyOf:
- type: string
- type: 'null'
title: City
state:
anyOf:
- type: string
- type: 'null'
title: State
country:
type: string
enum:
- AD
- AE
- AF
- AG
- AI
- AL
- AM
- AO
- AQ
- AR
- AS
- AT
- AU
- AW
- AX
- AZ
- BA
- BB
- BD
- BE
- BF
- BG
- BH
- BI
- BJ
- BL
- BM
- BN
- BO
- BQ
- BR
- BS
- BT
- BV
- BW
- BY
- BZ
- CA
- CC
- CD
- CF
- CG
- CH
- CI
- CK
- CL
- CM
- CN
- CO
- CR
- CV
- CW
- CX
- CY
- CZ
- DE
- DJ
- DK
- DM
- DO
- DZ
- EC
- EE
- EG
- EH
- ER
- ES
- ET
- FI
- FJ
- FK
- FM
- FO
- FR
- GA
- GB
- GD
- GE
- GF
- GG
- GH
- GI
- GL
- GM
- GN
- GP
- GQ
- GR
- GS
- GT
- GU
- GW
- GY
- HK
- HM
- HN
- HR
- HT
- HU
- ID
- IE
- IL
- IM
- IN
- IO
- IQ
- IS
- IT
- JE
- JM
- JO
- JP
- KE
- KG
- KH
- KI
- KM
- KN
- KR
- KW
- KY
- KZ
- LA
- LB
- LC
- LI
- LK
- LR
- LS
- LT
- LU
- LV
- LY
- MA
- MC
- MD
- ME
- MF
- MG
- MH
- MK
- ML
- MM
- MN
- MO
- MP
- MQ
- MR
- MS
- MT
- MU
- MV
- MW
- MX
- MY
- MZ
- NA
- NC
- NE
- NF
- NG
- NI
- NL
- 'NO'
- NP
- NR
- NU
- NZ
- OM
- PA
- PE
- PF
- PG
- PH
- PK
- PL
- PM
- PN
- PR
- PS
- PT
- PW
- PY
- QA
- RE
- RO
- RS
- RW
- SA
- SB
- SC
- SD
- SE
- SG
- SH
- SI
- SJ
- SK
- SL
- SM
- SN
- SO
- SR
- SS
- ST
- SV
- SX
- SZ
- TC
- TD
- TF
- TG
- TH
- TJ
- TK
- TL
- TM
- TN
- TO
- TR
- TT
- TV
- TW
- TZ
- UA
- UG
- UM
- US
- UY
- UZ
- VA
- VC
- VE
- VG
- VI
- VN
- VU
- WF
- WS
- YE
- YT
- ZA
- ZM
- ZW
title: CountryAlpha2Input
examples:
- US
- SE
- FR
x-speakeasy-enums:
- AD
- AE
- AF
- AG
- AI
- AL
- AM
- AO
- AQ
- AR
- AS
- AT
- AU
- AW
- AX
- AZ
- BA
- BB
- BD
- BE
- BF
- BG
- BH
- BI
- BJ
- BL
- BM
- BN
- BO
- BQ
- BR
- BS
- BT
- BV
- BW
- BY
- BZ
- CA
- CC
- CD
- CF
- CG
- CH
- CI
- CK
- CL
- CM
- CN
- CO
- CR
- CV
- CW
- CX
- CY
- CZ
- DE
- DJ
- DK
- DM
- DO
- DZ
- EC
- EE
- EG
- EH
- ER
- ES
- ET
- FI
- FJ
- FK
- FM
- FO
- FR
- GA
- GB
- GD
- GE
- GF
- GG
- GH
- GI
- GL
- GM
- GN
- GP
- GQ
- GR
- GS
- GT
- GU
- GW
- GY
- HK
- HM
- HN
- HR
- HT
- HU
- ID
- IE
- IL
- IM
- IN
- IO
- IQ
- IS
- IT
- JE
- JM
- JO
- JP
- KE
- KG
- KH
- KI
- KM
- KN
- KR
- KW
- KY
- KZ
- LA
- LB
- LC
- LI
- LK
- LR
- LS
- LT
- LU
- LV
- LY
- MA
- MC
- MD
- ME
- MF
- MG
- MH
- MK
- ML
- MM
- MN
- MO
- MP
- MQ
- MR
- MS
- MT
- MU
- MV
- MW
- MX
- MY
- MZ
- NA
- NC
- NE
- NF
- NG
- NI
- NL
- 'NO'
- NP
- NR
- NU
- NZ
- OM
- PA
- PE
- PF
- PG
- PH
- PK
- PL
- PM
- PN
- PR
- PS
- PT
- PW
- PY
- QA
- RE
- RO
- RS
- RW
- SA
- SB
- SC
- SD
- SE
- SG
- SH
- SI
- SJ
- SK
- SL
- SM
- SN
- SO
- SR
- SS
- ST
- SV
- SX
- SZ
- TC
- TD
- TF
- TG
- TH
- TJ
- TK
- TL
- TM
- TN
- TO
- TR
- TT
- TV
- TW
- TZ
- UA
- UG
- UM
- US
- UY
- UZ
- VA
- VC
- VE
- VG
- VI
- VN
- VU
- WF
- WS
- YE
- YT
- ZA
- ZM
- ZW
type: object
required:
- country
title: AddressInput
PaymentProcessor:
type: string
enum:
- stripe
title: PaymentProcessor
TrialInterval:
type: string
enum:
- day
- week
- month
- year
title: TrialInterval
Address:
properties:
line1:
anyOf:
- type: string
- type: 'null'
title: Line1
line2:
anyOf:
- type: string
- type: 'null'
title: Line2
postal_code:
anyOf:
- type: string
- type: 'null'
title: Postal Code
city:
anyOf:
- type: string
- type: 'null'
title: City
state:
anyOf:
- type: string
- type: 'null'
title: State
country:
type: string
enum:
- AD
- AE
- AF
- AG
- AI
- AL
- AM
- AO
- AQ
- AR
- AS
- AT
- AU
- AW
- AX
- AZ
- BA
- BB
- BD
- BE
- BF
- BG
- BH
- BI
- BJ
- BL
- BM
- BN
- BO
- BQ
- BR
- BS
- BT
- BV
- BW
- BY
- BZ
- CA
- CC
- CD
- CF
- CG
- CH
- CI
- CK
- CL
- CM
- CN
- CO
- CR
- CU
- CV
- CW
- CX
- CY
- CZ
- DE
- DJ
- DK
- DM
- DO
- DZ
- EC
- EE
- EG
- EH
- ER
- ES
- ET
- FI
- FJ
- FK
- FM
- FO
- FR
- GA
- GB
- GD
- GE
- GF
- GG
- GH
- GI
- GL
- GM
- GN
- GP
- GQ
- GR
- GS
- GT
- GU
- GW
- GY
- HK
- HM
- HN
- HR
- HT
- HU
- ID
- IE
- IL
- IM
- IN
- IO
- IQ
- IR
- IS
- IT
- JE
- JM
- JO
- JP
- KE
- KG
- KH
- KI
- KM
- KN
- KP
- KR
- KW
- KY
- KZ
- LA
- LB
- LC
- LI
- LK
- LR
- LS
- LT
- LU
- LV
- LY
- MA
- MC
- MD
- ME
- MF
- MG
- MH
- MK
- ML
- MM
- MN
- MO
- MP
- MQ
- MR
- MS
- MT
- MU
- MV
- MW
- MX
- MY
- MZ
- NA
- NC
- NE
- NF
- NG
- NI
- NL
- 'NO'
- NP
- NR
- NU
- NZ
- OM
- PA
- PE
- PF
- PG
- PH
- PK
- PL
- PM
- PN
- PR
- PS
- PT
- PW
- PY
- QA
- RE
- RO
- RS
- RU
- RW
- SA
- SB
- SC
- SD
- SE
- SG
- SH
- SI
- SJ
- SK
- SL
- SM
- SN
- SO
- SR
- SS
- ST
- SV
- SX
- SY
- SZ
- TC
- TD
- TF
- TG
- TH
- TJ
- TK
- TL
- TM
- TN
- TO
- TR
- TT
- TV
- TW
- TZ
- UA
- UG
- UM
- US
- UY
- UZ
- VA
- VC
- VE
- VG
- VI
- VN
- VU
- WF
- WS
- YE
- YT
- ZA
- ZM
- ZW
title: CountryAlpha2
examples:
- US
- SE
- FR
x-speakeasy-enums:
- AD
- AE
- AF
- AG
- AI
- AL
- AM
- AO
- AQ
- AR
- AS
- AT
- AU
- AW
- AX
- AZ
- BA
- BB
- BD
- BE
- BF
- BG
- BH
- BI
- BJ
- BL
- BM
- BN
- BO
- BQ
- BR
- BS
- BT
- BV
- BW
- BY
- BZ
- CA
- CC
- CD
- CF
- CG
- CH
- CI
- CK
- CL
- CM
- CN
- CO
- CR
- CU
- CV
- CW
- CX
- CY
- CZ
- DE
- DJ
- DK
- DM
- DO
- DZ
- EC
- EE
- EG
- EH
- ER
- ES
- ET
- FI
- FJ
- FK
- FM
- FO
- FR
- GA
- GB
- GD
- GE
- GF
- GG
- GH
- GI
- GL
- GM
- GN
- GP
- GQ
- GR
- GS
- GT
- GU
- GW
- GY
- HK
- HM
- HN
- HR
- HT
- HU
- ID
- IE
- IL
- IM
- IN
- IO
- IQ
- IR
- IS
- IT
- JE
- JM
- JO
- JP
- KE
- KG
- KH
- KI
- KM
- KN
- KP
- KR
- KW
- KY
- KZ
- LA
- LB
- LC
- LI
- LK
- LR
- LS
- LT
- LU
- LV
- LY
- MA
- MC
- MD
- ME
- MF
- MG
- MH
- MK
- ML
- MM
- MN
- MO
- MP
- MQ
- MR
- MS
- MT
- MU
- MV
- MW
- MX
- MY
- MZ
- NA
- NC
- NE
- NF
- NG
- NI
- NL
- 'NO'
- NP
- NR
- NU
- NZ
- OM
- PA
- PE
- PF
- PG
- PH
- PK
- PL
- PM
- PN
- PR
- PS
- PT
- PW
- PY
- QA
- RE
- RO
- RS
- RU
- RW
- SA
- SB
- SC
- SD
- SE
- SG
- SH
- SI
- SJ
- SK
- SL
- SM
- SN
- SO
- SR
- SS
- ST
- SV
- SX
- SY
- SZ
- TC
- TD
- TF
- TG
- TH
- TJ
- TK
- TL
- TM
- TN
- TO
- TR
- TT
- TV
- TW
- TZ
- UA
- UG
- UM
- US
- UY
- UZ
- VA
- VC
- VE
- VG
- VI
- VN
- VU
- WF
- WS
- YE
- YT
- ZA
- ZM
- ZW
type: object
required:
- country
title: Address
CheckoutBillingAddressFields:
properties:
country:
$ref: '#/components/schemas/BillingAddressFieldMode'
state:
$ref: '#/components/schemas/BillingAddressFieldMode'
city:
$ref: '#/components/schemas/BillingAddressFieldMode'
postal_code:
$ref: '#/components/schemas/BillingAddressFieldMode'
line1:
$ref: '#/components/schemas/BillingAddressFieldMode'
line2:
$ref: '#/components/schemas/BillingAddressFieldMode'
type: object
required:
- country
- state
- city
- postal_code
- line1
- line2
title: CheckoutBillingAddressFields
CheckoutProduct:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
trial_interval:
anyOf:
- $ref: '#/components/schemas/TrialInterval'
- type: 'null'
description: The interval unit for the trial period.
trial_interval_count:
anyOf:
- type: integer
- type: 'null'
title: Trial Interval Count
description: The number of interval units for the trial period.
name:
type: string
title: Name
description: The name of the product.
description:
anyOf:
- type: string
- type: 'null'
title: Description
description: The description of the product.
recurring_interval:
anyOf:
- $ref: '#/components/schemas/SubscriptionRecurringInterval'
- type: 'null'
description: >-
The recurring interval of the product. If `None`, the product is a
one-time purchase.
recurring_interval_count:
anyOf:
- type: integer
- type: 'null'
title: Recurring Interval Count
description: >-
Number of interval units of the subscription. If this is set to 1
the charge will happen every interval (e.g. every month), if set to
2 it will be every other month, and so on. None for one-time
products.
is_recurring:
type: boolean
title: Is Recurring
description: Whether the product is a subscription.
is_archived:
type: boolean
title: Is Archived
description: Whether the product is archived and no longer available.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the product.
prices:
items:
oneOf:
- $ref: '#/components/schemas/LegacyRecurringProductPrice'
- $ref: '#/components/schemas/ProductPrice'
type: array
title: Prices
description: List of prices for this product.
benefits:
items:
$ref: '#/components/schemas/BenefitPublic'
type: array
title: BenefitPublic
description: List of benefits granted by the product.
medias:
items:
$ref: '#/components/schemas/ProductMediaFileRead'
type: array
title: Medias
description: List of medias associated to the product.
type: object
required:
- id
- created_at
- modified_at
- trial_interval
- trial_interval_count
- name
- description
- recurring_interval
- recurring_interval_count
- is_recurring
- is_archived
- organization_id
- prices
- benefits
- medias
title: CheckoutProduct
description: Product data for a checkout session.
LegacyRecurringProductPrice:
oneOf:
- $ref: '#/components/schemas/LegacyRecurringProductPriceFixed'
- $ref: '#/components/schemas/LegacyRecurringProductPriceCustom'
- $ref: '#/components/schemas/LegacyRecurringProductPriceFree'
discriminator:
propertyName: amount_type
mapping:
custom: '#/components/schemas/LegacyRecurringProductPriceCustom'
fixed: '#/components/schemas/LegacyRecurringProductPriceFixed'
free: '#/components/schemas/LegacyRecurringProductPriceFree'
ProductPrice:
oneOf:
- $ref: '#/components/schemas/ProductPriceFixed'
- $ref: '#/components/schemas/ProductPriceCustom'
- $ref: '#/components/schemas/ProductPriceFree'
- $ref: '#/components/schemas/ProductPriceSeatBased'
- $ref: '#/components/schemas/ProductPriceMeteredUnit'
discriminator:
propertyName: amount_type
mapping:
custom: '#/components/schemas/ProductPriceCustom'
fixed: '#/components/schemas/ProductPriceFixed'
free: '#/components/schemas/ProductPriceFree'
metered_unit: '#/components/schemas/ProductPriceMeteredUnit'
seat_based: '#/components/schemas/ProductPriceSeatBased'
CheckoutDiscountFixedOnceForeverDuration:
properties:
duration:
$ref: '#/components/schemas/DiscountDuration'
type:
$ref: '#/components/schemas/DiscountType'
amount:
type: integer
title: Amount
examples:
- 1000
currency:
type: string
title: Currency
examples:
- usd
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
name:
type: string
title: Name
code:
anyOf:
- type: string
- type: 'null'
title: Code
type: object
required:
- duration
- type
- amount
- currency
- id
- name
- code
title: CheckoutDiscountFixedOnceForeverDuration
description: Schema for a fixed amount discount that is applied once or forever.
CheckoutDiscountFixedRepeatDuration:
properties:
duration:
$ref: '#/components/schemas/DiscountDuration'
duration_in_months:
type: integer
title: Duration In Months
type:
$ref: '#/components/schemas/DiscountType'
amount:
type: integer
title: Amount
examples:
- 1000
currency:
type: string
title: Currency
examples:
- usd
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
name:
type: string
title: Name
code:
anyOf:
- type: string
- type: 'null'
title: Code
type: object
required:
- duration
- duration_in_months
- type
- amount
- currency
- id
- name
- code
title: CheckoutDiscountFixedRepeatDuration
description: |-
Schema for a fixed amount discount that is applied on every invoice
for a certain number of months.
CheckoutDiscountPercentageOnceForeverDuration:
properties:
duration:
$ref: '#/components/schemas/DiscountDuration'
type:
$ref: '#/components/schemas/DiscountType'
basis_points:
type: integer
title: Basis Points
description: >-
Discount percentage in basis points. A basis point is 1/100th of a
percent. For example, 1000 basis points equals a 10% discount.
examples:
- 1000
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
name:
type: string
title: Name
code:
anyOf:
- type: string
- type: 'null'
title: Code
type: object
required:
- duration
- type
- basis_points
- id
- name
- code
title: CheckoutDiscountPercentageOnceForeverDuration
description: Schema for a percentage discount that is applied once or forever.
CheckoutDiscountPercentageRepeatDuration:
properties:
duration:
$ref: '#/components/schemas/DiscountDuration'
duration_in_months:
type: integer
title: Duration In Months
type:
$ref: '#/components/schemas/DiscountType'
basis_points:
type: integer
title: Basis Points
description: >-
Discount percentage in basis points. A basis point is 1/100th of a
percent. For example, 1000 basis points equals a 10% discount.
examples:
- 1000
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
name:
type: string
title: Name
code:
anyOf:
- type: string
- type: 'null'
title: Code
type: object
required:
- duration
- duration_in_months
- type
- basis_points
- id
- name
- code
title: CheckoutDiscountPercentageRepeatDuration
description: |-
Schema for a percentage discount that is applied on every invoice
for a certain number of months.
CheckoutOrganization:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
name:
type: string
title: Name
description: Organization name shown in checkout, customer portal, emails etc.
slug:
type: string
title: Slug
description: >-
Unique organization slug in checkout, customer portal and credit
card statements.
avatar_url:
anyOf:
- type: string
- type: 'null'
title: Avatar Url
description: Avatar URL shown in checkout, customer portal, emails etc.
proration_behavior:
$ref: '#/components/schemas/SubscriptionProrationBehavior'
description: >-
Proration behavior applied when customer updates their subscription
from the portal.
allow_customer_updates:
type: boolean
title: Allow Customer Updates
description: >-
Whether customers can update their subscriptions from the customer
portal.
type: object
required:
- created_at
- modified_at
- id
- name
- slug
- avatar_url
- proration_behavior
- allow_customer_updates
title: CheckoutOrganization
AttachedCustomField:
properties:
custom_field_id:
type: string
format: uuid4
title: Custom Field Id
description: ID of the custom field.
custom_field:
$ref: '#/components/schemas/CustomField'
title: CustomField
order:
type: integer
title: Order
description: Order of the custom field in the resource.
required:
type: boolean
title: Required
description: Whether the value is required for this custom field.
type: object
required:
- custom_field_id
- custom_field
- order
- required
title: AttachedCustomField
description: Schema of a custom field attached to a resource.
AlreadyActiveSubscriptionError:
properties:
error:
type: string
const: AlreadyActiveSubscriptionError
title: Error
examples:
- AlreadyActiveSubscriptionError
detail:
type: string
title: Detail
type: object
required:
- error
- detail
title: AlreadyActiveSubscriptionError
NotOpenCheckout:
properties:
error:
type: string
const: NotOpenCheckout
title: Error
examples:
- NotOpenCheckout
detail:
type: string
title: Detail
type: object
required:
- error
- detail
title: NotOpenCheckout
PaymentNotReady:
properties:
error:
type: string
const: PaymentNotReady
title: Error
examples:
- PaymentNotReady
detail:
type: string
title: Detail
type: object
required:
- error
- detail
title: PaymentNotReady
TrialAlreadyRedeemed:
properties:
error:
type: string
const: TrialAlreadyRedeemed
title: Error
examples:
- TrialAlreadyRedeemed
detail:
type: string
title: Detail
type: object
required:
- error
- detail
title: TrialAlreadyRedeemed
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
msg:
type: string
title: Message
type:
type: string
title: Error Type
type: object
required:
- loc
- msg
- type
title: ValidationError
BillingAddressFieldMode:
type: string
enum:
- required
- optional
- disabled
title: BillingAddressFieldMode
SubscriptionRecurringInterval:
type: string
enum:
- day
- week
- month
- year
title: SubscriptionRecurringInterval
BenefitPublic:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the benefit.
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
type:
$ref: '#/components/schemas/BenefitType'
description: The type of the benefit.
description:
type: string
title: Description
description: The description of the benefit.
selectable:
type: boolean
title: Selectable
description: Whether the benefit is selectable when creating a product.
deletable:
type: boolean
title: Deletable
description: Whether the benefit is deletable.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the benefit.
type: object
required:
- id
- created_at
- modified_at
- type
- description
- selectable
- deletable
- organization_id
title: BenefitPublic
ProductMediaFileRead:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
organization_id:
type: string
format: uuid4
title: Organization Id
name:
type: string
title: Name
path:
type: string
title: Path
mime_type:
type: string
title: Mime Type
size:
type: integer
title: Size
storage_version:
anyOf:
- type: string
- type: 'null'
title: Storage Version
checksum_etag:
anyOf:
- type: string
- type: 'null'
title: Checksum Etag
checksum_sha256_base64:
anyOf:
- type: string
- type: 'null'
title: Checksum Sha256 Base64
checksum_sha256_hex:
anyOf:
- type: string
- type: 'null'
title: Checksum Sha256 Hex
last_modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Last Modified At
version:
anyOf:
- type: string
- type: 'null'
title: Version
service:
type: string
const: product_media
title: Service
is_uploaded:
type: boolean
title: Is Uploaded
created_at:
type: string
format: date-time
title: Created At
size_readable:
type: string
title: Size Readable
public_url:
type: string
title: Public Url
type: object
required:
- id
- organization_id
- name
- path
- mime_type
- size
- storage_version
- checksum_etag
- checksum_sha256_base64
- checksum_sha256_hex
- last_modified_at
- version
- service
- is_uploaded
- created_at
- size_readable
- public_url
title: ProductMediaFileRead
description: File to be used as a product media file.
LegacyRecurringProductPriceFixed:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: fixed
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
type: string
const: recurring
title: Type
description: The type of the price.
recurring_interval:
$ref: '#/components/schemas/SubscriptionRecurringInterval'
description: The recurring interval of the price.
price_currency:
type: string
title: Price Currency
description: The currency.
price_amount:
type: integer
title: Price Amount
description: The price in cents.
legacy:
type: boolean
const: true
title: Legacy
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- price_currency
- price_amount
- legacy
title: LegacyRecurringProductPriceFixed
description: >-
A recurring price for a product, i.e. a subscription.
**Deprecated**: The recurring interval should be set on the product
itself.
LegacyRecurringProductPriceCustom:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: custom
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
type: string
const: recurring
title: Type
description: The type of the price.
recurring_interval:
$ref: '#/components/schemas/SubscriptionRecurringInterval'
description: The recurring interval of the price.
price_currency:
type: string
title: Price Currency
description: The currency.
minimum_amount:
type: integer
title: Minimum Amount
description: >-
The minimum amount the customer can pay. If 0, the price is 'free or
pay what you want'. Defaults to 50 cents.
maximum_amount:
anyOf:
- type: integer
- type: 'null'
title: Maximum Amount
description: The maximum amount the customer can pay.
preset_amount:
anyOf:
- type: integer
- type: 'null'
title: Preset Amount
description: The initial amount shown to the customer.
legacy:
type: boolean
const: true
title: Legacy
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- price_currency
- minimum_amount
- maximum_amount
- preset_amount
- legacy
title: LegacyRecurringProductPriceCustom
description: >-
A pay-what-you-want recurring price for a product, i.e. a subscription.
**Deprecated**: The recurring interval should be set on the product
itself.
LegacyRecurringProductPriceFree:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: free
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
type: string
const: recurring
title: Type
description: The type of the price.
recurring_interval:
$ref: '#/components/schemas/SubscriptionRecurringInterval'
description: The recurring interval of the price.
legacy:
type: boolean
const: true
title: Legacy
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- legacy
title: LegacyRecurringProductPriceFree
description: >-
A free recurring price for a product, i.e. a subscription.
**Deprecated**: The recurring interval should be set on the product
itself.
ProductPriceFixed:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: fixed
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
$ref: '#/components/schemas/ProductPriceType'
deprecated: true
recurring_interval:
anyOf:
- $ref: '#/components/schemas/SubscriptionRecurringInterval'
- type: 'null'
deprecated: true
price_currency:
type: string
title: Price Currency
description: The currency.
price_amount:
type: integer
title: Price Amount
description: The price in cents.
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- price_currency
- price_amount
title: ProductPriceFixed
description: A fixed price for a product.
ProductPriceCustom:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: custom
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
$ref: '#/components/schemas/ProductPriceType'
deprecated: true
recurring_interval:
anyOf:
- $ref: '#/components/schemas/SubscriptionRecurringInterval'
- type: 'null'
deprecated: true
price_currency:
type: string
title: Price Currency
description: The currency.
minimum_amount:
type: integer
title: Minimum Amount
description: >-
The minimum amount the customer can pay. If 0, the price is 'free or
pay what you want'. Defaults to 50 cents.
maximum_amount:
anyOf:
- type: integer
- type: 'null'
title: Maximum Amount
description: The maximum amount the customer can pay.
preset_amount:
anyOf:
- type: integer
- type: 'null'
title: Preset Amount
description: The initial amount shown to the customer.
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- price_currency
- minimum_amount
- maximum_amount
- preset_amount
title: ProductPriceCustom
description: A pay-what-you-want price for a product.
ProductPriceFree:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: free
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
$ref: '#/components/schemas/ProductPriceType'
deprecated: true
recurring_interval:
anyOf:
- $ref: '#/components/schemas/SubscriptionRecurringInterval'
- type: 'null'
deprecated: true
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
title: ProductPriceFree
description: A free price for a product.
ProductPriceSeatBased:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: seat_based
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
$ref: '#/components/schemas/ProductPriceType'
deprecated: true
recurring_interval:
anyOf:
- $ref: '#/components/schemas/SubscriptionRecurringInterval'
- type: 'null'
deprecated: true
price_currency:
type: string
title: Price Currency
description: The currency.
seat_tiers:
$ref: '#/components/schemas/ProductPriceSeatTiers-Output'
description: Tiered pricing based on seat quantity
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- price_currency
- seat_tiers
title: ProductPriceSeatBased
description: A seat-based price for a product.
ProductPriceMeteredUnit:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: metered_unit
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
$ref: '#/components/schemas/ProductPriceType'
deprecated: true
recurring_interval:
anyOf:
- $ref: '#/components/schemas/SubscriptionRecurringInterval'
- type: 'null'
deprecated: true
price_currency:
type: string
title: Price Currency
description: The currency.
unit_amount:
type: string
pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
title: Unit Amount
description: The price per unit in cents.
cap_amount:
anyOf:
- type: integer
- type: 'null'
title: Cap Amount
description: >-
The maximum amount in cents that can be charged, regardless of the
number of units consumed.
meter_id:
type: string
format: uuid4
title: Meter Id
description: The ID of the meter associated to the price.
meter:
$ref: '#/components/schemas/ProductPriceMeter'
description: The meter associated to the price.
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- price_currency
- unit_amount
- cap_amount
- meter_id
- meter
title: ProductPriceMeteredUnit
description: A metered, usage-based, price for a product, with a fixed unit price.
DiscountDuration:
type: string
enum:
- once
- forever
- repeating
title: DiscountDuration
DiscountType:
type: string
enum:
- fixed
- percentage
title: DiscountType
SubscriptionProrationBehavior:
type: string
enum:
- invoice
- prorate
title: SubscriptionProrationBehavior
CustomField:
oneOf:
- $ref: '#/components/schemas/CustomFieldText'
- $ref: '#/components/schemas/CustomFieldNumber'
- $ref: '#/components/schemas/CustomFieldDate'
- $ref: '#/components/schemas/CustomFieldCheckbox'
- $ref: '#/components/schemas/CustomFieldSelect'
discriminator:
propertyName: type
mapping:
checkbox: '#/components/schemas/CustomFieldCheckbox'
date: '#/components/schemas/CustomFieldDate'
number: '#/components/schemas/CustomFieldNumber'
select: '#/components/schemas/CustomFieldSelect'
text: '#/components/schemas/CustomFieldText'
BenefitType:
type: string
enum:
- custom
- discord
- github_repository
- downloadables
- license_keys
- meter_credit
title: BenefitType
ProductPriceSource:
type: string
enum:
- catalog
- ad_hoc
title: ProductPriceSource
ProductPriceType:
type: string
enum:
- one_time
- recurring
title: ProductPriceType
ProductPriceSeatTiers-Output:
properties:
tiers:
items:
$ref: '#/components/schemas/ProductPriceSeatTier'
type: array
minItems: 1
title: Tiers
description: List of pricing tiers
minimum_seats:
type: integer
title: Minimum Seats
description: >-
Minimum number of seats required for purchase, derived from first
tier.
maximum_seats:
anyOf:
- type: integer
- type: 'null'
title: Maximum Seats
description: >-
Maximum number of seats allowed for purchase, derived from last
tier. None for unlimited.
type: object
required:
- tiers
- minimum_seats
- maximum_seats
title: ProductPriceSeatTiers
description: |-
List of pricing tiers for seat-based pricing.
The minimum and maximum seat limits are derived from the tiers:
- minimum_seats = first tier's min_seats
- maximum_seats = last tier's max_seats (None for unlimited)
ProductPriceMeter:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
name:
type: string
title: Name
description: The name of the meter.
type: object
required:
- id
- name
title: ProductPriceMeter
description: A meter associated to a metered price.
CustomFieldText:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
metadata:
$ref: '#/components/schemas/MetadataOutputType'
type:
type: string
const: text
title: Type
slug:
type: string
title: Slug
description: >-
Identifier of the custom field. It'll be used as key when storing
the value.
name:
type: string
title: Name
description: Name of the custom field.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the custom field.
examples:
- 1dbfc517-0bbf-4301-9ba8-555ca42b9737
x-polar-selector-widget:
displayProperty: name
resourceName: Organization
resourceRoot: /v1/organizations
properties:
$ref: '#/components/schemas/CustomFieldTextProperties'
type: object
required:
- created_at
- modified_at
- id
- metadata
- type
- slug
- name
- organization_id
- properties
title: CustomFieldText
description: Schema for a custom field of type text.
CustomFieldNumber:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
metadata:
$ref: '#/components/schemas/MetadataOutputType'
type:
type: string
const: number
title: Type
slug:
type: string
title: Slug
description: >-
Identifier of the custom field. It'll be used as key when storing
the value.
name:
type: string
title: Name
description: Name of the custom field.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the custom field.
examples:
- 1dbfc517-0bbf-4301-9ba8-555ca42b9737
x-polar-selector-widget:
displayProperty: name
resourceName: Organization
resourceRoot: /v1/organizations
properties:
$ref: '#/components/schemas/CustomFieldNumberProperties'
type: object
required:
- created_at
- modified_at
- id
- metadata
- type
- slug
- name
- organization_id
- properties
title: CustomFieldNumber
description: Schema for a custom field of type number.
CustomFieldDate:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
metadata:
$ref: '#/components/schemas/MetadataOutputType'
type:
type: string
const: date
title: Type
slug:
type: string
title: Slug
description: >-
Identifier of the custom field. It'll be used as key when storing
the value.
name:
type: string
title: Name
description: Name of the custom field.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the custom field.
examples:
- 1dbfc517-0bbf-4301-9ba8-555ca42b9737
x-polar-selector-widget:
displayProperty: name
resourceName: Organization
resourceRoot: /v1/organizations
properties:
$ref: '#/components/schemas/CustomFieldDateProperties'
type: object
required:
- created_at
- modified_at
- id
- metadata
- type
- slug
- name
- organization_id
- properties
title: CustomFieldDate
description: Schema for a custom field of type date.
CustomFieldCheckbox:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
metadata:
$ref: '#/components/schemas/MetadataOutputType'
type:
type: string
const: checkbox
title: Type
slug:
type: string
title: Slug
description: >-
Identifier of the custom field. It'll be used as key when storing
the value.
name:
type: string
title: Name
description: Name of the custom field.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the custom field.
examples:
- 1dbfc517-0bbf-4301-9ba8-555ca42b9737
x-polar-selector-widget:
displayProperty: name
resourceName: Organization
resourceRoot: /v1/organizations
properties:
$ref: '#/components/schemas/CustomFieldCheckboxProperties'
type: object
required:
- created_at
- modified_at
- id
- metadata
- type
- slug
- name
- organization_id
- properties
title: CustomFieldCheckbox
description: Schema for a custom field of type checkbox.
CustomFieldSelect:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
metadata:
$ref: '#/components/schemas/MetadataOutputType'
type:
type: string
const: select
title: Type
slug:
type: string
title: Slug
description: >-
Identifier of the custom field. It'll be used as key when storing
the value.
name:
type: string
title: Name
description: Name of the custom field.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the custom field.
examples:
- 1dbfc517-0bbf-4301-9ba8-555ca42b9737
x-polar-selector-widget:
displayProperty: name
resourceName: Organization
resourceRoot: /v1/organizations
properties:
$ref: '#/components/schemas/CustomFieldSelectProperties'
type: object
required:
- created_at
- modified_at
- id
- metadata
- type
- slug
- name
- organization_id
- properties
title: CustomFieldSelect
description: Schema for a custom field of type select.
ProductPriceSeatTier:
properties:
min_seats:
type: integer
minimum: 1
title: Min Seats
description: Minimum number of seats (inclusive)
max_seats:
anyOf:
- type: integer
minimum: 1
- type: 'null'
title: Max Seats
description: Maximum number of seats (inclusive). None for unlimited.
price_per_seat:
type: integer
maximum: 99999999
minimum: 0
title: Price Per Seat
description: Price per seat in cents for this tier
type: object
required:
- min_seats
- price_per_seat
title: ProductPriceSeatTier
description: A pricing tier for seat-based pricing.
MetadataOutputType:
additionalProperties:
anyOf:
- type: string
- type: integer
- type: number
- type: boolean
type: object
CustomFieldTextProperties:
properties:
form_label:
type: string
minLength: 1
title: Form Label
form_help_text:
type: string
minLength: 1
title: Form Help Text
form_placeholder:
type: string
minLength: 1
title: Form Placeholder
textarea:
type: boolean
title: Textarea
min_length:
type: integer
maximum: 2147483647
minimum: 0
title: Min Length
max_length:
type: integer
maximum: 2147483647
minimum: 0
title: Max Length
type: object
title: CustomFieldTextProperties
CustomFieldNumberProperties:
properties:
form_label:
type: string
minLength: 1
title: Form Label
form_help_text:
type: string
minLength: 1
title: Form Help Text
form_placeholder:
type: string
minLength: 1
title: Form Placeholder
ge:
type: integer
maximum: 2147483647
minimum: -2147483648
title: Ge
le:
type: integer
maximum: 2147483647
minimum: -2147483648
title: Le
type: object
title: CustomFieldNumberProperties
CustomFieldDateProperties:
properties:
form_label:
type: string
minLength: 1
title: Form Label
form_help_text:
type: string
minLength: 1
title: Form Help Text
form_placeholder:
type: string
minLength: 1
title: Form Placeholder
ge:
type: integer
maximum: 2147483647
minimum: -2147483648
title: Ge
le:
type: integer
maximum: 2147483647
minimum: -2147483648
title: Le
type: object
title: CustomFieldDateProperties
CustomFieldCheckboxProperties:
properties:
form_label:
type: string
minLength: 1
title: Form Label
form_help_text:
type: string
minLength: 1
title: Form Help Text
form_placeholder:
type: string
minLength: 1
title: Form Placeholder
type: object
title: CustomFieldCheckboxProperties
CustomFieldSelectProperties:
properties:
form_label:
type: string
minLength: 1
title: Form Label
form_help_text:
type: string
minLength: 1
title: Form Help Text
form_placeholder:
type: string
minLength: 1
title: Form Placeholder
options:
items:
$ref: '#/components/schemas/CustomFieldSelectOption'
type: array
minItems: 1
title: Options
type: object
required:
- options
title: CustomFieldSelectProperties
CustomFieldSelectOption:
properties:
value:
type: string
minLength: 1
title: Value
label:
type: string
minLength: 1
title: Label
type: object
required:
- value
- label
title: CustomFieldSelectOption
securitySchemes:
access_token:
type: http
scheme: bearer
description: >-
You can generate an **Organization Access Token** from your
organization's settings.
````
---
# Source: https://polar.sh/docs/integrate/oauth2/connect.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# OAuth 2.0 Connect
## Authorize
To start the authorization flow you need to redirect the user to the authorization URL. It looks like this:
```
https://polar.sh/oauth2/authorize?
response_type=code
&client_id=CLIENT_ID
&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
&scope=openid%20email
```
The parameters are the one described in the [OpenID Connect specification](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). The most important ones are:
Indicates that you want to use the authorization code flow. Most common and
the only one supported by Polar.
The Client ID you got when creating the OAuth 2.0 client.
The URL where the user will be redirected after granting access to their data.
Make sure you declared it when creating the OAuth2 client.
A space-separated list of scopes you want to ask for. Make sure they are part
of the scopes you declared when creating the OAuth2 client.
If you redirect the user to this URL, they'll see a page asking them to grant access to their data, corresponding to the scopes you asked for. By default, the user will also be prompted to select one of their organizations, as Polar generates organization-level access tokens by default.
If they allow it and select an organization, they'll be redirected to your `redirect_uri` with a `code` parameter in the query string. This code is a one-time code that you can exchange for an access token.
To skip the organization selection and get a user-scoped token instead, you can add `sub_type=user` to the authorization URL:
```
https://polar.sh/oauth2/authorize?
response_type=code
&client_id=CLIENT_ID
&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
&scope=openid%20email
&sub_type=user
```
#### Exchange code token
Once you have the authorization code, you can exchange it for an access token. To do so, you'll need to make a `POST` request to the token endpoint. This call needs to be authenticated with the Client ID and Client Secret you got when creating the OAuth2 client.
Here is an example with cURL:
```bash Terminal theme={null}
curl -X POST https://api.polar.sh/v1/oauth2/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=authorization_code&code=AUTHORIZATION_CODE&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&redirect_uri=https://example.com/callback'
```
You should get the following response:
```json theme={null}
{
"token_type": "Bearer",
"access_token": "polar_at_XXX",
"expires_in": 864000,
"refresh_token": "polar_rt_XXX",
"scope": "openid email",
"id_token": "ID_TOKEN"
}
```
The `access_token` will allow you to make authenticated API requests on behalf of the user. The `refresh_token` is a long-lived token that you can use to get new access tokens when the current one expires. The `id_token` is a signed JWT token containing information about the user, as per the [OpenID Connect specification](https://openid.net/specs/openid-connect-core-1_0.html#IDToken).
#### Organization vs User Access Tokens
By default, Polar OAuth2 flow generates **organization-level** access tokens. These tokens are tied to a specific organization rather than a user, allowing requests to operate only on that organization's data, which improves privacy and security.
When using the default flow, the user will be prompted to select one of their organizations before allowing access to their data:
```
https://polar.sh/oauth2/authorize?response_type=code&client_id=polar_ci_j3X95_MgfdSCeCd2qkFnUw&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback&scope=openid%20email
```
To request a **user-scoped** access token instead, you need to explicitly add the parameter `sub_type=user` to the authorization URL:
```
https://polar.sh/oauth2/authorize?response_type=code&client_id=polar_ci_j3X95_MgfdSCeCd2qkFnUw&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback&scope=openid%20email&sub_type=user
```
The rest of the flow remains unchanged. The access token you'll get will be tied to either the selected organization (default) or the user (when explicitly requested).
#### Public Clients
Public clients are clients where the Client Secret can't be kept safe, as it would be accessible by the final user. This is the case for SPA, mobile applications, or any client running on the user's device.
In this case, **and only if the client is configured as a Public Client**, the request to the token endpoint won't require the `client_secret` parameter. However, the [PKCE](https://oauth.net/2/pkce/) method will be required to maximize security.
### Make authenticated requests
Once you have an access token, either from a Personal Access Token or from the OpenID Connect flow, you can make authenticated requests to the API. Here is a simple example with cURL:
```bash Terminal theme={null}
curl -X GET https://api.polar.sh/v1/oauth2/userinfo \
-H 'Authorization: Bearer polar_at_XXX'
```
---
# Source: https://polar.sh/docs/features/cost-insights/cost-events.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Cost Events
> Track costs by adding cost metadata to your ingested events
Cost Insights works by allowing you to add a special `_cost` property to any event you ingest through Polar's Event Ingestion API. These costs are then aggregated and made available through the Metrics API alongside revenue metrics.
## The `_cost` Property
### Basic Structure
To track costs, add a `_cost` property to your event's metadata when ingesting events.
```typescript icon="square-js" TypeScript (SDK) theme={null}
import { Polar } from "@polar-sh/sdk";
const polar = new Polar({
accessToken: process.env.POLAR_ACCESS_TOKEN,
});
await polar.events.ingest({
events: [
{
name: "llm.inference",
externalCustomerId: "user_123",
metadata: {
_cost: {
amount: 0.025,
currency: "usd",
},
},
},
],
});
```
```json cURL theme={null}
POST https://api.polar.sh/v1/events/ingest
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
{
"events": [
{
"name": "llm.inference",
"external_customer_id": "user_123",
"metadata": {
"_cost": {
"amount": 0.025,
"currency": "usd"
}
}
}
]
}
```
### Cost Metadata Schema
The `_cost` property has the following structure:
* **`amount`** (required): The cost amount in cents as a decimal number
* Example: `0.025` for \$0.00025 (a fraction of a cent)
* Example: `150` for \$1.50
* Supports up to 17 digits with 12 decimal places for precision
* **`currency`** (required): The currency code
* Currently only `"usd"` is supported
**Amount must be in cents**: The `amount` field represents the cost in cents,
not dollars. For example, `100 = $1.00`, `0.5 = $0.005` (half a cent), and
`0.001 = $0.00001` (one hundredth of a cent).
## Use Cases
### AI/LLM Applications
Track the cost of LLM API calls per customer:
```typescript icon="square-js" TypeScript theme={null}
import { Polar } from "@polar-sh/sdk";
import OpenAI from "openai";
const polar = new Polar({
accessToken: process.env.POLAR_ACCESS_TOKEN,
});
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
// Make LLM API call
const completion = await openai.chat.completions.create({
model: "gpt-4",
messages: [{ role: "user", content: "Hello!" }],
});
// Calculate cost (example: $0.03 per 1K input tokens, $0.06 per 1K output tokens)
const inputCost = ((completion.usage.prompt * tokens) / 1000) * 3; // in cents
const outputCost = ((completion.usage.completion * tokens) / 1000) * 6; // in cents
const totalCost = inputCost + outputCost;
// Track the cost in Polar
await polar.events.ingest({
events: [
{
name: "gpt4.completion",
customerId: "cus_abc123",
metadata: {
_cost: {
amount: totalCost,
currency: "usd",
},
_llm: {
vendor: "openai",
model: "gpt-4",
input_tokens: completion.usage.prompt_tokens,
output_tokens: completion.usage.completion_tokens,
total_tokens: completion.usage.total_tokens,
},
},
},
],
});
```
### Infrastructure Costs
Track compute, storage, or API costs:
```json theme={null}
{
"events": [
{
"name": "video.processing",
"external_customer_id": "user_123",
"metadata": {
"_cost": {
"amount": 45.5, // $0.455
"currency": "usd"
},
"duration_seconds": 120,
"resolution": "1080p"
}
}
]
}
```
### Third-Party Service Costs
Track costs from external services:
```json theme={null}
{
"events": [
{
"name": "email.sent",
"external_customer_id": "user_123",
"metadata": {
"_cost": {
"amount": 0.0001, // $0.000001
"currency": "usd"
},
"provider": "sendgrid",
"recipients": 1
}
}
]
}
```
## Best Practices
### Track Costs in Real-Time
Ingest cost events as they occur to maintain accurate, up-to-date metrics:
```typescript icon="square-js" TypeScript theme={null}
import { Polar } from "@polar-sh/sdk";
const polar = new Polar({
accessToken: process.env.POLAR_ACCESS_TOKEN,
});
// When making an LLM API call
const completion = await openai.chat.completions.create({
model: "gpt-4",
messages: [{ role: "user", content: "Hello!" }],
});
const cost = calculateCost(completion.usage); // Cost should be in cents
await polar.events.ingest({
events: [
{
name: "llm.completion",
externalCustomerId: "user_123",
metadata: {
_cost: {
amount: cost,
currency: "usd",
},
},
},
],
});
```
### Use Precise Amounts
The `amount` field supports up to 12 decimal places, perfect for tracking micro-costs:
```json theme={null}
{
"_cost": {
"amount": 0.000125, // $0.00000125
"currency": "usd"
}
}
```
### Add Context with Additional Metadata
Combine `_cost` with other metadata to understand cost drivers:
```json theme={null}
{
"metadata": {
"_cost": {
"amount": 0.05, // $0.0005
"currency": "usd"
},
"model": "gpt-4-turbo",
"tokens": 1000,
"feature": "chatbot"
}
}
```
---
# Source: https://polar.sh/docs/features/cost-insights/cost-traces.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Cost Traces
> Aggregate events by user sessions to calculate costs
Cost Traces is a feature that allows you to define session boundaries and calculate costs for each session.
Coming soon.
---
# Source: https://polar.sh/docs/guides/create-checkout-session.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# How to Create Checkout Session
> Learn how to create checkout sessions via API.
## Creating a checkout session using the API
Create a new organization token by following our [Organization Access Tokens](https://polar.sh/docs/integrate/oat) guide.
After creating your access token, you will be able to view it. Please copy and save your access token.
In the Polar dashboard sidebar, navigate to **Products** > **Catalogue** for your organization.
You can also go directly to:\
`https://polar.sh/dashboard/${org_slug}/products`
Retrieve the Product IDs for the items you wish to include in checkout by clicking on the **⋮ (More options) menu** next to chosen products and selecting **Copy Product ID**.\
These IDs will be required in the next step to create a checkout session.
Open your terminal and paste the following curl command to make an API call for creating a checkout session.
Be sure to replace:
* \ with your actual access token
* \, \, etc., with the product IDs you want to include in the session
```bash Terminal theme={null}
curl --request POST \
--url https://api.polar.sh/v1/checkouts/ \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"products": [
"",
"",
""
]
}'
```
Find the description of all the parameters in the [Create Checkout Session API](https://polar.sh/docs/api-reference/checkouts/create-session).
The curl command returns a JSON. Access the checkout URL from the "url" key of the JSON.
```json theme={null}
{
"...": "...",
"url": "https://buy.polar.sh/polar_c_...", // [!code ++]
"...": "..."
}
```
---
# Source: https://polar.sh/docs/guides/create-multiple-organizations.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# How to Create Multiple Organizations
> Learn how to create multiple organizations.
To create your first organization, sign up on [Polar](https://polar.sh).
To create an organization in addition to your first organization, open the menu in the bottom left corner in the dashboard and click `New Organization`.
Now that you have multiple organizations, to switch between then, just open the menu in the bottom left corner in the dashboard, and then select the desired organization you want to switch to.
---
# Source: https://polar.sh/docs/api-reference/checkouts/create-session.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Create Checkout Session
> Create a checkout session.
**Scopes**: `checkouts:write`
## OpenAPI
````yaml post /v1/checkouts/
openapi: 3.1.0
info:
title: Polar API
summary: Polar HTTP and Webhooks API
description: Read the docs at https://polar.sh/docs/api-reference
version: 0.1.0
servers:
- url: https://api.polar.sh
description: Production environment
x-speakeasy-server-id: production
- url: https://sandbox-api.polar.sh
description: Sandbox environment
x-speakeasy-server-id: sandbox
security:
- access_token: []
tags:
- name: public
description: >-
Endpoints shown and documented in the Polar API documentation and
available in our SDKs.
- name: private
description: >-
Endpoints that should appear in the schema only in development to generate
our internal JS SDK.
- name: mcp
description: Endpoints enabled in the MCP server.
paths:
/v1/checkouts/:
post:
tags:
- checkouts
- public
summary: Create Checkout Session
description: |-
Create a checkout session.
**Scopes**: `checkouts:write`
operationId: checkouts:create
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CheckoutCreate'
responses:
'201':
description: Checkout session created.
content:
application/json:
schema:
$ref: '#/components/schemas/Checkout'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
components:
schemas:
CheckoutCreate:
$ref: '#/components/schemas/CheckoutProductsCreate'
Checkout:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
custom_field_data:
additionalProperties:
anyOf:
- type: string
- type: integer
- type: boolean
- type: string
format: date-time
- type: 'null'
type: object
title: Custom Field Data
description: Key-value object storing custom field values.
payment_processor:
$ref: '#/components/schemas/PaymentProcessor'
description: Payment processor used.
status:
$ref: '#/components/schemas/CheckoutStatus'
description: |2-
Status of the checkout session.
- Open: the checkout session was opened.
- Expired: the checkout session was expired and is no more accessible.
- Confirmed: the user on the checkout session clicked Pay. This is not indicative of the payment's success status.
- Failed: the checkout definitely failed for technical reasons and cannot be retried. In most cases, this state is never reached.
- Succeeded: the payment on the checkout was performed successfully.
client_secret:
type: string
title: Client Secret
description: >-
Client secret used to update and complete the checkout session from
the client.
url:
type: string
title: Url
description: URL where the customer can access the checkout session.
expires_at:
type: string
format: date-time
title: Expires At
description: Expiration date and time of the checkout session.
success_url:
type: string
title: Success Url
description: >-
URL where the customer will be redirected after a successful
payment.
return_url:
anyOf:
- type: string
- type: 'null'
title: Return Url
description: >-
When set, a back button will be shown in the checkout to return to
this URL.
embed_origin:
anyOf:
- type: string
- type: 'null'
title: Embed Origin
description: >-
When checkout is embedded, represents the Origin of the page
embedding the checkout. Used as a security measure to send messages
only to the embedding page.
amount:
type: integer
title: Amount
description: Amount in cents, before discounts and taxes.
seats:
anyOf:
- type: integer
- type: 'null'
title: Seats
description: Number of seats for seat-based pricing.
price_per_seat:
anyOf:
- type: integer
- type: 'null'
title: Price Per Seat
description: >-
Price per seat in cents for the current seat count, based on the
applicable tier. Only relevant for seat-based pricing.
discount_amount:
type: integer
title: Discount Amount
description: Discount amount in cents.
net_amount:
type: integer
title: Net Amount
description: Amount in cents, after discounts but before taxes.
tax_amount:
anyOf:
- type: integer
- type: 'null'
title: Tax Amount
description: >-
Sales tax amount in cents. If `null`, it means there is no enough
information yet to calculate it.
total_amount:
type: integer
title: Total Amount
description: Amount in cents, after discounts and taxes.
currency:
type: string
title: Currency
description: Currency code of the checkout session.
allow_trial:
anyOf:
- type: boolean
- type: 'null'
title: Allow Trial
description: >-
Whether to enable the trial period for the checkout session. If
`false`, the trial period will be disabled, even if the selected
product has a trial configured.
active_trial_interval:
anyOf:
- $ref: '#/components/schemas/TrialInterval'
- type: 'null'
description: >-
Interval unit of the trial period, if any. This value is either set
from the checkout, if `trial_interval` is set, or from the selected
product.
active_trial_interval_count:
anyOf:
- type: integer
- type: 'null'
title: Active Trial Interval Count
description: >-
Number of interval units of the trial period, if any. This value is
either set from the checkout, if `trial_interval_count` is set, or
from the selected product.
trial_end:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Trial End
description: End date and time of the trial period, if any.
organization_id:
type: string
format: uuid4
title: Organization Id
description: ID of the organization owning the checkout session.
product_id:
anyOf:
- type: string
format: uuid4
- type: 'null'
title: Product Id
description: ID of the product to checkout.
product_price_id:
anyOf:
- type: string
format: uuid4
- type: 'null'
title: Product Price Id
description: ID of the product price to checkout.
deprecated: true
discount_id:
anyOf:
- type: string
format: uuid4
- type: 'null'
title: Discount Id
description: ID of the discount applied to the checkout.
allow_discount_codes:
type: boolean
title: Allow Discount Codes
description: >-
Whether to allow the customer to apply discount codes. If you apply
a discount through `discount_id`, it'll still be applied, but the
customer won't be able to change it.
require_billing_address:
type: boolean
title: Require Billing Address
description: >-
Whether to require the customer to fill their full billing address,
instead of just the country. Customers in the US will always be
required to fill their full address, regardless of this setting. If
you preset the billing address, this setting will be automatically
set to `true`.
is_discount_applicable:
type: boolean
title: Is Discount Applicable
description: >-
Whether the discount is applicable to the checkout. Typically, free
and custom prices are not discountable.
is_free_product_price:
type: boolean
title: Is Free Product Price
description: Whether the product price is free, regardless of discounts.
is_payment_required:
type: boolean
title: Is Payment Required
description: >-
Whether the checkout requires payment, e.g. in case of free products
or discounts that cover the total amount.
is_payment_setup_required:
type: boolean
title: Is Payment Setup Required
description: >-
Whether the checkout requires setting up a payment method,
regardless of the amount, e.g. subscriptions that have first free
cycles.
is_payment_form_required:
type: boolean
title: Is Payment Form Required
description: >-
Whether the checkout requires a payment form, whether because of a
payment or payment method setup.
customer_id:
anyOf:
- type: string
format: uuid4
- type: 'null'
title: Customer Id
is_business_customer:
type: boolean
title: Is Business Customer
description: >-
Whether the customer is a business or an individual. If `true`, the
customer will be required to fill their full billing address and
billing name.
customer_name:
anyOf:
- type: string
- type: 'null'
title: Customer Name
description: Name of the customer.
customer_email:
anyOf:
- type: string
- type: 'null'
title: Customer Email
description: Email address of the customer.
customer_ip_address:
anyOf:
- type: string
format: ipvanyaddress
- type: 'null'
title: Customer Ip Address
customer_billing_name:
anyOf:
- type: string
- type: 'null'
title: Customer Billing Name
customer_billing_address:
anyOf:
- $ref: '#/components/schemas/Address'
description: Billing address of the customer.
- type: 'null'
customer_tax_id:
anyOf:
- type: string
- type: 'null'
title: Customer Tax Id
payment_processor_metadata:
additionalProperties:
type: string
type: object
title: Payment Processor Metadata
billing_address_fields:
$ref: '#/components/schemas/CheckoutBillingAddressFields'
description: >-
Determine which billing address fields should be disabled, optional
or required in the checkout form.
trial_interval:
anyOf:
- $ref: '#/components/schemas/TrialInterval'
- type: 'null'
description: The interval unit for the trial period.
trial_interval_count:
anyOf:
- type: integer
- type: 'null'
title: Trial Interval Count
description: The number of interval units for the trial period.
metadata:
$ref: '#/components/schemas/MetadataOutputType'
external_customer_id:
anyOf:
- type: string
- type: 'null'
title: External Customer Id
description: >-
ID of the customer in your system. If a matching customer exists on
Polar, the resulting order will be linked to this customer.
Otherwise, a new customer will be created with this external ID set.
customer_external_id:
anyOf:
- type: string
- type: 'null'
title: Customer External Id
deprecated: true
products:
items:
$ref: '#/components/schemas/CheckoutProduct'
type: array
title: Products
description: List of products available to select.
product:
anyOf:
- $ref: '#/components/schemas/CheckoutProduct'
- type: 'null'
description: Product selected to checkout.
product_price:
anyOf:
- oneOf:
- $ref: '#/components/schemas/LegacyRecurringProductPrice'
- $ref: '#/components/schemas/ProductPrice'
- type: 'null'
title: Product Price
description: Price of the selected product.
deprecated: true
prices:
anyOf:
- additionalProperties:
items:
oneOf:
- $ref: '#/components/schemas/LegacyRecurringProductPrice'
- $ref: '#/components/schemas/ProductPrice'
type: array
description: List of prices for this product.
propertyNames:
format: uuid4
type: object
- type: 'null'
title: Prices
description: Mapping of product IDs to their list of prices.
discount:
anyOf:
- oneOf:
- $ref: >-
#/components/schemas/CheckoutDiscountFixedOnceForeverDuration
- $ref: '#/components/schemas/CheckoutDiscountFixedRepeatDuration'
- $ref: >-
#/components/schemas/CheckoutDiscountPercentageOnceForeverDuration
- $ref: >-
#/components/schemas/CheckoutDiscountPercentageRepeatDuration
- type: 'null'
title: Discount
subscription_id:
anyOf:
- type: string
format: uuid4
- type: 'null'
title: Subscription Id
attached_custom_fields:
anyOf:
- items:
$ref: '#/components/schemas/AttachedCustomField'
type: array
- type: 'null'
title: Attached Custom Fields
customer_metadata:
additionalProperties:
anyOf:
- type: string
- type: integer
- type: boolean
type: object
title: Customer Metadata
type: object
required:
- id
- created_at
- modified_at
- payment_processor
- status
- client_secret
- url
- expires_at
- success_url
- return_url
- embed_origin
- amount
- discount_amount
- net_amount
- tax_amount
- total_amount
- currency
- allow_trial
- active_trial_interval
- active_trial_interval_count
- trial_end
- organization_id
- product_id
- product_price_id
- discount_id
- allow_discount_codes
- require_billing_address
- is_discount_applicable
- is_free_product_price
- is_payment_required
- is_payment_setup_required
- is_payment_form_required
- customer_id
- is_business_customer
- customer_name
- customer_email
- customer_ip_address
- customer_billing_name
- customer_billing_address
- customer_tax_id
- payment_processor_metadata
- billing_address_fields
- trial_interval
- trial_interval_count
- metadata
- external_customer_id
- customer_external_id
- products
- product
- product_price
- prices
- discount
- subscription_id
- attached_custom_fields
- customer_metadata
title: Checkout
description: Checkout session data retrieved using an access token.
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
type: object
title: HTTPValidationError
CheckoutProductsCreate:
properties:
trial_interval:
anyOf:
- $ref: '#/components/schemas/TrialInterval'
- type: 'null'
description: The interval unit for the trial period.
trial_interval_count:
anyOf:
- type: integer
maximum: 1000
minimum: 1
- type: 'null'
title: Trial Interval Count
description: The number of interval units for the trial period.
metadata:
additionalProperties:
anyOf:
- type: string
maxLength: 500
minLength: 1
- type: integer
- type: number
- type: boolean
propertyNames:
maxLength: 40
minLength: 1
type: object
maxProperties: 50
title: Metadata
description: |-
Key-value object allowing you to store additional information.
The key must be a string with a maximum length of **40 characters**.
The value must be either:
* A string with a maximum length of **500 characters**
* An integer
* A floating-point number
* A boolean
You can store up to **50 key-value pairs**.
custom_field_data:
additionalProperties:
anyOf:
- type: string
- type: integer
- type: boolean
- type: string
format: date-time
- type: 'null'
type: object
title: Custom Field Data
description: Key-value object storing custom field values.
discount_id:
anyOf:
- type: string
format: uuid4
- type: 'null'
title: Discount Id
description: ID of the discount to apply to the checkout.
allow_discount_codes:
type: boolean
title: Allow Discount Codes
description: >-
Whether to allow the customer to apply discount codes. If you apply
a discount through `discount_id`, it'll still be applied, but the
customer won't be able to change it.
default: true
require_billing_address:
type: boolean
title: Require Billing Address
description: >-
Whether to require the customer to fill their full billing address,
instead of just the country. Customers in the US will always be
required to fill their full address, regardless of this setting. If
you preset the billing address, this setting will be automatically
set to `true`.
default: false
amount:
anyOf:
- type: integer
maximum: 99999999
minimum: 0
description: >-
Amount in cents, before discounts and taxes. Only useful for
custom prices, it'll be ignored for fixed and free prices.
- type: 'null'
title: Amount
seats:
anyOf:
- type: integer
maximum: 1000
minimum: 1
- type: 'null'
title: Seats
description: >-
Number of seats for seat-based pricing. Required for seat-based
products.
allow_trial:
type: boolean
title: Allow Trial
description: >-
Whether to enable the trial period for the checkout session. If
`false`, the trial period will be disabled, even if the selected
product has a trial configured.
default: true
customer_id:
anyOf:
- type: string
format: uuid4
- type: 'null'
title: Customer Id
description: >-
ID of an existing customer in the organization. The customer data
will be pre-filled in the checkout form. The resulting order will be
linked to this customer.
is_business_customer:
type: boolean
title: Is Business Customer
description: >-
Whether the customer is a business or an individual. If `true`, the
customer will be required to fill their full billing address and
billing name.
default: false
external_customer_id:
anyOf:
- type: string
- type: 'null'
title: External Customer Id
description: >-
ID of the customer in your system. If a matching customer exists on
Polar, the resulting order will be linked to this customer.
Otherwise, a new customer will be created with this external ID set.
customer_name:
anyOf:
- type: string
maxLength: 256
description: The name of the customer.
examples:
- John Doe
- type: 'null'
title: Customer Name
customer_email:
anyOf:
- type: string
format: email
description: Email address of the customer.
- type: 'null'
title: Customer Email
customer_ip_address:
anyOf:
- type: string
format: ipvanyaddress
- type: 'null'
title: Customer Ip Address
customer_billing_name:
anyOf:
- type: string
- type: 'null'
title: Customer Billing Name
customer_billing_address:
anyOf:
- $ref: '#/components/schemas/AddressInput'
description: Billing address of the customer.
- type: 'null'
customer_tax_id:
anyOf:
- type: string
- type: 'null'
title: Customer Tax Id
customer_metadata:
additionalProperties:
anyOf:
- type: string
maxLength: 500
minLength: 1
- type: integer
- type: number
- type: boolean
propertyNames:
maxLength: 40
minLength: 1
type: object
maxProperties: 50
title: Customer Metadata
description: >-
Key-value object allowing you to store additional information
that'll be copied to the created customer.
The key must be a string with a maximum length of **40 characters**.
The value must be either:
* A string with a maximum length of **500 characters**
* An integer
* A floating-point number
* A boolean
You can store up to **50 key-value pairs**.
subscription_id:
anyOf:
- type: string
format: uuid4
- type: 'null'
title: Subscription Id
description: >-
ID of a subscription to upgrade. It must be on a free pricing. If
checkout is successful, metadata set on this checkout will be copied
to the subscription, and existing keys will be overwritten.
success_url:
anyOf:
- type: string
maxLength: 2083
minLength: 1
format: uri
- type: 'null'
title: Success Url
description: >-
URL where the customer will be redirected after a successful
payment.You can add the `checkout_id={CHECKOUT_ID}` query parameter
to retrieve the checkout session id.
return_url:
anyOf:
- type: string
maxLength: 2083
minLength: 1
format: uri
- type: 'null'
title: Return Url
description: >-
When set, a back button will be shown in the checkout to return to
this URL.
embed_origin:
anyOf:
- type: string
- type: 'null'
title: Embed Origin
description: >-
If you plan to embed the checkout session, set this to the Origin of
the embedding page. It'll allow the Polar iframe to communicate with
the parent page.
currency:
anyOf:
- $ref: '#/components/schemas/PresentmentCurrency'
maxLength: 3
minLength: 3
- type: 'null'
products:
items:
type: string
format: uuid4
type: array
minItems: 1
title: Products
description: >-
List of product IDs available to select at that checkout. The first
one will be selected by default.
prices:
anyOf:
- additionalProperties:
items:
oneOf:
- $ref: '#/components/schemas/ProductPriceFixedCreate'
- $ref: '#/components/schemas/ProductPriceCustomCreate'
- $ref: '#/components/schemas/ProductPriceFreeCreate'
- $ref: '#/components/schemas/ProductPriceSeatBasedCreate'
- $ref: '#/components/schemas/ProductPriceMeteredUnitCreate'
discriminator:
propertyName: amount_type
mapping:
custom: '#/components/schemas/ProductPriceCustomCreate'
fixed: '#/components/schemas/ProductPriceFixedCreate'
free: '#/components/schemas/ProductPriceFreeCreate'
metered_unit: '#/components/schemas/ProductPriceMeteredUnitCreate'
seat_based: '#/components/schemas/ProductPriceSeatBasedCreate'
type: array
minItems: 1
description: >-
List of prices for the product. At most one static price
(fixed, custom or free) is allowed. Any number of metered
prices can be added.
propertyNames:
format: uuid4
type: object
- type: 'null'
title: Prices
description: >-
Optional mapping of product IDs to a list of ad-hoc prices to create
for that product. If not set, catalog prices of the product will be
used.
type: object
required:
- products
title: CheckoutProductsCreate
description: |-
Create a new checkout session from a list of products.
Customers will be able to switch between those products.
Metadata set on the checkout will be copied
to the resulting order and/or subscription.
PaymentProcessor:
type: string
enum:
- stripe
title: PaymentProcessor
CheckoutStatus:
type: string
enum:
- open
- expired
- confirmed
- succeeded
- failed
title: CheckoutStatus
TrialInterval:
type: string
enum:
- day
- week
- month
- year
title: TrialInterval
Address:
properties:
line1:
anyOf:
- type: string
- type: 'null'
title: Line1
line2:
anyOf:
- type: string
- type: 'null'
title: Line2
postal_code:
anyOf:
- type: string
- type: 'null'
title: Postal Code
city:
anyOf:
- type: string
- type: 'null'
title: City
state:
anyOf:
- type: string
- type: 'null'
title: State
country:
type: string
enum:
- AD
- AE
- AF
- AG
- AI
- AL
- AM
- AO
- AQ
- AR
- AS
- AT
- AU
- AW
- AX
- AZ
- BA
- BB
- BD
- BE
- BF
- BG
- BH
- BI
- BJ
- BL
- BM
- BN
- BO
- BQ
- BR
- BS
- BT
- BV
- BW
- BY
- BZ
- CA
- CC
- CD
- CF
- CG
- CH
- CI
- CK
- CL
- CM
- CN
- CO
- CR
- CU
- CV
- CW
- CX
- CY
- CZ
- DE
- DJ
- DK
- DM
- DO
- DZ
- EC
- EE
- EG
- EH
- ER
- ES
- ET
- FI
- FJ
- FK
- FM
- FO
- FR
- GA
- GB
- GD
- GE
- GF
- GG
- GH
- GI
- GL
- GM
- GN
- GP
- GQ
- GR
- GS
- GT
- GU
- GW
- GY
- HK
- HM
- HN
- HR
- HT
- HU
- ID
- IE
- IL
- IM
- IN
- IO
- IQ
- IR
- IS
- IT
- JE
- JM
- JO
- JP
- KE
- KG
- KH
- KI
- KM
- KN
- KP
- KR
- KW
- KY
- KZ
- LA
- LB
- LC
- LI
- LK
- LR
- LS
- LT
- LU
- LV
- LY
- MA
- MC
- MD
- ME
- MF
- MG
- MH
- MK
- ML
- MM
- MN
- MO
- MP
- MQ
- MR
- MS
- MT
- MU
- MV
- MW
- MX
- MY
- MZ
- NA
- NC
- NE
- NF
- NG
- NI
- NL
- 'NO'
- NP
- NR
- NU
- NZ
- OM
- PA
- PE
- PF
- PG
- PH
- PK
- PL
- PM
- PN
- PR
- PS
- PT
- PW
- PY
- QA
- RE
- RO
- RS
- RU
- RW
- SA
- SB
- SC
- SD
- SE
- SG
- SH
- SI
- SJ
- SK
- SL
- SM
- SN
- SO
- SR
- SS
- ST
- SV
- SX
- SY
- SZ
- TC
- TD
- TF
- TG
- TH
- TJ
- TK
- TL
- TM
- TN
- TO
- TR
- TT
- TV
- TW
- TZ
- UA
- UG
- UM
- US
- UY
- UZ
- VA
- VC
- VE
- VG
- VI
- VN
- VU
- WF
- WS
- YE
- YT
- ZA
- ZM
- ZW
title: CountryAlpha2
examples:
- US
- SE
- FR
x-speakeasy-enums:
- AD
- AE
- AF
- AG
- AI
- AL
- AM
- AO
- AQ
- AR
- AS
- AT
- AU
- AW
- AX
- AZ
- BA
- BB
- BD
- BE
- BF
- BG
- BH
- BI
- BJ
- BL
- BM
- BN
- BO
- BQ
- BR
- BS
- BT
- BV
- BW
- BY
- BZ
- CA
- CC
- CD
- CF
- CG
- CH
- CI
- CK
- CL
- CM
- CN
- CO
- CR
- CU
- CV
- CW
- CX
- CY
- CZ
- DE
- DJ
- DK
- DM
- DO
- DZ
- EC
- EE
- EG
- EH
- ER
- ES
- ET
- FI
- FJ
- FK
- FM
- FO
- FR
- GA
- GB
- GD
- GE
- GF
- GG
- GH
- GI
- GL
- GM
- GN
- GP
- GQ
- GR
- GS
- GT
- GU
- GW
- GY
- HK
- HM
- HN
- HR
- HT
- HU
- ID
- IE
- IL
- IM
- IN
- IO
- IQ
- IR
- IS
- IT
- JE
- JM
- JO
- JP
- KE
- KG
- KH
- KI
- KM
- KN
- KP
- KR
- KW
- KY
- KZ
- LA
- LB
- LC
- LI
- LK
- LR
- LS
- LT
- LU
- LV
- LY
- MA
- MC
- MD
- ME
- MF
- MG
- MH
- MK
- ML
- MM
- MN
- MO
- MP
- MQ
- MR
- MS
- MT
- MU
- MV
- MW
- MX
- MY
- MZ
- NA
- NC
- NE
- NF
- NG
- NI
- NL
- 'NO'
- NP
- NR
- NU
- NZ
- OM
- PA
- PE
- PF
- PG
- PH
- PK
- PL
- PM
- PN
- PR
- PS
- PT
- PW
- PY
- QA
- RE
- RO
- RS
- RU
- RW
- SA
- SB
- SC
- SD
- SE
- SG
- SH
- SI
- SJ
- SK
- SL
- SM
- SN
- SO
- SR
- SS
- ST
- SV
- SX
- SY
- SZ
- TC
- TD
- TF
- TG
- TH
- TJ
- TK
- TL
- TM
- TN
- TO
- TR
- TT
- TV
- TW
- TZ
- UA
- UG
- UM
- US
- UY
- UZ
- VA
- VC
- VE
- VG
- VI
- VN
- VU
- WF
- WS
- YE
- YT
- ZA
- ZM
- ZW
type: object
required:
- country
title: Address
CheckoutBillingAddressFields:
properties:
country:
$ref: '#/components/schemas/BillingAddressFieldMode'
state:
$ref: '#/components/schemas/BillingAddressFieldMode'
city:
$ref: '#/components/schemas/BillingAddressFieldMode'
postal_code:
$ref: '#/components/schemas/BillingAddressFieldMode'
line1:
$ref: '#/components/schemas/BillingAddressFieldMode'
line2:
$ref: '#/components/schemas/BillingAddressFieldMode'
type: object
required:
- country
- state
- city
- postal_code
- line1
- line2
title: CheckoutBillingAddressFields
MetadataOutputType:
additionalProperties:
anyOf:
- type: string
- type: integer
- type: number
- type: boolean
type: object
CheckoutProduct:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
trial_interval:
anyOf:
- $ref: '#/components/schemas/TrialInterval'
- type: 'null'
description: The interval unit for the trial period.
trial_interval_count:
anyOf:
- type: integer
- type: 'null'
title: Trial Interval Count
description: The number of interval units for the trial period.
name:
type: string
title: Name
description: The name of the product.
description:
anyOf:
- type: string
- type: 'null'
title: Description
description: The description of the product.
recurring_interval:
anyOf:
- $ref: '#/components/schemas/SubscriptionRecurringInterval'
- type: 'null'
description: >-
The recurring interval of the product. If `None`, the product is a
one-time purchase.
recurring_interval_count:
anyOf:
- type: integer
- type: 'null'
title: Recurring Interval Count
description: >-
Number of interval units of the subscription. If this is set to 1
the charge will happen every interval (e.g. every month), if set to
2 it will be every other month, and so on. None for one-time
products.
is_recurring:
type: boolean
title: Is Recurring
description: Whether the product is a subscription.
is_archived:
type: boolean
title: Is Archived
description: Whether the product is archived and no longer available.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the product.
prices:
items:
oneOf:
- $ref: '#/components/schemas/LegacyRecurringProductPrice'
- $ref: '#/components/schemas/ProductPrice'
type: array
title: Prices
description: List of prices for this product.
benefits:
items:
$ref: '#/components/schemas/BenefitPublic'
type: array
title: BenefitPublic
description: List of benefits granted by the product.
medias:
items:
$ref: '#/components/schemas/ProductMediaFileRead'
type: array
title: Medias
description: List of medias associated to the product.
type: object
required:
- id
- created_at
- modified_at
- trial_interval
- trial_interval_count
- name
- description
- recurring_interval
- recurring_interval_count
- is_recurring
- is_archived
- organization_id
- prices
- benefits
- medias
title: CheckoutProduct
description: Product data for a checkout session.
LegacyRecurringProductPrice:
oneOf:
- $ref: '#/components/schemas/LegacyRecurringProductPriceFixed'
- $ref: '#/components/schemas/LegacyRecurringProductPriceCustom'
- $ref: '#/components/schemas/LegacyRecurringProductPriceFree'
discriminator:
propertyName: amount_type
mapping:
custom: '#/components/schemas/LegacyRecurringProductPriceCustom'
fixed: '#/components/schemas/LegacyRecurringProductPriceFixed'
free: '#/components/schemas/LegacyRecurringProductPriceFree'
ProductPrice:
oneOf:
- $ref: '#/components/schemas/ProductPriceFixed'
- $ref: '#/components/schemas/ProductPriceCustom'
- $ref: '#/components/schemas/ProductPriceFree'
- $ref: '#/components/schemas/ProductPriceSeatBased'
- $ref: '#/components/schemas/ProductPriceMeteredUnit'
discriminator:
propertyName: amount_type
mapping:
custom: '#/components/schemas/ProductPriceCustom'
fixed: '#/components/schemas/ProductPriceFixed'
free: '#/components/schemas/ProductPriceFree'
metered_unit: '#/components/schemas/ProductPriceMeteredUnit'
seat_based: '#/components/schemas/ProductPriceSeatBased'
CheckoutDiscountFixedOnceForeverDuration:
properties:
duration:
$ref: '#/components/schemas/DiscountDuration'
type:
$ref: '#/components/schemas/DiscountType'
amount:
type: integer
title: Amount
examples:
- 1000
currency:
type: string
title: Currency
examples:
- usd
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
name:
type: string
title: Name
code:
anyOf:
- type: string
- type: 'null'
title: Code
type: object
required:
- duration
- type
- amount
- currency
- id
- name
- code
title: CheckoutDiscountFixedOnceForeverDuration
description: Schema for a fixed amount discount that is applied once or forever.
CheckoutDiscountFixedRepeatDuration:
properties:
duration:
$ref: '#/components/schemas/DiscountDuration'
duration_in_months:
type: integer
title: Duration In Months
type:
$ref: '#/components/schemas/DiscountType'
amount:
type: integer
title: Amount
examples:
- 1000
currency:
type: string
title: Currency
examples:
- usd
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
name:
type: string
title: Name
code:
anyOf:
- type: string
- type: 'null'
title: Code
type: object
required:
- duration
- duration_in_months
- type
- amount
- currency
- id
- name
- code
title: CheckoutDiscountFixedRepeatDuration
description: |-
Schema for a fixed amount discount that is applied on every invoice
for a certain number of months.
CheckoutDiscountPercentageOnceForeverDuration:
properties:
duration:
$ref: '#/components/schemas/DiscountDuration'
type:
$ref: '#/components/schemas/DiscountType'
basis_points:
type: integer
title: Basis Points
description: >-
Discount percentage in basis points. A basis point is 1/100th of a
percent. For example, 1000 basis points equals a 10% discount.
examples:
- 1000
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
name:
type: string
title: Name
code:
anyOf:
- type: string
- type: 'null'
title: Code
type: object
required:
- duration
- type
- basis_points
- id
- name
- code
title: CheckoutDiscountPercentageOnceForeverDuration
description: Schema for a percentage discount that is applied once or forever.
CheckoutDiscountPercentageRepeatDuration:
properties:
duration:
$ref: '#/components/schemas/DiscountDuration'
duration_in_months:
type: integer
title: Duration In Months
type:
$ref: '#/components/schemas/DiscountType'
basis_points:
type: integer
title: Basis Points
description: >-
Discount percentage in basis points. A basis point is 1/100th of a
percent. For example, 1000 basis points equals a 10% discount.
examples:
- 1000
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
name:
type: string
title: Name
code:
anyOf:
- type: string
- type: 'null'
title: Code
type: object
required:
- duration
- duration_in_months
- type
- basis_points
- id
- name
- code
title: CheckoutDiscountPercentageRepeatDuration
description: |-
Schema for a percentage discount that is applied on every invoice
for a certain number of months.
AttachedCustomField:
properties:
custom_field_id:
type: string
format: uuid4
title: Custom Field Id
description: ID of the custom field.
custom_field:
$ref: '#/components/schemas/CustomField'
title: CustomField
order:
type: integer
title: Order
description: Order of the custom field in the resource.
required:
type: boolean
title: Required
description: Whether the value is required for this custom field.
type: object
required:
- custom_field_id
- custom_field
- order
- required
title: AttachedCustomField
description: Schema of a custom field attached to a resource.
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
msg:
type: string
title: Message
type:
type: string
title: Error Type
type: object
required:
- loc
- msg
- type
title: ValidationError
AddressInput:
properties:
line1:
anyOf:
- type: string
- type: 'null'
title: Line1
line2:
anyOf:
- type: string
- type: 'null'
title: Line2
postal_code:
anyOf:
- type: string
- type: 'null'
title: Postal Code
city:
anyOf:
- type: string
- type: 'null'
title: City
state:
anyOf:
- type: string
- type: 'null'
title: State
country:
type: string
enum:
- AD
- AE
- AF
- AG
- AI
- AL
- AM
- AO
- AQ
- AR
- AS
- AT
- AU
- AW
- AX
- AZ
- BA
- BB
- BD
- BE
- BF
- BG
- BH
- BI
- BJ
- BL
- BM
- BN
- BO
- BQ
- BR
- BS
- BT
- BV
- BW
- BY
- BZ
- CA
- CC
- CD
- CF
- CG
- CH
- CI
- CK
- CL
- CM
- CN
- CO
- CR
- CV
- CW
- CX
- CY
- CZ
- DE
- DJ
- DK
- DM
- DO
- DZ
- EC
- EE
- EG
- EH
- ER
- ES
- ET
- FI
- FJ
- FK
- FM
- FO
- FR
- GA
- GB
- GD
- GE
- GF
- GG
- GH
- GI
- GL
- GM
- GN
- GP
- GQ
- GR
- GS
- GT
- GU
- GW
- GY
- HK
- HM
- HN
- HR
- HT
- HU
- ID
- IE
- IL
- IM
- IN
- IO
- IQ
- IS
- IT
- JE
- JM
- JO
- JP
- KE
- KG
- KH
- KI
- KM
- KN
- KR
- KW
- KY
- KZ
- LA
- LB
- LC
- LI
- LK
- LR
- LS
- LT
- LU
- LV
- LY
- MA
- MC
- MD
- ME
- MF
- MG
- MH
- MK
- ML
- MM
- MN
- MO
- MP
- MQ
- MR
- MS
- MT
- MU
- MV
- MW
- MX
- MY
- MZ
- NA
- NC
- NE
- NF
- NG
- NI
- NL
- 'NO'
- NP
- NR
- NU
- NZ
- OM
- PA
- PE
- PF
- PG
- PH
- PK
- PL
- PM
- PN
- PR
- PS
- PT
- PW
- PY
- QA
- RE
- RO
- RS
- RW
- SA
- SB
- SC
- SD
- SE
- SG
- SH
- SI
- SJ
- SK
- SL
- SM
- SN
- SO
- SR
- SS
- ST
- SV
- SX
- SZ
- TC
- TD
- TF
- TG
- TH
- TJ
- TK
- TL
- TM
- TN
- TO
- TR
- TT
- TV
- TW
- TZ
- UA
- UG
- UM
- US
- UY
- UZ
- VA
- VC
- VE
- VG
- VI
- VN
- VU
- WF
- WS
- YE
- YT
- ZA
- ZM
- ZW
title: CountryAlpha2Input
examples:
- US
- SE
- FR
x-speakeasy-enums:
- AD
- AE
- AF
- AG
- AI
- AL
- AM
- AO
- AQ
- AR
- AS
- AT
- AU
- AW
- AX
- AZ
- BA
- BB
- BD
- BE
- BF
- BG
- BH
- BI
- BJ
- BL
- BM
- BN
- BO
- BQ
- BR
- BS
- BT
- BV
- BW
- BY
- BZ
- CA
- CC
- CD
- CF
- CG
- CH
- CI
- CK
- CL
- CM
- CN
- CO
- CR
- CV
- CW
- CX
- CY
- CZ
- DE
- DJ
- DK
- DM
- DO
- DZ
- EC
- EE
- EG
- EH
- ER
- ES
- ET
- FI
- FJ
- FK
- FM
- FO
- FR
- GA
- GB
- GD
- GE
- GF
- GG
- GH
- GI
- GL
- GM
- GN
- GP
- GQ
- GR
- GS
- GT
- GU
- GW
- GY
- HK
- HM
- HN
- HR
- HT
- HU
- ID
- IE
- IL
- IM
- IN
- IO
- IQ
- IS
- IT
- JE
- JM
- JO
- JP
- KE
- KG
- KH
- KI
- KM
- KN
- KR
- KW
- KY
- KZ
- LA
- LB
- LC
- LI
- LK
- LR
- LS
- LT
- LU
- LV
- LY
- MA
- MC
- MD
- ME
- MF
- MG
- MH
- MK
- ML
- MM
- MN
- MO
- MP
- MQ
- MR
- MS
- MT
- MU
- MV
- MW
- MX
- MY
- MZ
- NA
- NC
- NE
- NF
- NG
- NI
- NL
- 'NO'
- NP
- NR
- NU
- NZ
- OM
- PA
- PE
- PF
- PG
- PH
- PK
- PL
- PM
- PN
- PR
- PS
- PT
- PW
- PY
- QA
- RE
- RO
- RS
- RW
- SA
- SB
- SC
- SD
- SE
- SG
- SH
- SI
- SJ
- SK
- SL
- SM
- SN
- SO
- SR
- SS
- ST
- SV
- SX
- SZ
- TC
- TD
- TF
- TG
- TH
- TJ
- TK
- TL
- TM
- TN
- TO
- TR
- TT
- TV
- TW
- TZ
- UA
- UG
- UM
- US
- UY
- UZ
- VA
- VC
- VE
- VG
- VI
- VN
- VU
- WF
- WS
- YE
- YT
- ZA
- ZM
- ZW
type: object
required:
- country
title: AddressInput
PresentmentCurrency:
type: string
enum:
- usd
- eur
- gbp
- cad
- aud
- jpy
- chf
- sek
title: PresentmentCurrency
ProductPriceFixedCreate:
properties:
amount_type:
type: string
const: fixed
title: Amount Type
price_amount:
type: integer
maximum: 99999999
minimum: 50
title: Price Amount
description: The price in cents.
price_currency:
type: string
pattern: usd
title: Price Currency
description: The currency. Currently, only `usd` is supported.
default: usd
type: object
required:
- amount_type
- price_amount
title: ProductPriceFixedCreate
description: Schema to create a fixed price.
ProductPriceCustomCreate:
properties:
amount_type:
type: string
const: custom
title: Amount Type
price_currency:
type: string
pattern: usd
title: Price Currency
description: The currency. Currently, only `usd` is supported.
default: usd
minimum_amount:
type: integer
minimum: 0
title: Minimum Amount
description: >-
The minimum amount the customer can pay. If set to 0, the price is
'free or pay what you want' and $0 is accepted. If set to a value
between 1-49, it will be rejected. Defaults to 50 cents.
default: 50
maximum_amount:
anyOf:
- type: integer
maximum: 1000000
minimum: 50
description: The price in cents.
- type: 'null'
title: Maximum Amount
description: The maximum amount the customer can pay.
preset_amount:
anyOf:
- type: integer
maximum: 1000000
minimum: 0
description: The price in cents.
- type: 'null'
title: Preset Amount
description: >-
The initial amount shown to the customer. If 0, the customer will
see $0 as the default. Values between 1-49 are rejected.
type: object
required:
- amount_type
title: ProductPriceCustomCreate
description: Schema to create a pay-what-you-want price.
ProductPriceFreeCreate:
properties:
amount_type:
type: string
const: free
title: Amount Type
type: object
required:
- amount_type
title: ProductPriceFreeCreate
description: Schema to create a free price.
ProductPriceSeatBasedCreate:
properties:
amount_type:
type: string
const: seat_based
title: Amount Type
price_currency:
type: string
pattern: usd
title: Price Currency
description: The currency. Currently, only `usd` is supported.
default: usd
seat_tiers:
$ref: '#/components/schemas/ProductPriceSeatTiers-Input'
description: Tiered pricing based on seat quantity
type: object
required:
- amount_type
- seat_tiers
title: ProductPriceSeatBasedCreate
description: Schema to create a seat-based price with volume-based tiers.
ProductPriceMeteredUnitCreate:
properties:
amount_type:
type: string
const: metered_unit
title: Amount Type
meter_id:
type: string
format: uuid4
title: Meter Id
description: The ID of the meter associated to the price.
price_currency:
type: string
pattern: usd
title: Price Currency
description: The currency. Currently, only `usd` is supported.
default: usd
unit_amount:
anyOf:
- type: number
exclusiveMinimum: 0
- type: string
pattern: >-
^(?!^[-+.]*$)[+-]?0*(?:\d{0,5}|(?=[\d.]{1,18}0*$)\d{0,5}\.\d{0,12}0*$)
title: Unit Amount
description: The price per unit in cents. Supports up to 12 decimal places.
cap_amount:
anyOf:
- type: integer
maximum: 2147483647
minimum: 0
- type: 'null'
title: Cap Amount
description: >-
Optional maximum amount in cents that can be charged, regardless of
the number of units consumed.
type: object
required:
- amount_type
- meter_id
- unit_amount
title: ProductPriceMeteredUnitCreate
description: Schema to create a metered price with a fixed unit price.
BillingAddressFieldMode:
type: string
enum:
- required
- optional
- disabled
title: BillingAddressFieldMode
SubscriptionRecurringInterval:
type: string
enum:
- day
- week
- month
- year
title: SubscriptionRecurringInterval
BenefitPublic:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the benefit.
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
type:
$ref: '#/components/schemas/BenefitType'
description: The type of the benefit.
description:
type: string
title: Description
description: The description of the benefit.
selectable:
type: boolean
title: Selectable
description: Whether the benefit is selectable when creating a product.
deletable:
type: boolean
title: Deletable
description: Whether the benefit is deletable.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the benefit.
type: object
required:
- id
- created_at
- modified_at
- type
- description
- selectable
- deletable
- organization_id
title: BenefitPublic
ProductMediaFileRead:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
organization_id:
type: string
format: uuid4
title: Organization Id
name:
type: string
title: Name
path:
type: string
title: Path
mime_type:
type: string
title: Mime Type
size:
type: integer
title: Size
storage_version:
anyOf:
- type: string
- type: 'null'
title: Storage Version
checksum_etag:
anyOf:
- type: string
- type: 'null'
title: Checksum Etag
checksum_sha256_base64:
anyOf:
- type: string
- type: 'null'
title: Checksum Sha256 Base64
checksum_sha256_hex:
anyOf:
- type: string
- type: 'null'
title: Checksum Sha256 Hex
last_modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Last Modified At
version:
anyOf:
- type: string
- type: 'null'
title: Version
service:
type: string
const: product_media
title: Service
is_uploaded:
type: boolean
title: Is Uploaded
created_at:
type: string
format: date-time
title: Created At
size_readable:
type: string
title: Size Readable
public_url:
type: string
title: Public Url
type: object
required:
- id
- organization_id
- name
- path
- mime_type
- size
- storage_version
- checksum_etag
- checksum_sha256_base64
- checksum_sha256_hex
- last_modified_at
- version
- service
- is_uploaded
- created_at
- size_readable
- public_url
title: ProductMediaFileRead
description: File to be used as a product media file.
LegacyRecurringProductPriceFixed:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: fixed
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
type: string
const: recurring
title: Type
description: The type of the price.
recurring_interval:
$ref: '#/components/schemas/SubscriptionRecurringInterval'
description: The recurring interval of the price.
price_currency:
type: string
title: Price Currency
description: The currency.
price_amount:
type: integer
title: Price Amount
description: The price in cents.
legacy:
type: boolean
const: true
title: Legacy
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- price_currency
- price_amount
- legacy
title: LegacyRecurringProductPriceFixed
description: >-
A recurring price for a product, i.e. a subscription.
**Deprecated**: The recurring interval should be set on the product
itself.
LegacyRecurringProductPriceCustom:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: custom
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
type: string
const: recurring
title: Type
description: The type of the price.
recurring_interval:
$ref: '#/components/schemas/SubscriptionRecurringInterval'
description: The recurring interval of the price.
price_currency:
type: string
title: Price Currency
description: The currency.
minimum_amount:
type: integer
title: Minimum Amount
description: >-
The minimum amount the customer can pay. If 0, the price is 'free or
pay what you want'. Defaults to 50 cents.
maximum_amount:
anyOf:
- type: integer
- type: 'null'
title: Maximum Amount
description: The maximum amount the customer can pay.
preset_amount:
anyOf:
- type: integer
- type: 'null'
title: Preset Amount
description: The initial amount shown to the customer.
legacy:
type: boolean
const: true
title: Legacy
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- price_currency
- minimum_amount
- maximum_amount
- preset_amount
- legacy
title: LegacyRecurringProductPriceCustom
description: >-
A pay-what-you-want recurring price for a product, i.e. a subscription.
**Deprecated**: The recurring interval should be set on the product
itself.
LegacyRecurringProductPriceFree:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: free
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
type: string
const: recurring
title: Type
description: The type of the price.
recurring_interval:
$ref: '#/components/schemas/SubscriptionRecurringInterval'
description: The recurring interval of the price.
legacy:
type: boolean
const: true
title: Legacy
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- legacy
title: LegacyRecurringProductPriceFree
description: >-
A free recurring price for a product, i.e. a subscription.
**Deprecated**: The recurring interval should be set on the product
itself.
ProductPriceFixed:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: fixed
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
$ref: '#/components/schemas/ProductPriceType'
deprecated: true
recurring_interval:
anyOf:
- $ref: '#/components/schemas/SubscriptionRecurringInterval'
- type: 'null'
deprecated: true
price_currency:
type: string
title: Price Currency
description: The currency.
price_amount:
type: integer
title: Price Amount
description: The price in cents.
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- price_currency
- price_amount
title: ProductPriceFixed
description: A fixed price for a product.
ProductPriceCustom:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: custom
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
$ref: '#/components/schemas/ProductPriceType'
deprecated: true
recurring_interval:
anyOf:
- $ref: '#/components/schemas/SubscriptionRecurringInterval'
- type: 'null'
deprecated: true
price_currency:
type: string
title: Price Currency
description: The currency.
minimum_amount:
type: integer
title: Minimum Amount
description: >-
The minimum amount the customer can pay. If 0, the price is 'free or
pay what you want'. Defaults to 50 cents.
maximum_amount:
anyOf:
- type: integer
- type: 'null'
title: Maximum Amount
description: The maximum amount the customer can pay.
preset_amount:
anyOf:
- type: integer
- type: 'null'
title: Preset Amount
description: The initial amount shown to the customer.
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- price_currency
- minimum_amount
- maximum_amount
- preset_amount
title: ProductPriceCustom
description: A pay-what-you-want price for a product.
ProductPriceFree:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: free
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
$ref: '#/components/schemas/ProductPriceType'
deprecated: true
recurring_interval:
anyOf:
- $ref: '#/components/schemas/SubscriptionRecurringInterval'
- type: 'null'
deprecated: true
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
title: ProductPriceFree
description: A free price for a product.
ProductPriceSeatBased:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: seat_based
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
$ref: '#/components/schemas/ProductPriceType'
deprecated: true
recurring_interval:
anyOf:
- $ref: '#/components/schemas/SubscriptionRecurringInterval'
- type: 'null'
deprecated: true
price_currency:
type: string
title: Price Currency
description: The currency.
seat_tiers:
$ref: '#/components/schemas/ProductPriceSeatTiers-Output'
description: Tiered pricing based on seat quantity
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- price_currency
- seat_tiers
title: ProductPriceSeatBased
description: A seat-based price for a product.
ProductPriceMeteredUnit:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the price.
source:
$ref: '#/components/schemas/ProductPriceSource'
description: >-
The source of the price . `catalog` is a predefined price, while
`ad_hoc` is a price created dynamically on a Checkout session.
amount_type:
type: string
const: metered_unit
title: Amount Type
is_archived:
type: boolean
title: Is Archived
description: Whether the price is archived and no longer available.
product_id:
type: string
format: uuid4
title: Product Id
description: The ID of the product owning the price.
type:
$ref: '#/components/schemas/ProductPriceType'
deprecated: true
recurring_interval:
anyOf:
- $ref: '#/components/schemas/SubscriptionRecurringInterval'
- type: 'null'
deprecated: true
price_currency:
type: string
title: Price Currency
description: The currency.
unit_amount:
type: string
pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
title: Unit Amount
description: The price per unit in cents.
cap_amount:
anyOf:
- type: integer
- type: 'null'
title: Cap Amount
description: >-
The maximum amount in cents that can be charged, regardless of the
number of units consumed.
meter_id:
type: string
format: uuid4
title: Meter Id
description: The ID of the meter associated to the price.
meter:
$ref: '#/components/schemas/ProductPriceMeter'
description: The meter associated to the price.
type: object
required:
- created_at
- modified_at
- id
- source
- amount_type
- is_archived
- product_id
- type
- recurring_interval
- price_currency
- unit_amount
- cap_amount
- meter_id
- meter
title: ProductPriceMeteredUnit
description: A metered, usage-based, price for a product, with a fixed unit price.
DiscountDuration:
type: string
enum:
- once
- forever
- repeating
title: DiscountDuration
DiscountType:
type: string
enum:
- fixed
- percentage
title: DiscountType
CustomField:
oneOf:
- $ref: '#/components/schemas/CustomFieldText'
- $ref: '#/components/schemas/CustomFieldNumber'
- $ref: '#/components/schemas/CustomFieldDate'
- $ref: '#/components/schemas/CustomFieldCheckbox'
- $ref: '#/components/schemas/CustomFieldSelect'
discriminator:
propertyName: type
mapping:
checkbox: '#/components/schemas/CustomFieldCheckbox'
date: '#/components/schemas/CustomFieldDate'
number: '#/components/schemas/CustomFieldNumber'
select: '#/components/schemas/CustomFieldSelect'
text: '#/components/schemas/CustomFieldText'
ProductPriceSeatTiers-Input:
properties:
tiers:
items:
$ref: '#/components/schemas/ProductPriceSeatTier'
type: array
minItems: 1
title: Tiers
description: List of pricing tiers
type: object
required:
- tiers
title: ProductPriceSeatTiers
description: |-
List of pricing tiers for seat-based pricing.
The minimum and maximum seat limits are derived from the tiers:
- minimum_seats = first tier's min_seats
- maximum_seats = last tier's max_seats (None for unlimited)
BenefitType:
type: string
enum:
- custom
- discord
- github_repository
- downloadables
- license_keys
- meter_credit
title: BenefitType
ProductPriceSource:
type: string
enum:
- catalog
- ad_hoc
title: ProductPriceSource
ProductPriceType:
type: string
enum:
- one_time
- recurring
title: ProductPriceType
ProductPriceSeatTiers-Output:
properties:
tiers:
items:
$ref: '#/components/schemas/ProductPriceSeatTier'
type: array
minItems: 1
title: Tiers
description: List of pricing tiers
minimum_seats:
type: integer
title: Minimum Seats
description: >-
Minimum number of seats required for purchase, derived from first
tier.
maximum_seats:
anyOf:
- type: integer
- type: 'null'
title: Maximum Seats
description: >-
Maximum number of seats allowed for purchase, derived from last
tier. None for unlimited.
type: object
required:
- tiers
- minimum_seats
- maximum_seats
title: ProductPriceSeatTiers
description: |-
List of pricing tiers for seat-based pricing.
The minimum and maximum seat limits are derived from the tiers:
- minimum_seats = first tier's min_seats
- maximum_seats = last tier's max_seats (None for unlimited)
ProductPriceMeter:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
name:
type: string
title: Name
description: The name of the meter.
type: object
required:
- id
- name
title: ProductPriceMeter
description: A meter associated to a metered price.
CustomFieldText:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
metadata:
$ref: '#/components/schemas/MetadataOutputType'
type:
type: string
const: text
title: Type
slug:
type: string
title: Slug
description: >-
Identifier of the custom field. It'll be used as key when storing
the value.
name:
type: string
title: Name
description: Name of the custom field.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the custom field.
examples:
- 1dbfc517-0bbf-4301-9ba8-555ca42b9737
x-polar-selector-widget:
displayProperty: name
resourceName: Organization
resourceRoot: /v1/organizations
properties:
$ref: '#/components/schemas/CustomFieldTextProperties'
type: object
required:
- created_at
- modified_at
- id
- metadata
- type
- slug
- name
- organization_id
- properties
title: CustomFieldText
description: Schema for a custom field of type text.
CustomFieldNumber:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
metadata:
$ref: '#/components/schemas/MetadataOutputType'
type:
type: string
const: number
title: Type
slug:
type: string
title: Slug
description: >-
Identifier of the custom field. It'll be used as key when storing
the value.
name:
type: string
title: Name
description: Name of the custom field.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the custom field.
examples:
- 1dbfc517-0bbf-4301-9ba8-555ca42b9737
x-polar-selector-widget:
displayProperty: name
resourceName: Organization
resourceRoot: /v1/organizations
properties:
$ref: '#/components/schemas/CustomFieldNumberProperties'
type: object
required:
- created_at
- modified_at
- id
- metadata
- type
- slug
- name
- organization_id
- properties
title: CustomFieldNumber
description: Schema for a custom field of type number.
CustomFieldDate:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
metadata:
$ref: '#/components/schemas/MetadataOutputType'
type:
type: string
const: date
title: Type
slug:
type: string
title: Slug
description: >-
Identifier of the custom field. It'll be used as key when storing
the value.
name:
type: string
title: Name
description: Name of the custom field.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the custom field.
examples:
- 1dbfc517-0bbf-4301-9ba8-555ca42b9737
x-polar-selector-widget:
displayProperty: name
resourceName: Organization
resourceRoot: /v1/organizations
properties:
$ref: '#/components/schemas/CustomFieldDateProperties'
type: object
required:
- created_at
- modified_at
- id
- metadata
- type
- slug
- name
- organization_id
- properties
title: CustomFieldDate
description: Schema for a custom field of type date.
CustomFieldCheckbox:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
metadata:
$ref: '#/components/schemas/MetadataOutputType'
type:
type: string
const: checkbox
title: Type
slug:
type: string
title: Slug
description: >-
Identifier of the custom field. It'll be used as key when storing
the value.
name:
type: string
title: Name
description: Name of the custom field.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the custom field.
examples:
- 1dbfc517-0bbf-4301-9ba8-555ca42b9737
x-polar-selector-widget:
displayProperty: name
resourceName: Organization
resourceRoot: /v1/organizations
properties:
$ref: '#/components/schemas/CustomFieldCheckboxProperties'
type: object
required:
- created_at
- modified_at
- id
- metadata
- type
- slug
- name
- organization_id
- properties
title: CustomFieldCheckbox
description: Schema for a custom field of type checkbox.
CustomFieldSelect:
properties:
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
id:
type: string
format: uuid4
title: Id
description: The ID of the object.
metadata:
$ref: '#/components/schemas/MetadataOutputType'
type:
type: string
const: select
title: Type
slug:
type: string
title: Slug
description: >-
Identifier of the custom field. It'll be used as key when storing
the value.
name:
type: string
title: Name
description: Name of the custom field.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the custom field.
examples:
- 1dbfc517-0bbf-4301-9ba8-555ca42b9737
x-polar-selector-widget:
displayProperty: name
resourceName: Organization
resourceRoot: /v1/organizations
properties:
$ref: '#/components/schemas/CustomFieldSelectProperties'
type: object
required:
- created_at
- modified_at
- id
- metadata
- type
- slug
- name
- organization_id
- properties
title: CustomFieldSelect
description: Schema for a custom field of type select.
ProductPriceSeatTier:
properties:
min_seats:
type: integer
minimum: 1
title: Min Seats
description: Minimum number of seats (inclusive)
max_seats:
anyOf:
- type: integer
minimum: 1
- type: 'null'
title: Max Seats
description: Maximum number of seats (inclusive). None for unlimited.
price_per_seat:
type: integer
maximum: 99999999
minimum: 0
title: Price Per Seat
description: Price per seat in cents for this tier
type: object
required:
- min_seats
- price_per_seat
title: ProductPriceSeatTier
description: A pricing tier for seat-based pricing.
CustomFieldTextProperties:
properties:
form_label:
type: string
minLength: 1
title: Form Label
form_help_text:
type: string
minLength: 1
title: Form Help Text
form_placeholder:
type: string
minLength: 1
title: Form Placeholder
textarea:
type: boolean
title: Textarea
min_length:
type: integer
maximum: 2147483647
minimum: 0
title: Min Length
max_length:
type: integer
maximum: 2147483647
minimum: 0
title: Max Length
type: object
title: CustomFieldTextProperties
CustomFieldNumberProperties:
properties:
form_label:
type: string
minLength: 1
title: Form Label
form_help_text:
type: string
minLength: 1
title: Form Help Text
form_placeholder:
type: string
minLength: 1
title: Form Placeholder
ge:
type: integer
maximum: 2147483647
minimum: -2147483648
title: Ge
le:
type: integer
maximum: 2147483647
minimum: -2147483648
title: Le
type: object
title: CustomFieldNumberProperties
CustomFieldDateProperties:
properties:
form_label:
type: string
minLength: 1
title: Form Label
form_help_text:
type: string
minLength: 1
title: Form Help Text
form_placeholder:
type: string
minLength: 1
title: Form Placeholder
ge:
type: integer
maximum: 2147483647
minimum: -2147483648
title: Ge
le:
type: integer
maximum: 2147483647
minimum: -2147483648
title: Le
type: object
title: CustomFieldDateProperties
CustomFieldCheckboxProperties:
properties:
form_label:
type: string
minLength: 1
title: Form Label
form_help_text:
type: string
minLength: 1
title: Form Help Text
form_placeholder:
type: string
minLength: 1
title: Form Placeholder
type: object
title: CustomFieldCheckboxProperties
CustomFieldSelectProperties:
properties:
form_label:
type: string
minLength: 1
title: Form Label
form_help_text:
type: string
minLength: 1
title: Form Help Text
form_placeholder:
type: string
minLength: 1
title: Form Placeholder
options:
items:
$ref: '#/components/schemas/CustomFieldSelectOption'
type: array
minItems: 1
title: Options
type: object
required:
- options
title: CustomFieldSelectProperties
CustomFieldSelectOption:
properties:
value:
type: string
minLength: 1
title: Value
label:
type: string
minLength: 1
title: Label
type: object
required:
- value
- label
title: CustomFieldSelectOption
securitySchemes:
access_token:
type: http
scheme: bearer
description: >-
You can generate an **Organization Access Token** from your
organization's settings.
````
---
# Source: https://polar.sh/docs/guides/create-variants.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# How to create product variants
> Learn how create product variants in Polar and how customers can easily switch between them in the customer portal.
## Creating product variants (3 subscription products)
In the Polar dashboard sidebar, navigate to **Products** > **Catalogue** for your organization.
You can also go directly to:\
`https://polar.sh/dashboard/${org_slug}/products`
Click on **New Product** and fill the product information. Here, we are creating a monthly subscription product **Basic version** with cost \$20.
Your product catalogue should now show this product as follows:
Click on **New Product** and create two more subscription products one by one.
* **Mid version**: Fill the product information. We create a monthly subscription product named **Mid version** with cost \$30.
* **Advanced version**: We create a monthly subscription product named **Advanced version** with cost \$40.
* **Product Catalogue**: You should be able to see all your products on Product Catalogue.
## Creating checkout links with variants
In the Polar dashboard sidebar, navigate to **Products** > **Checkout Links**.
You can also go directly to:\
`https://polar.sh/dashboard/${org_slug}/products/checkout-links`
Click on **New Link** and select all your products which you want to offer as variants.
At this step, you may add a label, success URL and metadata. You may also configure whether discount codes are allowed and whether billing address is required from customers.
Click on **Create Link** after adding your configurations.
You should be able to see your label name in **Checkout Links**. In our case, **3 products** is the default label name assigned by the system.
Click on your label to see the checkout link.
You can copy this link and share to your customers for them to purchase a variant.
## Purchasing from variants
On opening the checkout link, the customer will need to select the variant they want to purchase and fill their email address and card details.
Once the customer has purchased the subscription, they will receive an email containing the link to access their purchase.
## Downgrading to another product variant
On opening the link from the email received, the customer needs to click on **Change Plan**.
Then, they can select the plan they want to downgrade to and click on **Change Plan**.
Now, the product is changed to **Basic version** instead of **Mid version** on the portal.
## Upgrading to another product variant
On opening the link from the email received, the customer needs to click on **Change Plan**.
Then, they need to select the variant they want to upgrade to, **Advanced version** and click on **Change Plan**.
Now, the product is changed to **Advanced version** on the portal.
---
# Source: https://polar.sh/docs/api-reference/webhooks/endpoints/create.md
# Source: https://polar.sh/docs/api-reference/subscriptions/create.md
# Source: https://polar.sh/docs/api-reference/refunds/create.md
# Source: https://polar.sh/docs/api-reference/products/create.md
# Source: https://polar.sh/docs/api-reference/organizations/create.md
# Source: https://polar.sh/docs/api-reference/meters/create.md
# Source: https://polar.sh/docs/api-reference/files/create.md
# Source: https://polar.sh/docs/api-reference/discounts/create.md
# Source: https://polar.sh/docs/api-reference/customers/create.md
# Source: https://polar.sh/docs/api-reference/customer-portal/sessions/create.md
# Source: https://polar.sh/docs/api-reference/custom-fields/create.md
# Source: https://polar.sh/docs/api-reference/checkout-links/create.md
# Source: https://polar.sh/docs/api-reference/benefits/create.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Create Benefit
> Create a benefit.
**Scopes**: `benefits:write`
## OpenAPI
````yaml post /v1/benefits/
openapi: 3.1.0
info:
title: Polar API
summary: Polar HTTP and Webhooks API
description: Read the docs at https://polar.sh/docs/api-reference
version: 0.1.0
servers:
- url: https://api.polar.sh
description: Production environment
x-speakeasy-server-id: production
- url: https://sandbox-api.polar.sh
description: Sandbox environment
x-speakeasy-server-id: sandbox
security:
- access_token: []
tags:
- name: public
description: >-
Endpoints shown and documented in the Polar API documentation and
available in our SDKs.
- name: private
description: >-
Endpoints that should appear in the schema only in development to generate
our internal JS SDK.
- name: mcp
description: Endpoints enabled in the MCP server.
paths:
/v1/benefits/:
post:
tags:
- benefits
- public
summary: Create Benefit
description: |-
Create a benefit.
**Scopes**: `benefits:write`
operationId: benefits:create
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BenefitCreate'
responses:
'201':
description: Benefit created.
content:
application/json:
schema:
$ref: '#/components/schemas/Benefit'
title: Benefit
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
components:
schemas:
BenefitCreate:
oneOf:
- $ref: '#/components/schemas/BenefitCustomCreate'
- $ref: '#/components/schemas/BenefitDiscordCreate'
- $ref: '#/components/schemas/BenefitGitHubRepositoryCreate'
- $ref: '#/components/schemas/BenefitDownloadablesCreate'
- $ref: '#/components/schemas/BenefitLicenseKeysCreate'
- $ref: '#/components/schemas/BenefitMeterCreditCreate'
discriminator:
propertyName: type
mapping:
custom: '#/components/schemas/BenefitCustomCreate'
discord: '#/components/schemas/BenefitDiscordCreate'
downloadables: '#/components/schemas/BenefitDownloadablesCreate'
github_repository: '#/components/schemas/BenefitGitHubRepositoryCreate'
license_keys: '#/components/schemas/BenefitLicenseKeysCreate'
meter_credit: '#/components/schemas/BenefitMeterCreditCreate'
Benefit:
anyOf:
- $ref: '#/components/schemas/BenefitCustom'
- $ref: '#/components/schemas/BenefitDiscord'
- $ref: '#/components/schemas/BenefitGitHubRepository'
- $ref: '#/components/schemas/BenefitDownloadables'
- $ref: '#/components/schemas/BenefitLicenseKeys'
- $ref: '#/components/schemas/BenefitMeterCredit'
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
type: object
title: HTTPValidationError
BenefitCustomCreate:
properties:
metadata:
additionalProperties:
anyOf:
- type: string
maxLength: 500
minLength: 1
- type: integer
- type: number
- type: boolean
propertyNames:
maxLength: 40
minLength: 1
type: object
maxProperties: 50
title: Metadata
description: |-
Key-value object allowing you to store additional information.
The key must be a string with a maximum length of **40 characters**.
The value must be either:
* A string with a maximum length of **500 characters**
* An integer
* A floating-point number
* A boolean
You can store up to **50 key-value pairs**.
type:
type: string
const: custom
title: Type
description:
type: string
maxLength: 42
minLength: 3
title: Description
description: >-
The description of the benefit. Will be displayed on products having
this benefit.
organization_id:
anyOf:
- type: string
format: uuid4
description: The organization ID.
examples:
- 1dbfc517-0bbf-4301-9ba8-555ca42b9737
x-polar-selector-widget:
displayProperty: name
resourceName: Organization
resourceRoot: /v1/organizations
- type: 'null'
title: Organization Id
description: >-
The ID of the organization owning the benefit. **Required unless you
use an organization token.**
properties:
$ref: '#/components/schemas/BenefitCustomCreateProperties'
type: object
required:
- type
- description
- properties
title: BenefitCustomCreate
description: Schema to create a benefit of type `custom`.
BenefitDiscordCreate:
properties:
metadata:
additionalProperties:
anyOf:
- type: string
maxLength: 500
minLength: 1
- type: integer
- type: number
- type: boolean
propertyNames:
maxLength: 40
minLength: 1
type: object
maxProperties: 50
title: Metadata
description: |-
Key-value object allowing you to store additional information.
The key must be a string with a maximum length of **40 characters**.
The value must be either:
* A string with a maximum length of **500 characters**
* An integer
* A floating-point number
* A boolean
You can store up to **50 key-value pairs**.
type:
type: string
const: discord
title: Type
description:
type: string
maxLength: 42
minLength: 3
title: Description
description: >-
The description of the benefit. Will be displayed on products having
this benefit.
organization_id:
anyOf:
- type: string
format: uuid4
description: The organization ID.
examples:
- 1dbfc517-0bbf-4301-9ba8-555ca42b9737
x-polar-selector-widget:
displayProperty: name
resourceName: Organization
resourceRoot: /v1/organizations
- type: 'null'
title: Organization Id
description: >-
The ID of the organization owning the benefit. **Required unless you
use an organization token.**
properties:
$ref: '#/components/schemas/BenefitDiscordCreateProperties'
type: object
required:
- type
- description
- properties
title: BenefitDiscordCreate
BenefitGitHubRepositoryCreate:
properties:
metadata:
additionalProperties:
anyOf:
- type: string
maxLength: 500
minLength: 1
- type: integer
- type: number
- type: boolean
propertyNames:
maxLength: 40
minLength: 1
type: object
maxProperties: 50
title: Metadata
description: |-
Key-value object allowing you to store additional information.
The key must be a string with a maximum length of **40 characters**.
The value must be either:
* A string with a maximum length of **500 characters**
* An integer
* A floating-point number
* A boolean
You can store up to **50 key-value pairs**.
type:
type: string
const: github_repository
title: Type
description:
type: string
maxLength: 42
minLength: 3
title: Description
description: >-
The description of the benefit. Will be displayed on products having
this benefit.
organization_id:
anyOf:
- type: string
format: uuid4
description: The organization ID.
examples:
- 1dbfc517-0bbf-4301-9ba8-555ca42b9737
x-polar-selector-widget:
displayProperty: name
resourceName: Organization
resourceRoot: /v1/organizations
- type: 'null'
title: Organization Id
description: >-
The ID of the organization owning the benefit. **Required unless you
use an organization token.**
properties:
$ref: '#/components/schemas/BenefitGitHubRepositoryCreateProperties'
type: object
required:
- type
- description
- properties
title: BenefitGitHubRepositoryCreate
BenefitDownloadablesCreate:
properties:
metadata:
additionalProperties:
anyOf:
- type: string
maxLength: 500
minLength: 1
- type: integer
- type: number
- type: boolean
propertyNames:
maxLength: 40
minLength: 1
type: object
maxProperties: 50
title: Metadata
description: |-
Key-value object allowing you to store additional information.
The key must be a string with a maximum length of **40 characters**.
The value must be either:
* A string with a maximum length of **500 characters**
* An integer
* A floating-point number
* A boolean
You can store up to **50 key-value pairs**.
type:
type: string
const: downloadables
title: Type
description:
type: string
maxLength: 42
minLength: 3
title: Description
description: >-
The description of the benefit. Will be displayed on products having
this benefit.
organization_id:
anyOf:
- type: string
format: uuid4
description: The organization ID.
examples:
- 1dbfc517-0bbf-4301-9ba8-555ca42b9737
x-polar-selector-widget:
displayProperty: name
resourceName: Organization
resourceRoot: /v1/organizations
- type: 'null'
title: Organization Id
description: >-
The ID of the organization owning the benefit. **Required unless you
use an organization token.**
properties:
$ref: '#/components/schemas/BenefitDownloadablesCreateProperties'
type: object
required:
- type
- description
- properties
title: BenefitDownloadablesCreate
BenefitLicenseKeysCreate:
properties:
metadata:
additionalProperties:
anyOf:
- type: string
maxLength: 500
minLength: 1
- type: integer
- type: number
- type: boolean
propertyNames:
maxLength: 40
minLength: 1
type: object
maxProperties: 50
title: Metadata
description: |-
Key-value object allowing you to store additional information.
The key must be a string with a maximum length of **40 characters**.
The value must be either:
* A string with a maximum length of **500 characters**
* An integer
* A floating-point number
* A boolean
You can store up to **50 key-value pairs**.
type:
type: string
const: license_keys
title: Type
description:
type: string
maxLength: 42
minLength: 3
title: Description
description: >-
The description of the benefit. Will be displayed on products having
this benefit.
organization_id:
anyOf:
- type: string
format: uuid4
description: The organization ID.
examples:
- 1dbfc517-0bbf-4301-9ba8-555ca42b9737
x-polar-selector-widget:
displayProperty: name
resourceName: Organization
resourceRoot: /v1/organizations
- type: 'null'
title: Organization Id
description: >-
The ID of the organization owning the benefit. **Required unless you
use an organization token.**
properties:
$ref: '#/components/schemas/BenefitLicenseKeysCreateProperties'
type: object
required:
- type
- description
- properties
title: BenefitLicenseKeysCreate
BenefitMeterCreditCreate:
properties:
metadata:
additionalProperties:
anyOf:
- type: string
maxLength: 500
minLength: 1
- type: integer
- type: number
- type: boolean
propertyNames:
maxLength: 40
minLength: 1
type: object
maxProperties: 50
title: Metadata
description: |-
Key-value object allowing you to store additional information.
The key must be a string with a maximum length of **40 characters**.
The value must be either:
* A string with a maximum length of **500 characters**
* An integer
* A floating-point number
* A boolean
You can store up to **50 key-value pairs**.
type:
type: string
const: meter_credit
title: Type
description:
type: string
maxLength: 42
minLength: 3
title: Description
description: >-
The description of the benefit. Will be displayed on products having
this benefit.
organization_id:
anyOf:
- type: string
format: uuid4
description: The organization ID.
examples:
- 1dbfc517-0bbf-4301-9ba8-555ca42b9737
x-polar-selector-widget:
displayProperty: name
resourceName: Organization
resourceRoot: /v1/organizations
- type: 'null'
title: Organization Id
description: >-
The ID of the organization owning the benefit. **Required unless you
use an organization token.**
properties:
$ref: '#/components/schemas/BenefitMeterCreditCreateProperties'
type: object
required:
- type
- description
- properties
title: BenefitMeterCreditCreate
description: Schema to create a benefit of type `meter_unit`.
BenefitCustom:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the benefit.
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
type:
type: string
const: custom
title: Type
description:
type: string
title: Description
description: The description of the benefit.
selectable:
type: boolean
title: Selectable
description: Whether the benefit is selectable when creating a product.
deletable:
type: boolean
title: Deletable
description: Whether the benefit is deletable.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the benefit.
metadata:
$ref: '#/components/schemas/MetadataOutputType'
properties:
$ref: '#/components/schemas/BenefitCustomProperties'
type: object
required:
- id
- created_at
- modified_at
- type
- description
- selectable
- deletable
- organization_id
- metadata
- properties
title: BenefitCustom
description: |-
A benefit of type `custom`.
Use it to grant any kind of benefit that doesn't fit in the other types.
BenefitDiscord:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the benefit.
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
type:
type: string
const: discord
title: Type
description:
type: string
title: Description
description: The description of the benefit.
selectable:
type: boolean
title: Selectable
description: Whether the benefit is selectable when creating a product.
deletable:
type: boolean
title: Deletable
description: Whether the benefit is deletable.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the benefit.
metadata:
$ref: '#/components/schemas/MetadataOutputType'
properties:
$ref: '#/components/schemas/BenefitDiscordProperties'
type: object
required:
- id
- created_at
- modified_at
- type
- description
- selectable
- deletable
- organization_id
- metadata
- properties
title: BenefitDiscord
description: |-
A benefit of type `discord`.
Use it to automatically invite your backers to a Discord server.
BenefitGitHubRepository:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the benefit.
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
type:
type: string
const: github_repository
title: Type
description:
type: string
title: Description
description: The description of the benefit.
selectable:
type: boolean
title: Selectable
description: Whether the benefit is selectable when creating a product.
deletable:
type: boolean
title: Deletable
description: Whether the benefit is deletable.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the benefit.
metadata:
$ref: '#/components/schemas/MetadataOutputType'
properties:
$ref: '#/components/schemas/BenefitGitHubRepositoryProperties'
type: object
required:
- id
- created_at
- modified_at
- type
- description
- selectable
- deletable
- organization_id
- metadata
- properties
title: BenefitGitHubRepository
description: >-
A benefit of type `github_repository`.
Use it to automatically invite your backers to a private GitHub
repository.
BenefitDownloadables:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the benefit.
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
type:
type: string
const: downloadables
title: Type
description:
type: string
title: Description
description: The description of the benefit.
selectable:
type: boolean
title: Selectable
description: Whether the benefit is selectable when creating a product.
deletable:
type: boolean
title: Deletable
description: Whether the benefit is deletable.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the benefit.
metadata:
$ref: '#/components/schemas/MetadataOutputType'
properties:
$ref: '#/components/schemas/BenefitDownloadablesProperties'
type: object
required:
- id
- created_at
- modified_at
- type
- description
- selectable
- deletable
- organization_id
- metadata
- properties
title: BenefitDownloadables
BenefitLicenseKeys:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the benefit.
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
type:
type: string
const: license_keys
title: Type
description:
type: string
title: Description
description: The description of the benefit.
selectable:
type: boolean
title: Selectable
description: Whether the benefit is selectable when creating a product.
deletable:
type: boolean
title: Deletable
description: Whether the benefit is deletable.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the benefit.
metadata:
$ref: '#/components/schemas/MetadataOutputType'
properties:
$ref: '#/components/schemas/BenefitLicenseKeysProperties'
type: object
required:
- id
- created_at
- modified_at
- type
- description
- selectable
- deletable
- organization_id
- metadata
- properties
title: BenefitLicenseKeys
BenefitMeterCredit:
properties:
id:
type: string
format: uuid4
title: Id
description: The ID of the benefit.
created_at:
type: string
format: date-time
title: Created At
description: Creation timestamp of the object.
modified_at:
anyOf:
- type: string
format: date-time
- type: 'null'
title: Modified At
description: Last modification timestamp of the object.
type:
type: string
const: meter_credit
title: Type
description:
type: string
title: Description
description: The description of the benefit.
selectable:
type: boolean
title: Selectable
description: Whether the benefit is selectable when creating a product.
deletable:
type: boolean
title: Deletable
description: Whether the benefit is deletable.
organization_id:
type: string
format: uuid4
title: Organization Id
description: The ID of the organization owning the benefit.
metadata:
$ref: '#/components/schemas/MetadataOutputType'
properties:
$ref: '#/components/schemas/BenefitMeterCreditProperties'
type: object
required:
- id
- created_at
- modified_at
- type
- description
- selectable
- deletable
- organization_id
- metadata
- properties
title: BenefitMeterCredit
description: |-
A benefit of type `meter_unit`.
Use it to grant a number of units on a specific meter.
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
msg:
type: string
title: Message
type:
type: string
title: Error Type
type: object
required:
- loc
- msg
- type
title: ValidationError
BenefitCustomCreateProperties:
properties:
note:
anyOf:
- anyOf:
- type: string
- type: 'null'
description: >-
Private note to be shared with customers who have this benefit
granted.
- type: 'null'
title: Note
type: object
title: BenefitCustomCreateProperties
description: Properties for creating a benefit of type `custom`.
BenefitDiscordCreateProperties:
properties:
guild_token:
type: string
title: Guild Token
role_id:
type: string
title: Role Id
description: The ID of the Discord role to grant.
kick_member:
type: boolean
title: Kick Member
description: Whether to kick the member from the Discord server on revocation.
type: object
required:
- guild_token
- role_id
- kick_member
title: BenefitDiscordCreateProperties
description: Properties to create a benefit of type `discord`.
BenefitGitHubRepositoryCreateProperties:
properties:
repository_owner:
type: string
title: Repository Owner
description: The owner of the repository.
examples:
- polarsource
repository_name:
type: string
title: Repository Name
description: The name of the repository.
examples:
- private_repo
permission:
type: string
enum:
- pull
- triage
- push
- maintain
- admin
title: Permission
description: >-
The permission level to grant. Read more about roles and their
permissions on [GitHub
documentation](https://docs.github.com/en/organizations/managing-user-access-to-your-organizations-repositories/managing-repository-roles/repository-roles-for-an-organization#permissions-for-each-role).
type: object
required:
- repository_owner
- repository_name
- permission
title: BenefitGitHubRepositoryCreateProperties
description: Properties to create a benefit of type `github_repository`.
BenefitDownloadablesCreateProperties:
properties:
archived:
additionalProperties:
type: boolean
propertyNames:
format: uuid4
type: object
title: Archived
default: {}
files:
items:
type: string
format: uuid4
type: array
minItems: 1
title: Files
type: object
required:
- files
title: BenefitDownloadablesCreateProperties
BenefitLicenseKeysCreateProperties:
properties:
prefix:
anyOf:
- type: string
- type: 'null'
title: Prefix
expires:
anyOf:
- $ref: '#/components/schemas/BenefitLicenseKeyExpirationProperties'
- type: 'null'
activations:
anyOf:
- $ref: '#/components/schemas/BenefitLicenseKeyActivationCreateProperties'
- type: 'null'
limit_usage:
anyOf:
- type: integer
exclusiveMinimum: 0
- type: 'null'
title: Limit Usage
type: object
title: BenefitLicenseKeysCreateProperties
BenefitMeterCreditCreateProperties:
properties:
units:
type: integer
maximum: 2147483647
exclusiveMinimum: 0
title: Units
rollover:
type: boolean
title: Rollover
meter_id:
type: string
format: uuid4
title: Meter Id
type: object
required:
- units
- rollover
- meter_id
title: BenefitMeterCreditCreateProperties
description: Properties for creating a benefit of type `meter_unit`.
MetadataOutputType:
additionalProperties:
anyOf:
- type: string
- type: integer
- type: number
- type: boolean
type: object
BenefitCustomProperties:
properties:
note:
anyOf:
- anyOf:
- type: string
- type: 'null'
description: >-
Private note to be shared with customers who have this benefit
granted.
- type: 'null'
title: Note
type: object
required:
- note
title: BenefitCustomProperties
description: Properties for a benefit of type `custom`.
BenefitDiscordProperties:
properties:
guild_id:
type: string
title: Guild Id
description: The ID of the Discord server.
role_id:
type: string
title: Role Id
description: The ID of the Discord role to grant.
kick_member:
type: boolean
title: Kick Member
description: Whether to kick the member from the Discord server on revocation.
guild_token:
type: string
title: Guild Token
type: object
required:
- guild_id
- role_id
- kick_member
- guild_token
title: BenefitDiscordProperties
description: Properties for a benefit of type `discord`.
BenefitGitHubRepositoryProperties:
properties:
repository_owner:
type: string
title: Repository Owner
description: The owner of the repository.
examples:
- polarsource
repository_name:
type: string
title: Repository Name
description: The name of the repository.
examples:
- private_repo
permission:
type: string
enum:
- pull
- triage
- push
- maintain
- admin
title: Permission
description: >-
The permission level to grant. Read more about roles and their
permissions on [GitHub
documentation](https://docs.github.com/en/organizations/managing-user-access-to-your-organizations-repositories/managing-repository-roles/repository-roles-for-an-organization#permissions-for-each-role).
type: object
required:
- repository_owner
- repository_name
- permission
title: BenefitGitHubRepositoryProperties
description: Properties for a benefit of type `github_repository`.
BenefitDownloadablesProperties:
properties:
archived:
additionalProperties:
type: boolean
propertyNames:
format: uuid4
type: object
title: Archived
files:
items:
type: string
format: uuid4
type: array
title: Files
type: object
required:
- archived
- files
title: BenefitDownloadablesProperties
BenefitLicenseKeysProperties:
properties:
prefix:
anyOf:
- type: string
- type: 'null'
title: Prefix
expires:
anyOf:
- $ref: '#/components/schemas/BenefitLicenseKeyExpirationProperties'
- type: 'null'
activations:
anyOf:
- $ref: '#/components/schemas/BenefitLicenseKeyActivationProperties'
- type: 'null'
limit_usage:
anyOf:
- type: integer
- type: 'null'
title: Limit Usage
type: object
required:
- prefix
- expires
- activations
- limit_usage
title: BenefitLicenseKeysProperties
BenefitMeterCreditProperties:
properties:
units:
type: integer
title: Units
rollover:
type: boolean
title: Rollover
meter_id:
type: string
format: uuid4
title: Meter Id
type: object
required:
- units
- rollover
- meter_id
title: BenefitMeterCreditProperties
description: Properties for a benefit of type `meter_unit`.
BenefitLicenseKeyExpirationProperties:
properties:
ttl:
type: integer
exclusiveMinimum: 0
title: Ttl
timeframe:
type: string
enum:
- year
- month
- day
title: Timeframe
type: object
required:
- ttl
- timeframe
title: BenefitLicenseKeyExpirationProperties
BenefitLicenseKeyActivationCreateProperties:
properties:
limit:
type: integer
maximum: 50
exclusiveMinimum: 0
title: Limit
enable_customer_admin:
type: boolean
title: Enable Customer Admin
type: object
required:
- limit
- enable_customer_admin
title: BenefitLicenseKeyActivationCreateProperties
BenefitLicenseKeyActivationProperties:
properties:
limit:
type: integer
title: Limit
enable_customer_admin:
type: boolean
title: Enable Customer Admin
type: object
required:
- limit
- enable_customer_admin
title: BenefitLicenseKeyActivationProperties
securitySchemes:
access_token:
type: http
scheme: bearer
description: >-
You can generate an **Organization Access Token** from your
organization's settings.
````
---
# Source: https://polar.sh/docs/features/usage-based-billing/credits.md
# Source: https://polar.sh/docs/features/benefits/credits.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Credits Benefit
> Create your own Credits benefit
The Credits benefit allows you to credit a customer's Usage Meter balance.
## Crediting Usage Meter Balance
The Credits benefit will credit a customer's Usage Meter balance at different points in time depending on the type of product purchased.
### Subscription Products
The customer will be credited the amount of units specified in the benefit at the beginning of every subscription cycle period — monthly or yearly.
### One-Time Products
The customer will be credited the amount of units specified in the benefit once at the time of purchase.
## Rollover unused credits
You can choose to rollover unused credits to the next billing cycle. This means that if a customer doesn't use all of their credits in a given billing cycle, the remaining credits will be added to their balance for the next billing cycle. To enable this feature, check the "Rollover unused credits" checkbox when creating or editing the Credits benefit.
If you change the rollover setting for a benefit, it will only apply to new
credits issued after the change. Existing credits will not be affected.
---
# Source: https://polar.sh/docs/features/custom-fields.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Custom Fields
> Learn how to add custom input fields to your checkout with Polar
By default, the Checkout form will only ask basic information from the customer to fulfill the order: a name, an email address, billing information, etc. But you might need more! A few examples:
* A checkbox asking the customer to accept your terms
* An opt-in newsletter consent
* A select menu to ask where they heard from you
* ...
With Polar, you can easily add such fields to your checkout using **Custom Fields**.
## Create Custom Fields
Custom Fields are managed at an organization's level. To create them, go to **Settings** and **Custom Fields**. You'll see the list of all the available fields on your organization.
Click on **New Custom Field** to create a new one.
### Type
The type of the field is the most important thing to select. It determines what type of input will be displayed to the customer during checkout.
The type can't be changed after the field is created.
We support five types of fields:
#### Text
This will display a simple text field to input textual data. By default, it'll render a simple input field but you can render a **textarea** by toggling the option under `Form input options`.
Under `Validation constraints`, you can add minimum and maximum length validation.
Underneath, the data will be stored as a string.
#### Number
This will display a number input field. Under `Validation constraints`, you can add minimum and maximum validation.
Underneath, the data will be stored as a number.
#### Date
This will display a date input field. Under `Validation constraints`, you can add minimum and maximum validation.
Underneath, the data will be stored as a string using the ISO 8601 format.
#### Checkbox
This will display a checkbox field.
Underneath, the data will be stored as a boolean (`true` or `false`).
#### Select
This will display a select field with a predefined set of options. Each option is a pair of `Value` and `Label`, the first one being the value that'll be stored underneath and the latter the one that will be shown to the customer.
### Slug and name
The slug determines the key that'll be used to store the data inside objects related to the checkout, like Orders and Subscriptions. It must be unique across your organization. You can change it afterwards, we'll automatically update the data to reflect the new slug.
The name is what we'll be displayed to you to recognize the field across your dashboard. By default, it'll also be the label of the field displayed to the customer, unless you customize it under `Form input options`.
### Form input options
Those options allow you to customize how the field is displayed to the customer. You can set:
* The label, displayed above the field
* The help text, displayed below the field
* The placeholder, displayed inside the field when there is no value
The label and help text supports basic Markdown syntax, so you can add bold, italic or even links.
## Add Custom Field to Checkout
Custom Fields are enabled on Checkout specifically on each **product**. While [creating or updating](/features/products) a product, you can select the custom fields you want to include in the checkout for this product.
Note that you can make the field `Required`.
If you make a **checkbox** field **required**, customers will have to check
the box before submitting the checkout. Very useful for terms acceptance!
The fields are now added as part of the Checkout form for this product.
## Read data
Once you have added Custom Fields to your organization, they'll be automatically displayed as a column in your `Sales` page, both on Orders and Subscriptions. From there, you'll be able to see the data input by the customer.
This data is also available from the [Orders](/api-reference/orders/get) and [Subscriptions](/api-reference/subscriptions/get) API, under the `custom_field_data` property. Each value is referenced by the **slug** of the field.
```json theme={null}
{
// ...
"custom_field_value": {
"terms": true,
"source": "social_media"
}
}
```
---
# Source: https://polar.sh/docs/features/benefits/custom.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Custom Benefit
> Create your own Custom benefit
You can add a simple, custom benefit, which allows you to attach a note to paying customers.
## **Custom Notes**
Secret message only customers can see, e.g [Cal.com](http://Cal.com) link, private email for support etc.
For custom integrations you can also distinguish benefits granted to customers to offer even more bespoke user benefits.
---
# Source: https://polar.sh/docs/features/customer-management.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Customer Management
> Get insights on your customers and sales
## Managing Customers
Polar has a built in feature to view and manage your Customers.
Everyone who has ever purchased something from you will be recorded as a Customer to your Organization. You’re able to see past orders and their ongoing subscriptions, as well as some additional metrics.
## External ID
Quite often, you'll have our own users management system in your application, where your customer already have an ID. To ease reconciliation between Polar and your system, we have a dedicated [`external_id`](/api-reference/customers/get-external#response-external-id) field on Customers. It's unique across your organization and can't be changed once set.
We have dedicated API endpoints that work with the `external_id` field, so you don't even have to store the internal Polar ID in your system.
## Metadata
You may set additional metadata on Customers. This can be very useful to store additional data about your customer you want to be available through our API and webhooks.
It can be set through the dashboard or through the [API](/api-reference/customers/update#body-metadata). It can also be pre-set when creating a Checkout Session by using the [`customer_metadata`](/api-reference/checkouts/create-session#body-customer-metadata) field. This way, after a successful checkout, the metadata will automatically be set on the newly created Customer.
---
# Source: https://polar.sh/docs/features/customer-portal.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Customer Portal
> Enable customers to view & manage orders and subscriptions easily
The Customer Portal is a destination where your customers can see their orders and ongoing subscriptions. It’s also where they’re able to get hands on receipts, benefits, and more.
## Redirect to your Customer Portal
The customer portal is directly available from the URL `https://polar.sh/your-org-slug/portal`. Your customers will be able to authenticate there by entering the email they used to purchase or subscribe to your products.
Customer Portal Sign In
## Creating an authenticated Customer Portal Link
You can provide a pre-authenticated Customer Portal Link to your customers. This is handy if you want to redirect them directly from your application.
Using the Polar API, all you need is to call the `customerSessions` endpoint. Here’s an example using our TypeScript SDK.
```typescript theme={null}
import { Polar } from "@polar-sh/sdk";
const polar = new Polar({
accessToken: process.env["POLAR_ACCESS_TOKEN"] ?? "",
});
async function run() {
const result = await polar.customerSessions.create({
customerId: "",
});
redirect(result.customerPortalUrl)
}
run();
```
Or, if you use Next.js as your framework, we have a handy utility which shortens down your code significantly.
```typescript theme={null}
// app/portal/route.ts
import { CustomerPortal } from "@polar-sh/nextjs";
export const GET = CustomerPortal({
accessToken: process.env.POLAR_ACCESS_TOKEN,
getCustomerId: async (req) => '',
server: 'sandbox' // Use sandbox if you're testing Polar - pass 'production' otherwise
});
```
---
# Source: https://polar.sh/docs/integrate/customer-state.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Customer State
> The quickest way to integrate billing in your application
Customer State is a concept allowing you to query for the current state of a customer, including their active subscriptions and granted [benefits](/features/benefits/introduction), in a single [API call](/api-reference/customers/state-external) or single [webhook event](/api-reference/webhooks/customer.state_changed).
Combined with the [External ID](/features/customer-management#external-id) feature, you can get up-and-running in minutes.
## The customer state object
The customer state object contains:
* All the data about the customer.
* The list of their **active** subscriptions.
* The list of their **granted** benefits.
* The list of their **active** meters, with their current balance.
Thus, with that single object, you have all the required information to check if you should provision access to your service or not.
One endpoint to rule them all, using your own customer ID.
The same one, but with internal Polar customer ID.
## The `customer.state_changed` webhook
To be notified of the customer state changes, you can listen to the `customer.state_changed` webhook event. It's triggered when:
* Customer is created, updated or deleted.
* A subscription is created or updated.
* A benefit is granted or revoked.
By subscribing to this webhook event, you keep your system up-to-date and update your customer's access accordingly.
One webhook to rule them all.
---
# Source: https://polar.sh/docs/api-reference/webhooks/customer.created.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# customer.created
---
# Source: https://polar.sh/docs/api-reference/webhooks/customer.deleted.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# customer.deleted
---
# Source: https://polar.sh/docs/api-reference/webhooks/customer.state_changed.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# customer.state_changed
---
# Source: https://polar.sh/docs/api-reference/webhooks/customer.updated.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# customer.updated
---
# Source: https://polar.sh/docs/api-reference/webhooks/customer_seat.assigned.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# customer_seat.assigned
---
# Source: https://polar.sh/docs/api-reference/webhooks/customer_seat.claimed.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# customer_seat.claimed
---
# Source: https://polar.sh/docs/api-reference/webhooks/customer_seat.revoked.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# customer_seat.revoked
---
# Source: https://polar.sh/docs/guides/customize-benefits-order-in-checkouts.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# How to Customize Benefits Order in Checkouts
> Learn how to customize the order in which Benefits appear in checkouts.
## Create a Product with Benefits
* [Create a Custom Benefit](https://polar.sh/docs/guides/automate-post-purchase-link-sharing#create-a-custom-benefit)
* [Create a File Downloads Benefit](https://polar.sh/docs/features/benefits/file-downloads#create-downloadable-benefit)
[Create a Product](https://polar.sh/docs/features/products#create-a-product) that includes the two **Benefits** created above.
Instead of creating the Benefits beforehand, you can also create them while creating the product by clicking the `Create New` button under the desired Benefit Type in the Automated Benefits section of the product configuration.
[Create a Checkout Link](https://polar.sh/docs/features/checkout/links#create-a-checkout-link) for the product.
The checkout session looks like below. The Custom Benefit named **Product Link** appears first, followed by the File Downloads Benefit named **Product File**.
## Reorder Benefits
In the Polar dashboard sidebar, navigate to **Products** > **Catalogue** for your organization. You can also go directly to `https://polar.sh/dashboard/${org_slug}/products`.
Choose the product whose Benefits you want to reorder, click on it and scroll down to the **Automated Benefits** section.
Click the `Reorder` button to change the order of benefits.
Drag the Benefits up or down to change their order as desired.
Open the product checkout page. The benefits have been reordered successfully.
You can also Reorder the Benefits while creating the Product itself by clicking on `Reorder` button in Automated Benefits section.
---
# Source: https://polar.sh/docs/guides/customize-products-order-in-checkouts.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# How to Customize Products Order in Checkouts
> Learn how to customize the order in which products appear in checkouts.
Currently, customizing the products order in checkout is only supported via the APIs.
## Create Organization Access Token and Product IDs
Create a new organization token by following our [Organization Access Tokens](https://polar.sh/docs/integrate/oat) guide.
After creating your access token, you will be able to view it. Please copy and save your access token.
In the Polar dashboard sidebar, navigate to **Products** > **Catalogue** for your organization.
You can also go directly to `https://polar.sh/dashboard/${org_slug}/products`.
Retrieve the Product IDs for the items you wish to include in checkout by clicking on the **⋮ (More options) menu** next to chosen products and selecting **Copy Product ID**.\
These IDs will be required in the next step to create a checkout.
## Reordering Products In Checkout Links API
Open your terminal and paste the following curl command to make an API call for creating a checkout link.
Be sure to replace:
* \ with your actual access token.
Make sure your token has the **`checkout_links:write`** scope enabled to use [Create Checkout Link API](/api-reference/checkout-links/create).
* \, \, etc., with the product IDs in the order you want them to appear in the checkout.
```bash Terminal theme={null}
curl --request POST \
--url https://api.polar.sh/v1/checkout-links/ \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"products": [
"",
""
]
}'
```
Find all the available parameters along with the description in the [Create Checkout Link API](https://polar.sh/docs/api-reference/checkout-links/create).
The curl command returns a JSON. Access the checkout link URL from the "url" key of the JSON and open it.
```json theme={null}
{
"...": "...",
"...": "...",
"url": "https://buy.polar.sh/polar_cl_..." // [!code ++]
}
```
It looks like below:
If you want to change the order and make Product 2 appear before Product 1, place Product 2's ID first, followed by Product 1's ID in the API call.
```bash Terminal theme={null}
curl --request POST \
--url https://api.polar.sh/v1/checkouts/ \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"products": [
"",
""
]
}'
```
The checkout looks like below:
## Reordering Products In Checkout Session API
Open your terminal and paste the following curl command to make an API call for creating a checkout session.
Be sure to replace:
* \ with your actual access token.
Make sure your token has the **`checkouts:write`** scope enabled to use [Create Checkout Session API](/api-reference/checkouts/create-session).
* \, \, etc., with the product IDs in the order you want them to appear in the checkout.
```bash Terminal theme={null}
curl --request POST \
--url https://api.polar.sh/v1/checkouts/ \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"products": [
"",
""
]
}'
```
Find all the available parameters along with the description in the [Create Checkout Session API](https://polar.sh/docs/api-reference/checkouts/create-session).
The curl command returns a JSON. Access the checkout session URL from the "url" key of the JSON and open it.
```json theme={null}
{
"...": "...",
"url": "https://buy.polar.sh/polar_c_...", // [!code ++]
"...": "..."
}
```
It looks like below:
If you want to change the order and make Product 2 appear before Product 1, place Product 2's ID first, followed by Product 1's ID in the API call.
```bash Terminal theme={null}
curl --request POST \
--url https://api.polar.sh/v1/checkouts/ \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"products": [
"",
""
]
}'
```
The checkout looks like below:
---
# Source: https://polar.sh/docs/api-reference/license-keys/deactivate.md
# Source: https://polar.sh/docs/api-reference/customer-portal/license-keys/deactivate.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Deactivate License Key
> Deactivate a license key instance.
> This endpoint doesn't require authentication and can be safely used on a public
> client, like a desktop application or a mobile app.
> If you plan to validate a license key on a server, use the `/v1/license-keys/deactivate`
> endpoint instead.
## OpenAPI
````yaml post /v1/customer-portal/license-keys/deactivate
openapi: 3.1.0
info:
title: Polar API
summary: Polar HTTP and Webhooks API
description: Read the docs at https://polar.sh/docs/api-reference
version: 0.1.0
servers:
- url: https://api.polar.sh
description: Production environment
x-speakeasy-server-id: production
- url: https://sandbox-api.polar.sh
description: Sandbox environment
x-speakeasy-server-id: sandbox
security:
- access_token: []
tags:
- name: public
description: >-
Endpoints shown and documented in the Polar API documentation and
available in our SDKs.
- name: private
description: >-
Endpoints that should appear in the schema only in development to generate
our internal JS SDK.
- name: mcp
description: Endpoints enabled in the MCP server.
paths:
/v1/customer-portal/license-keys/deactivate:
post:
tags:
- customer_portal
- license_keys
- public
summary: Deactivate License Key
description: >-
Deactivate a license key instance.
> This endpoint doesn't require authentication and can be safely used on
a public
> client, like a desktop application or a mobile app.
> If you plan to validate a license key on a server, use the
`/v1/license-keys/deactivate`
> endpoint instead.
operationId: customer_portal:license_keys:deactivate
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/LicenseKeyDeactivate'
required: true
responses:
'204':
description: License key activation deactivated.
'404':
description: License key not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ResourceNotFound'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
security:
- {}
components:
schemas:
LicenseKeyDeactivate:
properties:
key:
type: string
title: Key
organization_id:
type: string
format: uuid4
title: Organization Id
activation_id:
type: string
format: uuid4
title: Activation Id
type: object
required:
- key
- organization_id
- activation_id
title: LicenseKeyDeactivate
ResourceNotFound:
properties:
error:
type: string
const: ResourceNotFound
title: Error
examples:
- ResourceNotFound
detail:
type: string
title: Detail
type: object
required:
- error
- detail
title: ResourceNotFound
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
type: object
title: HTTPValidationError
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
msg:
type: string
title: Message
type:
type: string
title: Error Type
type: object
required:
- loc
- msg
- type
title: ValidationError
securitySchemes:
access_token:
type: http
scheme: bearer
description: >-
You can generate an **Organization Access Token** from your
organization's settings.
````
---
# Source: https://polar.sh/docs/api-reference/customers/delete-external.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Delete Customer by External ID
> Delete a customer by external ID.
Immediately cancels any active subscriptions and revokes any active benefits.
Set `anonymize=true` to also anonymize PII for GDPR compliance.
**Scopes**: `customers:write`
## OpenAPI
````yaml delete /v1/customers/external/{external_id}
openapi: 3.1.0
info:
title: Polar API
summary: Polar HTTP and Webhooks API
description: Read the docs at https://polar.sh/docs/api-reference
version: 0.1.0
servers:
- url: https://api.polar.sh
description: Production environment
x-speakeasy-server-id: production
- url: https://sandbox-api.polar.sh
description: Sandbox environment
x-speakeasy-server-id: sandbox
security:
- access_token: []
tags:
- name: public
description: >-
Endpoints shown and documented in the Polar API documentation and
available in our SDKs.
- name: private
description: >-
Endpoints that should appear in the schema only in development to generate
our internal JS SDK.
- name: mcp
description: Endpoints enabled in the MCP server.
paths:
/v1/customers/external/{external_id}:
delete:
tags:
- customers
- public
- mcp
summary: Delete Customer by External ID
description: >-
Delete a customer by external ID.
Immediately cancels any active subscriptions and revokes any active
benefits.
Set `anonymize=true` to also anonymize PII for GDPR compliance.
**Scopes**: `customers:write`
operationId: customers:delete_external
parameters:
- name: external_id
in: path
required: true
schema:
type: string
description: The customer external ID.
title: External Id
description: The customer external ID.
- name: anonymize
in: query
required: false
schema:
type: boolean
description: >-
If true, also anonymize the customer's personal data for GDPR
compliance.
default: false
title: Anonymize
description: >-
If true, also anonymize the customer's personal data for GDPR
compliance.
responses:
'204':
description: Customer deleted.
'404':
description: Customer not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ResourceNotFound'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
components:
schemas:
ResourceNotFound:
properties:
error:
type: string
const: ResourceNotFound
title: Error
examples:
- ResourceNotFound
detail:
type: string
title: Detail
type: object
required:
- error
- detail
title: ResourceNotFound
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
type: object
title: HTTPValidationError
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
msg:
type: string
title: Message
type:
type: string
title: Error Type
type: object
required:
- loc
- msg
- type
title: ValidationError
securitySchemes:
access_token:
type: http
scheme: bearer
description: >-
You can generate an **Organization Access Token** from your
organization's settings.
````
---
# Source: https://polar.sh/docs/api-reference/webhooks/endpoints/delete.md
# Source: https://polar.sh/docs/api-reference/files/delete.md
# Source: https://polar.sh/docs/api-reference/discounts/delete.md
# Source: https://polar.sh/docs/api-reference/customers/delete.md
# Source: https://polar.sh/docs/api-reference/custom-fields/delete.md
# Source: https://polar.sh/docs/api-reference/checkout-links/delete.md
# Source: https://polar.sh/docs/api-reference/benefits/delete.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Delete Benefit
> Delete a benefit.
> [!WARNING]
> Every grants associated with the benefit will be revoked.
> Users will lose access to the benefit.
**Scopes**: `benefits:write`
## OpenAPI
````yaml delete /v1/benefits/{id}
openapi: 3.1.0
info:
title: Polar API
summary: Polar HTTP and Webhooks API
description: Read the docs at https://polar.sh/docs/api-reference
version: 0.1.0
servers:
- url: https://api.polar.sh
description: Production environment
x-speakeasy-server-id: production
- url: https://sandbox-api.polar.sh
description: Sandbox environment
x-speakeasy-server-id: sandbox
security:
- access_token: []
tags:
- name: public
description: >-
Endpoints shown and documented in the Polar API documentation and
available in our SDKs.
- name: private
description: >-
Endpoints that should appear in the schema only in development to generate
our internal JS SDK.
- name: mcp
description: Endpoints enabled in the MCP server.
paths:
/v1/benefits/{id}:
delete:
tags:
- benefits
- public
summary: Delete Benefit
description: |-
Delete a benefit.
> [!WARNING]
> Every grants associated with the benefit will be revoked.
> Users will lose access to the benefit.
**Scopes**: `benefits:write`
operationId: benefits:delete
parameters:
- name: id
in: path
required: true
schema:
type: string
format: uuid4
description: The benefit ID.
x-polar-selector-widget:
resourceRoot: /v1/benefits
resourceName: Benefit
displayProperty: description
title: Id
responses:
'204':
description: Benefit deleted.
'403':
description: This benefit is not deletable.
content:
application/json:
schema:
$ref: '#/components/schemas/NotPermitted'
'404':
description: Benefit not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ResourceNotFound'
'422':
description: Validation Error
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
components:
schemas:
NotPermitted:
properties:
error:
type: string
const: NotPermitted
title: Error
examples:
- NotPermitted
detail:
type: string
title: Detail
type: object
required:
- error
- detail
title: NotPermitted
ResourceNotFound:
properties:
error:
type: string
const: ResourceNotFound
title: Error
examples:
- ResourceNotFound
detail:
type: string
title: Detail
type: object
required:
- error
- detail
title: ResourceNotFound
HTTPValidationError:
properties:
detail:
items:
$ref: '#/components/schemas/ValidationError'
type: array
title: Detail
type: object
title: HTTPValidationError
ValidationError:
properties:
loc:
items:
anyOf:
- type: string
- type: integer
type: array
title: Location
msg:
type: string
title: Message
type:
type: string
title: Error Type
type: object
required:
- loc
- msg
- type
title: ValidationError
securitySchemes:
access_token:
type: http
scheme: bearer
description: >-
You can generate an **Organization Access Token** from your
organization's settings.
````
---
# Source: https://polar.sh/docs/integrate/webhooks/delivery.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Handle & monitor webhook deliveries
> How to parse, validate and handle webhooks and monitor their deliveries on Polar
Once a webhook endpoint is setup you will have access to the delivery overview
page. Here you can:
* See historic deliveries
* Review payload sent
* Trigger redelivery in case of failure
Now, let's integrate our endpoint route to validate, parse & handle incoming webhooks.
## Validate & parse webhooks
You now need to setup a route handler for the endpoint registered on Polar to
receive, validate and parse webhooks before handling them according to your
needs.
### Using our SDKs
Our TypeScript & Python SDKs come with a built-in helper function to easily
validate and parse the webhook event - see full examples below.
```typescript icon="square-js" JS (Express) theme={null}
import express, { Request, Response } from 'express'
import { validateEvent, WebhookVerificationError } from '@polar-sh/sdk/webhooks'
const app = express()
app.post(
'/webhook',
express.raw({ type: 'application/json' }),
(req: Request, res: Response) => {
try {
const event = validateEvent(
req.body,
req.headers,
process.env['POLAR_WEBHOOK_SECRET'] ?? '',
)
// Process the event
res.status(202).send('')
} catch (error) {
if (error instanceof WebhookVerificationError) {
res.status(403).send('')
}
throw error
}
},
)
```
```python Python (Flask) theme={null}
import os
from flask import Flask, request
from polar_sdk.webhooks import validate_event, WebhookVerificationError
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def webhook():
try:
event = validate_event(
body=request.data,
headers=request.headers,
secret=os.getenv('POLAR_WEBHOOK_SECRET', ''),
)
# Process the event
return "", 202
except WebhookVerificationError as e:
return "", 403
```
Both examples above expect an environment variable named `POLAR_WEBHOOK_SECRET`
to be set to the secret you configured during the endpoint setup.
### Custom validation
We follow the [Standard Webhooks](https://www.standardwebhooks.com/)
standard which offers [many libraries across languages](https://github.com/standard-webhooks/standard-webhooks/tree/main/libraries) to
easily validate signatures. Or you can follow their
[specification](https://github.com/standard-webhooks/standard-webhooks/blob/main/spec/standard-webhooks.md)
in case you want to roll your own.
**Note: Secret needs to be base64 encoded**
One common gotcha with the specification is that the webhook secret is expected to be
base64 encoded. You don't have to do this with our SDK as it takes care of the
implementation details with better developer ergonomics.
## IP Allowlist
If you are using a firewall or a reverse proxy that requires IP allowlisting, here are the IPs range you need to allow:
**New IP ranges**
Starting **October 27th, 2025**, new IP ranges will be added:
```
74.220.50.0/24
74.220.58.0/24
```
```txt Production theme={null}
3.134.238.10
3.129.111.220
52.15.118.168
74.220.50.0/24
74.220.58.0/24
```
```txt Sandbox theme={null}
3.134.238.10
3.129.111.220
52.15.118.168
74.220.50.0/24
74.220.58.0/24
```
## Failure Handling
### Delivery Retries
If we hit an error while trying to reach your endpoint, whether it is a temporary network error or a bug, we'll retry to send the event up to **10 times** with an exponential backoff.
### Delivery Timeouts
We currently timeout our requests to your endpoint after **10 seconds**, triggering a
retry attempt after a delay as explained above. However, we strongly recommend you optimize your endpoint route to respond within **2 seconds** to ensure reliable delivery. We may lower the timeout threshold in the future, so we advise implementing your webhook handler to queue a background worker task to handle the
payload asynchronously.
### Endpoint Disabling
Webhook endpoints are automatically disabled after **10 consecutive failed deliveries** (non-2xx responses). When this happens:
* The endpoint is marked as disabled and will no longer receive new events.
* Admin of the organization will receive an email notification.
To re-enable a disabled endpoint, go to your organization's webhook settings in the dashboard and manually enable it. Before re-enabling, ensure your endpoint is properly configured and reachable to avoid repeated disabling.
## Troubleshooting
### Not receiving webhooks
Seeing deliveries on Polar, but not receiving them on your end? Below are some
common techniques to resolve the issue depending on the reported error status.
**General**
*Start ngrok or similar*
Make sure you have started `ngrok` or whatever tunneling service you're using
during local development.
*Add excessive logging*
E.g
`console.log('webhook.handler_called')`,
`console.log('webhook.validate_signature')`,
`console.log('webhook.signature_validated')` etc.
So you can easily confirm if the handler is called and how far it gets before
any issues arise.
`HTTP 404`
* Try `curl -vvv -X POST ` in your terminal to confirm the
route exists and see any issues along the way
* Try adding trailing `/` to the URL on Polar. Often `/foo` is resolved to
`/foo/` by frameworks.
`HTTP 3xx`
Redirect responses (301, 302, 307, etc.) are treated as failures. Polar does not follow redirects for webhook deliveries. Update your webhook URL to the final destination URL to avoid redirects.
A common cause is hosting providers like Vercel that redirect between `www` and non-`www` domains. Make sure your configured URL matches your actual domain.
`HTTP 403`
* Using middleware for authorization? Make sure to exclude the webhook route
from it since it needs to be publicly accessible
* Using Cloudflare?
* Check the firewall logs to verify if they are blocking our requests and setup a custom WAF rule to accept incoming requests from Polar.
* Webhook delivery failures with 403 errors can occur when Cloudflare's Bot Fight Mode is enabled. Bot Fight Mode automatically blocks requests it identifies as bots, including legitimate webhook requests from Polar. Adding Polar's IP addresses to your IP Allow List or creating custom WAF rules will not resolve this issue. To fix webhook delivery problems, disable Bot Fight Mode in your Cloudflare dashboard under Security > Bots. Alternatively, you can check your Cloudflare firewall logs to confirm if requests are being blocked and create appropriate firewall rules if needed.
### Invalid signature exceptions
Rolling your own webhook validation logic? Make sure to base64 encode the secret
you configured on Polar in your code before generating the signature to validate
against.
---
# Source: https://polar.sh/docs/features/usage-based-billing/ingestion-strategies/delta-time-strategy.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Delta Time Strategy
> Ingest delta time of arbitrary execution
## Javascript SDK
Ingest delta time of arbitrary execution. Bring your own now-resolver.
```
pnpm add @polar-sh/ingestion
```
```typescript theme={null}
import { Ingestion } from "@polar-sh/ingestion";
import { DeltaTimeStrategy } from "@polar-sh/ingestion/strategies/DeltaTime";
const nowResolver = () => performance.now();
// const nowResolver = () => Number(hrtime.bigint())
// const nowResolver = () => Date.now()
// Setup the Delta Time Ingestion Strategy
const deltaTimeIngestion = Ingestion({
accessToken: process.env.POLAR_ACCESS_TOKEN,
})
.strategy(new DeltaTimeStrategy(nowResolver))
.ingest("execution-time");
export async function GET(request: Request) {
try {
// Get the wrapped start clock function
// Pass Customer Id to properly annotate the ingestion events with a specific customer
const start = deltaTimeIngestion.client({
customerId: request.headers.get("X-Polar-Customer-Id") ?? "",
});
const stop = start();
await sleep(1000);
// { deltaTime: xxx } is automatically ingested to Polar
const delta = stop();
return Response.json({ delta });
} catch (error) {
return Response.json({ error: error.message });
}
}
```
#### Ingestion Payload
```json theme={null}
{
"customerId": "123",
"name": "execution-time",
"metadata": {
"deltaTime": 1000
}
}
```
---
# Source: https://polar.sh/docs/integrate/sdk/adapters/deno.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Deno
> Payments and Checkouts made dead simple with Deno
## Examples
* [With Deno](https://github.com/polarsource/examples/tree/main/with-deno)
## Checkout
Create a Checkout handler which takes care of redirections.
```typescript icon="square-js" theme={null}
import { Checkout } from "jsr:@polar-sh/deno";
Deno.serve(
Checkout({
accessToken: "xxx",
returnUrl: "https://myapp.com", // An optional URL which renders a back-button in the Checkout
theme: "dark", // Enforces the theme - System-preferred theme will be set if left omitted
})
);
```
### Query Params
Pass query params to this route.
* products `?products=123`
* customerId (optional) `?products=123&customerId=xxx`
* customerExternalId (optional) `?products=123&customerExternalId=xxx`
* customerEmail (optional) `?products=123&customerEmail=janedoe@gmail.com`
* customerName (optional) `?products=123&customerName=Jane`
* metadata (optional) `URL-Encoded JSON string`
## Customer Portal
Create a customer portal where your customer can view orders and subscriptions.
```typescript icon="square-js" theme={null}
import { CustomerPortal } from "jsr:@polar-sh/deno";
Deno.serve(
CustomerPortal({
accessToken: "xxx",
getCustomerId: (req) => "",
returnUrl: "https://myapp.com", // An optional URL which renders a back-button in the Customer Portal
server: "sandbox",
})
);
```
## Webhooks
A simple utility which resolves incoming webhook payloads by signing the webhook secret properly.
```typescript icon="square-js" theme={null}
import { Webhooks } from "jsr:@polar-sh/deno";
Deno.serve(
Webhooks({
webhookSecret: Deno.env.get('POLAR_WEBHOOK_SECRET'),
onPayload: async (payload) => /** Handle payload */,
})
);
```
### Payload Handlers
The Webhook handler also supports granular handlers for easy integration.
* `onPayload` - Catch-all handler for any incoming Webhook event
* `onCheckoutCreated` - Triggered when a checkout is created
* `onCheckoutUpdated` - Triggered when a checkout is updated
* `onOrderCreated` - Triggered when an order is created
* `onOrderPaid` - Triggered when an order is paid
* `onOrderRefunded` - Triggered when an order is refunded
* `onRefundCreated` - Triggered when a refund is created
* `onRefundUpdated` - Triggered when a refund is updated
* `onSubscriptionCreated` - Triggered when a subscription is created
* `onSubscriptionUpdated` - Triggered when a subscription is updated
* `onSubscriptionActive` - Triggered when a subscription becomes active
* `onSubscriptionCanceled` - Triggered when a subscription is canceled
* `onSubscriptionRevoked` - Triggered when a subscription is revoked
* `onSubscriptionUncanceled` - Triggered when a subscription cancellation is reversed
* `onProductCreated` - Triggered when a product is created
* `onProductUpdated` - Triggered when a product is updated
* `onOrganizationUpdated` - Triggered when an organization is updated
* `onBenefitCreated` - Triggered when a benefit is created
* `onBenefitUpdated` - Triggered when a benefit is updated
* `onBenefitGrantCreated` - Triggered when a benefit grant is created
* `onBenefitGrantUpdated` - Triggered when a benefit grant is updated
* `onBenefitGrantRevoked` - Triggered when a benefit grant is revoked
* `onCustomerCreated` - Triggered when a customer is created
* `onCustomerUpdated` - Triggered when a customer is updated
* `onCustomerDeleted` - Triggered when a customer is deleted
* `onCustomerStateChanged` - Triggered when a customer state changes
---
# Source: https://polar.sh/docs/guides/disable-email-editing-in-checkout.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# How to disable email editing in checkout
> Learn how to prevent customers from editing their email address during checkout by linking to existing customers.
When you want to prevent customers from changing their email address during the checkout process, you can link the checkout session to an existing customer. This is useful when customers are already authenticated in your application and you want to ensure the purchase is associated with their verified account.
## Overview
By passing either `customer_id` or `external_customer_id` when creating a checkout session, Polar will:
* Pre-fill the customer's information in the checkout form
* **Disable the email field** so it cannot be edited
* Link the resulting order to the specified customer
## Using Customer ID
If you've already created a customer in Polar and have their Polar customer ID, you can use it directly.
Retrieve the customer ID from your Polar dashboard or through the [Customers API](/api-reference/customers/list).
The customer ID is a UUID format like: `992fae2a-2a17-4b7a-8d9e-e287cf90131b`
Pass the `customer_id` parameter when creating the checkout session.
```ts TypeScript theme={null}
import { Polar } from "@polar-sh/sdk";
const polar = new Polar({ accessToken: process.env["POLAR_ACCESS_TOKEN"] });
const checkout = await polar.checkouts.create({
products: [""],
customerId: "992fae2a-2a17-4b7a-8d9e-e287cf90131b", // [!code ++]
});
console.log(checkout.url);
```
```py Python theme={null}
from polar_sdk import Polar
with Polar(
access_token="",
) as polar:
checkout = polar.checkouts.create(request={
"products": [""],
"customer_id": "992fae2a-2a17-4b7a-8d9e-e287cf90131b", # [!code ++]
})
print(checkout.url)
```
```bash cURL theme={null}
curl --request POST \
--url https://api.polar.sh/v1/checkouts/ \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"products": [""],
"customer_id": "992fae2a-2a17-4b7a-8d9e-e287cf90131b"
}'
```
Redirect your customer to the checkout URL returned in the response. The email field will be pre-filled and disabled for editing.
## Using External Customer ID
If you have your own user management system, you can use your internal customer ID. This is the recommended approach as it makes reconciliation between your system and Polar easier.
When creating a checkout session, pass your application's user ID as the `external_customer_id`.
Polar will:
* Look for an existing customer with this external ID
* If found, link to that customer and pre-fill their data
```ts TypeScript theme={null}
import { Polar } from "@polar-sh/sdk";
const polar = new Polar({ accessToken: process.env["POLAR_ACCESS_TOKEN"] });
const checkout = await polar.checkouts.create({
products: [""],
externalCustomerId: "user_12345", // Your application's user ID // [!code ++]
});
console.log(checkout.url);
```
```py Python theme={null}
from polar_sdk import Polar
with Polar(
access_token="",
) as polar:
checkout = polar.checkouts.create(request={
"products": [""],
"external_customer_id": "user_12345", # Your application's user ID # [!code ++]
})
print(checkout.url)
```
```bash cURL theme={null}
curl --request POST \
--url https://api.polar.sh/v1/checkouts/ \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"products": [""],
"external_customer_id": "user_12345"
}'
```
Redirect your customer to the checkout URL. The email field will be disabled from editing.
---
# Source: https://polar.sh/docs/guides/disable-subscription-changes-in-customer-portal.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# How to disable subscription upgrades/downgrades in customer portal
> Learn how to disable the option for customers to upgrade or downgrade subscription plans from the customer portal.
In the Polar dashboard sidebar, click on **Settings**.
You can also go directly to:\
`https://polar.sh/dashboard/${org_slug}/settings`\
Scroll down to **Subscriptions** section.
**Toggle OFF** Allow price changes to prevent customers from upgrading or downgrading their subscriptions from the customer portal.
Click **Save** in the **Subscriptions** section to save the changed settings.
---
# Source: https://polar.sh/docs/features/benefits/discord-access.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Automate Discord Invites & Roles
> Sell Discord access & roles with ease
Automating Discord server invites and roles for customers or subscribers is super easy and powerful with Polar.
* Fully automated Discord server invitations
* You can even setup multiple Discord servers, or...
* Offer different roles for different subscription tiers or products
## Create Discord Benefit
Click on `Connect your Discord server`. You'll be redirected to Discord where you can grant the Polar App for your desired server.
Next, you'll be prompted to approve the permissions our app requires to function. It needs all of them.
### **Manage Roles**
Access to your Discord roles. You'll be able to select which ones to grant to your customers later.
### **Kick Members**
Ability to kick members who have this benefit and connected Discord with Polar.
### **Create Invite**
Ability to invite members who purchase a product or subscribes to a tier with this benefit.
You're now redirected back to Polar and can finish setting up the Discord benefit on our end.
### **Connected Discord server**
The Discord server you connected cannot be changed. However, you can create multiple benefits and connect more Discord servers if you want.
### **Granted role**
Which Discord role do you want to grant as part of this benefit?
## Adding Benefit to Product
Head over to the product you want to associate this new Discord benefit with. You should be able to toggle the benefit in the bottom of the Edit Product form.
---
# Source: https://polar.sh/docs/features/discounts.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Discounts
> Create discounts on products and subscriptions
Discounts are a way to reduce the price of a product or subscription. They can be applied to one-time purchasable products or subscriptions.
## Create a discount
Go to the **Products** page and click on the **Discounts** tab.
#### Name
Displayed to the customer when they apply the discount.
#### Code
Optional code (case insensitive) that the customer can use to apply the discount. If left empty, the discount can only be applied through a Checkout Link or the API.
#### Percentage Discount
The percentage discount to apply to the product or subscription.
#### Fixed Amount Discount
The discount deducts a fixed amount from the price of the product or subscription.
#### Recurring Discount
The percentage discount to apply to the product or subscription.
* **Once** The discount is applied once.
* **Several Months** The discount is applied for a fixed number of months.
* **Forever** The discount is applied indefinitely.
#### Restrictions
* **Products** The discount can only be applied to specific products. By default the discount can be applied to all products, also ones created after the discount was created.
* **Starts at** The discount can only be applied after this date
* **Ends at** The discount can only be applied before this date
* **Maximum redemptions** The maximum number of times the discount can be applied.
## Apply a discount
Discounts can be applied to a Checkout Link or a Checkout Session.
---
# Source: https://polar.sh/docs/integrate/sdk/adapters/elysia.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Elysia
> Payments and Checkouts made dead simple with Elysia
## Examples
* [With Elysia](https://github.com/polarsource/examples/tree/main/with-elysia)
## Installation
Install the required Polar packages using the following command:
```bash Terminal theme={null}
npm install zod @polar-sh/elysia
```
```bash Terminal theme={null}
yarn add zod @polar-sh/elysia
```
```bash Terminal theme={null}
pnpm add zod @polar-sh/elysia
```
```bash Terminal theme={null}
bun add zod @polar-sh/elysia
```
### Checkout
Create a Checkout handler which takes care of redirections.
```typescript icon="square-js" theme={null}
import { Elysia } from "elysia";
import { Checkout } from "@polar-sh/elysia";
const app = new Elysia();
app.get(
"/checkout",
Checkout({
accessToken: "xxx", // Or set an environment variable to POLAR_ACCESS_TOKEN
successUrl: process.env.SUCCESS_URL,
returnUrl: "https://myapp.com", // An optional URL which renders a back-button in the Checkout
server: "sandbox", // Use sandbox if you're testing Polar - omit the parameter or pass 'production' otherwise
theme: "dark", // Enforces the theme - System-preferred theme will be set if left omitted
})
);
```
#### Query Params
Pass query params to this route.
* products `?products=123`
* customerId (optional) `?products=123&customerId=xxx`
* customerExternalId (optional) `?products=123&customerExternalId=xxx`
* customerEmail (optional) `?products=123&customerEmail=janedoe@gmail.com`
* customerName (optional) `?products=123&customerName=Jane`
* metadata (optional) `URL-Encoded JSON string`
### Customer Portal
Create a customer portal where your customer can view orders and subscriptions.
```typescript icon="square-js" theme={null}
import { Elysia } from "elysia";
import { CustomerPortal } from "@polar-sh/elysia";
const app = new Elysia();
app.get(
"/portal",
CustomerPortal({
accessToken: "xxx", // Or set an environment variable to POLAR_ACCESS_TOKEN
getCustomerId: (event) => "", // Function to resolve a Polar Customer ID
returnUrl: "https://myapp.com", // An optional URL which renders a back-button in the Customer Portal
server: "sandbox", // Use sandbox if you're testing Polar - omit the parameter or pass 'production' otherwise
})
);
```
### Webhooks
A simple utility which resolves incoming webhook payloads by signing the webhook secret properly.
```typescript icon="square-js" theme={null}
import { Elysia } from 'elysia'
import { Webhooks } from "@polar-sh/elysia";
const app = new Elysia()
app.post('/polar/webhooks', Webhooks({
webhookSecret: process.env.POLAR_WEBHOOK_SECRET!,
onPayload: async (payload) => /** Handle payload */,
}))
```
### Payload Handlers
The Webhook handler also supports granular handlers for easy integration.
* `onPayload` - Catch-all handler for any incoming Webhook event
* `onCheckoutCreated` - Triggered when a checkout is created
* `onCheckoutUpdated` - Triggered when a checkout is updated
* `onOrderCreated` - Triggered when an order is created
* `onOrderPaid` - Triggered when an order is paid
* `onOrderRefunded` - Triggered when an order is refunded
* `onRefundCreated` - Triggered when a refund is created
* `onRefundUpdated` - Triggered when a refund is updated
* `onSubscriptionCreated` - Triggered when a subscription is created
* `onSubscriptionUpdated` - Triggered when a subscription is updated
* `onSubscriptionActive` - Triggered when a subscription becomes active
* `onSubscriptionCanceled` - Triggered when a subscription is canceled
* `onSubscriptionRevoked` - Triggered when a subscription is revoked
* `onSubscriptionUncanceled` - Triggered when a subscription cancellation is reversed
* `onProductCreated` - Triggered when a product is created
* `onProductUpdated` - Triggered when a product is updated
* `onOrganizationUpdated` - Triggered when an organization is updated
* `onBenefitCreated` - Triggered when a benefit is created
* `onBenefitUpdated` - Triggered when a benefit is updated
* `onBenefitGrantCreated` - Triggered when a benefit grant is created
* `onBenefitGrantUpdated` - Triggered when a benefit grant is updated
* `onBenefitGrantRevoked` - Triggered when a benefit grant is revoked
* `onCustomerCreated` - Triggered when a customer is created
* `onCustomerUpdated` - Triggered when a customer is updated
* `onCustomerDeleted` - Triggered when a customer is deleted
* `onCustomerStateChanged` - Triggered when a customer state changes
---
# Source: https://polar.sh/docs/features/checkout/embed.md
> ## Documentation Index
> Fetch the complete documentation index at: https://polar.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.
# Embedded Checkout
> Embed our checkout directly on your site
You can either copy and paste our code snippet to get up and running in a second or use our JavaScript library for more advanced integrations. Our embedded checkout allows you to provide a seamless purchasing experience without redirecting users away from your site.
## Code Snippet
The code snippet can be used on any website or CMS that allows you to insert HTML.
First, create a [Checkout Link](/features/checkout/links) as described in the previous section. The code snippet can directly be copied from there by clicking on `Copy Embed Code`.
The snippet looks like this:
```typescript theme={null}
Purchase
```
This will display a `Purchase` link which will open an inline checkout when clicked.
You can style the trigger element any way you want, as long as you keep the `data-polar-checkout` attribute.
## Import Library
If you have a more advanced project in JavaScript, like a React app, adding the `