# Get Offer Details
> Source: /api-reference/members/loyalty/get-offer
> Get detailed information about a specific offer with eligibility status
> Endpoint: GET /members/me/loyalty/offers/{offerId}

## Overview [#overview]

Returns comprehensive details about a specific offer including eligibility status, restrictions, and redemption instructions. Use this endpoint to show full offer details before allowing the member to claim it.

## Authentication [#authentication]

Requires a valid Clerk JWT token in the Authorization header.

## Path Parameters [#path-parameters]

<ParamField path="offerId" type="string" required>
  Offer document ID
</ParamField>

## Query Parameters [#query-parameters]

<ParamField query="propertyId" type="string">
  Property document ID for property context (affects eligibility)
</ParamField>

<ParamField query="reservationId" type="string">
  Reservation external ID for stay context (affects eligibility)
</ParamField>

<ParamField query="checkInDate" type="string">
  Check-in date for time-sensitive offers (ISO 8601 date)
</ParamField>

<RequestExample>

```bash cURL
curl -X GET "http://localhost:3000/v1/members/me/loyalty/offers/offer_spa_discount?propertyId=prop_luxury_resort" \
  -H "Authorization: Bearer YOUR_CLERK_JWT"
```

```typescript TypeScript
const offerId = "offer_spa_discount";
const response = await fetch(`http://localhost:3000/v1/members/me/loyalty/offers/${offerId}?propertyId=prop_luxury_resort`, {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_CLERK_JWT'
  }
});

const offer = await response.json();
```

</RequestExample>

## Response [#response]

<ResponseField name="offerId" type="string" required>
  Offer document ID
</ResponseField>

<ResponseField name="name" type="string" required>
  Display name of the offer
</ResponseField>

<ResponseField name="shortDescription" type="string">
  Brief description for card display
</ResponseField>

<ResponseField name="description" type="string">
  Full description of the offer
</ResponseField>

<ResponseField name="pointsRequired" type="number" required>
  Points cost to claim this offer
</ResponseField>

<ResponseField name="retailValue" type="number">
  Retail value of the offer in dollars
</ResponseField>

<ResponseField name="discountAmount" type="number">
  Dollar amount of discount if applicable
</ResponseField>

<ResponseField name="discountType" type="string">
  Type of discount: "percentage", "fixed", etc.
</ResponseField>

<ResponseField name="redemptionType" type="string" required>
  How offer is redeemed: "direct", "externalCode", "propertySpecific", etc.
</ResponseField>

<ResponseField name="category" type="object">
  Offer category information
  
  <Expandable title="properties">
    <ResponseField name="id" type="number" required>
      Category ID
    </ResponseField>
    
    <ResponseField name="name" type="string" required>
      Category name
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="heroImageUrl" type="string">
  URL for hero image
</ResponseField>

<ResponseField name="cardImageUrl" type="string">
  URL for card thumbnail image
</ResponseField>

<ResponseField name="howToRedeem" type="string">
  Instructions for redeeming the offer
</ResponseField>

<ResponseField name="termsAndConditions" type="string">
  Full terms and conditions text
</ResponseField>

<ResponseField name="rules" type="string">
  Additional rules and restrictions
</ResponseField>

<ResponseField name="isEligible" type="boolean" required>
  Whether the member can claim this offer
</ResponseField>

<ResponseField name="eligibilityReason" type="string">
  Reason if not eligible (e.g., "Insufficient points", "Tier too low")
</ResponseField>

<ResponseField name="restrictions" type="array">
  Active restrictions preventing claim
  
  <Expandable title="array items">
    <ResponseField name="type" type="string" required>
      Restriction type: "requires_stay", "check_in_window"
    </ResponseField>
    
    <ResponseField name="message" type="string" required>
      Human-readable restriction message
    </ResponseField>
    
    <ResponseField name="details" type="object">
      Additional restriction details
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="requiresStay" type="boolean" required>
  Whether offer requires an active reservation
</ResponseField>

<ResponseField name="disableBeforeCheckInHours" type="number">
  Hours before check-in when offer becomes unavailable
</ResponseField>

<ResponseField name="validUntil" type="string">
  ISO 8601 timestamp when offer expires
</ResponseField>

<ResponseField name="isCustomOffer" type="boolean">
  Whether this is a custom/personalized offer
</ResponseField>

<ResponseField name="isGlobal" type="boolean">
  Whether this offer is available globally
</ResponseField>

<ResponseField name="propertyDocumentId" type="string">
  Primary property document ID for property-specific offers
</ResponseField>

<ResponseExample>

```json 200 Response - Eligible Offer
{
  "offerId": "offer_spa_discount",
  "name": "Spa Treatment Discount",
  "shortDescription": "25% off all spa treatments",
  "description": "Indulge in ultimate relaxation with a 25% discount on any spa treatment at our award-winning wellness center. Choose from massages, facials, body treatments, and wellness packages.",
  "pointsRequired": 1500,
  "retailValue": 200,
  "discountAmount": 50,
  "discountType": "percentage",
  "redemptionType": "propertySpecific",
  "category": {
    "id": 3,
    "name": "Spa & Wellness"
  },
  "heroImageUrl": "https://cdn.journey.com/offers/spa-hero.jpg",
  "cardImageUrl": "https://cdn.journey.com/offers/spa-card.jpg",
  "howToRedeem": "Present your verification code at the spa reception when booking or arriving for your treatment.",
  "termsAndConditions": "Valid for single use per stay. Cannot be combined with other offers. Subject to spa availability. Advance booking recommended.",
  "rules": "Minimum treatment value of $100 required. Valid Monday through Thursday only. Not valid on holidays.",
  "isEligible": true,
  "eligibilityReason": null,
  "restrictions": [],
  "requiresStay": true,
  "disableBeforeCheckInHours": 24,
  "validUntil": "2024-12-31T23:59:59Z",
  "isCustomOffer": false,
  "isGlobal": false,
  "propertyDocumentId": "prop_luxury_resort"
}
```

```json 200 Response - Ineligible Offer
{
  "offerId": "offer_suite_upgrade",
  "name": "Premium Suite Upgrade",
  "shortDescription": "Upgrade to premium suite",
  "description": "Enhance your stay with an upgrade to our premium suite featuring ocean views, separate living area, and luxury amenities.",
  "pointsRequired": 3000,
  "retailValue": 500,
  "redemptionType": "propertySpecific",
  "category": {
    "id": 2,
    "name": "Room Upgrades"
  },
  "heroImageUrl": "https://cdn.journey.com/offers/suite-hero.jpg",
  "cardImageUrl": "https://cdn.journey.com/offers/suite-card.jpg",
  "howToRedeem": "Contact front desk with your verification code during check-in.",
  "termsAndConditions": "Subject to availability at check-in. Cannot be reserved in advance.",
  "isEligible": false,
  "eligibilityReason": "Insufficient points (3000 required, 2500 available)",
  "restrictions": [
    {
      "type": "requires_stay",
      "message": "This offer requires an active reservation",
      "details": {}
    }
  ],
  "requiresStay": true,
  "disableBeforeCheckInHours": 12,
  "validUntil": "2024-12-31T23:59:59Z",
  "isCustomOffer": false,
  "isGlobal": false,
  "propertyDocumentId": "prop_luxury_resort"
}
```

```json 404 Response - Not Found
{
  "statusCode": 404,
  "message": "Offer not found"
}
```

</ResponseExample>

## Eligibility Factors [#eligibility-factors]

### Points Balance [#points-balance]
- Member must have sufficient points to purchase the offer
- Check current balance using the [wallet balance endpoint](/api-reference/members/wallet/get-balance)

### Tier Level [#tier-level]
- Some offers require minimum tier levels
- Member's current tier is checked against offer requirements

### Property Context [#property-context]
- Property-specific offers require being at or having a reservation at that property
- Pass `propertyId` and `reservationId` for accurate eligibility

### Time Restrictions [#time-restrictions]
- Some offers have check-in windows (e.g., must claim within 24 hours of arrival)
- `disableBeforeCheckInHours` indicates when offer becomes unavailable

### Stay Requirements [#stay-requirements]
- `requiresStay: true` means member must have an active or upcoming reservation
- Pass `reservationId` to satisfy this requirement

## Related Endpoints [#related-endpoints]

- [Claim Offer](/api-reference/members/loyalty/claim-offer) - Purchase this offer with points
- [Get Available Offers](/api-reference/members/loyalty/get-offers) - Browse all available offers
- [Get Wallet Balance](/api-reference/members/wallet/get-balance) - Check points balance
