Get All Coupons
Retrieve all coupons sorted by creation date (newest first). Requires admin authentication.Authentication
Requires Clerk authentication with admin role. Protected byprotectRoute and adminOnly middleware.
Response
Array of coupon objects
MongoDB ObjectId
Coupon code (uppercase, unique)
Type of discount: “percentage” or “fixed”
Discount value (1-100 for percentage, any positive number for fixed)
ISO 8601 expiration date (null if no expiration)
Whether the coupon is active
Array of user IDs who have used this coupon
ISO 8601 timestamp
ISO 8601 timestamp
Create Coupon
Create a new discount coupon with validation rules.Authentication
Requires Clerk authentication with admin role.Request
Coupon code. Will be converted to uppercase and trimmed. Must be unique.
Type of discount:
percentage- Percentage discount (1-100)fixed- Fixed amount discount
Discount value. Must be:
- 1-100 for percentage discounts
- Any positive number >= 1 for fixed discounts
ISO 8601 expiration date. Optional - if not provided, coupon never expires.
Response
The created coupon object
Error Responses
Update Coupon
Update an existing coupon. All fields are optional.Authentication
Requires Clerk authentication with admin role.Path Parameters
MongoDB ObjectId of the coupon to update
Request
Updated coupon code (will be uppercase and trimmed)
Updated discount type: “percentage” or “fixed”
Updated discount value (validated based on discount type)
Updated expiration date (ISO 8601)
Updated active status
Response
The updated coupon object
Error Responses
Delete Coupon
Permanently delete a coupon.Authentication
Requires Clerk authentication with admin role.Path Parameters
MongoDB ObjectId of the coupon to delete
Response
Success message
Coupon Validation
For customer-facing coupon validation, see the public endpoint:POST /api/coupons/validate- Validate and calculate discount (requires user authentication)
- Coupon exists and is active
- Not expired (
expiresAtis null or in the future) - User hasn’t already used the coupon (tracked in
usedByarray) - If
firstOrderOnlyis set, user must have no completed orders
- Percentage:
min(round(subtotal * discountValue / 100), subtotal) - Fixed:
min(discountValue, subtotal)