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:
data
Array of deliverable data to be delivered. Consists of the following:serials
Only applicable ifdeliverable.types
containsTEXT
. This array should contain all of your serials, separated by the delimiter you set inparsingMode
.removeDuplicate
Whether duplicateTEXT
values should be removed.parsingMode
In which wayTEXT
values are separated/parsed.comment
Only applicable ifdeliverable.types
containsMANUAL
. This string should specify what the next steps are for the manual delivery to be completed.file
Only applicable ifdeliverable.types
containsDOWNLOADABLE
. If wanting to upload a file, make sure to send the request as a Multipart form instead of JSON.webhook
Only applicable ifdeliverable.types
containsDYNAMIC
. This string should be your dynamic webhook endpoint, which we ping following a successful purchase.stock
Specifies how much stock there is for the deliverable. Not required ifdeliverable.types
containsTEXT
as it is calculated automatically. If not present, stock will be set to infinite.
types
Array with values of the deliverable type(s) this product variant contains. Supported values:DOWNLOADABLE
Downloadable file of any type.TEXT
Text products delivered one-by-one.DYNAMIC
Generate a product via your webhook URL.MANUAL
A product that is manually carried out and/or delivered.
- Name
pricing
- Type
- array
- Description
The product variant pricing array, contains the following values:
humble
Whether 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.frequency
array that specifies how often a product should be charged. Consists of two values:value
that specifies the period durationinterval
that specifies the interval between values. Can be days, weeks, months. Up to 1 year.
type
that contains a string of the charge frequency. One of two values:SINGLE_PAYMENT
for one-off chargesSUBSCRIPTION
for recurring charges- At the moment, only Stripe is supported for subscriptions
price
which contains the product price array. Consists of two values:price
product price, in centscurrency
Country 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_amount
The quantity at which the bulk discount gets triggered.discount_percentage
The 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:
PAYPAL
PayPalSTRIPE
StripeCASHAPP
Cash AppCOINBASE
Coinbase CommercePADDLE
PaddlePAYSTACK
PayStackBTCPAY
BitcoinVENMO
VenmoSQUARE
Square
- Cryptocurrency payment methods:
BTC
BitcoinLTC
LitecoinETH
EthereumXMR
MoneroSOL
SolanaADA
Cardano
- 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_increments
that 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_required
which 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:
required
specifying whether the additional information is requiredkey
unique key of the additional information inputtype
One of the followingTEXT
NUMBER
HIDDEN
TEXTAREA
CHECKBOX
label
specifying what the customer needs to enter. Examples belowTEXT
What is your in-game username?NUMBER
To what mobile number do you want this delivered?HIDDEN
n.a. (as this is a hidden input not visible to the end-user)TEXTAREA
Please specify what your website should look like.CHECKBOX
Would 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:
data
Array of deliverable data to be delivered. Consists of the following:serials
Only applicable ifdeliverable.types
containsTEXT
. This array should contain all of your serials, separated by the delimiter you set inparsingMode
.removeDuplicate
Whether duplicateTEXT
values should be removed.parsingMode
In which wayTEXT
values are separated/parsed.comment
Only applicable ifdeliverable.types
containsMANUAL
. This string should specify what the next steps are for the manual delivery to be completed.file
Only applicable ifdeliverable.types
containsDOWNLOADABLE
. If wanting to upload a file, make sure to send the request as a Multipart form instead of JSON.webhook
Only applicable ifdeliverable.types
containsDYNAMIC
. This string should be your dynamic webhook endpoint, which we ping following a successful purchase.stock
Specifies how much stock there is for the deliverable. Not required ifdeliverable.types
containsTEXT
as it is calculated automatically. If not present, stock will be set to infinite.
types
Array with values of the deliverable type(s) this product variant contains. Supported values:DOWNLOADABLE
Downloadable file of any type.TEXT
Text products delivered one-by-one.DYNAMIC
Generate a product via your webhook URL.MANUAL
A product that is manually carried out and/or delivered.
- Name
pricing
- Type
- array
- Description
The product variant pricing array, contains the following values:
humble
Whether 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.price
which contains the product price array. Consists of two values:price
product price, in centscurrency
Country 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:
PAYPAL
PayPalSTRIPE
StripeCASHAPP
Cash AppCOINBASE
Coinbase CommercePADDLE
PaddlePAYSTACK
PayStackBTCPAY
BitcoinVENMO
VenmoSQUARE
Square
- Cryptocurrency payment methods:
BTC
BitcoinLTC
LitecoinETH
EthereumXMR
MoneroSOL
SolanaADA
Cardano
- 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_amount
The quantity at which the bulk discount gets triggered.discount_percentage
The 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_increments
that 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": [
"BTCPAY",
"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": [
"BTCPAY",
"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": [
"BTCPAY",
"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:
data
Array of deliverable data to be delivered. Consists of the following:serials
Only applicable ifdeliverable.types
containsTEXT
. This array should contain all of your serials, separated by the delimiter you set inparsingMode
.removeDuplicate
Whether duplicateTEXT
values should be removed.parsingMode
In which wayTEXT
values are separated/parsed.comment
Only applicable ifdeliverable.types
containsMANUAL
. This string should specify what the next steps are for the manual delivery to be completed.file
Only applicable ifdeliverable.types
containsDOWNLOADABLE
. If wanting to upload a file, make sure to send the request as a Multipart form instead of JSON.webhook
Only applicable ifdeliverable.types
containsDYNAMIC
. This string should be your dynamic webhook endpoint, which we ping following a successful purchase.stock
Specifies how much stock there is for the deliverable. Not required ifdeliverable.types
containsTEXT
as it is calculated automatically. If not present, stock will be set to infinite.
types
Array with values of the deliverable type(s) this product variant contains. Supported values:DOWNLOADABLE
Downloadable file of any type.TEXT
Text products delivered one-by-one.DYNAMIC
Generate a product via your webhook URL.MANUAL
A product that is manually carried out and/or delivered.
- Name
pricing
- Type
- array
- Description
The product variant pricing array, contains the following values:
humble
Whether 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.price
which contains the product price array. Consists of two values:price
product price, in centscurrency
Country 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:
PAYPAL
PayPalSTRIPE
StripeCASHAPP
Cash AppCOINBASE
Coinbase CommercePADDLE
PaddlePAYSTACK
PayStackBTCPAY
BitcoinVENMO
VenmoSQUARE
Square
- Cryptocurrency payment methods:
BTC
BitcoinLTC
LitecoinETH
EthereumXMR
MoneroSOL
SolanaADA
Cardano
- 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_amount
The quantity at which the bulk discount gets triggered.discount_percentage
The 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_increments
that 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": [
"BTCPAY",
"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();