Delete a product
curl --request DELETE \
--url https://api-eu.flexportal.io/v1/products/{productId} \
--header 'Authorization: Bearer <token>' \
--header 'Tenant-ID: <tenant-id>'import requests
url = "https://api-eu.flexportal.io/v1/products/{productId}"
headers = {
"Tenant-ID": "<tenant-id>",
"Authorization": "Bearer <token>"
}
response = requests.delete(url, headers=headers)
print(response.text)const options = {
method: 'DELETE',
headers: {'Tenant-ID': '<tenant-id>', Authorization: 'Bearer <token>'}
};
fetch('https://api-eu.flexportal.io/v1/products/{productId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-eu.flexportal.io/v1/products/{productId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Tenant-ID: <tenant-id>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api-eu.flexportal.io/v1/products/{productId}"
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("Tenant-ID", "<tenant-id>")
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.delete("https://api-eu.flexportal.io/v1/products/{productId}")
.header("Tenant-ID", "<tenant-id>")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-eu.flexportal.io/v1/products/{productId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["Tenant-ID"] = '<tenant-id>'
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"success": true,
"message": "<string>",
"productId": "<string>",
"productSku": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}Products
Delete Product
Soft deletes a product by setting status to discontinued. Also deactivates all associated variants.
DELETE
/
v1
/
products
/
{productId}
Delete a product
curl --request DELETE \
--url https://api-eu.flexportal.io/v1/products/{productId} \
--header 'Authorization: Bearer <token>' \
--header 'Tenant-ID: <tenant-id>'import requests
url = "https://api-eu.flexportal.io/v1/products/{productId}"
headers = {
"Tenant-ID": "<tenant-id>",
"Authorization": "Bearer <token>"
}
response = requests.delete(url, headers=headers)
print(response.text)const options = {
method: 'DELETE',
headers: {'Tenant-ID': '<tenant-id>', Authorization: 'Bearer <token>'}
};
fetch('https://api-eu.flexportal.io/v1/products/{productId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-eu.flexportal.io/v1/products/{productId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Tenant-ID: <tenant-id>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api-eu.flexportal.io/v1/products/{productId}"
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("Tenant-ID", "<tenant-id>")
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.delete("https://api-eu.flexportal.io/v1/products/{productId}")
.header("Tenant-ID", "<tenant-id>")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-eu.flexportal.io/v1/products/{productId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["Tenant-ID"] = '<tenant-id>'
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"success": true,
"message": "<string>",
"productId": "<string>",
"productSku": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}Overview
Discontinue a product by marking it as inactive. This is a soft delete—the product is hidden from active catalog queries but preserved for historical records and existing subscriptions.Products cannot be permanently deleted if they have associated orders or subscriptions. This ensures data integrity and accurate historical reporting.
What Happens When You Delete a Product
- Product status changes to
discontinued - All variants are marked as
inactive - New orders cannot use this product’s SKUs
- Existing subscriptions continue unaffected
- Historical data is preserved for reporting
Common Use Cases
- End of Life: Product is no longer available from suppliers
- Catalog Cleanup: Remove products that are no longer offered
- Replacement: Old product replaced by new model
- Temporary Removal: Pause product while resolving supply issues
Before Deleting
Check for active usage:// Get product details to check for active orders
const product = await getProduct('prod_abc123');
// Check for pending orders using this product's variants
const pendingOrders = await listOrders({
status: 'pending',
// Filter by product variants would need to be done client-side
});
// Check for active subscriptions
const activeSubscriptions = await listSubscriptions({
status: 'active',
sku: product.variants[0].sku
});
if (activeSubscriptions.count > 0) {
console.log('Warning: Product has active subscriptions');
}
Reactivating a Discontinued Product
To bring back a discontinued product, use the Update Product endpoint:PUT /v1/products/{productId}
{
"status": "active"
}
Alternative: Deactivate Specific Variants
If you only want to remove certain variants (not the whole product), update individual variant status instead:PATCH /v1/products/variants/{variantId}/status
{
"status": "inactive"
}
Error Handling
| Error Code | Cause | Solution |
|---|---|---|
NOT_FOUND | Product doesn’t exist | Verify product ID |
PRODUCT_HAS_ACTIVE_ORDERS | Cannot delete with pending orders | Complete or cancel orders first |
Related Endpoints
- Get Product - Check product details before deletion
- Update Product - Reactivate or modify product
- List Products - View active catalog
Authorizations
API key obtained from FlexPortal dashboard
Headers
Your tenant identifier
Path Parameters
The product ID
Was this page helpful?