curl --request POST \
--url https://api.loyalty.dog/v2/giftcards/programs/{programId}/consolidate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"cardNumbers": [
"<string>"
],
"merchantId": "5eb7cf5a86d9755df3a6c593"
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({cardNumbers: ['<string>'], merchantId: '5eb7cf5a86d9755df3a6c593'})
};
fetch('https://api.loyalty.dog/v2/giftcards/programs/{programId}/consolidate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.loyalty.dog/v2/giftcards/programs/{programId}/consolidate"
payload = {
"cardNumbers": ["<string>"],
"merchantId": "5eb7cf5a86d9755df3a6c593"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"success": true,
"message": "<string>",
"newCard": {
"id": "5eb7cf5a86d9755df3a6c593",
"cardNumber": "<string>",
"balance": "<string>",
"initialValue": "<string>",
"status": "pending",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"activatedAt": "2023-11-07T05:31:56Z",
"expiresAt": "2023-11-07T05:31:56Z",
"suspendedReason": "<string>",
"suspendedUntil": "2023-11-07T05:31:56Z",
"suspendedAt": "2023-11-07T05:31:56Z",
"customerId": "5eb7cf5a86d9755df3a6c593",
"customerEmail": "<string>",
"customerPhone": "<string>",
"customerName": "<string>",
"merchantId": "5eb7cf5a86d9755df3a6c593",
"isPhysical": true,
"designTemplate": "<string>",
"customMessage": "<string>",
"lastFourDigits": "<string>",
"programId": "5eb7cf5a86d9755df3a6c593",
"card": {
"serialNumber": "<string>",
"passTypeIdentifier": "<string>",
"url": "<string>"
},
"senderName": "<string>",
"merchantName": "<string>",
"deliverAt": "2023-11-07T05:31:56Z",
"delivered": false
},
"voidedCards": [
"<string>"
],
"totalConsolidatedAmount": "<string>",
"consolidationTransactions": [
"<string>"
],
"referenceId": "<string>"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Consolidategiftcards
Consolidates multiple ACTIVE gift cards from the same program and customer into a single new active card with the combined balance.
Performs validation (2–10 unique cards, all ACTIVE, positive balances, same customer, total ≤ $10,000), acquires per-card locks to prevent concurrent modifications, creates a new card with a cryptographically generated number and security code, voids source cards (setting their balances to zero), and records consolidation transactions inside an atomic database transaction.
Returns:
ConsolidateResponse: Details of the consolidation including newCard (the created gift card), voidedCards (IDs of source cards), totalConsolidatedAmount, consolidationTransactions (transaction IDs), and an informational message.
Idempotency Scope:
Keys are scoped to programId + consolidate + sorted source card ids.
Reusing the same key for a different source-card set is treated as a fresh operation.
curl --request POST \
--url https://api.loyalty.dog/v2/giftcards/programs/{programId}/consolidate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"cardNumbers": [
"<string>"
],
"merchantId": "5eb7cf5a86d9755df3a6c593"
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({cardNumbers: ['<string>'], merchantId: '5eb7cf5a86d9755df3a6c593'})
};
fetch('https://api.loyalty.dog/v2/giftcards/programs/{programId}/consolidate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.loyalty.dog/v2/giftcards/programs/{programId}/consolidate"
payload = {
"cardNumbers": ["<string>"],
"merchantId": "5eb7cf5a86d9755df3a6c593"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"success": true,
"message": "<string>",
"newCard": {
"id": "5eb7cf5a86d9755df3a6c593",
"cardNumber": "<string>",
"balance": "<string>",
"initialValue": "<string>",
"status": "pending",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"activatedAt": "2023-11-07T05:31:56Z",
"expiresAt": "2023-11-07T05:31:56Z",
"suspendedReason": "<string>",
"suspendedUntil": "2023-11-07T05:31:56Z",
"suspendedAt": "2023-11-07T05:31:56Z",
"customerId": "5eb7cf5a86d9755df3a6c593",
"customerEmail": "<string>",
"customerPhone": "<string>",
"customerName": "<string>",
"merchantId": "5eb7cf5a86d9755df3a6c593",
"isPhysical": true,
"designTemplate": "<string>",
"customMessage": "<string>",
"lastFourDigits": "<string>",
"programId": "5eb7cf5a86d9755df3a6c593",
"card": {
"serialNumber": "<string>",
"passTypeIdentifier": "<string>",
"url": "<string>"
},
"senderName": "<string>",
"merchantName": "<string>",
"deliverAt": "2023-11-07T05:31:56Z",
"delivered": false
},
"voidedCards": [
"<string>"
],
"totalConsolidatedAmount": "<string>",
"consolidationTransactions": [
"<string>"
],
"referenceId": "<string>"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Authorizations
JWT access token obtained from POST /v2/token.
Headers
Path Parameters
24^[0-9a-f]{24}$"5eb7cf5a86d9755df3a6c593"
Query Parameters
24^[0-9a-f]{24}$"5eb7cf5a86d9755df3a6c593"
Body
2 - 10 elements24^[0-9a-f]{24}$"5eb7cf5a86d9755df3a6c593"
255255100500100500