Jifiti Gifting Solutions
HomeMulticardsOur SolutionsCase StudyCompany
Contact Us
Jifiti Gifting Solutions

The platform behind digital payouts at scale. Launch a branded gift card marketplace, send corporate rewards at scale, or integrate gifting directly into your product.

Solutions

White-Label MarketplaceCorporate Gifting PlatformGifting APIMulticard

Company

About UsCase StudyContact

© 2026 Jifiti Gifting Solutions. All rights reserved.

Privacy Policy & Terms of ServiceCookie Policy

Gifting APIDocumentation

Browse a gift card catalog, place orders against your prepaid balance, and track those orders. This reference covers v2 of the Cheers Gifting API.

v2https://sandbox.api.cheers.gift

Contact your Cheers account manager for a sandbox API key.

On this page

Getting started

  • Key concepts
  • Endpoint summary
  • Authentication
  • Quick start
  • Conventions

Concepts

  • Brand identifiers
  • Issuance types

Endpoints

  • Get catalog
  • Create an order
  • Get an order
  • Get balance
  • List transactions

Guides

  • Handling Processing
  • Fees
  • Idempotency

Reference

  • Order status
  • Transaction status
  • Card
  • Card type
  • Error handling

Getting started

  • Key concepts
  • Endpoint summary
  • Authentication
  • Quick start
  • Conventions

Concepts

  • Brand identifiers
  • Issuance types

Endpoints

  • Get catalog
  • Create an order
  • Get an order
  • Get balance
  • List transactions

Guides

  • Handling Processing
  • Fees
  • Idempotency

Reference

  • Order status
  • Transaction status
  • Card
  • Card type
  • Error handling

Key concepts

ConceptDetail
Choose when the card is issuedissuanceType on order creation: get a redeem link now, or the card itself
Order by brand and amountOrders take a brandId and an amount instead of a product identifier
Opaque brand identifiersbrandId is an opaque string — see Brand identifiers
Read your ordersGET /api/v2/order/{orderId} returns the same shape as order creation
Retry-safe order creationReusing an idempotency key replays or resumes the order instead of failing
URL-only gift cards are not supported. Brands that can only be redeemed via a URL are excluded from the catalog.

Endpoint summary

MethodPathPurpose
GET/api/v2/catalogGet catalog
POST/api/v2/orderCreate an order
GET/api/v2/order/{orderId}Get an order
GET/api/v2/balanceGet balance
GET/api/v2/order/transactionsList transactions

Authentication

Every endpoint requires an API key, sent in the X-API-KEY request header. The key identifies your tenant — all catalogs, balances, orders, and transactions are scoped to it automatically.

Header
X-API-KEY: your-api-key-here

A request with a missing or invalid key returns 401 Unauthorized.

Keep the key on the server

Treat the API key as a secret. Call the API from your backend only — never embed the key in a browser, mobile app, or any client you don't control.

Quick start

1. Find a brand. Fetch the catalog for the currency you want to spend in, then pick a brandId and one of its denominations.

cURL
curl -X GET "https://sandbox.api.cheers.gift/api/v2/catalog?currency=USD" \
  -H "X-API-KEY: your-api-key"

2. Create the order. Choose how you want it issued.

cURL
curl -X POST "https://sandbox.api.cheers.gift/api/v2/order" \
  -H "X-API-KEY: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "brandId": "bmctMTpjYXQtMTIzNDU",
    "amount": 25.00,
    "idempotencyKey": "3f9a1c7e-1d2b-4f8a-9c31-0f4b2d6a77e1",
    "issuanceType": "OnDemand"
  }'

3. Deliver the gift. For OnDemand you get redeem.url — hand that to your customer. For JustInTime you get card with the card details themselves.

Conventions

TopicDetail
VersioningThe version is part of the path: /api/v{version}/…. This document covers v2.
Content typeRequest bodies are JSON; send Content-Type: application/json. Responses are JSON.
Field namingJSON fields are camelCase.
EnumsSent and returned by name (for example "OnDemand"). Numeric values are also accepted on input.
CurrenciesISO 4217 three-letter codes (USD, EUR, GBP). Codes are case-insensitive and normalized to uppercase.
AmountsDecimal numbers in the currency's major unit — 25.00 means 25 dollars, not 25 cents.
TimestampsISO 8601, UTC.
ErrorsNon-2xx responses carry a JSON body with a message field. See Error handling.

Brand identifiers

In v2, brandId is an opaque string. Read it from the catalog and send it back unchanged when you create an order.

  • Do store it and echo it back verbatim.
  • Don't parse it, decode it, derive meaning from it, or construct one yourself.

Its internal format is not part of this contract and will change. Treat it the way you would treat a session token.

Cache brand identifiers for no longer than 24 hours. A brandId that is no longer recognised returns 400 — re-fetch the catalog and retry with a current one.

Issuance types

issuanceType decides when the gift card is issued.

ValueBehaviourYou receive
OnDemandThe card is issued later, when the recipient opens the redeem linkredeem.url
JustInTimeThe card is issued immediatelycard with the card details

OnDemand returns as soon as the order is paid for. It is the right choice when you are sending a link to a recipient and do not need the card yourself.

JustInTime waits for the card to be issued, which involves two asynchronous steps on our side. It usually completes within the request. When it does not, you get status: "Processing" and a retryAfter — the order is fine, it is simply not finished yet. See Handling Processing.

Get catalog

GET/api/v2/catalog

Returns the brands available to your tenant for a given currency, with the amounts each can be ordered at.

Request headers

HeaderRequiredDescription
X-API-KEYYesYour API key

Query parameters

ParameterTypeRequiredDescription
currencystringYesISO 4217 currency code (e.g. USD, EUR, GBP)

Response 200 OK

JSON
{
  "catalogId": "Y2F0LTEyMzQ1",
  "currency": "USD",
  "brands": [
    {
      "brandId": "bmctMTpjYXQtMTIzNDU",
      "name": "Example Brand",
      "imageUrl": "https://cdn.progifts.io/brands/77.png",
      "thumbnailUrl": "https://cdn.progifts.io/brands/77-thumb.png",
      "cardType": "ClosedLoop",
      "denominations": [25.00, 50.00, 100.00],
      "ranges": []
    }
  ]
}
FieldTypeDescription
catalogIdstringOpaque identifier of the catalog
currencystringISO 4217 currency code of this catalog
brandsarrayBrands available to your tenant in this currency

Brand object

FieldTypeDescription
brandIdstringOpaque brand identifier — see Brand identifiers
namestringDisplay name of the brand
imageUrlstringURL of the brand's card image (nullable)
thumbnailUrlstringURL of the brand's thumbnail image (nullable)
cardTypestringClosedLoop, OpenLoop or Multicard (nullable)
denominationsarrayThe exact amounts this brand can be ordered at
rangesarrayOpen amount ranges. Currently always empty — see below
Multicard brands only support issuanceType: "OnDemand". They package several brands into one card, so there is nothing single to issue on the spot — requesting JustInTime for one returns 400.

Range object (reserved)

FieldTypeDescription
mindecimalLowest orderable amount
maxdecimalHighest orderable amount
incrementdecimalStep between valid amounts (nullable)

ranges is always empty today — every brand uses fixed denominations. It is present so that brands accepting an open amount can be added without a breaking change. Handle it if you can; ignoring it is safe for now.

Errors

StatusWhen
400currency is missing or empty
401Missing or invalid API key

Example

cURL
curl -X GET "https://sandbox.api.cheers.gift/api/v2/catalog?currency=USD" \
  -H "X-API-KEY: your-api-key"

Create an order

POST/api/v2/order

Creates a gift card order, pays for it from your tenant balance, and returns either a redeem link or the issued card, depending on issuanceType.

Request headers

HeaderRequiredDescription
X-API-KEYYesYour API key
Content-TypeYesapplication/json

Request body

JSON
{
  "brandId": "bmctMTpjYXQtMTIzNDU",
  "amount": 25.00,
  "idempotencyKey": "3f9a1c7e-1d2b-4f8a-9c31-0f4b2d6a77e1",
  "issuanceType": "JustInTime",
  "metadata": {
    "externalCustomerId": "customer-abc-001"
  }
}
FieldTypeRequiredDescription
brandIdstringYesOpaque brand identifier from the catalog. Max 500 characters
amountdecimalYesThe gift card's value. Must be one of the brand's denominations. Some brands add a fee on top — see Fees
idempotencyKeystringYesYour unique key for this order. Max 500 characters; must be unique per tenant. See Idempotency
issuanceTypestringYesOnDemand or JustInTime — see Issuance types
metadataobjectNoOptional extra data to record against the order
metadata.externalCustomerIdstringNoYour own identifier for the customer. Max 500 characters
There is no currency field. The currency is determined by the brandId, which already belongs to one catalog and one currency.

Response 200 OK

JSON
{
  "orderId": 987654,
  "idempotencyKey": "3f9a1c7e-1d2b-4f8a-9c31-0f4b2d6a77e1",
  "issuanceType": "OnDemand",
  "status": "Completed",
  "amount": 25.00,
  "currency": "USD",
  "redeem": {
    "url": "https://redeem.progifts.io/o/abc123"
  }
}
FieldTypeDescription
orderIdintegerUnique identifier of the created order
idempotencyKeystringThe key you sent, echoed back
issuanceTypestringThe issuance type of this order
statusstringCompleted or Processing — see Order status
amountdecimalThe gift card's value — the amount you requested. Not the total billed; see Fees
currencystringISO 4217 currency code
redeemobjectPresent for a completed OnDemand order
redeem.urlstringURL the recipient uses to redeem the gift card
cardobjectPresent for a completed JustInTime order — see Card
retryAfterdate-timePresent only while status is Processing

Processing is not an error

A Processing response is not an error and the order is not lost. It is already paid for. See Handling Processing.

Errors

StatusWhen
400Unknown or malformed brandId, amount is not one of the brand's denominations, the brand's currency is not enabled for your tenant, or issuanceType: "JustInTime" was requested for a Multicard brand
401Missing or invalid API key
409The idempotencyKey was already used with a different request body
502The payment could not be completed downstream
500Unexpected server error

Example

cURL
curl -X POST "https://sandbox.api.cheers.gift/api/v2/order" \
  -H "X-API-KEY: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "brandId": "bmctMTpjYXQtMTIzNDU",
    "amount": 25.00,
    "idempotencyKey": "3f9a1c7e-1d2b-4f8a-9c31-0f4b2d6a77e1",
    "issuanceType": "JustInTime",
    "metadata": { "externalCustomerId": "customer-abc-001" }
  }'

Get an order

GET/api/v2/order/{orderId}

Returns one of your orders, in exactly the same shape as Create an order.

Safe to poll: it checks for progress at most once per call and never blocks. It is a pure read — to move a Processing order forward, re-POST it. See Handling Processing.

Request headers

HeaderRequiredDescription
X-API-KEYYesYour API key

Path parameters

ParameterTypeRequiredDescription
orderIdintegerYesThe orderId returned by Create an order

Response 200 OK

Identical to the create-order response.

Errors

StatusWhen
401Missing or invalid API key
404No such order for your tenant. Orders belonging to another tenant are reported as 404, not 403
502The payment could not be completed downstream

Example

cURL
curl -X GET "https://sandbox.api.cheers.gift/api/v2/order/987654" \
  -H "X-API-KEY: your-api-key"

Get balance

GET/api/v2/balance

Returns your tenant's prepaid wallet balance. Orders are funded from this balance, so check it before placing large batches.

Request headers

HeaderRequiredDescription
X-API-KEYYesYour API key

Query parameters

ParameterTypeRequiredDescription
currencyCodestringYesISO 4217 currency code to report the balance in

Response 200 OK

JSON
{
  "partnerId": "1042",
  "balances": [
    {
      "currency": "USD",
      "amount": 1520.75
    }
  ]
}
FieldTypeDescription
partnerIdstringYour tenant/partner identifier
balancesarrayWallet balances

Wallet balance object

FieldTypeDescription
currencystringISO 4217 currency code
amountdecimalAvailable amount in that currency

Errors

StatusWhen
400currencyCode is missing or empty
401Missing or invalid API key
404No balance exists for the requested currency
500Unexpected server error

Example

cURL
curl -X GET "https://sandbox.api.cheers.gift/api/v2/balance?currencyCode=USD" \
  -H "X-API-KEY: your-api-key"

List transactions

GET/api/v2/order/transactions

Returns your tenant's orders as a paged, date-filtered list — useful for reconciliation and reporting.

Request headers

HeaderRequiredDescription
X-API-KEYYesYour API key

Query parameters

ParameterTypeRequiredDefaultDescription
pageintegerNo1Page number, starting at 1
pageSizeintegerNo10Items per page. Between 1 and 100
orderByAscbooleanNofalseSort oldest-first when true, newest-first when false
startDatedate-timeNoendDate minus the history windowStart of the period (inclusive)
endDatedate-timeNonow (UTC)End of the period (inclusive)

History is limited to a rolling window — one year by default. A startDate older than that window is rejected with 400, and endDate must not be earlier than startDate.

Response 200 OK

JSON
{
  "page": 1,
  "pageSize": 10,
  "totalCount": 42,
  "totalPages": 5,
  "items": [
    {
      "orderId": "987654",
      "storeName": "Example Store",
      "storeId": 321,
      "productId": 12345,
      "price": 25.00,
      "currency": "USD",
      "timestamp": "2026-08-05T09:31:44Z",
      "orderStatus": "Committed",
      "metaData": null
    }
  ]
}
FieldTypeDescription
pageintegerThe page that was returned
pageSizeintegerItems per page
totalCountintegerTotal transactions matching the filter
totalPagesintegerTotal number of pages
itemsarrayThe transactions on this page

Transaction object

FieldTypeDescription
orderIdstringIdentifier of the order
storeNamestringBrand/store the gift card belongs to (nullable)
storeIdintegerIdentifier of the store (nullable)
productIdintegerThe underlying provider product id — not your brandId
pricedecimalAmount charged, fees included. This is where you see the order's billed total — the order response itself reports only the requested amount
currencystringISO 4217 currency code
timestampdate-timeWhen the transaction took place
orderStatusstringStatus name — see Transaction status (nullable)
metaDatastringAdditional order metadata (nullable)

Errors

StatusWhen
400page < 1, pageSize outside 1–100, or an invalid/out-of-window date range
401Missing or invalid API key
500Unexpected server error

Example

cURL
curl -X GET "https://sandbox.api.cheers.gift/api/v2/order/transactions?page=1&pageSize=25&orderByAsc=false&startDate=2026-01-01&endDate=2026-08-05" \
  -H "X-API-KEY: your-api-key"

Handling Processing

JustInTime issuance waits on two asynchronous steps. Most orders finish inside the original request. When one does not, you get:

JSON
{
  "orderId": 987654,
  "status": "Processing",
  "retryAfter": "2026-08-12T09:15:05Z"
}

The order exists and is paid for. Wait until retryAfter, then re-POST the order — same body, same idempotencyKey:

cURL
curl -X POST "https://sandbox.api.cheers.gift/api/v2/order" \
  -H "X-API-KEY: your-api-key" -H "Content-Type: application/json" \
  -d '{ ...exactly the same body, including the same idempotencyKey... }'

This resumes the existing order — it never creates a second one — and waits for the card.

GET /api/v2/order/{orderId} is a read: it reports the current state and is safe to call as often as you like, but it does not itself advance a stalled order. Use it to check; use the re-POST to make progress.

Do not mint a new key

Keep going until status is Completed. If it stays Processing across several attempts, the order is likely held for review — contact Jifiti support with the orderId. Never retry with a new idempotencyKey. That creates a second order and charges you twice.

Fees

amount is the gift card's value — what the recipient receives, and what you asked for. It is not necessarily what you are billed.

Some brands carry a processing fee, applied by the platform on top of the card value. A $50 card on a brand with a $4.90 fee draws $54.90 from your balance while amount still reads 50.00.

To see what was actually billed, use List transactions — its price is the total for the order, fees included.

Idempotency

Create an order is the only endpoint that moves money, so it is guarded by an idempotency key that you generate and send in idempotencyKey.

  • The key must be unique within your tenant — a UUID per order attempt works well.
  • Store the key alongside your own order record before you call the API.
  • If a call fails with a network error or timeout, retry with the same key.

Reusing a key with the same request body returns 200 OK — it replays the original order, or resumes it if it was left unfinished. Reusing a key with a different request body returns 409 Conflict.

So a retry after a timeout simply returns the order — you never need to reconcile a 409 to find out whether the first attempt succeeded.

JSON
{ "message": "Duplicate request detected. This idempotency key has already been used." }

Order status

ValueMeaning
CompletedThe redeem link (OnDemand) or the card (JustInTime) is ready
ProcessingIssuance has not finished yet. Retry after retryAfter

Transaction status

orderStatus on List transactions — a separate vocabulary from Order status above, describing the payment transaction rather than issuance.

ValueMeaning
AuthorizedFunds authorized, order not yet finalized
CommittedOrder completed successfully
VoidedOrder cancelled before completion
RefundedOrder refunded
ErrorAuthorizingAuthorization failed
ErrorCommittingCommit failed
ErrorRefundingRefund failed

Card

Returned as card on a completed JustInTime order.

FieldTypeDescription
redemptionTypestringCode or Url — how the card is redeemed
redemptionValuestringThe card number, or the redemption URL
verificationCodeTypestringPinCode, SecurityCode, SecretCode or Token (nullable)
verificationCodestringThe accompanying code, when the card has one (nullable)
expiresAtdate-timeWhen the card expires (nullable)
issuedAtdate-timeWhen the card was issued

There is no Barcode redemption type. A card displayed as a barcode is a Code — the barcode is a way of presenting the value, not a separate way of redeeming it.

Treat card details as credentials

redemptionValue and verificationCode are the gift card itself. Store them encrypted, keep them out of logs, and send them only over TLS.

Card type

ValueMeaning
ClosedLoopRedeemable with one brand
OpenLoopRedeemable anywhere the card network is accepted
MulticardA card covering a group of brands

Error handling

The API uses standard HTTP status codes.

StatusMeaning
200Success — including status: "Processing"
400Bad Request — unknown brandId, invalid amount, or unsupported currency
401Unauthorized — missing or invalid API key
404Not Found — no such order for your tenant
409Conflict — the idempotency key was reused with a different request
500Internal Server Error
502Bad Gateway — the payment could not be completed downstream

Error responses carry a JSON body with a human-readable message:

JSON
{ "message": "Amount 37 is not available for brand 'bmctMTpjYXQtMTIzNDU'. Valid denominations: 25, 50, 100." }

Log the message verbatim when reporting an issue to Jifiti support, along with the request timestamp (UTC) and, where relevant, the idempotencyKey or orderId.

Retry guidance

StatusRetry?
400, 401, 404No — fix the request or the key first
409No — the key was reused with a different body. Use a new key, or resend the original body
500Yes, with exponential backoff, reusing the same idempotencyKey
502No — the payment failed. Contact support with the orderId

Need a sandbox key? Talk to our team.

Ready to integrate?

Get a sandbox API key and start issuing gift cards from your product.
Talk to Our Team