---
title: "Product Card API: Render Shoppable Product Images"
description: "Render product cards on demand with the Product Card API. Send a photo URL, price, sale price, and CTA copy as JSON, get back a 1200x800 PNG."
url: "https://html2img.com/templates/product-card/"
---

# Product Card: Product Image Generator API

Send product photo, price, and CTA copy as JSON, get back a 1200x800 marketplace-ready PNG.

E-commerce teams and affiliate networks use the Product Card API to keep marketplace, ad, and email artwork in sync with the underlying catalog. Whenever a price changes or a product enters a sale, the next render reflects the new state without a designer sitting between the database and the storefront. You post the photo URL, prices, brand details, and CTA copy as JSON, and the response holds a 1200x800 PNG ready to attach to an ad set or email blast.

## At a glance

- **Template slug:** `product-card`
- **Category:** business
- **Endpoint:** `POST https://app.html2img.com/api/v1/templates/product-card`
- **Authentication:** `X-API-Key` header
- **Cost:** one credit per render, PNG or PDF
- **Page:** https://html2img.com/templates/product-card/

## Fields

| Field | Type | Required | Example |
| --- | --- | --- | --- |
| `product_name` | string | Yes | Linden Lounge Chair |
| `product_subtitle` | string | No | Solid oak frame with wool boucle upholstery |
| `price` | string | Yes | $1,290 |
| `sale_price` | string | No | $890 |
| `badge` | string | No | Limited stock |
| `cta_label` | string | No | Shop the Linden → |
| `product_image_url` | url | No | https://picsum.photos/seed/product-card/720/720 |
| `brand_name` | string | No | Northwind Home |
| `logo_url` | url | No |  |
| `background_color` | string | No | #F5F1EA |
| `accent_color` | string | No | #1F2937 |

## Defaults

| Field | Default |
| --- | --- |
| `width` | 1200 |
| `height` | 800 |

## Example request

```bash
curl -X POST https://app.html2img.com/api/v1/templates/product-card \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"product_name":"Linden Lounge Chair","product_subtitle":"Solid oak frame with wool boucle upholstery","price":"$1,290","sale_price":"$890","badge":"Limited stock","cta_label":"Shop the Linden \u2192","product_image_url":"https://picsum.photos/seed/product-card/720/720","brand_name":"Northwind Home","background_color":"#F5F1EA","accent_color":"#1F2937"}'
```

## In your language

### PHP

```php
<?php
$response = \Illuminate\Support\Facades\Http::withHeaders([
    'X-API-Key' => 'YOUR_API_KEY',
])->post('https://app.html2img.com/api/v1/templates/product-card', ['product_name' => 'Linden Lounge Chair', 'product_subtitle' => 'Solid oak frame with wool boucle upholstery', 'price' => '$1,290', 'sale_price' => '$890', 'badge' => 'Limited stock', 'cta_label' => 'Shop the Linden →', 'product_image_url' => 'https://picsum.photos/seed/product-card/720/720', 'brand_name' => 'Northwind Home', 'background_color' => '#F5F1EA', 'accent_color' => '#1F2937']);

$url = $response->json('url');
```

### Node.js

```javascript
const response = await fetch('https://app.html2img.com/api/v1/templates/product-card', {
  method: 'POST',
  headers: {
    'X-API-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "product_name": "Linden Lounge Chair",
    "product_subtitle": "Solid oak frame with wool boucle upholstery",
    "price": "$1,290",
    "sale_price": "$890",
    "badge": "Limited stock",
    "cta_label": "Shop the Linden \u2192",
    "product_image_url": "https://picsum.photos/seed/product-card/720/720",
    "brand_name": "Northwind Home",
    "background_color": "#F5F1EA",
    "accent_color": "#1F2937"
}),
});

const { url } = await response.json();
```

### Python

```python
import requests

response = requests.post(
    'https://app.html2img.com/api/v1/templates/product-card',
    headers={'X-API-Key': 'YOUR_API_KEY'},
    json={'product_name': 'Linden Lounge Chair', 'product_subtitle': 'Solid oak frame with wool boucle upholstery', 'price': '$1,290', 'sale_price': '$890', 'badge': 'Limited stock', 'cta_label': 'Shop the Linden →', 'product_image_url': 'https://picsum.photos/seed/product-card/720/720', 'brand_name': 'Northwind Home', 'background_color': '#F5F1EA', 'accent_color': '#1F2937'},
)

url = response.json()['url']
```

## What it is for

### Shopify catalog ad creation at scale

Run a Shopify storefront with 600 active SKUs and you do not have time to design ad creative for each one. Loop through your products in Shopify's API, post each to the Product Card endpoint, and feed the resulting URLs into Meta Ads Manager. Every variant gets a card that matches its current price and stock state. Northwind Home automated 380 cards in two hours through this pipeline, replacing a freelancer rotation that took two weeks per refresh.

### Paid social variants from one product feed

Marketing teams often A/B test five visual treatments per product to find the highest-CTR creative. Generate each variant by changing accent_color, background_color, or cta_label between requests, while holding the photo and price constant. The endpoint is fast enough to render an entire creative test in a single CI/CD run, so you can iterate weekly instead of quarterly.

### Marketplace listing image refresh

Sellers on Amazon, Etsy, and eBay need to keep their main product image current with seasonal pricing and badges. Render the card with the latest sale_price and a "Limited stock" badge, upload via each marketplace's API, and the new image is live within their image-processing window. Riverside Bakery refreshes its 240 marketplace listings every Sunday night through this workflow.

### Abandoned cart email artwork

When a shopper leaves items in their cart, the recovery email performs better with a real image of what they almost bought. Pull the cart contents, render one product card per item, and embed in the email body. The customer sees the actual products at the actual prices instead of a plain text reminder. Linden & Co reports a 22 percent recovery uplift versus the text-only template they sent before.

### Affiliate partner share cards

Affiliate programs benefit when partners share branded card images instead of plain product links. Generate one card per product per partner, with the partner referral parameter baked into the cta_label or a separate query string in the destination URL. Partners post the cards directly to their channels and earn higher click-through than they would from a stock product photo.

## Output

- **Dimensions:** 1200x800
- **Colour space:** sRGB
- **Transparency:** Supported
- **Typical file size:** 70 KB to 200 KB
- **Platform specification:** [Product feed image guidelines (Shopify, Meta Commerce)](https://help.shopify.com/manual/products/product-media)

## Common mistakes

### Long product titles crop at marketplace ad limits

A 90-character product title fits the card layout but Meta Ads truncates it in feed view, leaving the buyer with half the message. Keep the title under 50 characters or shorten the marketplace-facing version while keeping the long form in your catalog.

### Sale price shown without strikethrough on original

Some teams send only the sale_price field and the buyer cannot tell whether the price reflects a discount. Send both price (the original) and sale_price (the new), so the template strikes through the original and emphasizes the savings.

### Currency symbol position differs across locales

A merchant ships to both UK and Germany sees "£" before the value and "€" after, depending on locale convention. Pre-format the price strings on your side using each customer's locale rather than treating the field as a number that the renderer would format.

## Questions

### Will this work as a Shopify product image?

The 1200x800 output works directly as a variant image or in metafields. Shopify accepts it without re-cropping for most theme grids, though some themes prefer a square. Check your theme's expected aspect ratio before bulk-applying to a live store. For wholesale line sheets, the same request with format: "pdf" returns the card on an A4 page buyers can file or print.

### Can I show a sale price?

Yes, send price (the original) and sale_price (the discounted value) as separate fields. The template strikes through the original and emphasizes the new value. If you only send price, the strikethrough does not appear.

### What CTA copy is allowed?

Any string up to 24 characters renders cleanly inside the button. Longer text wraps to two lines and looks crowded, so keep CTAs short ("Shop the Linden", "Buy now", "Add to cart"). Emoji are supported and render in color.

### Does it support a transparent background?

Yes, set background_color to "transparent" to get a PNG with alpha. This is useful when you plan to composite the card into an ad creative on your side. The text and accent colors remain opaque so the readable areas stay sharp.

### How do I localize the currency?

Pre-format the price and sale_price strings on your side. The endpoint treats the values as display strings and renders them exactly as posted. This keeps the rendering layer free of locale rules and avoids drift between your checkout and the card.

### Can I batch-render variants?

The endpoint serves one render per call. For a parallel batch, fan out requests from your worker pool and collect the URLs, or use the webhook_url field to receive completion callbacks. Most teams render at catalog-update time rather than at request time.

## Preview

![Product Card: Product Image Generator API example render](https://i.html2img.com/image-1777560084193-953247.png)

## Related templates

- [invoice-image](https://html2img.com/templates/invoice-image/)
- [event-ticket](https://html2img.com/templates/event-ticket/)
- [receipt-image](https://html2img.com/templates/receipt-image/)

## See also

- [Every template](https://html2img.com/templates/)
- [Templates API reference](https://html2img.com/docs/templates/)
- [OpenAPI specification](https://html2img.com/openapi.json)
