openapi: 3.0.1
info:
title: Polar API
description: >-
Polar is an open-source Merchant of Record (MoR) and monetization platform
for developers. This document models the core organization-facing REST
surface of the Polar API - products and prices, checkouts, customers,
subscriptions, orders, benefits and license keys, usage meters and events,
and webhooks. All requests are authenticated with a Bearer Organization
Access Token. The canonical, machine-generated specification is published by
Polar at https://api.polar.sh/openapi.json; this is a curated subset for the
API Evangelist catalog.
termsOfService: https://polar.sh/legal/terms
contact:
name: Polar Support
email: support@polar.sh
url: https://polar.sh/docs
license:
name: Apache-2.0
url: https://github.com/polarsource/polar/blob/main/LICENSE
version: '2026-04'
servers:
- url: https://api.polar.sh/v1
description: Production environment
- url: https://sandbox-api.polar.sh/v1
description: Sandbox environment
security:
- oat: []
tags:
- name: products
description: Product catalog and embedded pricing.
- name: checkouts
description: Hosted checkout sessions and reusable checkout links.
- name: customers
description: Customers, external IDs, and aggregated customer state.
- name: subscriptions
description: Recurring subscriptions.
- name: orders
description: Orders, invoices, and receipts.
- name: benefits
description: Benefits (entitlements) attached to products.
- name: license_keys
description: License key issuance, validation, and activation.
- name: meters
description: Usage meters aggregating ingested events.
- name: events
description: Usage event ingestion for metered billing.
- name: customer_portal
description: Customer-facing portal endpoints (Customer Session token).
- name: webhooks
description: Webhook endpoint management and deliveries.
paths:
/products/:
get:
operationId: products:list
tags:
- products
summary: List Products
parameters:
- name: organization_id
in: query
required: false
schema:
type: string
format: uuid
- name: is_archived
in: query
required: false
schema:
type: boolean
- name: page
in: query
required: false
schema:
type: integer
default: 1
- name: limit
in: query
required: false
schema:
type: integer
default: 10
responses:
'200':
description: A paginated list of products.
content:
application/json:
schema:
$ref: '#/components/schemas/ListResourceProduct'
post:
operationId: products:create
tags:
- products
summary: Create Product
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProductCreate'
responses:
'201':
description: The created product.
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
/products/{id}:
get:
operationId: products:get
tags:
- products
summary: Get Product
parameters:
- $ref: '#/components/parameters/IdPath'
responses:
'200':
description: The requested product.
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
patch:
operationId: products:update
tags:
- products
summary: Update Product
parameters:
- $ref: '#/components/parameters/IdPath'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProductUpdate'
responses:
'200':
description: The updated product.
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
/products/{id}/benefits:
post:
operationId: products:updateBenefits
tags:
- products
- benefits
summary: Update Product Benefits
parameters:
- $ref: '#/components/parameters/IdPath'
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- benefits
properties:
benefits:
type: array
items:
type: string
format: uuid
responses:
'200':
description: The updated product with attached benefits.
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
/checkouts/:
get:
operationId: checkouts:list
tags:
- checkouts
summary: List Checkout Sessions
responses:
'200':
description: A paginated list of checkout sessions.
content:
application/json:
schema:
$ref: '#/components/schemas/ListResourceCheckout'
post:
operationId: checkouts:create
tags:
- checkouts
summary: Create Checkout Session
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CheckoutCreate'
responses:
'201':
description: The created checkout session.
content:
application/json:
schema:
$ref: '#/components/schemas/Checkout'
/checkouts/{id}:
get:
operationId: checkouts:get
tags:
- checkouts
summary: Get Checkout Session
parameters:
- $ref: '#/components/parameters/IdPath'
responses:
'200':
description: The requested checkout session.
content:
application/json:
schema:
$ref: '#/components/schemas/Checkout'
/checkout-links/:
get:
operationId: checkoutLinks:list
tags:
- checkouts
summary: List Checkout Links
responses:
'200':
description: A paginated list of checkout links.
content:
application/json:
schema:
$ref: '#/components/schemas/ListResourceCheckout'
post:
operationId: checkoutLinks:create
tags:
- checkouts
summary: Create Checkout Link
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- products
properties:
products:
type: array
items:
type: string
format: uuid
success_url:
type: string
nullable: true
responses:
'201':
description: The created checkout link.
content:
application/json:
schema:
type: object
additionalProperties: true
/customers/:
get:
operationId: customers:list
tags:
- customers
summary: List Customers
responses:
'200':
description: A paginated list of customers.
content:
application/json:
schema:
$ref: '#/components/schemas/ListResourceCustomer'
post:
operationId: customers:create
tags:
- customers
summary: Create Customer
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CustomerCreate'
responses:
'201':
description: The created customer.
content:
application/json:
schema:
$ref: '#/components/schemas/Customer'
/customers/{id}:
get:
operationId: customers:get
tags:
- customers
summary: Get Customer
parameters:
- $ref: '#/components/parameters/IdPath'
responses:
'200':
description: The requested customer.
content:
application/json:
schema:
$ref: '#/components/schemas/Customer'
delete:
operationId: customers:delete
tags:
- customers
summary: Delete Customer
parameters:
- $ref: '#/components/parameters/IdPath'
responses:
'204':
description: The customer was deleted.
/customers/{id}/state:
get:
operationId: customers:getState
tags:
- customers
summary: Get Customer State
description: >-
Returns the aggregated state of a customer - active subscriptions,
granted benefits, and active meters - in a single response.
parameters:
- $ref: '#/components/parameters/IdPath'
responses:
'200':
description: The aggregated customer state.
content:
application/json:
schema:
type: object
additionalProperties: true
/subscriptions/:
get:
operationId: subscriptions:list
tags:
- subscriptions
summary: List Subscriptions
responses:
'200':
description: A paginated list of subscriptions.
content:
application/json:
schema:
$ref: '#/components/schemas/ListResourceSubscription'
/subscriptions/{id}:
get:
operationId: subscriptions:get
tags:
- subscriptions
summary: Get Subscription
parameters:
- $ref: '#/components/parameters/IdPath'
responses:
'200':
description: The requested subscription.
content:
application/json:
schema:
$ref: '#/components/schemas/Subscription'
patch:
operationId: subscriptions:update
tags:
- subscriptions
summary: Update Subscription
parameters:
- $ref: '#/components/parameters/IdPath'
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: true
responses:
'200':
description: The updated subscription.
content:
application/json:
schema:
$ref: '#/components/schemas/Subscription'
delete:
operationId: subscriptions:revoke
tags:
- subscriptions
summary: Revoke Subscription
parameters:
- $ref: '#/components/parameters/IdPath'
responses:
'200':
description: The revoked subscription.
content:
application/json:
schema:
$ref: '#/components/schemas/Subscription'
/orders/:
get:
operationId: orders:list
tags:
- orders
summary: List Orders
responses:
'200':
description: A paginated list of orders.
content:
application/json:
schema:
$ref: '#/components/schemas/ListResourceOrder'
/orders/{id}:
get:
operationId: orders:get
tags:
- orders
summary: Get Order
parameters:
- $ref: '#/components/parameters/IdPath'
responses:
'200':
description: The requested order.
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
/orders/{id}/invoice:
get:
operationId: orders:getInvoice
tags:
- orders
summary: Get Order Invoice
parameters:
- $ref: '#/components/parameters/IdPath'
responses:
'200':
description: The order invoice.
content:
application/json:
schema:
type: object
properties:
url:
type: string
/benefits/:
get:
operationId: benefits:list
tags:
- benefits
summary: List Benefits
responses:
'200':
description: A paginated list of benefits.
content:
application/json:
schema:
$ref: '#/components/schemas/ListResourceBenefit'
post:
operationId: benefits:create
tags:
- benefits
summary: Create Benefit
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BenefitCreate'
responses:
'201':
description: The created benefit.
content:
application/json:
schema:
$ref: '#/components/schemas/Benefit'
/benefits/{id}:
get:
operationId: benefits:get
tags:
- benefits
summary: Get Benefit
parameters:
- $ref: '#/components/parameters/IdPath'
responses:
'200':
description: The requested benefit.
content:
application/json:
schema:
$ref: '#/components/schemas/Benefit'
/license-keys/:
get:
operationId: licenseKeys:list
tags:
- license_keys
summary: List License Keys
responses:
'200':
description: A paginated list of license keys.
content:
application/json:
schema:
$ref: '#/components/schemas/ListResourceLicenseKey'
/license-keys/{id}:
get:
operationId: licenseKeys:get
tags:
- license_keys
summary: Get License Key
parameters:
- $ref: '#/components/parameters/IdPath'
responses:
'200':
description: The requested license key.
content:
application/json:
schema:
$ref: '#/components/schemas/LicenseKey'
/license-keys/validate:
post:
operationId: licenseKeys:validate
tags:
- license_keys
summary: Validate License Key
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- key
- organization_id
properties:
key:
type: string
organization_id:
type: string
format: uuid
benefit_id:
type: string
format: uuid
responses:
'200':
description: The validation result.
content:
application/json:
schema:
$ref: '#/components/schemas/LicenseKey'
/license-keys/activate:
post:
operationId: licenseKeys:activate
tags:
- license_keys
summary: Activate License Key
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- key
- organization_id
- label
properties:
key:
type: string
organization_id:
type: string
format: uuid
label:
type: string
responses:
'200':
description: The activation record.
content:
application/json:
schema:
type: object
additionalProperties: true
/meters/:
get:
operationId: meters:list
tags:
- meters
summary: List Meters
responses:
'200':
description: A paginated list of meters.
content:
application/json:
schema:
$ref: '#/components/schemas/ListResourceMeter'
post:
operationId: meters:create
tags:
- meters
summary: Create Meter
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/MeterCreate'
responses:
'201':
description: The created meter.
content:
application/json:
schema:
$ref: '#/components/schemas/Meter'
/meters/{id}:
get:
operationId: meters:get
tags:
- meters
summary: Get Meter
parameters:
- $ref: '#/components/parameters/IdPath'
responses:
'200':
description: The requested meter.
content:
application/json:
schema:
$ref: '#/components/schemas/Meter'
/events/:
get:
operationId: events:list
tags:
- events
summary: List Events
responses:
'200':
description: A paginated list of ingested events.
content:
application/json:
schema:
type: object
additionalProperties: true
/events/ingest:
post:
operationId: events:ingest
tags:
- events
summary: Ingest Events
description: >-
Ingest a batch of usage events. Events are later aggregated by meters
into billable quantities for usage-based (metered) prices.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/EventsIngest'
responses:
'200':
description: The ingestion result.
content:
application/json:
schema:
type: object
properties:
inserted:
type: integer
/webhooks/endpoints:
get:
operationId: webhooks:listEndpoints
tags:
- webhooks
summary: List Webhook Endpoints
responses:
'200':
description: A paginated list of webhook endpoints.
content:
application/json:
schema:
$ref: '#/components/schemas/ListResourceWebhookEndpoint'
post:
operationId: webhooks:createEndpoint
tags:
- webhooks
summary: Create Webhook Endpoint
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookEndpointCreate'
responses:
'201':
description: The created webhook endpoint.
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookEndpoint'
/webhooks/endpoints/{id}:
get:
operationId: webhooks:getEndpoint
tags:
- webhooks
summary: Get Webhook Endpoint
parameters:
- $ref: '#/components/parameters/IdPath'
responses:
'200':
description: The requested webhook endpoint.
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookEndpoint'
delete:
operationId: webhooks:deleteEndpoint
tags:
- webhooks
summary: Delete Webhook Endpoint
parameters:
- $ref: '#/components/parameters/IdPath'
responses:
'204':
description: The webhook endpoint was deleted.
/customer-portal/license-keys/validate:
post:
operationId: customerPortal:validateLicenseKey
tags:
- customer_portal
- license_keys
summary: Validate License Key (Customer Portal)
description: >-
Customer-facing license key validation using a Customer Session token
rather than an Organization Access Token.
security:
- customer_session: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- key
- organization_id
properties:
key:
type: string
organization_id:
type: string
format: uuid
responses:
'200':
description: The validation result.
content:
application/json:
schema:
$ref: '#/components/schemas/LicenseKey'
components:
securitySchemes:
oat:
type: http
scheme: bearer
description: Organization Access Token used for backend, organization-scoped operations.
pat:
type: http
scheme: bearer
description: Personal Access Token scoped to a user.
customer_session:
type: http
scheme: bearer
description: Customer Session token used for customer portal endpoints.
parameters:
IdPath:
name: id
in: path
required: true
schema:
type: string
format: uuid
schemas:
Pagination:
type: object
properties:
total_count:
type: integer
max_page:
type: integer
Product:
type: object
properties:
id:
type: string
format: uuid
created_at:
type: string
format: date-time
modified_at:
type: string
format: date-time
nullable: true
name:
type: string
description:
type: string
nullable: true
recurring_interval:
type: string
nullable: true
enum: [month, year, null]
is_recurring:
type: boolean
is_archived:
type: boolean
organization_id:
type: string
format: uuid
prices:
type: array
items:
$ref: '#/components/schemas/ProductPrice'
benefits:
type: array
items:
$ref: '#/components/schemas/Benefit'
metadata:
type: object
additionalProperties: true
ProductCreate:
type: object
required:
- name
- prices
properties:
name:
type: string
description:
type: string
nullable: true
recurring_interval:
type: string
nullable: true
enum: [month, year, null]
prices:
type: array
items:
$ref: '#/components/schemas/ProductPriceCreate'
organization_id:
type: string
format: uuid
nullable: true
ProductUpdate:
type: object
properties:
name:
type: string
description:
type: string
nullable: true
is_archived:
type: boolean
ProductPrice:
type: object
properties:
id:
type: string
format: uuid
amount_type:
type: string
enum: [fixed, custom, free, metered_unit]
price_amount:
type: integer
nullable: true
description: Amount in the smallest currency unit (e.g. cents).
price_currency:
type: string
nullable: true
example: usd
recurring_interval:
type: string
nullable: true
enum: [month, year, null]
ProductPriceCreate:
type: object
required:
- amount_type
properties:
amount_type:
type: string
enum: [fixed, custom, free, metered_unit]
price_amount:
type: integer
nullable: true
price_currency:
type: string
default: usd
meter_id:
type: string
format: uuid
nullable: true
unit_amount:
type: string
nullable: true
Checkout:
type: object
properties:
id:
type: string
format: uuid
status:
type: string
enum: [open, expired, confirmed, succeeded, failed]
client_secret:
type: string
url:
type: string
expires_at:
type: string
format: date-time
product_id:
type: string
format: uuid
nullable: true
amount:
type: integer
nullable: true
currency:
type: string
nullable: true
customer_email:
type: string
nullable: true
success_url:
type: string
nullable: true
CheckoutCreate:
type: object
required:
- products
properties:
products:
type: array
description: One or more product IDs offered in the checkout.
items:
type: string
format: uuid
customer_email:
type: string
nullable: true
customer_external_id:
type: string
nullable: true
success_url:
type: string
nullable: true
discount_id:
type: string
format: uuid
nullable: true
metadata:
type: object
additionalProperties: true
Customer:
type: object
properties:
id:
type: string
format: uuid
created_at:
type: string
format: date-time
email:
type: string
name:
type: string
nullable: true
external_id:
type: string
nullable: true
organization_id:
type: string
format: uuid
metadata:
type: object
additionalProperties: true
CustomerCreate:
type: object
required:
- email
properties:
email:
type: string
name:
type: string
nullable: true
external_id:
type: string
nullable: true
metadata:
type: object
additionalProperties: true
Subscription:
type: object
properties:
id:
type: string
format: uuid
created_at:
type: string
format: date-time
status:
type: string
enum: [incomplete, trialing, active, past_due, canceled, unpaid]
current_period_start:
type: string
format: date-time
current_period_end:
type: string
format: date-time
nullable: true
cancel_at_period_end:
type: boolean
product_id:
type: string
format: uuid
customer_id:
type: string
format: uuid
recurring_interval:
type: string
enum: [month, year]
amount:
type: integer
nullable: true
currency:
type: string
nullable: true
Order:
type: object
properties:
id:
type: string
format: uuid
created_at:
type: string
format: date-time
status:
type: string
enum: [pending, paid, refunded, partially_refunded]
billing_reason:
type: string
enum: [purchase, subscription_create, subscription_cycle, subscription_update]
amount:
type: integer
tax_amount:
type: integer
currency:
type: string
customer_id:
type: string
format: uuid
product_id:
type: string
format: uuid
subscription_id:
type: string
format: uuid
nullable: true
Benefit:
type: object
properties:
id:
type: string
format: uuid
created_at:
type: string
format: date-time
type:
type: string
enum: [custom, discord, github_repository, downloadables, license_keys, meter_credit]
description:
type: string
selectable:
type: boolean
deletable:
type: boolean
organization_id:
type: string
format: uuid
properties:
type: object
additionalProperties: true
BenefitCreate:
type: object
required:
- type
- description
properties:
type:
type: string
enum: [custom, discord, github_repository, downloadables, license_keys, meter_credit]
description:
type: string
properties:
type: object
additionalProperties: true
LicenseKey:
type: object
properties:
id:
type: string
format: uuid
key:
type: string
status:
type: string
enum: [granted, revoked, disabled]
organization_id:
type: string
format: uuid
customer_id:
type: string
format: uuid
benefit_id:
type: string
format: uuid
usage:
type: integer
limit_usage:
type: integer
nullable: true
expires_at:
type: string
format: date-time
nullable: true
Meter:
type: object
properties:
id:
type: string
format: uuid
created_at:
type: string
format: date-time
name:
type: string
aggregation:
type: object
additionalProperties: true
description: How matching events are aggregated (e.g. count or sum over a property).
filter:
type: object
additionalProperties: true
description: Clauses selecting which events this meter counts.
organization_id:
type: string
format: uuid
MeterCreate:
type: object
required:
- name
- filter
- aggregation
properties:
name:
type: string
filter:
type: object
additionalProperties: true
aggregation:
type: object
additionalProperties: true
Event:
type: object
properties:
name:
type: string
external_customer_id:
type: string
nullable: true
customer_id:
type: string
format: uuid
nullable: true
timestamp:
type: string
format: date-time
nullable: true
metadata:
type: object
additionalProperties: true
EventsIngest:
type: object
required:
- events
properties:
events:
type: array
items:
$ref: '#/components/schemas/Event'
WebhookEndpoint:
type: object
properties:
id:
type: string
format: uuid
created_at:
type: string
format: date-time
url:
type: string
format:
type: string
enum: [raw, discord, slack]
events:
type: array
items:
type: string
organization_id:
type: string
format: uuid
WebhookEndpointCreate:
type: object
required:
- url
properties:
url:
type: string
format:
type: string
enum: [raw, discord, slack]
default: raw
secret:
type: string
nullable: true
events:
type: array
items:
type: string
example: order.created
ListResourceProduct:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/Product'
pagination:
$ref: '#/components/schemas/Pagination'
ListResourceCheckout:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/Checkout'
pagination:
$ref: '#/components/schemas/Pagination'
ListResourceCustomer:
type: object
# --- truncated at 32 KB (33 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/polar-sh/refs/heads/main/openapi/polar-sh-openapi.yml