Delete Product
curl --request DELETE \
--url https://api.example.com/api/products/{product_id} \
--header 'X-API-Key: <x-api-key>'import requests
url = "https://api.example.com/api/products/{product_id}"
headers = {"X-API-Key": "<x-api-key>"}
response = requests.delete(url, headers=headers)
print(response.text)const options = {method: 'DELETE', headers: {'X-API-Key': '<x-api-key>'}};
fetch('https://api.example.com/api/products/{product_id}', 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.example.com/api/products/{product_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_HTTPHEADER => [
"X-API-Key: <x-api-key>"
],
]);
$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.example.com/api/products/{product_id}"
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("X-API-Key", "<x-api-key>")
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.example.com/api/products/{product_id}")
.header("X-API-Key", "<x-api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/products/{product_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["X-API-Key"] = '<x-api-key>'
response = http.request(request)
puts response.read_body{
"message": "<string>"
}Product APIs
Delete Product
Permanently delete a product from your store
DELETE
/
api
/
products
/
{product_id}
Delete Product
curl --request DELETE \
--url https://api.example.com/api/products/{product_id} \
--header 'X-API-Key: <x-api-key>'import requests
url = "https://api.example.com/api/products/{product_id}"
headers = {"X-API-Key": "<x-api-key>"}
response = requests.delete(url, headers=headers)
print(response.text)const options = {method: 'DELETE', headers: {'X-API-Key': '<x-api-key>'}};
fetch('https://api.example.com/api/products/{product_id}', 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.example.com/api/products/{product_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_HTTPHEADER => [
"X-API-Key: <x-api-key>"
],
]);
$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.example.com/api/products/{product_id}"
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("X-API-Key", "<x-api-key>")
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.example.com/api/products/{product_id}")
.header("X-API-Key", "<x-api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/products/{product_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["X-API-Key"] = '<x-api-key>'
response = http.request(request)
puts response.read_body{
"message": "<string>"
}Overview
Permanently delete a product from your store. This action cannot be undone.Important: Products can only be deleted if they have no active orders. Products with orders in
processing or dispatched status cannot be deleted.Rate Limit: 10 requests per minute (intentionally limited for safety)
Endpoint
DELETE https://api.tribemade.in/api/products/{product_id}
Path Parameters
string
required
UUID of the product to delete
Authentication
string
required
Your TribeMade API key (format:
tb-xxxx-xxx-xxxx)Response
string
Success message: “Product deleted successfully”
Deletion Rules
✅ CAN Delete
Products with no orders or only completed/cancelled orders:- Products with no orders at all
- Products with only completed orders (delivered)
- Products with only cancelled orders
- Products with mix of completed/cancelled orders
❌ CANNOT Delete
Products with active orders:- Products with started orders (payment received)
- Products with processing orders (being prepared)
- Products with dispatched orders (shipped)
This prevents breaking order fulfillment. Wait for active orders to complete or cancel them first.
Examples
Basic Delete
curl -X DELETE https://api.tribemade.in/api/products/660e8400-e29b-41d4-a716-446655440123 \
-H "X-API-Key: tb-a1b2-c3d-e4f5"
import requests
product_id = "660e8400-e29b-41d4-a716-446655440123"
url = f"https://api.tribemade.in/api/products/{product_id}"
headers = {
"X-API-Key": "tb-a1b2-c3d-e4f5"
}
response = requests.delete(url, headers=headers)
print(response.json())
# Output: {"message": "Product deleted successfully"}
const fetch = require('node-fetch');
const productId = '660e8400-e29b-41d4-a716-446655440123';
const url = `https://api.tribemade.in/api/products/${productId}`;
const headers = {
'X-API-Key': 'tb-a1b2-c3d-e4f5'
};
fetch(url, {
method: 'DELETE',
headers: headers
})
.then(response => response.json())
.then(data => console.log(data));
// Output: {"message": "Product deleted successfully"}
<?php
$product_id = '660e8400-e29b-41d4-a716-446655440123';
$url = "https://api.tribemade.in/api/products/{$product_id}";
$headers = array(
'X-API-Key: tb-a1b2-c3d-e4f5'
);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
// Output: {"message": "Product deleted successfully"}
?>
Success Response
{
"message": "Product deleted successfully"
}
Error Responses
404 Not Found
{
"error": "Product not found or does not belong to this store"
}
- Product ID doesn’t exist
- Product belongs to a different store
- Product was already deleted
400 Bad Request - Has Active Orders
{
"error": "Cannot delete product with active orders in processing or dispatched status. Please wait for orders to complete or cancel them first."
}
- Wait for orders to complete - Orders will naturally progress to delivered status
- Cancel the orders - Use Update Order Status API to cancel orders
- Deactivate instead - Use Edit Product to set
is_active: falseto hide the product
Consider deactivating products (
is_active: false) instead of deleting if you want to preserve product history.401 Unauthorized
{
"error": "Invalid API key"
}
{
"error": "Missing API key"
}
429 Too Many Requests
{
"error": "Rate limit exceeded",
"retry_after": 60
}
Safe Deletion Workflow
Step 1: Check for Active Orders
Before deleting, check if the product has active orders:import requests
def can_delete_product(product_id):
"""
Check if a product can be safely deleted
Returns: (can_delete: bool, reason: str)
"""
# In a real implementation, you'd query your order database
# or use a hypothetical "Get Product Orders" endpoint
# For now, just attempt deletion and handle the error
url = f"https://api.tribemade.in/api/products/{product_id}"
headers = {"X-API-Key": "tb-a1b2-c3d-e4f5"}
response = requests.delete(url, headers=headers)
if response.status_code == 200:
return True, "Product deleted successfully"
elif response.status_code == 400:
error = response.json()['error']
if 'active orders' in error:
return False, "Has active orders"
elif response.status_code == 404:
return False, "Product not found"
return False, "Unknown error"
# Usage
can_delete, reason = can_delete_product("660e8400-...")
print(f"Can delete: {can_delete}, Reason: {reason}")
Step 2: Deactivate Instead
If deletion fails due to active orders, deactivate the product instead:import requests
def delete_or_deactivate_product(product_id):
"""
Try to delete product, deactivate if deletion fails
"""
base_url = "https://api.tribemade.in/api/products"
headers = {
"X-API-Key": "tb-a1b2-c3d-e4f5",
"Content-Type": "application/json"
}
# Try to delete
delete_url = f"{base_url}/{product_id}"
response = requests.delete(delete_url, headers=headers)
if response.status_code == 200:
print(f"✓ Product {product_id} deleted successfully")
return "deleted"
elif response.status_code == 400:
error = response.json()['error']
if 'active orders' in error:
# Deactivate instead
edit_url = f"{base_url}/{product_id}/edit"
data = {
"is_active": False,
"internal_note": "Marked for deletion - has active orders"
}
edit_response = requests.put(edit_url, headers=headers, json=data)
if edit_response.status_code == 200:
print(f"⚠ Product {product_id} has active orders - deactivated instead")
return "deactivated"
print(f"✗ Failed to delete or deactivate product {product_id}")
return "failed"
# Usage
result = delete_or_deactivate_product("660e8400-...")
Bulk Deletion
Delete multiple products with proper error handling:import requests
import time
def bulk_delete_products(product_ids):
"""
Delete multiple products with safety checks
Returns: {
"deleted": [...],
"deactivated": [...],
"failed": [...]
}
"""
base_url = "https://api.tribemade.in/api/products"
headers = {
"X-API-Key": "tb-a1b2-c3d-e4f5",
"Content-Type": "application/json"
}
results = {
"deleted": [],
"deactivated": [],
"failed": []
}
for i, product_id in enumerate(product_ids):
# Try to delete
delete_url = f"{base_url}/{product_id}"
response = requests.delete(delete_url, headers=headers)
if response.status_code == 200:
results["deleted"].append(product_id)
print(f"✓ Deleted: {product_id}")
elif response.status_code == 400:
error = response.json()['error']
if 'active orders' in error:
# Deactivate instead
edit_url = f"{base_url}/{product_id}/edit"
data = {"is_active": False}
edit_response = requests.put(edit_url, headers=headers, json=data)
if edit_response.status_code == 200:
results["deactivated"].append(product_id)
print(f"⚠ Deactivated (has orders): {product_id}")
else:
results["failed"].append(product_id)
print(f"✗ Failed: {product_id}")
elif response.status_code == 404:
print(f"⚠ Not found: {product_id}")
results["failed"].append(product_id)
else:
results["failed"].append(product_id)
print(f"✗ Error: {product_id}")
# Respect rate limit (10 req/min for delete)
# Process ~8 per minute to be safe
if (i + 1) % 8 == 0 and i + 1 < len(product_ids):
print("Waiting 60s for rate limit...")
time.sleep(60)
else:
time.sleep(7) # ~8-9 requests per minute
return results
# Usage
product_ids = [
"660e8400-e29b-41d4-a716-446655440123",
"770e8400-e29b-41d4-a716-446655440124",
"880e8400-e29b-41d4-a716-446655440125"
]
results = bulk_delete_products(product_ids)
print(f"\nSummary:")
print(f"Deleted: {len(results['deleted'])}")
print(f"Deactivated: {len(results['deactivated'])}")
print(f"Failed: {len(results['failed'])}")
Alternative: Deactivate Instead of Delete
In most cases, it’s better to deactivate products rather than delete them:Why Deactivate?
Preserve History
Preserve History
- Maintains order references
- Keeps sales data for analytics
- Can be reactivated anytime
Maintain Analytics
Maintain Analytics
- Historical sales data remains intact
- Revenue reports stay accurate
- Customer order history preserved
Easy Reactivation
Easy Reactivation
- Seasonal products can be easily reactivated
- No need to recreate product data
- Images and details remain intact
Safer Operation
Safer Operation
- No risk of accidentally deleting important products
- Can’t delete products with active orders
- Reversible action
How to Deactivate
Use the Edit Product API:import requests
def deactivate_product(product_id, reason=""):
"""
Deactivate a product instead of deleting
"""
url = f"https://api.tribemade.in/api/products/{product_id}/edit"
headers = {
"X-API-Key": "tb-a1b2-c3d-e4f5",
"Content-Type": "application/json"
}
data = {
"is_active": False,
"internal_note": f"Deactivated: {reason}" if reason else "Deactivated"
}
response = requests.put(url, headers=headers, json=data)
if response.status_code == 200:
print(f"✓ Product {product_id} deactivated")
return True
else:
print(f"✗ Failed to deactivate {product_id}")
return False
# Usage
deactivate_product(
"660e8400-...",
reason="Out of stock, waiting for supplier"
)
Best Practices
Consider deactivation first
Consider deactivation first
Before deleting, ask yourself:
- Will I need this product again? (seasonal items)
- Does it have order history I want to preserve?
- Am I just temporarily out of stock?
Respect the lower rate limit
Respect the lower rate limit
Delete endpoint is limited to 10 requests per minute (vs 20 for other operations):
- Process ~8 products per minute to be safe
- Add delays between deletion requests
- This is intentional for safety
Always handle errors gracefully
Always handle errors gracefully
Products with active orders can’t be deleted:
- Implement fallback to deactivation
- Log products that couldn’t be deleted
- Retry later or manually handle edge cases
Keep deletion logs
Keep deletion logs
Track all deletion operations:
- Product ID and name
- Deletion timestamp
- Success/failure status
- Reason for deletion
Deletion is permanent
Deletion is permanent
Once deleted:
- Product data cannot be recovered
- Must recreate from scratch if needed
- All product details, images, and metadata are lost
When to Actually Delete
Delete products when:- ✅ Product was created by mistake
- ✅ Duplicate products that need cleanup
- ✅ Test products from development
- ✅ Products with no orders and never will be sold again
- ✅ Old products that have been replaced and all orders are completed
- ❌ Product is temporarily out of stock (deactivate instead)
- ❌ Seasonal products (deactivate and reactivate later)
- ❌ Products with active orders
- ❌ Products with valuable sales history
- ❌ You might want to resell similar products later
Next Steps
Edit Product
Deactivate products instead of deleting
Create Product
Create new products
Order APIs
Manage orders programmatically
Rate Limits
Understand deletion rate limits

