Products
Product variants are intertwined with products. It's what contains all data pertaining to deliverables and pricing.
As you might have already noticed, one product is able to have multiple variants which each can have their unique deliverables and pricing.
On this page, we'll dive into the different product variant endpoints you can use to manage products programmatically. We'll look at how to create, update, and delete product variants.
The product variant model
The product variant model contains all the information about the product variants located within a product, including the price and deliverables.
Properties
- Name
id- Type
- integer
- Description
The unique identifier for the product.
- Name
product_id- Type
- integer
- Description
The unique product identified this variant is linked to.
- Name
title- Type
- string
- Description
The product variant title.
- Name
description- Type
- string
- Description
The product variant description.
- Name
deliverable- Type
- array
- Description
Deliverable details of the product variant, consists of the following:
dataArray of deliverable data to be delivered. Consists of the following:serialsOnly applicable ifdeliverable.typescontainsTEXT. This array should contain all of your serials, separated by the delimiter you set inparsingMode.removeDuplicateWhether duplicateTEXTvalues should be removed.parsingModeIn which wayTEXTvalues are separated/parsed.commentOnly applicable ifdeliverable.typescontainsMANUAL. This string should specify what the next steps are for the manual delivery to be completed.fileOnly applicable ifdeliverable.typescontainsDOWNLOADABLE. If wanting to upload a file, make sure to send the request as a Multipart form instead of JSON.webhookOnly applicable ifdeliverable.typescontainsDYNAMIC. This string should be your dynamic webhook endpoint, which we ping following a successful purchase.stockSpecifies how much stock there is for the deliverable. Not required ifdeliverable.typescontainsTEXTas it is calculated automatically. If not present, stock will be set to infinite.
typesArray with values of the deliverable type(s) this product variant contains. Supported values:DOWNLOADABLEDownloadable file of any type.TEXTText products delivered one-by-one.DYNAMICGenerate a product via your webhook URL.MANUALA product that is manually carried out and/or delivered.
- Name
pricing- Type
- array
- Description
The product variant pricing array, contains the following values:
humbleWhether the product is of a "Pay what you want" type. If set totrue, the customer can add an extra amount of their choosing on top of the price.frequencyarray that specifies how often a product should be charged. Consists of two values:valuethat specifies the period durationintervalthat specifies the interval between values. Can be days, weeks, months. Up to 1 year.
typethat contains a string of the charge frequency. One of two values:SINGLE_PAYMENTfor one-off chargesSUBSCRIPTIONfor recurring charges- At the moment, only Stripe is supported for subscriptions
pricewhich contains the product price array. Consists of two values:priceproduct price, in centscurrencyCountry ISO code of the currency the product is priced in
- Name
minimum_purchase_quantity- Type
- integer
- Description
The minimum amount of stock a customer is required to purchase.
- Name
maximum_purchase_quantity- Type
- integer
- Description
The maximum amount of stock a customer is allowed to purchase. If set to null, the customer can purchase an unlimited amount of quantity.
- Name
bulk_discount- Type
- object
- Description
The bulk discount values of the product. Array consists of:
minimum_purchase_amountThe quantity at which the bulk discount gets triggered.discount_percentageThe discount value (in percentage) that gets applied to the product price.
- Name
payment_methods- Type
- array
- Description
This specifies which payment methods are available for the customer to check out with. Your store has to have a payment method activated in order for these to be set.
- Consists of at least one of the below values:
PAYPALPayPalSTRIPEStripeCASHAPPCash AppPADDLEPaddleAUTHNETAuthorize.netSQUARESquare
- Cryptocurrency payment methods:
BTCBitcoinLTCLitecoinETHEthereumXMRMoneroBNBBinance BNBTRXTronMATICPolygonETH_USDTUSDT (ETH network)ETH_USDCUSDC (ETH network)ETH_UNIUNI (ETH network)ETH_SHIBShiba (ETH network)ETH_DAIDAI (ETH network)BNB_USDTUSDT (BSC network)BNB_USDCUSDC (BSC network)TRX_USDTUSDT (TRX network)TRX_USDCUSDC (TRX network)
- Consists of at least one of the below values:
- Name
other_settings- Type
- array
- Description
Array of additional settings pertaining to the product variant. Consists of:
quantity_incrementsthat specifies by how much a product can be incremented.- The default is 1, which lets a customer purchase a quantity of 1,2,3 and so on
- When set to e.g. 2, the customer can only purchase a quantity of 1,3,5 and so on. A quantity of 2 would end up not being allowed.
discord_data_requiredwhich specifies whether a customer is required to authorize their Discord account before proceeding with the purchase. If enabled, a customer can not check out before linking their Discord account.
- Name
order- Type
- integer
- Description
The order of this variant relative to all other variants within the product
- Name
created_at- Type
- timestamp
- Description
The time at which this product variant was first created.
- Name
updated_at- Type
- timestamp
- Description
The time at which this product variant was last updated.
- Name
deleted_at- Type
- timestamp
- Description
The time at which this product variant was deleted.
- Name
product- Type
- array
- Description
The relevant product details attached to this variant (readonly). Consists of additional information input(s) of the product. Additional information input array consists of:
requiredspecifying whether the additional information is requiredkeyunique key of the additional information inputtypeOne of the followingTEXTNUMBERHIDDENTEXTAREACHECKBOX
labelspecifying what the customer needs to enter. Examples belowTEXTWhat is your in-game username?NUMBERTo what mobile number do you want this delivered?HIDDENn.a. (as this is a hidden input not visible to the end-user)TEXTAREAPlease specify what your website should look like.CHECKBOXWould you like a complimentary drink?
List all product variants
This endpoint allows you to retrieve a paginated list of all your product variants. By default, a maximum of fifteen product variants are shown per page.
Optional attributes
- Name
limit- Type
- integer
- Description
Limit the number of products returned
- Name
page- Type
- integer
- Description
The page number you are attempting to access.
- Name
with_trashed- Type
- boolean
- Description
Include deleted products in the results
- Name
only_trashed- Type
- boolean
- Description
Limit the results to only deleted products
Request
$client = new http\Client;
$request = new http\Client\Request;
$request->setRequestUrl('https://sell.app/api/v2/products/1/variants');
$request->setRequestMethod('GET');
$request->setHeaders([
'Content-Type' => 'application/json',
'Authorization' => 'Bearer {ApiKeyHere}'
]);
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();
Response
{
"data": [
{
"id": 1,
"product_id": 1,
"title": "Default",
"description": "default variant",
"deliverable": {
"data": {
"removeDuplicate": false,
"parsingMode": "COMMA",
"stock": 15,
"comment": "Thanks for the purchase! I'll send you a contract by email. Make sure to sign it with your blood."
},
"types": [
"MANUAL"
]
},
"pricing": {
"humble": false,
"frequency": {
"value": 1,
"interval": "MONTH"
},
"type": "SINGLE_PAYMENT",
"price": {
"price": "1999",
"currency": "USD"
}
},
"minimum_purchase_quantity": 1,
"maximum_purchase_quantity": null,
"bulk_discount": [
{
"discount_percentage": 5,
"minimum_purchase_amount": 2
},
{
"discount_percentage": 10,
"minimum_purchase_amount": 5
}
],
"payment_methods": [
"STRIPE"
],
"other_settings": {
"quantity_increments": 1,
"discord_data_required": false
},
"order": 1,
"created_at": "2024-01-09T23:13:16.000000Z",
"updated_at": "2024-01-10T17:27:01.000000Z",
"deleted_at": null,
"product": {
"additional_information": [
{
"required": true,
"key": "3aecffd000e00e2211e94558007ffc37",
"type": "CHECKBOX",
"label": "Do you agree to handing your soul over?"
}
]
}
}
],
"links": {
// ...
},
"meta": {
// ...
}
}
Create a product variant
This endpoint allows you to create a new product variant. See the code examples for how to create a new product variant with the SellApp API.
Required attributes
- Name
title- Type
- string
- Description
The product title.
- Name
description- Type
- string
- Description
The product description.
- Name
deliverable- Type
- array
- Description
Deliverable details of the product variant, consists of the following:
dataArray of deliverable data to be delivered. Consists of the following:serialsOnly applicable ifdeliverable.typescontainsTEXT. This array should contain all of your serials, separated by the delimiter you set inparsingMode.removeDuplicateWhether duplicateTEXTvalues should be removed.parsingModeIn which wayTEXTvalues are separated/parsed.commentOnly applicable ifdeliverable.typescontainsMANUAL. This string should specify what the next steps are for the manual delivery to be completed.fileOnly applicable ifdeliverable.typescontainsDOWNLOADABLE. If wanting to upload a file, make sure to send the request as a Multipart form instead of JSON.webhookOnly applicable ifdeliverable.typescontainsDYNAMIC. This string should be your dynamic webhook endpoint, which we ping following a successful purchase.stockSpecifies how much stock there is for the deliverable. Not required ifdeliverable.typescontainsTEXTas it is calculated automatically. If not present, stock will be set to infinite.
typesArray with values of the deliverable type(s) this product variant contains. Supported values:DOWNLOADABLEDownloadable file of any type.TEXTText products delivered one-by-one.DYNAMICGenerate a product via your webhook URL.MANUALA product that is manually carried out and/or delivered.
- Name
pricing- Type
- array
- Description
The product variant pricing array, contains the following values:
humbleWhether the product is of a "Pay what you want" type. If set totrue, the customer can add an extra amount of their choosing on top of the price.pricewhich contains the product price array. Consists of two values:priceproduct price, in centscurrencyCountry ISO code of the currency the product is priced in
- Name
minimum_purchase_quantity- Type
- integer
- Description
The minimum amount of stock a customer is required to purchase.
- Name
maximum_purchase_quantity- Type
- integer
- Description
The maximum amount of stock a customer is allowed to purchase. If set to null, the customer can purchase an unlimited amount of quantity.
- Name
payment_methods- Type
- array
- Description
This specifies which payment methods are available for the customer to check out with. Your store has to have a payment method activated in order for these to be set.
- Consists of at least one of the below values:
PAYPALPayPalSTRIPEStripeCASHAPPCash AppPADDLEPaddleAUTHNETAuthorize.netSQUARESquare
- Cryptocurrency payment methods:
BTCBitcoinLTCLitecoinETHEthereumXMRMoneroBNBBinance BNBTRXTronMATICPolygonETH_USDTUSDT (ETH network)ETH_USDCUSDC (ETH network)ETH_UNIUNI (ETH network)ETH_SHIBShiba (ETH network)ETH_DAIDAI (ETH network)BNB_USDTUSDT (BSC network)BNB_USDCUSDC (BSC network)TRX_USDTUSDT (TRX network)TRX_USDCUSDC (TRX network)
- Consists of at least one of the below values:
Optional attributes
- Name
bulk_discount- Type
- object
- Description
The bulk discount values of the product. Array consists of:
minimum_purchase_amountThe quantity at which the bulk discount gets triggered.discount_percentageThe discount value (in percentage) that gets applied to the product price.
- Name
other_settings- Type
- array
- Description
Array of additional settings pertaining to the product variant. Can consist of:
quantity_incrementsthat specifies by how much a product can be incremented.- The default is 1, which lets a customer purchase a quantity of 1,2,3 and so on
- When set to e.g. 2, the customer can only purchase a quantity of 1,3,5 and so on. A quantity of 2 would end up not being allowed.
Request
$client = new http\Client;
$request = new http\Client\Request;
$body = new http\Message\Body;
$body->append('{
"title": "Variant Title",
"description": "Variant Description",
"deliverable": {
"data": {
"serials": ["1", "2", "3"],
"comment": "Thanks for the purchase! I will send you a contract by email. Make sure to sign it with your blood.",
"removeDuplicate": false
},
"types": ["TEXT", "MANUAL"]
},
"pricing": {
"humble": true,
"price": {
"price": 1999,
"currency": "USD"
}
},
"minimum_purchase_quantity": 1,
"maximum_purchase_quantity": null,
"bulk_discount": [
{
"minimum_purchase_amount": 10,
"discount_percentage": 10
}
],
"payment_methods": [
"BTC",
"STRIPE"
],
"other_settings": {
"quantity_increments": 2
}
}');
$request->setRequestUrl('https://sell.app/api/v2/products/1/variants');
$request->setRequestMethod('POST');
$request->setBody($body);
$request->setHeaders([
'Content-Type' => 'application/json',
'Authorization' => 'Bearer {ApiKeyHere}'
]);
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();
Response
{
"data": {
"id": 2,
"product_id": 1,
"title": "Variant Title",
"description": "Variant Description",
"deliverable": {
"data": {
"removeDuplicate": false,
"parsingMode": "COMMA",
"stock": 3,
"comment": "Thanks for the purchase! I will send you a contract by email. Make sure to sign it with your blood.",
"serials": [
"1",
"2",
"3"
]
},
"types": [
"TEXT",
"MANUAL"
]
},
"pricing": {
"humble": true,
"frequency": {
"value": 1,
"interval": "MONTH"
},
"type": "SINGLE_PAYMENT",
"price": {
"price": "1999",
"currency": "USD"
}
},
"minimum_purchase_quantity": 1,
"maximum_purchase_quantity": 3,
"bulk_discount": [
{
"discount_percentage": 10,
"minimum_purchase_amount": 10
}
],
"payment_methods": [
"BTC",
"STRIPE"
],
"other_settings": {
"quantity_increments": 2,
"discord_data_required": false
},
"order": 1,
"created_at": "2024-01-10T18:47:22.000000Z",
"updated_at": "2024-01-10T18:47:22.000000Z",
"deleted_at": null,
"product": {
"additional_information": [
{
"required": true,
"key": "5ebae238c0afae7f4a4b96b30ff6f34c",
"type": "CHECKBOX",
"label": "I agree to handing over my soul"
}
]
}
}
}
Retrieve a product variant
This endpoint allows you to retrieve a specific product variant by providing the unique identifiers of both the product and variant. Refer to the list at the top of this page to see which properties are included with product objects.
Request
$client = new http\Client;
$request = new http\Client\Request;
$request->setRequestUrl('https://sell.app/api/v2/products/1/variants/2');
$request->setRequestMethod('GET');
$request->setHeaders([
'Content-Type' => 'application/json',
'Authorization' => 'Bearer {ApiKeyHere}'
]);
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();
Response
{
"data": {
"id": 2,
"product_id": 1,
"title": "Variant Title",
"description": "Variant Description",
"deliverable": {
"data": {
"removeDuplicate": false,
"parsingMode": "COMMA",
"stock": 3,
"comment": "Thanks for the purchase! I'll send you a contract by email. Make sure to sign it with your blood.",
"serials": [
"1",
"2",
"3"
]
},
"types": [
"TEXT",
"MANUAL"
]
},
"pricing": {
"humble": true,
"frequency": {
"value": 1,
"interval": "MONTH"
},
"type": "SINGLE_PAYMENT",
"price": {
"price": "1999",
"currency": "USD"
}
},
"minimum_purchase_quantity": 1,
"maximum_purchase_quantity": 3,
"bulk_discount": [
{
"discount_percentage": 10,
"minimum_purchase_amount": 10
}
],
"payment_methods": [
"BTC",
"STRIPE"
],
"other_settings": {
"quantity_increments": 2,
"discord_data_required": false
},
"order": 1,
"created_at": "2024-01-10T18:47:22.000000Z",
"updated_at": "2024-01-10T18:47:22.000000Z",
"deleted_at": null,
"product": {
"additional_information": [
{
"required": true,
"key": "5ebae238c0afae7f4a4b96b30ff6f34c",
"type": "CHECKBOX",
"label": "I agree to handing over my soul"
}
]
}
}
}
Update a product variant
This endpoint allows you to update a product variant's details.
Optional attributes
- Name
title- Type
- string
- Description
The product title.
- Name
description- Type
- string
- Description
The product description.
- Name
deliverable- Type
- array
- Description
Deliverable details of the product variant, consists of the following:
dataArray of deliverable data to be delivered. Consists of the following:serialsOnly applicable ifdeliverable.typescontainsTEXT. This array should contain all of your serials, separated by the delimiter you set inparsingMode.removeDuplicateWhether duplicateTEXTvalues should be removed.parsingModeIn which wayTEXTvalues are separated/parsed.commentOnly applicable ifdeliverable.typescontainsMANUAL. This string should specify what the next steps are for the manual delivery to be completed.fileOnly applicable ifdeliverable.typescontainsDOWNLOADABLE. If wanting to upload a file, make sure to send the request as a Multipart form instead of JSON.webhookOnly applicable ifdeliverable.typescontainsDYNAMIC. This string should be your dynamic webhook endpoint, which we ping following a successful purchase.stockSpecifies how much stock there is for the deliverable. Not required ifdeliverable.typescontainsTEXTas it is calculated automatically. If not present, stock will be set to infinite.
typesArray with values of the deliverable type(s) this product variant contains. Supported values:DOWNLOADABLEDownloadable file of any type.TEXTText products delivered one-by-one.DYNAMICGenerate a product via your webhook URL.MANUALA product that is manually carried out and/or delivered.
- Name
pricing- Type
- array
- Description
The product variant pricing array, contains the following values:
humbleWhether the product is of a "Pay what you want" type. If set totrue, the customer can add an extra amount of their choosing on top of the price.pricewhich contains the product price array. Consists of two values:priceproduct price, in centscurrencyCountry ISO code of the currency the product is priced in
- Name
minimum_purchase_quantity- Type
- integer
- Description
The minimum amount of stock a customer is required to purchase.
- Name
maximum_purchase_quantity- Type
- integer
- Description
The maximum amount of stock a customer is allowed to purchase. If set to null, the customer can purchase an unlimited amount of quantity.
- Name
payment_methods- Type
- array
- Description
This specifies which payment methods are available for the customer to check out with. Your store has to have a payment method activated in order for these to be set.
- Consists of at least one of the below values:
PAYPALPayPalSTRIPEStripeCASHAPPCash AppPADDLEPaddleAUTHNETAuthorize.netSQUARESquare
- Cryptocurrency payment methods:
BTCBitcoinLTCLitecoinETHEthereumXMRMoneroBNBBinance BNBTRXTronMATICPolygonETH_USDTUSDT (ETH network)ETH_USDCUSDC (ETH network)ETH_UNIUNI (ETH network)ETH_SHIBShiba (ETH network)ETH_DAIDAI (ETH network)BNB_USDTUSDT (BSC network)BNB_USDCUSDC (BSC network)TRX_USDTUSDT (TRX network)TRX_USDCUSDC (TRX network)
- Consists of at least one of the below values:
- Name
bulk_discount- Type
- object
- Description
The bulk discount values of the product. Array consists of:
minimum_purchase_amountThe quantity at which the bulk discount gets triggered.discount_percentageThe discount value (in percentage) that gets applied to the product price.
- Name
other_settings- Type
- array
- Description
Array of additional settings pertaining to the product variant. Can consist of:
quantity_incrementsthat specifies by how much a product can be incremented.- The default is 1, which lets a customer purchase a quantity of 1,2,3 and so on
- When set to e.g. 2, the customer can only purchase a quantity of 1,3,5 and so on. A quantity of 2 would end up not being allowed.
Request
$client = new http\Client;
$request = new http\Client\Request;
$body = new http\Message\Body;
$body->append('{
"title": "Updated Title"
}');
$request->setRequestUrl('https://sell.app/api/v2/products/1/variants/2');
$request->setRequestMethod('PATCH');
$request->setBody($body);
$request->setHeaders([
'Content-Type' => 'application/json',
'Authorization' => 'Bearer {ApiKeyHere}'
]);
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();
Response
{
"data": {
"id": 2,
"product_id": 1,
"title": "Updated Title",
"description": "Variant Description",
"deliverable": {
"data": {
"removeDuplicate": false,
"parsingMode": "COMMA",
"stock": 3,
"comment": "Thanks for the purchase! I'll send you a contract by email. Make sure to sign it with your blood.",
"serials": [
"1",
"2",
"3"
]
},
"types": [
"TEXT",
"MANUAL"
]
},
"pricing": {
"humble": true,
"frequency": {
"value": 1,
"interval": "MONTH"
},
"type": "SINGLE_PAYMENT",
"price": {
"price": "1999",
"currency": "USD"
}
},
"minimum_purchase_quantity": 1,
"maximum_purchase_quantity": 3,
"bulk_discount": [
{
"discount_percentage": 10,
"minimum_purchase_amount": 10
}
],
"payment_methods": [
"BTC",
"STRIPE"
],
"other_settings": {
"quantity_increments": 2,
"discord_data_required": false
},
"order": 1,
"created_at": "2024-01-10T18:47:22.000000Z",
"updated_at": "2024-01-10T18:47:22.000000Z",
"deleted_at": null,
"product": {
"additional_information": [
{
"required": true,
"key": "5ebae238c0afae7f4a4b96b30ff6f34c",
"type": "CHECKBOX",
"label": "I agree to handing over my soul"
}
]
}
}
}
Delete a product variant
This endpoint allows you to delete a product variant.
This will permanently delete the product variant and all of its details, including the sensitive deliverables, will no longer be retrievable.
Request
$client = new http\Client;
$request = new http\Client\Request;
$request->setRequestUrl('https://sell.app/api/v2/products/1/variants/2');
$request->setRequestMethod('DELETE');
$request->setHeaders([
'accept' => 'application/json',
'Authorization' => 'Bearer {ApiKeyHere}'
]);
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();