Fetch Product
The Fetch Product endpoint retrieves detailed information about a specific product by its unique identifier. This endpoint provides comprehensive product details including pricing, inventory, images, variations, transaction history, and associated wallet information.
Endpoint DetailsCopied!
-
Method:
GET
-
URL:
/api/v0/products/{id}
-
Authentication: Required (API Key & Secret)
-
Rate Limiting: 1000 requests per minute
Path ParametersCopied!
Parameter |
Type |
Required |
Description |
Example |
---|---|---|---|---|
|
string (UUID) |
Yes |
Unique product identifier |
|
Request ExamplesCopied!
Basic Product Fetch
curl -X GET "https://api.devdraft.com/api/v0/products/550e8400-e29b-41d4-a716-446655440000" \
-H "x-client-key: YOUR_CLIENT_KEY" \
-H "x-client-secret: YOUR_CLIENT_SECRET"
JavaScript/Node.js Example
const fetchProduct = async (productId) => {
try {
const response = await fetch(`https://api.devdraft.com/api/v0/products/${productId}`, {
method: 'GET',
headers: {
'x-client-key': 'YOUR_CLIENT_KEY',
'x-client-secret': 'YOUR_CLIENT_SECRET'
}
});
if (!response.ok) {
if (response.status === 404) {
throw new Error('Product not found');
}
throw new Error(`HTTP error! status: ${response.status}`);
}
const product = await response.json();
return product;
} catch (error) {
console.error('Error fetching product:', error);
throw error;
}
};
// Usage
try {
const product = await fetchProduct('550e8400-e29b-41d4-a716-446655440000');
console.log(`Product: ${product.name} - $${product.price}`);
console.log(`Stock: ${product.stockCount || 'Unlimited'}`);
} catch (error) {
console.error('Failed to fetch product:', error.message);
}
Python Example
import requests
import json
def fetch_product(product_id, client_key, client_secret):
url = f"https://api.devdraft.com/api/v0/products/{product_id}"
headers = {
'x-client-key': client_key,
'x-client-secret': client_secret
}
try:
response = requests.get(url, headers=headers)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
if response.status_code == 404:
raise ValueError("Product not found")
raise e
except requests.exceptions.RequestException as e:
raise e
# Usage
try:
product = fetch_product(
"550e8400-e29b-41d4-a716-446655440000",
"YOUR_CLIENT_KEY",
"YOUR_CLIENT_SECRET"
)
print(f"Product: {product['name']} - ${product['price']}")
except ValueError as e:
print(f"Error: {e}")
Response FormatCopied!
Success Response (200 OK)
Digital Product Example
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Premium Software License",
"description": "Annual license for our premium software suite with advanced features, priority support, and regular updates. Includes access to all premium modules, 24/7 customer support, and free upgrades for one year.",
"price": 299.99,
"currency": "USD",
"productType": "PRODUCT",
"status": "ACTIVE",
"stockCount": null,
"quantity": null,
"weight": null,
"unit": null,
"images": [
"https://devdraft-images.s3.amazonaws.com/products/software-license-main.jpg",
"https://devdraft-images.s3.amazonaws.com/products/software-license-features.jpg"
],
"variations": null,
"paymentLink": "https://pay.devdraft.com/p/premium-license",
"walletId": "abcd1234-5678-90ef-ghij-klmnopqrstuv",
"dateAdded": "2024-01-15T10:30:00.000Z",
"dateUpdated": "2024-01-15T10:30:00.000Z",
"wallet": {
"id": "abcd1234-5678-90ef-ghij-klmnopqrstuv",
"address": "0x742d35Cc6635C0532925a3b8d",
"blockchain": "ETHEREUM",
"type": "APP"
},
"transactions": []
}
Physical Product with Variations Example
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"name": "Wireless Bluetooth Headphones",
"description": "Premium wireless headphones with active noise cancellation, 30-hour battery life, and superior sound quality. Perfect for music, calls, and travel.",
"price": 199.99,
"currency": "USD",
"productType": "PRODUCT",
"status": "ACTIVE",
"stockCount": 85,
"quantity": 100,
"weight": 0.5,
"unit": "kg",
"images": [
"https://devdraft-images.s3.amazonaws.com/products/headphones-main.jpg",
"https://devdraft-images.s3.amazonaws.com/products/headphones-side.jpg",
"https://devdraft-images.s3.amazonaws.com/products/headphones-case.jpg"
],
"variations": [
{
"id": "color_variant",
"type": "Color",
"options": [
{
"name": "Midnight Black",
"value": "black",
"priceAdjustment": 0
},
{
"name": "Pearl White",
"value": "white",
"priceAdjustment": 0
},
{
"name": "Ocean Blue",
"value": "blue",
"priceAdjustment": 15.00
}
]
},
{
"id": "warranty_variant",
"type": "Warranty",
"options": [
{
"name": "Standard (1 Year)",
"value": "standard",
"priceAdjustment": 0
},
{
"name": "Extended (3 Years)",
"value": "extended",
"priceAdjustment": 49.99
}
]
}
],
"paymentLink": "https://pay.devdraft.com/p/wireless-headphones",
"walletId": "abcd1234-5678-90ef-ghij-klmnopqrstuv",
"dateAdded": "2024-01-14T14:20:00.000Z",
"dateUpdated": "2024-01-16T09:15:00.000Z",
"wallet": {
"id": "abcd1234-5678-90ef-ghij-klmnopqrstuv",
"address": "0x742d35Cc6635C0532925a3b8d",
"blockchain": "ETHEREUM",
"type": "APP"
},
"transactions": [
{
"id": "txn_123456789",
"amount": 199.99,
"currency": "USD",
"status": "PAYMENT_PROCESSED",
"type": "PAYMENT",
"dateCreated": "2024-01-16T09:15:00.000Z",
"customer": {
"id": "cust_987654321",
"email": "customer@example.com"
}
},
{
"id": "txn_123456790",
"amount": 214.99,
"currency": "USD",
"status": "PAYMENT_PROCESSED",
"type": "PAYMENT",
"dateCreated": "2024-01-15T16:30:00.000Z",
"customer": {
"id": "cust_987654322",
"email": "another@example.com"
}
}
]
}
Service Product Example
{
"id": "550e8400-e29b-41d4-a716-446655440002",
"name": "Business Strategy Consultation",
"description": "Comprehensive 90-minute business strategy consultation with industry experts. Includes market analysis, competitive positioning, and actionable recommendations for growth.",
"price": 250.00,
"currency": "USD",
"productType": "SERVICE",
"status": "ACTIVE",
"stockCount": null,
"quantity": 20,
"weight": null,
"unit": "session",
"images": [
"https://devdraft-images.s3.amazonaws.com/products/consultation-service.jpg"
],
"variations": [
{
"id": "duration_variant",
"type": "Duration",
"options": [
{
"name": "60 minutes",
"value": "60min",
"priceAdjustment": -50.00
},
{
"name": "90 minutes (Recommended)",
"value": "90min",
"priceAdjustment": 0
},
{
"name": "120 minutes",
"value": "120min",
"priceAdjustment": 75.00
}
]
}
],
"paymentLink": "https://pay.devdraft.com/p/strategy-consultation",
"walletId": "abcd1234-5678-90ef-ghij-klmnopqrstuv",
"dateAdded": "2024-01-10T08:00:00.000Z",
"dateUpdated": "2024-01-12T14:45:00.000Z",
"wallet": {
"id": "abcd1234-5678-90ef-ghij-klmnopqrstuv",
"address": "0x742d35Cc6635C0532925a3b8d",
"blockchain": "ETHEREUM",
"type": "APP"
},
"transactions": [
{
"id": "txn_123456791",
"amount": 325.00,
"currency": "USD",
"status": "PAYMENT_PROCESSED",
"type": "PAYMENT",
"dateCreated": "2024-01-12T10:20:00.000Z",
"customer": {
"id": "cust_987654323",
"email": "business@example.com"
}
}
]
}
Response Fields ReferenceCopied!
Core Product Fields
Field |
Type |
Description |
Example |
---|---|---|---|
|
string |
Unique product identifier (UUID) |
|
|
string |
Product display name |
|
|
string |
Detailed product description |
|
|
number |
Base product price |
|
|
string |
Price currency (USD, EUR, USDC, EURC) |
|
|
enum |
Product category ( |
|
|
enum |
Availability status ( |
|
Inventory & Physical Properties
Field |
Type |
Description |
Example |
---|---|---|---|
|
number|null |
Current stock level |
|
|
number|null |
Available quantity/slots |
|
|
number|null |
Product weight |
|
|
string|null |
Unit of measurement |
|
Media & Links
Field |
Type |
Description |
Example |
---|---|---|---|
|
array |
Product image URLs |
|
|
string|null |
Direct payment URL |
|
Variations & Options
Field |
Type |
Description |
Example |
---|---|---|---|
|
array|null |
Product variations/options |
See variation structure |
Timestamps
Field |
Type |
Description |
Example |
---|---|---|---|
|
string |
Creation timestamp (ISO 8601) |
|
|
string|null |
Last modification timestamp |
|
Related Objects
Field |
Type |
Description |
---|---|---|
|
object|null |
Associated wallet information |
|
array |
Recent product transactions |
Error ResponsesCopied!
Product Not Found (404 Not Found)
{
"statusCode": 404,
"message": "Product not found",
"error": "Not Found"
}
Invalid UUID Format (400 Bad Request)
{
"statusCode": 400,
"message": "Invalid product ID format. Must be a valid UUID.",
"error": "Bad Request"
}
Authentication Error (401 Unauthorized)
{
"statusCode": 401,
"message": "Invalid or missing API credentials",
"error": "Unauthorized"
}
Rate Limit Exceeded (429 Too Many Requests)
{
"statusCode": 429,
"message": "Rate limit exceeded. Maximum 1000 requests per minute.",
"error": "Too Many Requests",
"retryAfter": 60
}
Use Cases & ExamplesCopied!
Product Detail Display
// Display product in e-commerce interface
const displayProduct = async (productId) => {
try {
const product = await fetchProduct(productId);
// Calculate total price with variations
const calculatePrice = (basePrice, selectedVariations = []) => {
return selectedVariations.reduce((total, selection) => {
const variation = product.variations?.find(v => v.id === selection.variationId);
const option = variation?.options.find(o => o.value === selection.optionValue);
return total + (option?.priceAdjustment || 0);
}, basePrice);
};
// Check availability
const isAvailable = () => {
if (product.status !== 'ACTIVE') return false;
if (product.stockCount !== null && product.stockCount <= 0) return false;
return true;
};
return {
...product,
isAvailable: isAvailable(),
displayPrice: product.price,
hasVariations: product.variations && product.variations.length > 0,
inStock: product.stockCount === null || product.stockCount > 0
};
} catch (error) {
console.error('Error displaying product:', error);
throw error;
}
};
Inventory Management
// Monitor product inventory status
const checkInventoryStatus = async (productId) => {
const product = await fetchProduct(productId);
const inventoryStatus = {
productId: product.id,
name: product.name,
currentStock: product.stockCount,
status: 'UNKNOWN'
};
if (product.stockCount === null) {
inventoryStatus.status = 'UNLIMITED';
} else if (product.stockCount === 0) {
inventoryStatus.status = 'OUT_OF_STOCK';
} else if (product.stockCount <= 5) {
inventoryStatus.status = 'LOW_STOCK';
} else {
inventoryStatus.status = 'IN_STOCK';
}
return inventoryStatus;
};
Sales Analytics
// Analyze product performance
const getProductAnalytics = async (productId) => {
const product = await fetchProduct(productId);
const analytics = {
productId: product.id,
name: product.name,
totalTransactions: product.transactions.length,
totalRevenue: 0,
averageOrderValue: 0,
recentSales: [],
conversionMetrics: {}
};
// Calculate revenue metrics
const processedTransactions = product.transactions.filter(
t => t.status === 'PAYMENT_PROCESSED'
);
analytics.totalRevenue = processedTransactions.reduce(
(sum, t) => sum + t.amount, 0
);
analytics.averageOrderValue = processedTransactions.length > 0
? analytics.totalRevenue / processedTransactions.length
: 0;
// Get recent sales (last 30 days)
const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
analytics.recentSales = processedTransactions.filter(
t => new Date(t.dateCreated) >= thirtyDaysAgo
);
return analytics;
};
Variation Price Calculator
// Calculate product price with selected variations
const calculateVariationPrice = (product, selectedOptions = {}) => {
let totalPrice = product.price;
let selectedVariationDetails = [];
if (product.variations && Object.keys(selectedOptions).length > 0) {
product.variations.forEach(variation => {
const selectedValue = selectedOptions[variation.id];
if (selectedValue) {
const option = variation.options.find(opt => opt.value === selectedValue);
if (option) {
totalPrice += option.priceAdjustment;
selectedVariationDetails.push({
variationType: variation.type,
optionName: option.name,
priceAdjustment: option.priceAdjustment
});
}
}
});
}
return {
basePrice: product.price,
totalPrice,
variations: selectedVariationDetails,
savings: product.oldPrice ? product.oldPrice - totalPrice : 0
};
};
// Usage example
const product = await fetchProduct('product-id');
const selectedOptions = {
'color_variant': 'blue',
'warranty_variant': 'extended'
};
const pricing = calculateVariationPrice(product, selectedOptions);
console.log(`Total price: $${pricing.totalPrice}`);
Integration PatternsCopied!
Product Cache with Validation
class ProductCache {
constructor(apiClient, ttl = 300000) { // 5 minutes TTL
this.apiClient = apiClient;
this.cache = new Map();
this.ttl = ttl;
}
async getProduct(id, forceRefresh = false) {
const key = `product_${id}`;
const cached = this.cache.get(key);
// Return cached version if valid and not forcing refresh
if (!forceRefresh && cached && Date.now() - cached.timestamp < this.ttl) {
return cached.data;
}
try {
// Fetch fresh data
const product = await this.apiClient.fetchProduct(id);
// Update cache
this.cache.set(key, {
data: product,
timestamp: Date.now()
});
return product;
} catch (error) {
// Return cached version if fetch fails and we have cached data
if (cached && error.message !== 'Product not found') {
console.warn('Using cached product due to fetch error:', error.message);
return cached.data;
}
throw error;
}
}
invalidateProduct(id) {
this.cache.delete(`product_${id}`);
}
clear() {
this.cache.clear();
}
}
Error Handling Best Practices
const safelyFetchProduct = async (productId, fallbackOptions = {}) => {
try {
const product = await fetchProduct(productId);
return { success: true, product, error: null };
} catch (error) {
const errorResponse = { success: false, product: null, error: error.message };
// Handle specific error cases
if (error.message === 'Product not found') {
if (fallbackOptions.redirectToListing) {
window.location.href = '/products';
return errorResponse;
}
}
if (error.message.includes('Rate limit')) {
// Implement exponential backoff
await new Promise(resolve => setTimeout(resolve, 1000));
return safelyFetchProduct(productId, { ...fallbackOptions, retry: true });
}
// Log error for monitoring
console.error('Product fetch error:', {
productId,
error: error.message,
timestamp: new Date().toISOString()
});
return errorResponse;
}
};
Performance ConsiderationsCopied!
Optimized Loading
// Load product with progressive enhancement
const loadProductWithFallbacks = async (productId) => {
const loadingStates = {
basic: false,
images: false,
transactions: false
};
try {
// 1. Load basic product info first
const product = await fetchProduct(productId);
loadingStates.basic = true;
// 2. Preload first image
if (product.images && product.images.length > 0) {
const img = new Image();
img.onload = () => { loadingStates.images = true; };
img.src = product.images[0];
}
// 3. Process transaction data in background
setTimeout(() => {
if (product.transactions && product.transactions.length > 0) {
// Process transaction analytics
loadingStates.transactions = true;
}
}, 100);
return { product, loadingStates };
} catch (error) {
throw error;
}
};
Security ConsiderationsCopied!
Input Validation
// Validate product ID before API call
const validateProductId = (productId) => {
// Check UUID format
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
if (!productId || typeof productId !== 'string') {
throw new Error('Product ID must be a non-empty string');
}
if (!uuidRegex.test(productId)) {
throw new Error('Product ID must be a valid UUID');
}
return true;
};
// Safe product fetching with validation
const fetchProductSafely = async (productId) => {
validateProductId(productId);
return await fetchProduct(productId);
};
Next StepsCopied!
After fetching a product, you can:
-
Display Product Details: Show comprehensive product information in your UI
-
Update Product: Modify product attributes using the update endpoint
-
Add to Cart/Checkout: Include product in purchase workflows
-
Track Analytics: Monitor product performance and sales metrics
-
Manage Inventory: Update stock levels and availability
For more information, see: