Skip to content

Coupons & Add-ons

Coupons provide discounts that are applied to customer invoices during generation.

FieldTypeDescription
iduuidUnique identifier
codestringUnique coupon code
namestringDisplay name
descriptionstring | nullOptional description
coupon_typestringfixed_amount or percentage
amount_centsstring | nullDiscount amount (when fixed_amount)
amount_currencystring | nullCurrency code (when fixed_amount)
percentage_ratestring | nullPercentage discount (when percentage)
frequencystringonce, recurring, or forever
frequency_durationinteger | nullNumber of billing periods (when recurring)
reusablebooleanWhether coupon can be applied to multiple customers
expirationstringno_expiration or time_limit
expiration_atdatetime | nullExpiry timestamp (when time_limit)
statusstringactive or terminated
created_atdatetimeCreation timestamp
updated_atdatetimeLast update timestamp
Terminal window
curl -X POST /v1/coupons \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"code": "WELCOME20",
"name": "Welcome 20% Off",
"coupon_type": "percentage",
"percentage_rate": "20.00",
"frequency": "recurring",
"frequency_duration": 3,
"reusable": true,
"expiration": "time_limit",
"expiration_at": "2026-12-31T23:59:59Z"
}'
TypeDescriptionRequired field
fixed_amountFixed monetary discountamount_cents, amount_currency
percentagePercentage off subtotalpercentage_rate
FrequencyBehavior
onceApplied to one invoice, then terminated
recurringApplied for frequency_duration billing periods
foreverApplied indefinitely
ValueBehavior
no_expirationCoupon remains active until manually terminated
time_limitCoupon expires at expiration_at timestamp

Only name, description, expiration, expiration_at, and status can be modified after creation.

Terminal window
curl -X PUT /v1/coupons/WELCOME20 \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Welcome Discount 20%",
"expiration": "time_limit",
"expiration_at": "2027-06-30T23:59:59Z"
}'
Terminal window
curl -X POST /v1/coupons/apply \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"coupon_code": "WELCOME20",
"customer_id": "customer-uuid"
}'
  • Non-reusable coupons can only be applied to one customer (409 if already used)
  • Expired or terminated coupons cannot be applied (400)
  • amount_cents, amount_currency, and percentage_rate can be overridden per application
FieldTypeDescription
iduuidUnique identifier
coupon_iduuidReference to parent coupon
customer_iduuidReference to customer
amount_centsstring | nullOverride amount (if set)
amount_currencystring | nullOverride currency (if set)
percentage_ratenumber | nullOverride percentage (if set)
frequencystringInherited from coupon
frequency_durationinteger | nullTotal billing periods
frequency_duration_remaininginteger | nullRemaining billing periods
statusstringactive or terminated
terminated_atdatetime | nullWhen the application was terminated
created_atdatetimeCreation timestamp
updated_atdatetimeLast update timestamp
Terminal window
DELETE /v1/coupons/applied/{applied_coupon_id}

Terminates a specific coupon application for a customer without affecting the coupon itself.

Terminal window
GET /v1/customers/{customer_id}/applied_coupons?skip=0&limit=20

Returns all applied coupons for a customer with pagination.

During invoice generation:

  1. All active applied coupons for the customer are retrieved
  2. Percentage discounts: discount = subtotal × rate / 100
  3. Fixed amount discounts: min(amount_cents, remaining_subtotal)
  4. Discounts are applied sequentially — if the subtotal reaches zero, remaining coupons are skipped
  5. The total discount is recorded as coupons_amount_cents on the invoice
Terminal window
GET /v1/coupons/{code}/analytics

Returns usage statistics for a coupon:

FieldTypeDescription
times_appliedintegerTotal number of times applied
active_applicationsintegerCurrently active applications
terminated_applicationsintegerTerminated applications
total_discount_centsstringTotal discount amount given
remaining_usesinteger | nullRemaining applications (non-reusable coupons)
Terminal window
POST /v1/coupons/{code}/duplicate

Creates a copy of an existing coupon with a new code. Useful for creating variations of promotional campaigns.

Terminal window
DELETE /v1/coupons/{code}

Sets the coupon status to terminated. Existing applied coupons remain active until consumed.

Add-ons are one-time charges applied to customers. When an add-on is applied, a one-off invoice is generated.

FieldTypeDescription
iduuidUnique identifier
codestringUnique add-on code
namestringDisplay name
descriptionstring | nullOptional description
amount_centsstringDefault charge amount in cents
amount_currencystringCurrency code (default: USD)
invoice_display_namestring | nullCustom name shown on invoices
created_atdatetimeCreation timestamp
updated_atdatetimeLast update timestamp
Terminal window
curl -X POST /v1/add_ons \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"code": "onboarding",
"name": "Onboarding Fee",
"amount_cents": 50000,
"amount_currency": "USD",
"invoice_display_name": "Professional Onboarding Service"
}'
Terminal window
curl -X POST /v1/add_ons/apply \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"add_on_code": "onboarding",
"customer_id": "customer-uuid",
"amount_cents": 45000
}'

When applied:

  1. An AppliedAddOn record is created
  2. A one-off invoice is generated with the add-on as a line item
  3. A fee with fee_type: add_on is created

The amount_cents and amount_currency can be overridden from the default add-on price.

FieldTypeDescription
iduuidUnique identifier
add_on_iduuidReference to parent add-on
customer_iduuidReference to customer
amount_centsstringCharged amount in cents
amount_currencystringCurrency code
created_atdatetimeCreation timestamp
Terminal window
GET /v1/add_ons/{code}/applications

Returns the list of customers who have been charged this add-on, including customer_name for display.

Terminal window
GET /v1/add_ons/application_counts

Returns a map of {add_on_id: count} showing how many times each add-on has been applied.

Terminal window
GET /v1/customers/{customer_id}/applied_add_ons?skip=0&limit=20

Returns all applied add-ons for a customer with pagination.

Both coupons and add-ons are accessible through the customer portal API.

MethodPathDescription
GET/portal/couponsList applied coupons for authenticated customer
POST/portal/coupons/redeemRedeem a coupon code (body: {"coupon_code": "..."})
MethodPathDescription
GET/portal/add_onsList available add-ons for purchase
GET/portal/add_ons/purchasedList purchased add-ons
POST/portal/add_ons/{add_on_id}/purchasePurchase an add-on (creates invoice)

The portal purchase response includes the applied_add_on_id, invoice_id, add_on_name, amount_cents, and amount_currency.

MethodPathDescription
POST/v1/couponsCreate a coupon
GET/v1/couponsList coupons (filterable by status)
GET/v1/coupons/{code}Get coupon details
PUT/v1/coupons/{code}Update a coupon
DELETE/v1/coupons/{code}Terminate a coupon
POST/v1/coupons/{code}/duplicateDuplicate a coupon
GET/v1/coupons/{code}/analyticsGet coupon analytics
POST/v1/coupons/applyApply coupon to customer
DELETE/v1/coupons/applied/{applied_coupon_id}Remove applied coupon
GET/v1/customers/{customer_id}/applied_couponsList customer applied coupons
MethodPathDescription
POST/v1/add_onsCreate an add-on
GET/v1/add_onsList add-ons
GET/v1/add_ons/{code}Get add-on details
PUT/v1/add_ons/{code}Update an add-on
DELETE/v1/add_ons/{code}Delete an add-on
POST/v1/add_ons/applyApply add-on to customer
GET/v1/add_ons/{code}/applicationsGet application history
GET/v1/add_ons/application_countsGet application counts
GET/v1/customers/{customer_id}/applied_add_onsList customer applied add-ons