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
UUID of the product to delete
Authentication
Your TribeMade API key (format: tb-xxxx-xxx-xxxx)
Response
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"
Success Response
{
"message" : "Product deleted successfully"
}
Error Responses
404 Not Found
{
"error" : "Product not found or does not belong to this store"
}
Causes:
Product ID doesn’t exist
Product belongs to a different store
Product was already deleted
Fix: Verify the product ID is correct and belongs to your store.
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."
}
Cause: Product has orders in active states (started, processing, or dispatched).
Why: Deleting products with active orders would break order fulfillment and customer experience.
Solution Options:
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: false to 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"
}
or
{
"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 " \n Summary:" )
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?
Maintains order references
Keeps sales data for analytics
Can be reactivated anytime
Historical sales data remains intact
Revenue reports stay accurate
Customer order history preserved
Seasonal products can be easily reactivated
No need to recreate product data
Images and details remain intact
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
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?
If yes to any, use deactivation instead of deletion.
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
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
Track all deletion operations:
Product ID and name
Deletion timestamp
Success/failure status
Reason for deletion
Useful for audit trails and debugging.
Once deleted:
Product data cannot be recovered
Must recreate from scratch if needed
All product details, images, and metadata are lost
Consider exporting product data before bulk deletions.
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
Don’t delete when:
❌ 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