Skip to main content

Custom Brand Page

Custom Brand Page lets you build your own brand detail screen — the page where a user sees a specific gift card brand, its artwork, discount, and redemption instructions before purchasing. Hubble provides all the underlying brand data through a single voucher product API, and you render it in your own UI.

Use this approach together with Custom Listing: the listing gives you brand identifiers, and this API gives you everything needed to render the brand's detail page. Payment and purchase flows can still open in Hubble SDK screens.

How It Works

  1. Get a brandKey or product ID from Custom Listing search results, or from your own routing.
  2. Call the voucher product details API to fetch brand metadata, imagery, discount details, purchasable amounts, and how-to-redeem content.
  3. Render your own brand page — card artwork, brand colors, card worth, discounted price, and a "How to redeem" section.
  4. Open the purchase flow using the returned externalId.

Only ACTIVE products are returned. Reward and pricing data are resolved per client (X-CLIENT-ID).


Get Brand Details

GET/v1/store/products/voucher-product/{voucherProductIdOrBrandKey}

Returns the complete detail page payload for a single voucher product (gift card brand): brand metadata and imagery, reward (discount) details, purchasable amounts, purchase restrictions, how-to-redeem content, and variant SKUs for multi-SKU brands.

Path Parameters

ParameterTypeRequiredDescription
voucherProductIdOrBrandKeystringYesVoucher product ID or brand key (e.g. ikea, zomato). The identifier is resolved first as a product ID, then as a brand key, so both work in the same path segment.

Request Headers

This is a public store endpoint. It does not require bearer authentication, but it does require client context.

HeaderRequiredDescription
X-CLIENT-IDYesYour Hubble client ID. If omitted, store-service defaults to the hubble client.
X-Request-IdRecommendedUnique request identifier for tracing and support. Echoed back in error responses.

Example Request

curl "https://api.dev.myhubble.money/v1/store/products/voucher-product/ikea" \
-H "X-CLIENT-ID: <client_id>" \
-H "X-Request-Id: $(uuidgen)"

Example Response

{
"externalId": "01HSBD494BMXNNP9HA9CTXAQ16",
"brandKey": "ikea",
"name": "IKEA",
"status": "ACTIVE",
"voucherProductMetadata": {
"title": "IKEA",
"conditions": [
"The Gift Card cannot be used to purchase other gift cards.",
"Gift Vouchers can only be used in-store and on website for purchases, redemption of gift card on application is not allowed"
],
"cardImageUrl": "",
"cardBackgroundColor": "#015BB2",
"howToUseSteps": [
{
"retailMode": "ONLINE",
"retailModeName": "Offline",
"howToUseHints": {
"hints": [
"Visit the outlet near you.",
"At the billing counter inform cashier that you want to use Gift Card.",
"Show your Gift Card details & pay any balance amount by cash or card."
]
},
"howToUseInDetail": {
"steps": [
{
"description": "Visit the outlet near you.",
"imageUrl": null,
"imageSize": null
},
{
"description": "At the billing counter inform cashier that you want to use Gift Card.",
"imageUrl": null,
"imageSize": null
},
{
"description": "Show your Gift Card details & pay any balance amount by cash or card.",
"imageUrl": null,
"imageSize": null
}
]
}
},
{
"retailMode": "OFFLINE",
"retailModeName": "Online",
"howToUseHints": {
"hints": [
"On www.ikea.com add products to you cart",
"Before purchasing GC, please ensure that IKEA delivers to your location",
"To check, please follow these steps: https://coda.io/@sharad/does-ikea-deliver-to-my-location",
"Alternatively, you can check your PIN code against this list: https://coda.io/@sharad/ikea-servicable-pin-codes",
"Proceed to checkout, in the payment section, select Redeem an IKEA gift card",
"Enter the gift card details, complete checkout."
]
},
"howToUseInDetail": {
"steps": [
{
"description": "On www.ikea.com add products to you cart",
"imageUrl": null,
"imageSize": null
},
{
"description": "Before purchasing GC, please ensure that IKEA delivers to your location",
"imageUrl": null,
"imageSize": null
},
{
"description": "To check, please follow these steps: https://coda.io/@sharad/does-ikea-deliver-to-my-location",
"imageUrl": null,
"imageSize": null
},
{
"description": "Alternatively, you can check your PIN code against this list: https://coda.io/@sharad/ikea-servicable-pin-codes",
"imageUrl": null,
"imageSize": null
},
{
"description": "Proceed to checkout, in the payment section, select Redeem an IKEA gift card",
"imageUrl": null,
"imageSize": null
},
{
"description": "Enter the gift card details, complete checkout.",
"imageUrl": null,
"imageSize": null
}
]
}
}
],
"logoUrl": "https://assets.myhubble.money/brand-assets/logo-images-wp/ikea-logo.webp",
"plainLogoUrl": "https://assets.myhubble.money/brand-assets/wdmark-images-wp/ikea-wdmark.webp",
"plainFillLogoUrl": "",
"promoImageUrl": "https://gullak-assets.s3.ap-south-1.amazonaws.com/brand-images/promos/OldAppBrandCard_IKEA.png",
"promoImageUrlV2": "https://gullak-assets.s3.ap-south-1.amazonaws.com/brand-images/promos-v2/NewAppBrandCard_IKEA.png",
"heroImageUrl": "https://assets.myhubble.money/brand-assets/hero-images/ikea-hero1.png",
"iconImageUrl": "https://assets.myhubble.money/brand-assets/icon-images/Ikea_icon_0406.png",
"shareImageUrl": "https://gullak-assets.s3.ap-south-1.amazonaws.com/share-wa-brand-images/WA_ikea.png",
"rdSqLogoUrl": "https://assets.myhubble.money/brand-assets/rdsq-logo-images-wp/ikea-rdsq-logo.webp",
"sqLogoUrl": "https://assets.myhubble.money/brand-assets/sq-logo-images-wp/235-ikea-cpvsy0.webp",
"addVoucherBrandPageUrl": null,
"addVoucherBrandPageImageUrl": null
},
"amountConditions": {
"minAmount": 1,
"maxAmount": 100000,
"defaultAmount": 1000,
"denominations": null,
"defaultDenominationDetails": null,
"stepAmount": 1,
"maxNoOfVouchersPerDenomination": null,
"maxNoOfDenominationsPerOrder": null
},
"restrictions": {
"maxWorthOfVouchersInAMonth": null,
"maxWorthOfVouchersForApiPartnerInAMonth": null,
"maxNumberOfVouchersPerOrder": 10,
"maxNumberOfVouchersInAMonth": null,
"maxNumberOfVouchersInLast365Days": null,
"rewardCap": {
"unit": "PERC",
"value": 5
},
"vouchersWorthLimitInDateRange": null,
"voucherPreConditions": null,
"isCoinConsumptionAllowed": false,
"paymentSource": "PG_AND_WALLET_AND_COINS",
"allowedBusinessModels": "BOTH",
"ccEnabled": null,
"maxOrdersInAMonth": null,
"maxConsecutiveMonthlyOrders": null
},
"voucherProductProviderMetadata": {
"onlySingleDenominationAllowed": false
},
"rewardType": "PREPAID",
"rewardDetails": [
{
"discountPercentage": 5,
"rewardType": "PREPAID"
}
],
"variantDetailedResponse": null
}
note

This is a real sample response for one brand. Asset URLs, amounts, limits, and rewards vary by brand and by client. Deprecated fields still present in live responses are omitted here — see Deprecated Fields.

Response Fields

Top Level

FieldTypeDescription
externalIdstringVoucher product ID. Use this when opening the purchase flow.
brandKeystringStable brand identifier (e.g. ikea).
namestringBrand display name.
statusstringAlways ACTIVE — inactive products return an error instead.
voucherProductMetadataobjectBrand content and imagery — see below.
amountConditionsobjectPurchasable amounts — see below.
restrictionsobjectPurchase limits — see below.
voucherProductProviderMetadataobject{ onlySingleDenominationAllowed } — true when the provider only supports a single denomination per voucher.
rewardTypeenumPREPAID | POSTPAID.
rewardDetailsarrayOne entry per applicable reward: discountPercentage (number), rewardType (PREPAID | POSTPAID). Use this to render the discount and the discounted price.
variantDetailedResponsearray, nullablePresent only for multi-SKU (variant) brands — see below.

voucherProductMetadata

FieldTypeDescription
titlestringBrand title.
conditionsstring[]Brand-specific purchase and usage conditions. Display these on the brand page (e.g. in the terms section).
cardImageUrlstringCard artwork. Can be empty — fall back to your own card layout with the brand logo.
cardBackgroundColorstringHex color for the card background.
howToUseStepsarrayHow-to-redeem content, one entry per retail mode — see below.
logoUrl, sqLogoUrl, rdSqLogoUrl, plainLogoUrl, plainFillLogoUrl, promoImageUrl, promoImageUrlV2, heroImageUrl, iconImageUrl, shareImageUrlstring, nullableBrand imagery in various shapes and sizes for different placements. Individual URLs can be empty for some brands.
addVoucherBrandPageUrl, addVoucherBrandPageImageUrlstring, nullableLink and image for adding an externally purchased voucher of this brand.

howToUseSteps

This is the content behind the How to redeem section on the brand page. Each entry covers one retail mode:

FieldTypeDescription
retailModeenumONLINE | OFFLINE.
retailModeNamestringDisplay label for the mode. Use this as the tab/section label.
howToUseHintsobject{ hints: string[] } — short redemption hints for compact display.
howToUseInDetailobject{ steps: [{ description, imageUrl?, imageSize? }] } where imageSize is FULL | PARTIAL — detailed step-by-step instructions with optional imagery.

amountConditions

FieldTypeDescription
minAmountnumberMinimum purchase amount per voucher.
maxAmountnumberMaximum purchase amount per voucher.
defaultAmountnumber, nullablePre-selected amount to show on the page.
denominationsnumber[], nullableFixed purchasable denominations. When null, any amount between minAmount and maxAmount in stepAmount increments is allowed.
defaultDenominationDetailsarray, nullablePre-selected cart: { denomination, quantity }.
stepAmountnumberIncrement for custom amounts.
maxNoOfVouchersPerDenominationinteger, nullableCap on vouchers per denomination in one order.
maxNoOfDenominationsPerOrderinteger, nullableCap on distinct denominations in one order.

restrictions

FieldTypeDescription
maxNumberOfVouchersPerOrderintegerMaximum vouchers in a single order.
maxWorthOfVouchersInAMonthnumber, nullableMonthly spend cap for this brand.
maxWorthOfVouchersForApiPartnerInAMonthnumber, nullableMonthly spend cap specific to API partners.
maxNumberOfVouchersInAMonthinteger, nullableMonthly voucher count cap.
maxNumberOfVouchersInLast365Daysinteger, nullableRolling-year voucher count cap.
rewardCapobject, nullableCap on the reward: { unit, value } (e.g. PERC / 5).
vouchersWorthLimitInDateRangeobject, nullableSpend cap within a date range: { maxVoucherWorthInDateRange, fromDate, endDate }.
voucherPreConditionsobject, nullableEligibility gate: { excludeVoucherProductIds, minimumSuccessfulOrder }.
isCoinConsumptionAllowedbooleanWhether Hubble coins can be applied to this purchase.
paymentSourceenumAllowed payment sources for the client, e.g. PG_AND_WALLET_AND_COINS (default), COINS_ONLY.
allowedBusinessModelsenumB2B | B2C | BOTH.
ccEnabledboolean, nullableWhether credit card payment is enabled for this brand.
maxOrdersInAMonthinteger, nullableMonthly order count cap.
maxConsecutiveMonthlyOrdersinteger, nullableCap on consecutive months with orders.

variantDetailedResponse (multi-SKU brands only)

Present for brands sold as fixed variants (e.g. subscription tiers).

FieldTypeDescription
title, text, subtextstring, nullableDisplay copy for the variant.
rewardDetailsarrayPer-variant { discountPercentage, rewardType }.

Deprecated Fields

The response also contains the following fields. They are deprecated — they may still appear in live responses, but do not build on them:

  • voucherProductMetadata: tncUrl, tncResId, howItWorksVideoUrl, howItWorksCtaUrl, howItWorksSteps, howItWorksStepsAvailable, cardHighlights, canBalanceBeFetched, tips, showRetailModeHeader, howToUseDetailedStepsAvailable, preReviewPopupDetails, isVoucherAssured, brandLandingPageDetails, showDetailedInstructionCta, storeLocatorUrl
  • Top level: showRewardCapModal, isOneVoucherOneDenominationOnly, isCoinConsumptionEnabled, taxDetails

Error Responses

404 — no active product matches the identifier:

{
"code": "PRODUCT_NOT_FOUND",
"message": "Product not found",
"requestId": "01M1126M1VJ0MGYDXH36RFAG4N",
"subErrors": [{ "message": "Product not found" }]
}

400 — the product exists but is not ACTIVE:

{
"code": "OPERATION_NOT_ALLOWED",
"message": "IKEA is temporarily disabled owing to failures",
"requestId": "01M1126M1VJ0MGYDXH36RFAG4N",
"subErrors": [{ "message": "IKEA is temporarily disabled owing to failures" }]
}

Brand Card

  • Use cardImageUrl and cardBackgroundColor for the card artwork and background; when cardImageUrl is empty, render your own card layout with a brand logo on the background color
  • Use name (or voucherProductMetadata.title) as the page heading
  • Use the logo variants (logoUrl, sqLogoUrl, iconImageUrl, etc.) for the placement that fits your layout

Card Worth and Pricing

  • Pre-select amountConditions.defaultAmount as the card worth
  • When denominations is non-null, offer only those amounts; otherwise allow any amount between minAmount and maxAmount in stepAmount increments
  • Show the original amount struck through next to the discounted price

Purchase Limits

  • Enforce restrictions.maxNumberOfVouchersPerOrder (and denomination caps from amountConditions) in your quantity selector

How to Redeem

  • Render howToUseSteps as the How to redeem section
  • Use howToUseHints.hints for a compact bulleted summary per retail mode
  • Use howToUseInDetail.steps when you want detailed, illustrated instructions
  • When multiple retail modes are returned, show a mode switcher using each entry's retailModeName

Conditions and Warnings

  • Display voucherProductMetadata.conditions in the terms/conditions section of the page
  • Options with action: SHOW_WARNING should surface the warning copy; ALLOW_TRANSACTION proceeds directly
Do Not Cache Brand Details for Long Durations

Discounts, amounts, imagery, and brand availability can change, and inactive brands start returning errors. Refresh the brand details before showing a purchase screen.

Next Steps

  • Use Custom Listing to build the catalog and search experience that leads to this page.
  • Use Deep Links to open the SDK purchase flow from your custom brand page.
  • Use User Cohorts when brand visibility or discount rules should vary by user segment.