Skip to main content

Products API

The Products API enables you to create and manage in-app purchases including consumables, non-consumables, subscriptions, and virtual currency packs. Build a complete in-game economy with flexible pricing, product visibility controls, and comprehensive analytics.

Authentication

Most endpoints require authentication using either:

  • API Key: Include x-api-key header
  • Cognito JWT: Include Authorization: Bearer <token> header
  • Developer Auth: Special authentication for developer operations

Public endpoints like getProductById, getAppProducts, and getProductsByCategory don't require authentication.

Base URL

https://sdk.getjar.com/products

Product Types

GetJar supports four types of in-app products:

CONSUMABLE

Single-use items that can be purchased multiple times.

Examples:

  • Health potions
  • Energy refills
  • Booster packs
  • Consumable power-ups

NON_CONSUMABLE

One-time purchases that unlock permanent features.

Examples:

  • Premium features
  • Character unlocks
  • Level packs
  • Ad removal

SUBSCRIPTION

Recurring purchases that provide benefits for a period.

Examples:

  • Premium membership
  • VIP access
  • Season passes
  • Monthly content subscriptions

VIRTUAL_CURRENCY

In-game currency packs with optional bonus percentages.

Examples:

  • Gold coin packs
  • Gem bundles
  • Credit packages
  • Premium currency

Create Product

Create a new in-app product with custom configuration.

Endpoint

POST /products

Request Body

{
appId: string; // Required: Application ID
developerId: string; // Required: Developer ID
productReference?: string; // Unique reference code
name: string; // Required: Product name
description: string; // Required: Product description
shortDescription?: string; // Brief description for listings
productType: string; // Required: CONSUMABLE, NON_CONSUMABLE, SUBSCRIPTION, VIRTUAL_CURRENCY
category: string; // Required: Category (e.g., 'Currency', 'Power-ups')
subCategory?: string; // Optional subcategory
pricing: { // Required: Pricing configuration
amount: number; // Price amount
currency: string; // Currency code (USD, EUR, etc.)
displayPrice: string; // Formatted price for display
compareAtPrice?: number; // Original price for discounts
taxInclusive?: boolean; // Whether tax is included
};
isActive?: boolean; // Default: true
isVisible?: boolean; // Default: true
availableFrom?: string; // ISO date when product becomes available
availableUntil?: string; // ISO date when product expires
tags?: string[]; // Tags for filtering
metadata?: object; // Custom metadata
subscriptionConfig?: { // For subscription products
interval: string; // DAY, WEEK, MONTH, YEAR
intervalCount: number; // Number of intervals
trialPeriodDays?: number; // Free trial days
gracePeriodDays?: number; // Grace period after failed payment
maxRetries?: number; // Max payment retry attempts
};
virtualCurrency?: { // For virtual currency products
currencyToPay: number; // Cost in virtual currency
currencyToReceive: number; // Amount received
bonusPercentage?: number; // Bonus percentage
};
}

Response

{
productId: string;
productReference: string;
appId: string;
developerId: string;
name: string;
description: string;
productType: string;
category: string;
pricing: object;
isActive: boolean;
isVisible: boolean;
createdAt: string;
updatedAt: string;
}

Example: Consumable Product

import { ProductsApi } from "@getjar-iap/sdk";

const productsApi = new ProductsApi(configuration);

const product = await productsApi.createProduct({
createProductDto: {
appId: "app_123",
developerId: "dev_123",
productReference: "GOLD_PACK_100",
name: "100 Gold Coins",
description: "A pack of 100 gold coins for in-game purchases",
shortDescription: "100 gold coins",
productType: "CONSUMABLE",
category: "Currency",
subCategory: "Gold Packs",
pricing: {
amount: 4.99,
currency: "USD",
displayPrice: "$4.99",
compareAtPrice: 9.99,
taxInclusive: true,
},
isActive: true,
isVisible: true,
tags: ["popular", "best-value"],
},
});

console.log("Product ID:", product.data.productId);

Example: Subscription Product

const subscription = await productsApi.createProduct({
createProductDto: {
appId: "app_123",
developerId: "dev_123",
name: "Premium Monthly Subscription",
description: "Get premium features and exclusive content",
productType: "SUBSCRIPTION",
category: "Subscriptions",
pricing: {
amount: 9.99,
currency: "USD",
displayPrice: "$9.99/month",
},
subscriptionConfig: {
interval: "MONTH",
intervalCount: 1,
trialPeriodDays: 7,
gracePeriodDays: 3,
maxRetries: 3,
},
},
});

console.log("Subscription created:", subscription.data);

Example: Virtual Currency Product

const virtualCurrency = await productsApi.createProduct({
createProductDto: {
appId: "app_123",
developerId: "dev_123",
name: "Mega Gem Pack",
description: "1000 gems with 20% bonus!",
productType: "VIRTUAL_CURRENCY",
category: "Currency",
pricing: {
amount: 19.99,
currency: "USD",
displayPrice: "$19.99",
},
virtualCurrency: {
currencyToPay: 1999,
currencyToReceive: 1000,
bonusPercentage: 20,
},
},
});

console.log("Virtual currency pack created:", virtualCurrency.data);

Response Codes

CodeDescription
201Product created successfully
400Invalid product data
401Unauthorized
404App or developer does not exist

Update Product

Update an existing product's details including pricing, description, or availability.

Endpoint

PUT /products/:productId

Parameters

ParameterTypeRequiredDescription
productIdstringYesThe unique product identifier

Request Body

{
name?: string;
description?: string;
shortDescription?: string;
pricing?: {
amount?: number;
currency?: string;
displayPrice?: string;
compareAtPrice?: number;
};
category?: string;
subCategory?: string;
isActive?: boolean;
isVisible?: boolean;
availableFrom?: string;
availableUntil?: string;
tags?: string[];
metadata?: object;
subscriptionConfig?: object;
virtualCurrency?: object;
}

Example

const updated = await productsApi.updateProduct({
productId: "prod_123",
updateProductDto: {
name: "100 Gold Coins - Limited Edition",
description: "Updated with bonus content!",
pricing: {
amount: 3.99,
currency: "USD",
displayPrice: "$3.99",
compareAtPrice: 4.99,
},
tags: ["limited-time", "sale"],
},
});

console.log("Updated:", updated.data.name);

Response Codes

CodeDescription
200Product updated successfully
400Invalid update data
401Unauthorized
404Product does not exist

Toggle Product Visibility

Control whether a product is visible in the store. Hidden products can still be purchased if users have the direct link.

Endpoint

PUT /products/:productId/visibility

Parameters

ParameterTypeRequiredDescription
productIdstringYesThe unique product identifier

Request Body

{
isVisible: boolean; // Required
}

Example

// Hide product
await productsApi.toggleProductVisibility({
productId: "prod_123",
toggleProductVisibilityRequest: {
isVisible: false,
},
});

console.log("Product hidden from store");

// Show product
await productsApi.toggleProductVisibility({
productId: "prod_123",
toggleProductVisibilityRequest: {
isVisible: true,
},
});

console.log("Product visible in store");

Response Codes

CodeDescription
200Visibility updated successfully
401Unauthorized
404Product does not exist

Activate Product

Activate a product to make it available for purchase. Only active products can be sold.

Endpoint

POST /products/:productId/activate

Parameters

ParameterTypeRequiredDescription
productIdstringYesThe unique product identifier

Example

await productsApi.activateProduct({
productId: "prod_123",
});

console.log("Product activated");

Response Codes

CodeDescription
200Product activated successfully
401Unauthorized
404Product does not exist

Deactivate Product

Deactivate a product to prevent new purchases. Existing subscriptions will continue until expiration.

Endpoint

POST /products/:productId/deactivate

Parameters

ParameterTypeRequiredDescription
productIdstringYesThe unique product identifier

Example

await productsApi.deactivateProduct({
productId: "prod_123",
});

console.log("Product deactivated");

Response Codes

CodeDescription
200Product deactivated successfully
401Unauthorized
404Product does not exist

Upload Product Image

Upload or replace the product image. Images are stored in S3 and automatically optimized.

Endpoint

POST /products/image/upload/:productId

Parameters

ParameterTypeRequiredDescription
productIdstringYesThe unique product identifier

Request Body

multipart/form-data

Form Fields:

  • file: Image file (PNG, JPG, JPEG, WEBP)

Response

{
success: boolean;
key: string; // S3 storage key
url: string; // Public URL
uploadedAt: string;
}

Example

// Browser example
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];

const result = await productsApi.uploadProductImage({
productId: "prod_123",
file: file,
});

console.log("Image URL:", result.data.url);

Response Codes

CodeDescription
201Image uploaded successfully
400Invalid file type or size
401Unauthorized
404Product does not exist

Delete Product Image

Remove the product image from S3 storage and clear the image references.

Endpoint

DELETE /products/image/delete/:productId

Parameters

ParameterTypeRequiredDescription
productIdstringYesThe unique product identifier

Example

await productsApi.deleteProductImage({
productId: "prod_123",
});

console.log("Image deleted");

Response Codes

CodeDescription
200Image deleted successfully
401Unauthorized
404Product does not exist

Get Product by ID

Retrieve detailed information about a specific product. This endpoint is public.

Endpoint

GET /products/:productId

Parameters

ParameterTypeRequiredDescription
productIdstringYesThe unique product identifier

Response

{
productId: string;
productReference: string;
appId: string;
developerId: string;
name: string;
description: string;
shortDescription: string;
productType: string;
category: string;
subCategory: string;
isActive: boolean;
isVisible: boolean;
availableFrom: string | null;
availableUntil: string | null;
pricing: {
amount: number;
currency: string;
displayPrice: string;
compareAtPrice: number | null;
taxInclusive: boolean;
};
imageUrl: string | null;
imageKey: string | null;
subscriptionConfig: {
interval: string;
intervalCount: number;
trialPeriodDays: number;
gracePeriodDays: number;
maxRetries: number;
} | null;
virtualCurrency: {
currencyToPay: number;
currencyToReceive: number;
bonusPercentage: number;
} | null;
stats: {
totalSales: number;
totalRevenue: number;
averageRating: number;
reviewCount: number;
lastPurchasedAt: string;
} | null;
tags: string[];
metadata: object;
createdAt: string;
updatedAt: string;
}

Example

const product = await productsApi.getProductById({
productId: "prod_123",
});

console.log("Name:", product.data.name);
console.log("Price:", product.data.pricing.displayPrice);
console.log("Type:", product.data.productType);
console.log("Total Sales:", product.data.stats?.totalSales || 0);

Response Codes

CodeDescription
200Product retrieved
404Product does not exist

Get App Products

Retrieve a paginated list of products for a specific app with optional filters. This endpoint is public.

Endpoint

GET /products/app/:appId

Parameters

ParameterTypeRequiredDescription
appIdstringYesThe application identifier
pagenumberNoPage number (default: 1)
limitnumberNoItems per page (default: 20)
productTypestringNoFilter by product type
categorystringNoFilter by category
isActivebooleanNoFilter by active status
isVisiblebooleanNoFilter by visibility status

Response

{
items: Array<{
productId: string;
productReference: string;
name: string;
description: string;
productType: string;
category: string;
pricing: {
amount: number;
currency: string;
displayPrice: string;
};
imageUrl: string | null;
isActive: boolean;
isVisible: boolean;
}>;
pagination: {
total: number;
page: number;
limit: number;
totalPages: number;
hasNextPage: boolean;
hasPreviousPage: boolean;
}
}

Example

// Get all products
const products = await productsApi.getAppProducts({
appId: "app_123",
page: 1,
limit: 20,
});

console.log("Total products:", products.data.pagination.total);

// Get filtered products
const consumables = await productsApi.getAppProducts({
appId: "app_123",
productType: "CONSUMABLE",
category: "Currency",
isActive: true,
isVisible: true,
page: 1,
limit: 50,
});

console.log("Consumable products:", consumables.data.items);

Response Codes

CodeDescription
200Products retrieved
404App does not exist

Get Developer Products

Retrieve all products created by a specific developer across all their apps.

Endpoint

GET /products/developer/:developerId

Parameters

ParameterTypeRequiredDescription
developerIdstringYesThe developer identifier
pagenumberNoPage number (default: 1)
limitnumberNoItems per page (default: 20)

Example

const developerProducts = await productsApi.getDeveloperProducts({
developerId: "dev_123",
page: 1,
limit: 20,
});

console.log("Total products:", developerProducts.data.pagination.total);
developerProducts.data.items.forEach((product) => {
console.log(`${product.name} (${product.appId})`);
});

Response Codes

CodeDescription
200Products retrieved
401Unauthorized
404Developer does not exist

Get Products by Category

Retrieve products filtered by category across all apps. This endpoint is public.

Endpoint

GET /products/category/:category

Parameters

ParameterTypeRequiredDescription
categorystringYesCategory name
pagenumberNoPage number (default: 1)
limitnumberNoItems per page (default: 20)

Example

const currencyProducts = await productsApi.getProductsByCategory({
category: "Currency",
page: 1,
limit: 50,
});

console.log("Currency products:", currencyProducts.data.items);

Response Codes

CodeDescription
200Products retrieved

Get Product Analytics

Retrieve comprehensive analytics and performance metrics for a product including sales, revenue, and ratings.

Endpoint

GET /products/:productId/analytics

Parameters

ParameterTypeRequiredDescription
productIdstringYesThe unique product identifier

Response

{
totalSales: number;
totalRevenue: number;
averageRating: number | null;
reviewCount: number;
lastPurchasedAt: string;
conversionMetrics: {
isPopular: boolean;
performanceRating: "LOW" | "MEDIUM" | "HIGH";
}
revenueByPeriod: {
today: number;
thisWeek: number;
thisMonth: number;
}
}

Example

const analytics = await productsApi.getProductAnalytics({
productId: "prod_123",
});

console.log("Total Sales:", analytics.data.totalSales);
console.log("Total Revenue:", `$${analytics.data.totalRevenue.toFixed(2)}`);
console.log("Average Rating:", analytics.data.averageRating);
console.log("Performance:", analytics.data.conversionMetrics.performanceRating);
console.log(
"This Month:",
`$${analytics.data.revenueByPeriod.thisMonth.toFixed(2)}`
);

Response Codes

CodeDescription
200Analytics retrieved
401Unauthorized
404Product does not exist

Delete Product

Permanently delete a product. This will not affect existing user purchases or subscriptions.

Endpoint

DELETE /products/:productId

Parameters

ParameterTypeRequiredDescription
productIdstringYesThe unique product identifier

Example

await productsApi.deleteProduct({
productId: "prod_123",
});

console.log("Product deleted successfully");

Response Codes

CodeDescription
200Product deleted successfully
401Unauthorized
404Product does not exist

Complete Example

Here's a complete workflow for setting up products:

import { Configuration, ProductsApi } from "@getjar-iap/sdk";

const configuration = new Configuration({
basePath: "https://sdk.getjar.com",
apiKey: "your-api-key",
});

const productsApi = new ProductsApi(configuration);
const appId = "app_123";
const developerId = "dev_123";

async function setupProducts() {
console.log("🏪 Setting up product catalog...\n");

// 1. Create consumable products
const healthPotion = await productsApi.createProduct({
createProductDto: {
appId,
developerId,
productReference: "HEALTH_POTION",
name: "Health Potion",
description: "Restore 50 HP instantly",
productType: "CONSUMABLE",
category: "Consumables",
subCategory: "Potions",
pricing: {
amount: 0.99,
currency: "USD",
displayPrice: "$0.99",
},
tags: ["consumable", "health"],
},
});

console.log("✓ Created:", healthPotion.data.name);

// 2. Create virtual currency packs
const currencyPacks = [
{ amount: 100, price: 0.99, bonus: 0 },
{ amount: 500, price: 4.99, bonus: 10 },
{ amount: 1000, price: 9.99, bonus: 20 },
{ amount: 5000, price: 49.99, bonus: 50 },
];

for (const pack of currencyPacks) {
const product = await productsApi.createProduct({
createProductDto: {
appId,
developerId,
productReference: `GOLD_PACK_${pack.amount}`,
name: `${pack.amount} Gold Coins${
pack.bonus > 0 ? ` (+${pack.bonus}% Bonus)` : ""
}`,
description: `A pack of ${pack.amount} gold coins for in-game purchases`,
productType: "VIRTUAL_CURRENCY",
category: "Currency",
subCategory: "Gold Packs",
pricing: {
amount: pack.price,
currency: "USD",
displayPrice: `$${pack.price}`,
},
virtualCurrency: {
currencyToPay: Math.round(pack.price * 100),
currencyToReceive: pack.amount,
bonusPercentage: pack.bonus,
},
tags: pack.bonus > 0 ? ["popular", "best-value"] : ["starter"],
},
});

console.log("✓ Created:", product.data.name);
}

// 3. Create non-consumable products
const premiumFeature = await productsApi.createProduct({
createProductDto: {
appId,
developerId,
productReference: "REMOVE_ADS",
name: "Remove Ads Forever",
description: "Enjoy an ad-free experience permanently",
productType: "NON_CONSUMABLE",
category: "Premium",
subCategory: "Features",
pricing: {
amount: 4.99,
currency: "USD",
displayPrice: "$4.99",
},
tags: ["premium", "no-ads"],
},
});

console.log("✓ Created:", premiumFeature.data.name);

// 4. Create subscription
const subscription = await productsApi.createProduct({
createProductDto: {
appId,
developerId,
productReference: "PREMIUM_MONTHLY",
name: "Premium Membership",
description: "Get exclusive content, bonuses, and no ads",
productType: "SUBSCRIPTION",
category: "Subscriptions",
pricing: {
amount: 9.99,
currency: "USD",
displayPrice: "$9.99/month",
},
subscriptionConfig: {
interval: "MONTH",
intervalCount: 1,
trialPeriodDays: 7,
gracePeriodDays: 3,
maxRetries: 3,
},
tags: ["subscription", "premium"],
},
});

console.log("✓ Created:", subscription.data.name);

// 5. Get all products
const allProducts = await productsApi.getAppProducts({
appId,
page: 1,
limit: 100,
});

console.log("\n📦 Product Catalog:");
console.log(`Total products: ${allProducts.data.pagination.total}`);

// Group by type
const byType = allProducts.data.items.reduce((acc, product) => {
acc[product.productType] = (acc[product.productType] || 0) + 1;
return acc;
}, {} as Record<string, number>);

console.log("\nBy Type:");
Object.entries(byType).forEach(([type, count]) => {
console.log(` ${type}: ${count}`);
});

// 6. Get analytics for a product
const analytics = await productsApi.getProductAnalytics({
productId: healthPotion.data.productId,
});

console.log("\n📊 Analytics for", healthPotion.data.name);
console.log(" Total Sales:", analytics.data.totalSales);
console.log(" Total Revenue:", `$${analytics.data.totalRevenue.toFixed(2)}`);

return allProducts;
}

// Run the setup
setupProducts()
.then(() => console.log("\n✅ Product setup complete!"))
.catch((error) => console.error("❌ Error:", error));

Product Catalog Management

Creating a Store with Categories

async function createGameStore() {
const categories = {
Currency: [
{ name: "Starter Pack", amount: 100, price: 0.99 },
{ name: "Popular Pack", amount: 500, price: 4.99, bonus: 10 },
{ name: "Best Value", amount: 1000, price: 9.99, bonus: 20 },
{ name: "Mega Pack", amount: 5000, price: 49.99, bonus: 50 },
],
Consumables: [
{ name: "Health Potion", price: 0.99, description: "Restore 50 HP" },
{ name: "Mana Potion", price: 0.99, description: "Restore 50 MP" },
{
name: "Experience Boost",
price: 1.99,
description: "2x XP for 1 hour",
},
],
Premium: [
{ name: "Remove Ads", price: 4.99, description: "No ads forever" },
{
name: "VIP Status",
price: 14.99,
description: "Lifetime VIP benefits",
},
],
};

for (const [category, products] of Object.entries(categories)) {
for (const product of products) {
await productsApi.createProduct({
createProductDto: {
appId: "app_123",
developerId: "dev_123",
name: product.name,
description: product.description || `${product.name} pack`,
productType:
category === "Currency"
? "VIRTUAL_CURRENCY"
: category === "Premium"
? "NON_CONSUMABLE"
: "CONSUMABLE",
category,
pricing: {
amount: product.price,
currency: "USD",
displayPrice: `$${product.price}`,
},
...(category === "Currency" && {
virtualCurrency: {
currencyToPay: Math.round(product.price * 100),
currencyToReceive: product.amount,
bonusPercentage: product.bonus || 0,
},
}),
},
});
}
}
}

Managing Product Lifecycle

async function manageProductLifecycle(productId: string) {
// Launch product
await productsApi.activateProduct({ productId });
await productsApi.toggleProductVisibility({
productId,
toggleProductVisibilityRequest: { isVisible: true },
});
console.log("Product launched");

// Run a sale
await productsApi.updateProduct({
productId,
updateProductDto: {
pricing: {
amount: 2.99,
displayPrice: "$2.99",
compareAtPrice: 4.99,
},
tags: ["on-sale", "limited-time"],
},
});
console.log("Sale started");

// End sale
await productsApi.updateProduct({
productId,
updateProductDto: {
pricing: {
amount: 4.99,
displayPrice: "$4.99",
compareAtPrice: null,
},
tags: [],
},
});
console.log("Sale ended");

// Retire product
await productsApi.deactivateProduct({ productId });
await productsApi.toggleProductVisibility({
productId,
toggleProductVisibilityRequest: { isVisible: false },
});
console.log("Product retired");
}

Seasonal Products

async function createSeasonalProduct() {
const now = new Date();
const oneMonthLater = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000);

const seasonal = await productsApi.createProduct({
createProductDto: {
appId: "app_123",
developerId: "dev_123",
name: "Holiday Special Pack",
description: "Limited time holiday bundle!",
productType: "CONSUMABLE",
category: "Limited Time",
pricing: {
amount: 9.99,
currency: "USD",
displayPrice: "$9.99",
compareAtPrice: 19.99,
},
availableFrom: now.toISOString(),
availableUntil: oneMonthLater.toISOString(),
tags: ["limited-time", "seasonal", "holiday"],
},
});

console.log("Seasonal product created:", seasonal.data.name);
console.log("Available until:", seasonal.data.availableUntil);
}

Best Practices

Pricing Strategy

  1. Tiered Pricing: Offer multiple price points

    const tiers = [
    { amount: 100, price: 0.99, value: 0.99 },
    { amount: 500, price: 4.99, value: 1.0 }, // 5% better value
    { amount: 1000, price: 9.99, value: 1.01 }, // 10% better value
    { amount: 5000, price: 49.99, value: 1.0 }, // 50% better value
    ];
  2. Discount Display: Use compareAtPrice for sales

    pricing: {
    amount: 3.99,
    displayPrice: "$3.99",
    compareAtPrice: 4.99 // Shows original price
    }
  3. Currency Localization: Support multiple currencies

    const prices = {
    USD: { amount: 4.99, display: "$4.99" },
    EUR: { amount: 4.49, display: "€4.49" },
    GBP: { amount: 3.99, display: "£3.99" },
    };

Product Organization

  1. Use References: Always set meaningful productReference codes

    productReference: "GOLD_PACK_500"; // Clear and descriptive
  2. Categorize Effectively: Use clear categories and subcategories

    category: "Currency",
    subCategory: "Gold Packs"
  3. Tag Appropriately: Use tags for filtering and discovery

    tags: ["popular", "best-value", "limited-time"];
  4. Provide Clear Descriptions: Help users understand the value

    name: "500 Gold Coins (+10% Bonus)",
    description: "Get 500 gold coins plus 50 bonus coins",
    shortDescription: "550 gold coins total"

Subscription Management

  1. Offer Trials: Encourage subscriptions with free trials

    subscriptionConfig: {
    interval: "MONTH",
    intervalCount: 1,
    trialPeriodDays: 7 // 7-day free trial
    }
  2. Grace Periods: Prevent accidental cancellations

    subscriptionConfig: {
    gracePeriodDays: 3,
    maxRetries: 3
    }
  3. Clear Pricing: Show recurring costs clearly

    displayPrice: "$9.99/month"; // Not just "$9.99"

Image Management

  1. Optimize Images: Use appropriate sizes and formats

    • Recommended: 512x512px PNG or WEBP
    • Max file size: 2MB
    • Use transparent backgrounds for icons
  2. Update Images: Keep product images current

    // Replace old image
    await uploadProductImage({ productId, file });
  3. Clean Up: Remove unused images

    await deleteProductImage({ productId });

Analytics & Optimization

  1. Monitor Performance: Track sales and revenue

    const analytics = await getProductAnalytics({ productId });

    if (analytics.data.conversionMetrics.performanceRating === "LOW") {
    // Consider adjusting pricing or visibility
    }
  2. Test Pricing: A/B test different price points

    // Version A: $4.99
    // Version B: $3.99
    // Compare analytics after 1 week
  3. Identify Best Sellers: Focus on what works

    const products = await getAppProducts({ appId, limit: 100 });
    const sorted = products.data.items.sort(
    (a, b) => (b.stats?.totalSales || 0) - (a.stats?.totalSales || 0)
    );
    console.log("Top products:", sorted.slice(0, 5));

Common Patterns

Starter Pack Offer

async function createStarterPack() {
const starter = await productsApi.createProduct({
createProductDto: {
appId: "app_123",
developerId: "dev_123",
name: "New Player Starter Pack",
description: "Everything you need to get started!",
productType: "CONSUMABLE",
category: "Bundles",
pricing: {
amount: 0.99,
currency: "USD",
displayPrice: "$0.99",
compareAtPrice: 4.99, // Show 80% discount
},
tags: ["starter", "limited-time", "best-value"],
metadata: {
isOneTimeOffer: true,
targetAudience: "new_players",
},
},
});

return starter;
}

Flash Sale Implementation

async function runFlashSale(productId: string, discountPercent: number) {
const product = await productsApi.getProductById({ productId });
const originalPrice = product.data.pricing.amount;
const salePrice = originalPrice * (1 - discountPercent / 100);

await productsApi.updateProduct({
productId,
updateProductDto: {
pricing: {
amount: salePrice,
currency: product.data.pricing.currency,
displayPrice: `$${salePrice.toFixed(2)}`,
compareAtPrice: originalPrice,
},
tags: [...(product.data.tags || []), "flash-sale"],
},
});

console.log(`Flash sale started: ${discountPercent}% off`);

// Revert after 24 hours
setTimeout(async () => {
await productsApi.updateProduct({
productId,
updateProductDto: {
pricing: {
amount: originalPrice,
currency: product.data.pricing.currency,
displayPrice: product.data.pricing.displayPrice,
compareAtPrice: null,
},
tags: product.data.tags?.filter((tag) => tag !== "flash-sale"),
},
});
console.log("Flash sale ended");
}, 24 * 60 * 60 * 1000);
}

Bundle Products

async function createBundle() {
const bundle = await productsApi.createProduct({
createProductDto: {
appId: "app_123",
developerId: "dev_123",
name: "Ultimate Power Bundle",
description: "5 Health Potions + 5 Mana Potions + XP Boost",
productType: "CONSUMABLE",
category: "Bundles",
pricing: {
amount: 9.99,
currency: "USD",
displayPrice: "$9.99",
compareAtPrice: 14.99,
},
metadata: {
contents: [
{ item: "HEALTH_POTION", quantity: 5 },
{ item: "MANA_POTION", quantity: 5 },
{ item: "XP_BOOST_1H", quantity: 1 },
],
},
tags: ["bundle", "value-pack"],
},
});

return bundle;
}

Error Handling

async function safeProductOperation() {
try {
const product = await productsApi.createProduct({
createProductDto: {
/* ... */
},
});

return {
success: true,
data: product.data,
};
} catch (error) {
if (error.response) {
switch (error.response.status) {
case 400:
console.error("Invalid product data:", error.response.data.message);
break;
case 401:
console.error("Authentication required");
break;
case 404:
console.error("App or developer not found");
break;
default:
console.error("Unexpected error:", error.response.status);
}
}

return {
success: false,
error: error.message,
};
}
}

Migration Guide

From Manual Product Management

// Old system: Manual product tracking
const oldProducts = [
{ id: "old_1", name: "Gold Pack", price: 4.99 },
{ id: "old_2", name: "Health Potion", price: 0.99 },
];

// New system: Migrate to GetJar
for (const oldProduct of oldProducts) {
await productsApi.createProduct({
createProductDto: {
appId: "app_123",
developerId: "dev_123",
productReference: oldProduct.id,
name: oldProduct.name,
description: `Migrated from old system`,
productType: "CONSUMABLE",
category: "Legacy",
pricing: {
amount: oldProduct.price,
currency: "USD",
displayPrice: `$${oldProduct.price}`,
},
metadata: {
migratedFrom: "legacy_system",
originalId: oldProduct.id,
},
},
});
}

Support

For additional help or questions: