Account endpoints are scoped to the API-key owner. Client-safe license validation is scoped to the product bound to the zvl_ token. List endpoints are paginated and return data, links, and meta.
Getting started
Authentication, responses, and safety
Account API keys use bearer authentication and should only be stored on trusted servers. Never embed a zwy_ key in shipped software.
For software activation, create a product-scoped zvl_ validation token from Account API Keys and use the client-safe validation endpoint.
Rate limits are designed for ecommerce integrations that poll responsibly, sync in batches, and retry with backoff. Write requests use a stricter bucket and also count toward the general account API limit.
Account API
120 requests/minute
Writes
30 requests/minute
Client license validation
60 requests/minute
Invalid license attempts
20 requests/minute
Send Accept: application/json and authenticate with a bearer token on every API request.
Account API and write limits are keyed by the authenticated zwy_ API key.
Client-safe license validation is keyed by the zvl_ validation token and request IP.
Failed authentication is limited to 20 attempts per minute per IP.
Invalid license validation attempts are limited separately to slow brute-force key guessing.
Errors use JSON responses: 401 for missing or invalid tokens, 404 for missing or cross-account resources, 422 for validation errors, and 429 with Retry-After when limited.
Product object
Products
Products are the digital goods you sell through Zwely checkout buttons. They hold pricing, product copy, checkout button styling, discount eligibility, and delivery settings. A product can be a single product or a bundle shell that sells multiple existing products together.
Use products to keep your external catalog, storefront, or internal admin tools in sync with Zwely.
The API manages product metadata only. Delivery files, product images, and license key pools stay managed in the Zwely app in v1.
Bundles require at least two existing non-bundle products before creation. Bundle membership, including the list and order of included products, is managed in the Zwely app in v1.
Product type is immutable after creation. If you need a bundle instead of a regular product, create a new bundle product.
GET/api/v1/products
List products
Use this endpoint to mirror your Zwely product catalog into another admin tool, storefront, analytics pipeline, or fulfillment system.
Inputs
pagequery
Optional
Page number to fetch from the paginated collection. Defaults to 1.
per_pagequery
Optional
Number of records to return per page. Defaults to 25 and is capped at 100.
Returns
A paginated list of Product objects with price, checkout button settings, delivery status, and license inventory counts.
Auth
Account API key
Response properties
data[]array
Array of Product objects for the requested page.
linksobject
Pagination URLs for first, last, previous, and next pages.
metaobject
Pagination metadata including current_page, per_page, total, and last_page.
data[].idstring
Public product UUID. Use this as product_id in path parameters and license validation.
data[].product_typestring
Product kind: product for a single product, or bundle for a bundle shell. Product type is chosen at creation and cannot be changed later.
data[].titlestring
Customer-facing product name.
data[].descriptionstring|null
Product description shown in checkout and admin views.
data[].price_centsinteger
Current product price in cents.
data[].original_price_centsinteger|null
Optional compare-at price in cents.
data[].allow_discount_codesboolean
Whether checkout accepts discount codes for this product.
data[].auto_tagsarray<string>
Normalized product tags.
data[].requires_licenseboolean
Whether this product uses license key delivery.
data[].generate_license_keys_when_emptyboolean
Whether Zwely can generate license keys when the imported pool is empty.
data[].license_keys.totalinteger
Total license keys attached to the product.
data[].license_keys.usedinteger
License keys already assigned by checkout.
data[].license_keys.remaininginteger
Available license keys remaining.
data[].delivery.has_fileboolean
For products, whether a delivery file is attached in Zwely. For bundles, whether bundle product selection has been completed.
data[].delivery.file_namestring|null
Original delivery file name when present.
data[].delivery.bundle_product_countinteger|null
For bundles, the number of included products when the count is loaded. Regular products omit this value.
data[].image_urlstring|null
Public image URL when a product image is attached.
data[].checkout_button.textstring|null
Embedded checkout button label.
data[].checkout_button.colorstring|null
Embedded checkout button hex color.
data[].checkout_button.border_radiusinteger|null
Embedded checkout button corner radius.
data[].checkout_button.paddinginteger|null
Embedded checkout button padding value.
data[].checkout_button.font_sizeinteger|null
Embedded checkout button font size.
data[].checkout_button.font_familystring|null
Embedded checkout button and modal accent font family.
data[].checkout_button.effectstring
Embedded checkout button effect. Values include none, sparkle, rainbow-glow, and shimmer.
data[].created_atstring|null
ISO timestamp for creation.
data[].updated_atstring|null
ISO timestamp for last update.
GET/api/v1/products/{product_id}
Retrieve a product
Fetch one product when you need fresh pricing, availability, license inventory, or checkout button settings before rendering a custom interface.
Inputs
product_idpath
Required
Product UUID returned as id by the API. Internal integer IDs are never exposed.
Returns
A single Product object.
Auth
Account API key
Response properties
data.idstring
Public product UUID. Use this as product_id in path parameters and license validation.
data.product_typestring
Product kind: product for a single product, or bundle for a bundle shell. Product type is chosen at creation and cannot be changed later.
data.titlestring
Customer-facing product name.
data.descriptionstring|null
Product description shown in checkout and admin views.
data.price_centsinteger
Current product price in cents.
data.original_price_centsinteger|null
Optional compare-at price in cents.
data.allow_discount_codesboolean
Whether checkout accepts discount codes for this product.
data.auto_tagsarray<string>
Normalized product tags.
data.requires_licenseboolean
Whether this product uses license key delivery.
data.generate_license_keys_when_emptyboolean
Whether Zwely can generate license keys when the imported pool is empty.
data.license_keys.totalinteger
Total license keys attached to the product.
data.license_keys.usedinteger
License keys already assigned by checkout.
data.license_keys.remaininginteger
Available license keys remaining.
data.delivery.has_fileboolean
For products, whether a delivery file is attached in Zwely. For bundles, whether bundle product selection has been completed.
data.delivery.file_namestring|null
Original delivery file name when present.
data.delivery.bundle_product_countinteger|null
For bundles, the number of included products when the count is loaded. Regular products omit this value.
data.image_urlstring|null
Public image URL when a product image is attached.
data.checkout_button.textstring|null
Embedded checkout button label.
data.checkout_button.colorstring|null
Embedded checkout button hex color.
data.checkout_button.border_radiusinteger|null
Embedded checkout button corner radius.
data.checkout_button.paddinginteger|null
Embedded checkout button padding value.
data.checkout_button.font_sizeinteger|null
Embedded checkout button font size.
data.checkout_button.font_familystring|null
Embedded checkout button and modal accent font family.
data.checkout_button.effectstring
Embedded checkout button effect. Values include none, sparkle, rainbow-glow, and shimmer.
data.created_atstring|null
ISO timestamp for creation.
data.updated_atstring|null
ISO timestamp for last update.
PATCH/api/v1/products/{product_id}
Update a product
Patch product metadata when price, positioning, tags, or checkout button copy changes in your external catalog.
product_type cannot be changed with PATCH.
Inputs
product_idpath
Required
Product UUID returned as id by the API. Internal integer IDs are never exposed.
titlebody
Optional
Customer-facing product name. Maximum 120 characters.
product_typebody
Optional
Product kind. Use product for a single product or bundle for a bundle shell. Defaults to product. The type cannot be changed after creation; bundle creation requires at least two existing non-bundle products, and bundle membership is managed in the Zwely app in v1.
descriptionbody
Optional
Product description shown in checkout and admin views. Maximum 800 characters.
price_centsbody
Optional
Current price in cents. Use 3900 for $39.00.
original_price_centsbody
Optional
Optional compare-at price in cents. Must be greater than price_cents when set.
allow_discount_codesbody
Optional
Boolean that controls whether checkout accepts discount codes for this product.
auto_tagsbody
Optional
Array of up to 12 product tags. Each tag is normalized, deduplicated, and limited to 32 characters.
button_textbody
Optional
Checkout button label. Maximum 40 characters.
button_colorbody
Optional
Hex color for the embedded checkout button, such as #fd614c.
button_border_radiusbody
Optional
Button corner radius in pixels. Allowed range is 0 to 32.
button_paddingbody
Optional
Button vertical padding value. Allowed range is 8 to 26.
button_font_sizebody
Optional
Button font size in pixels. Allowed range is 13 to 22.
button_font_familybody
Optional
Google font family used by the checkout button and checkout modal headline/buttons. Use one of the supported Zwely font options, such as Rubik, Manrope, Sora, Playfair Display, or Space Grotesk.
button_effectbody
Optional
Optional checkout button effect. Use none for a clean button, sparkle for twinkling yellow sparkles, rainbow-glow for a pulsing color-spectrum glow, or shimmer for a diagonal light sweep around the embedded button and modal payment button.
Returns
The updated Product object.
Auth
Account API key
Response properties
data.idstring
Public product UUID. Use this as product_id in path parameters and license validation.
data.product_typestring
Product kind: product for a single product, or bundle for a bundle shell. Product type is chosen at creation and cannot be changed later.
data.titlestring
Customer-facing product name.
data.descriptionstring|null
Product description shown in checkout and admin views.
data.price_centsinteger
Current product price in cents.
data.original_price_centsinteger|null
Optional compare-at price in cents.
data.allow_discount_codesboolean
Whether checkout accepts discount codes for this product.
data.auto_tagsarray<string>
Normalized product tags.
data.requires_licenseboolean
Whether this product uses license key delivery.
data.generate_license_keys_when_emptyboolean
Whether Zwely can generate license keys when the imported pool is empty.
data.license_keys.totalinteger
Total license keys attached to the product.
data.license_keys.usedinteger
License keys already assigned by checkout.
data.license_keys.remaininginteger
Available license keys remaining.
data.delivery.has_fileboolean
For products, whether a delivery file is attached in Zwely. For bundles, whether bundle product selection has been completed.
data.delivery.file_namestring|null
Original delivery file name when present.
data.delivery.bundle_product_countinteger|null
For bundles, the number of included products when the count is loaded. Regular products omit this value.
data.image_urlstring|null
Public image URL when a product image is attached.
data.checkout_button.textstring|null
Embedded checkout button label.
data.checkout_button.colorstring|null
Embedded checkout button hex color.
data.checkout_button.border_radiusinteger|null
Embedded checkout button corner radius.
data.checkout_button.paddinginteger|null
Embedded checkout button padding value.
data.checkout_button.font_sizeinteger|null
Embedded checkout button font size.
data.checkout_button.font_familystring|null
Embedded checkout button and modal accent font family.
data.checkout_button.effectstring
Embedded checkout button effect. Values include none, sparkle, rainbow-glow, and shimmer.
data.created_atstring|null
ISO timestamp for creation.
data.updated_atstring|null
ISO timestamp for last update.
messagestring
Confirmation message for the update action.
Customer object
Customers
Customers are buyers or free-claim recipients created by checkout activity. Zwely keeps customer records account-scoped and attaches order history, tags, billing geography, and acquisition page data.
Customer endpoints are read-only so checkout remains the source of truth for buyer creation.
Use them for CRM syncs, support tooling, customer enrichment, and lifecycle reporting.
GET/api/v1/customers
List customers
Pull customers into your CRM, support dashboard, or analytics warehouse. The response includes order counts and lifetime order total when available.
Inputs
pagequery
Optional
Page number to fetch from the paginated collection. Defaults to 1.
per_pagequery
Optional
Number of records to return per page. Defaults to 25 and is capped at 100.
Returns
A paginated list of Customer objects.
Auth
Account API key
Response properties
data[]array
Array of Customer objects for the requested page.
linksobject
Pagination URLs for first, last, previous, and next pages.
metaobject
Pagination metadata including current_page, per_page, total, and last_page.
data[].idstring
Public customer UUID.
data[].emailstring
Customer email collected at checkout.
data[].namestring|null
Customer name when available.
data[].phonestring|null
Customer phone when available.
data[].billing_countrystring|null
Billing country from checkout or payment details.
data[].billing_regionstring|null
Billing region or state when available.
data[].tagsarray<string>
Customer tags stored in Zwely.
data[].first_checkout_page_urlstring|null
First checkout page URL where Zwely saw this customer.
data[].first_checkout_page_domainstring|null
Domain of the first checkout page.
data[].latest_checkout_page_urlstring|null
Most recent checkout page URL.
data[].latest_checkout_page_domainstring|null
Domain of the most recent checkout page.
data[].latest_order_atstring|null
ISO timestamp of the customer’s latest order.
data[].orders_countinteger
Number of orders attached to this customer.
data[].orders_total_centsinteger
Lifetime order total in cents.
data[].created_atstring|null
ISO timestamp for creation.
data[].updated_atstring|null
ISO timestamp for last update.
GET/api/v1/customers/{customer_id}
Retrieve a customer
Fetch one customer profile for a support view, entitlement check, or internal buyer detail page.
Inputs
customer_idpath
Required
Customer UUID returned as id by the API.
Returns
A single Customer object.
Auth
Account API key
Response properties
data.idstring
Public customer UUID.
data.emailstring
Customer email collected at checkout.
data.namestring|null
Customer name when available.
data.phonestring|null
Customer phone when available.
data.billing_countrystring|null
Billing country from checkout or payment details.
data.billing_regionstring|null
Billing region or state when available.
data.tagsarray<string>
Customer tags stored in Zwely.
data.first_checkout_page_urlstring|null
First checkout page URL where Zwely saw this customer.
data.first_checkout_page_domainstring|null
Domain of the first checkout page.
data.latest_checkout_page_urlstring|null
Most recent checkout page URL.
data.latest_checkout_page_domainstring|null
Domain of the most recent checkout page.
data.latest_order_atstring|null
ISO timestamp of the customer’s latest order.
data.orders_countinteger
Number of orders attached to this customer.
data.orders_total_centsinteger
Lifetime order total in cents.
data.created_atstring|null
ISO timestamp for creation.
data.updated_atstring|null
ISO timestamp for last update.
Order object
Orders
Orders are completed checkout records. They connect products, customers, optional discounts, optional license keys, gross revenue, refunds, Stripe fees, and Zwely application fees.
Orders are read-only through the API because payment state is controlled by checkout and Stripe.
Use orders for fulfillment audit trails, finance exports, dashboards, and customer support.
GET/api/v1/orders
List orders
Sync recent checkouts into your warehouse, fulfillment monitor, customer support queue, or revenue reporting system.
Inputs
pagequery
Optional
Page number to fetch from the paginated collection. Defaults to 1.
per_pagequery
Optional
Number of records to return per page. Defaults to 25 and is capped at 100.
Returns
A paginated list of Order objects with related product, customer, discount, payment, and fee summaries.
Auth
Account API key
Response properties
data[]array
Array of Order objects for the requested page.
linksobject
Pagination URLs for first, last, previous, and next pages.
metaobject
Pagination metadata including current_page, per_page, total, and last_page.
data[].idstring
Public order UUID.
data[].statusstring
Order status, such as completed, refunded, or failed.
Look up a specific order by UUID for support, refund investigation, license assignment inspection, or reconciliation.
Inputs
order_idpath
Required
Order UUID returned as id by the API.
Returns
A single Order object.
Auth
Account API key
Response properties
data.idstring
Public order UUID.
data.statusstring
Order status, such as completed, refunded, or failed.
data.customer_emailstring
Email used at checkout.
data.subtotal_centsinteger|null
Subtotal before discounts in cents.
data.discount_amount_centsinteger|null
Discount amount applied in cents.
data.amount_centsinteger
Final charged amount in cents.
data.refunded_amount_centsinteger
Amount refunded in cents.
data.currencystring
Three-letter lowercase currency code.
data.fees.stripe_fee_centsinteger|null
Total Stripe fee recorded for the order.
data.fees.stripe_processing_fee_centsinteger|null
Stripe processing fee portion when known.
data.fees.application_fee_centsinteger|null
Zwely application fee recorded for the order.
data.fees.creator_net_centsinteger|null
Estimated net amount to the seller.
data.product.idstring|null
Product UUID when loaded.
data.product.titlestring|null
Product title when loaded.
data.customer.idstring|null
Customer UUID when loaded.
data.customer.emailstring|null
Customer email when loaded.
data.customer.namestring|null
Customer name when available.
data.discount.idstring|null
Discount UUID when a code was applied.
data.discount.codestring|null
Discount code applied at checkout.
data.license_key.assignedboolean|null
True when a license key was assigned.
data.license_key.created_atstring|null
ISO timestamp for license key creation.
data.license_key.assigned_atstring|null
ISO timestamp when checkout assigned the key.
data.payment.typestring|null
Payment method type reported by Stripe.
data.payment.walletstring|null
Wallet type when a wallet was used.
data.payment.card_brandstring|null
Card brand when available.
data.payment.card_fundingstring|null
Card funding type when available.
data.payment.card_countrystring|null
Card issuing country when available.
data.payment.card_last4string|null
Last four digits of the card when available.
data.payment.receipt_urlstring|null
Stripe receipt URL when available.
data.completed_atstring|null
ISO timestamp when checkout completed.
data.refunded_atstring|null
ISO timestamp when the order was refunded.
data.created_atstring|null
ISO timestamp for creation.
data.updated_atstring|null
ISO timestamp for last update.
Discount code object
Discounts
Discount codes let you offer percentage or fixed-amount promotions in checkout. Codes can be globally usable, limited by total redemptions, restricted to a customer email, or restricted to one product.
Use discount endpoints to coordinate launch campaigns, affiliate codes, support coupons, and limited promotions from another system.
Product restrictions use product UUIDs, not internal database IDs.
GET/api/v1/discounts
List discounts
Audit active campaigns, sync coupons to support tools, or report on remaining redemption capacity.
Inputs
pagequery
Optional
Page number to fetch from the paginated collection. Defaults to 1.
per_pagequery
Optional
Number of records to return per page. Defaults to 25 and is capped at 100.
Returns
A paginated list of Discount Code objects.
Auth
Account API key
Response properties
data[]array
Array of Discount Code objects for the requested page.
linksobject
Pagination URLs for first, last, previous, and next pages.
metaobject
Pagination metadata including current_page, per_page, total, and last_page.
data[].idstring
Public discount UUID.
data[].codestring
Normalized uppercase checkout code.
data[].discount_typestring
Discount mode: percent or amount.
data[].percent_offinteger|null
Percentage off when discount_type is percent.
data[].amount_off_centsinteger|null
Fixed amount off in cents when discount_type is amount.
data[].max_redemptionsinteger|null
Maximum total uses, or null for unlimited.
data[].max_redemptions_per_customerinteger|null
Maximum uses per customer email, or null for unlimited.
data[].redemptions_countinteger
Number of completed redemptions.
data[].remaining_redemptionsinteger|null
Remaining uses based on max_redemptions.
data[].expires_atstring|null
ISO expiration timestamp when set.
data[].is_activeboolean
Whether the code can currently be redeemed.
data[].restricted_product.idstring|null
Restricted product UUID when the code is product-scoped.
data[].restricted_product.titlestring|null
Restricted product title when loaded.
data[].restricted_customer_emailstring|null
Email restriction when set.
data[].created_atstring|null
ISO timestamp for creation.
data[].updated_atstring|null
ISO timestamp for last update.
GET/api/v1/discounts/{discount_id}
Retrieve a discount
Fetch one discount when you need to show campaign details, redemption counts, remaining usage, or product restrictions in another tool.
Inputs
discount_idpath
Required
Discount UUID returned as id by the API.
Returns
A single Discount Code object.
Auth
Account API key
Response properties
data.idstring
Public discount UUID.
data.codestring
Normalized uppercase checkout code.
data.discount_typestring
Discount mode: percent or amount.
data.percent_offinteger|null
Percentage off when discount_type is percent.
data.amount_off_centsinteger|null
Fixed amount off in cents when discount_type is amount.
data.max_redemptionsinteger|null
Maximum total uses, or null for unlimited.
data.max_redemptions_per_customerinteger|null
Maximum uses per customer email, or null for unlimited.
data.redemptions_countinteger
Number of completed redemptions.
data.remaining_redemptionsinteger|null
Remaining uses based on max_redemptions.
data.expires_atstring|null
ISO expiration timestamp when set.
data.is_activeboolean
Whether the code can currently be redeemed.
data.restricted_product.idstring|null
Restricted product UUID when the code is product-scoped.
data.restricted_product.titlestring|null
Restricted product title when loaded.
data.restricted_customer_emailstring|null
Email restriction when set.
data.created_atstring|null
ISO timestamp for creation.
data.updated_atstring|null
ISO timestamp for last update.
PATCH/api/v1/discounts/{discount_id}
Update a discount
Pause a campaign, change redemption limits, extend an expiration date, or move a code to a different product restriction.
Inputs
discount_idpath
Required
Discount UUID returned as id by the API.
codebody
Optional
Discount code customers enter at checkout. Zwely normalizes it to uppercase letters and numbers.
discount_typebody
Optional
Discount mode. Use percent for percentage discounts or amount for fixed-cent discounts.
percent_offbody
Conditional
Percentage off from 1 to 100. Required when switching a code to percent.
amount_off_centsbody
Conditional
Fixed discount amount in cents. Required when switching a code to amount.
max_redemptionsbody
Optional
Maximum total uses for the code. Leave null for no account-level cap.
max_redemptions_per_customerbody
Optional
Maximum uses per customer email. Leave null for no per-customer cap.
expires_atbody
Optional
Future expiration timestamp. Send null to clear the expiration on update.
is_activebody
Optional
Boolean switch for whether the code can currently be used at checkout.
restricted_product_idbody
Optional
Optional product UUID that limits the code to one product. Send null to remove the restriction.
restricted_customer_emailbody
Optional
Optional customer email that limits redemption to one buyer. Zwely normalizes email casing.
Returns
The updated Discount Code object.
Auth
Account API key
Response properties
data.idstring
Public discount UUID.
data.codestring
Normalized uppercase checkout code.
data.discount_typestring
Discount mode: percent or amount.
data.percent_offinteger|null
Percentage off when discount_type is percent.
data.amount_off_centsinteger|null
Fixed amount off in cents when discount_type is amount.
data.max_redemptionsinteger|null
Maximum total uses, or null for unlimited.
data.max_redemptions_per_customerinteger|null
Maximum uses per customer email, or null for unlimited.
data.redemptions_countinteger
Number of completed redemptions.
data.remaining_redemptionsinteger|null
Remaining uses based on max_redemptions.
data.expires_atstring|null
ISO expiration timestamp when set.
data.is_activeboolean
Whether the code can currently be redeemed.
data.restricted_product.idstring|null
Restricted product UUID when the code is product-scoped.
data.restricted_product.titlestring|null
Restricted product title when loaded.
data.restricted_customer_emailstring|null
Email restriction when set.
data.created_atstring|null
ISO timestamp for creation.
data.updated_atstring|null
ISO timestamp for last update.
messagestring
Confirmation message for the update action.
License validation result
License validation
License validation checks whether a license key belongs to a product and was assigned by a real checkout. Use it to unlock paid software, plugins, downloads, or subscription-adjacent product access.
Server-side validation uses an account API key and can return customer and order details for your backend.
Client-safe validation uses a product-scoped validation token and omits customer email, order financials, and other sensitive data.
A key is valid only when it belongs to the product, has been assigned by checkout, has a customer and order, and the order is not failed or refunded.
Status values are valid, not_found, unassigned, email_mismatch, refunded, and inactive_order.
POST/api/v1/license-validations
Validate a license server-side
Call this from your own server when you need the richest answer: whether the key is valid, which buyer owns it, and which order assigned it.
Inputs
product_idbody
Required
Product UUID the license key must belong to.
license_keybody
Required
License key string issued by Zwely after checkout assignment.
customer_emailbody
Optional
Optional buyer email check. When provided, Zwely returns email_mismatch if the key belongs to a different email.
Returns
A rich License Validation Result with product, license, customer, and order details.
Auth
Account API key
Response properties
data.validboolean
True only when the key belongs to the product, is assigned, and the order is active.
data.statusstring
Validation status: valid, not_found, unassigned, email_mismatch, refunded, or inactive_order.
data.product.idstring|null
Product UUID when the key can be associated with the token-scoped product.
data.product.titlestring|null
Product title when available.
data.license.created_atstring|null
ISO timestamp when the license key was created.
data.license.assigned_atstring|null
ISO timestamp when checkout assigned the key.
data.license.keystring|null
Raw license key. Returned only by the server-side endpoint.
data.customer.idstring|null
Customer UUID when a customer is attached to the key.
data.customer.emailstring|null
Customer email. Returned only by the server-side endpoint.
data.customer.namestring|null
Customer name when available.
data.order.idstring|null
Order UUID when a checkout assigned the key.
data.order.statusstring|null
Order status used for validity checks.
data.order.amount_centsinteger|null
Order amount in cents. Returned only server-side.
data.order.currencystring|null
Order currency.
data.order.completed_atstring|null
ISO timestamp when the order completed.
POST/api/v1/public/license-validations
Validate a license from software
Call this from distributed software with a product-scoped validation token. The response is intentionally minimal so the app can unlock access without exposing private buyer or order data.
Inputs
license_keybody
Required
License key string issued by Zwely after checkout assignment.
product_idbody
Optional
Optional product UUID. If sent, it must match the product bound to the validation token.
customer_emailbody
Optional
Optional buyer email check. The public response still omits buyer PII.
Returns
A client-safe License Validation Result with valid status, product identity, and license timestamps.
Auth
Product-scoped validation token
Response properties
data.validboolean
True only when the key belongs to the product, is assigned, and the order is active.
data.statusstring
Validation status: valid, not_found, unassigned, email_mismatch, refunded, or inactive_order.
data.product.idstring|null
Product UUID when the key can be associated with the token-scoped product.
data.product.titlestring|null
Product title when available.
data.license.created_atstring|null
ISO timestamp when the license key was created.
data.license.assigned_atstring|null
ISO timestamp when checkout assigned the key.
Webhooks
Receive order events in your own app
Webhook endpoints let your backend react when a Zwely checkout creates an order. Zwely sends order.created for both free and paid orders, so you can update a CRM, grant access in another system, notify a team, or start your own onboarding flow without polling the Orders API.
Register webhook URLs from Account API Keys. Zwely posts JSON to each active endpoint after an order is created.
Each delivery includes Zwely-Event, Zwely-Delivery, and Zwely-Signature headers.
Bundle orders include delivery_items so your backend can see each included product, download availability, filename, and assigned license key.
The signature uses your endpoint signing secret. Build the signed payload as timestamp + "." + raw_request_body and verify the v1 HMAC SHA-256 value.
Return a 2xx response quickly. If your app needs more time, store the payload and process it asynchronously.