POST
/
{locale}
/
shop
/
offers
/
{id}
/
claim
curl -X POST "https://staging-api.loyalty.lt/en/shop/offers/101/claim" \
  -H "Authorization: Bearer your_jwt_token" \
  -H "Content-Type: application/json" \
  -d '{
    "card_id": 123,
    "metadata": {
      "preferred_redemption_date": "2024-01-20",
      "source": "app",
      "notes": "Planning to use this weekend"
    }
  }'
{
  "success": true,
  "message": "Offer claimed successfully",
  "data": {
    "claim": {
      "id": 5001,
      "claim_code": "DISCOUNT-ABC123-XYZ789",
      "status": "active",
      "claimed_at": "2024-01-15T16:30:00Z",
      "expires_at": "2024-03-15T23:59:59Z",
      "redemption_instructions": "Present this code at checkout to receive your 20% discount on purchases of €25 or more."
    },
    "offer": {
      "id": 101,
      "title": "20% Off Your Next Purchase",
      "description": "Get 20% discount on your next purchase of €25 or more",
      "value": 20,
      "offer_type": "percentage_discount",
      "terms_conditions": "Valid on purchases of €25 or more. Cannot be combined with other offers."
    },
    "points_transaction": {
      "id": 12350,
      "points_deducted": 200,
      "balance_before": 1250,
      "balance_after": 1050
    },
    "benefit": {
      "type": "discount_code",
      "value": "DISCOUNT20-CAFE123",
      "amount": 5.00,
      "usage_instructions": "Enter code 'DISCOUNT20-CAFE123' at checkout or show to cashier",
      "valid_until": "2024-03-15T23:59:59Z"
    }
  }
}

Claim Offer

Claim an available offer by spending the required loyalty points. This endpoint validates eligibility, deducts points, and generates the appropriate benefit (discount code, voucher, etc.).
Offers can only be claimed once per user (unless specified otherwise) and require sufficient points balance and tier status. Claimed offers are immediately activated.

Path Parameters

locale
string
required
Language code for localized content (e.g., “en”, “lt”)
id
integer
required
Unique identifier of the offer to claim

Request Body

card_id
integer
required
Loyalty card ID to use for claiming the offer
metadata
object
Additional claim context and preferences

Response

success
boolean
Indicates if the offer was successfully claimed
message
string
Human-readable message about the operation
data
object
curl -X POST "https://staging-api.loyalty.lt/en/shop/offers/101/claim" \
  -H "Authorization: Bearer your_jwt_token" \
  -H "Content-Type: application/json" \
  -d '{
    "card_id": 123,
    "metadata": {
      "preferred_redemption_date": "2024-01-20",
      "source": "app",
      "notes": "Planning to use this weekend"
    }
  }'
{
  "success": true,
  "message": "Offer claimed successfully",
  "data": {
    "claim": {
      "id": 5001,
      "claim_code": "DISCOUNT-ABC123-XYZ789",
      "status": "active",
      "claimed_at": "2024-01-15T16:30:00Z",
      "expires_at": "2024-03-15T23:59:59Z",
      "redemption_instructions": "Present this code at checkout to receive your 20% discount on purchases of €25 or more."
    },
    "offer": {
      "id": 101,
      "title": "20% Off Your Next Purchase",
      "description": "Get 20% discount on your next purchase of €25 or more",
      "value": 20,
      "offer_type": "percentage_discount",
      "terms_conditions": "Valid on purchases of €25 or more. Cannot be combined with other offers."
    },
    "points_transaction": {
      "id": 12350,
      "points_deducted": 200,
      "balance_before": 1250,
      "balance_after": 1050
    },
    "benefit": {
      "type": "discount_code",
      "value": "DISCOUNT20-CAFE123",
      "amount": 5.00,
      "usage_instructions": "Enter code 'DISCOUNT20-CAFE123' at checkout or show to cashier",
      "valid_until": "2024-03-15T23:59:59Z"
    }
  }
}

Claim Process Flow

The offer claiming process follows these steps:
1

Eligibility Validation

System checks user tier, points balance, usage limits, and offer availability
2

Points Reservation

Required points are temporarily reserved to prevent double-spending
3

Benefit Generation

Unique codes, vouchers, or access tokens are generated for the user
4

Points Deduction

Points are officially deducted and transaction is recorded
5

Claim Activation

Claim becomes active and benefit details are returned to user
6

Notification

User receives confirmation and redemption instructions

Benefit Types

Different offer types generate different benefits when claimed:

Claim Management

Tracking Claims

// Store claim for later reference
const storeClaimLocally = (claim) => {
  const claims = JSON.parse(localStorage.getItem('my_claims') || '[]');
  claims.push({
    id: claim.id,
    code: claim.claim_code,
    expires: claim.expires_at,
    offer_title: offer.title
  });
  localStorage.setItem('my_claims', JSON.stringify(claims));
};

// Check expiring claims
const checkExpiringClaims = () => {
  const claims = JSON.parse(localStorage.getItem('my_claims') || '[]');
  const soon = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000); // 7 days
  
  return claims.filter(claim => 
    new Date(claim.expires) < soon && 
    new Date(claim.expires) > new Date()
  );
};

Usage Validation

// Validate claim before use
const validateClaim = async (claimCode) => {
  const response = await fetch(`/en/shop/claims/${claimCode}/validate`);
  const data = await response.json();
  
  return {
    isValid: data.success,
    status: data.data?.status,
    expiresAt: data.data?.expires_at
  };
};

Error Handling

Common claim failures and recommended handling:

Insufficient Points

if (error.code === 'INSUFFICIENT_POINTS') {
  // Show points needed vs. available
  const needed = offer.points_required;
  const available = user.points_balance;
  const shortfall = needed - available;
  
  showMessage(`You need ${shortfall} more points to claim this offer.`);
  showEarnPointsOptions();
}

Tier Requirements

if (error.code === 'TIER_REQUIREMENT_NOT_MET') {
  const requiredTier = offer.minimum_tier;
  const currentTier = user.tier;
  
  showUpgradePath(currentTier, requiredTier);
}

Already Claimed

if (error.code === 'OFFER_ALREADY_CLAIMED') {
  // Redirect to claimed offers list
  navigateToClaimedOffers();
  showMessage('You\'ve already claimed this offer. Check your claimed offers.');
}

Security Considerations

Code Security: Claim codes should be treated as sensitive information. Never log them in analytics or store them in plain text logs.

Best Practices

  • Secure Storage: Store claim codes securely on client side
  • Expiration Handling: Implement client-side expiration warnings
  • Usage Tracking: Track when users actually redeem claims
  • Fraud Prevention: Monitor for unusual claiming patterns
Claim Persistence: Claimed offers remain accessible through user’s account even after the original offer expires, ensuring users can always access their benefits.