> ## Documentation Index
> Fetch the complete documentation index at: https://docs.voyantcloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Upsert Lodging Link

> Create or update the primary lodging link for a product, including optional property overrides.

## Method

`PUT` `/v1/products/:id/lodging`

## Path Parameters

<ParamField path="id" type="uuid">Product ID to link to a lodging property.</ParamField>

## Body Parameters

<ParamField name="propertyId" type="uuid" required>Property ID from the lodging catalog (required).</ParamField>
<ParamField name="roomTypeId" type="uuid">Optional default room type to associate with the link.</ParamField>
<ParamField name="ratePlanId" type="uuid">Optional rate plan to scope pricing.</ParamField>
<ParamField name="active" type="boolean">Whether the link should be active (defaults to `true`).</ParamField>
<ParamField name="override" type="object">Property-level override applied when rendering the product.</ParamField>

<Expandable title="Override object">
  <ParamField name="override.name" type="string">Display name shown instead of the property name.</ParamField>
  <ParamField name="override.shortDescription" type="string">Short summary (shown in cards).</ParamField>
  <ParamField name="override.description" type="string">Long-form description for property pages.</ParamField>
  <ParamField name="override.mediaSetRef" type="string">Reference to a gallery media set.</ParamField>
  <ParamField name="override.amenityKeys" type="array">List of amenity keys to highlight.</ParamField>
  <ParamField name="override.currency" type="string">Three-letter ISO currency for override pricing.</ParamField>
  <ParamField name="override.priceStrategy" type="string">`absolute`, `percent_delta`, or `inherit`.</ParamField>
  <ParamField name="override.priceAmountMinor" type="integer">Price amount in minor units (required when strategy is `absolute`).</ParamField>
  <ParamField name="override.priceReferenceRatePlanId" type="uuid">Reference rate plan for `percent_delta` strategy.</ParamField>
  <ParamField name="override.cancellationPolicyId" type="uuid">Override cancellation policy.</ParamField>
  <ParamField name="override.depositPolicyId" type="uuid">Override deposit policy.</ParamField>
</Expandable>

## Headers

<ParamField header="Authorization" type="string">Bearer token (requires `products:write`).</ParamField>
<ParamField header="content-type" type="string">`application/json`</ParamField>

## Request Example

<RequestExample>
  ```bash cURL theme={null}
  curl -X PUT "https://api.voyantcloud.com/v1/products/prod_123/lodging" \
    -H "Authorization: Bearer $VOYANT_API_KEY" \
    -H "content-type: application/json" \
    -d '{
      "propertyId": "prop_987",
      "ratePlanId": "rate_456",
      "active": true,
      "override": {
        "name": "Voyant Athens Hotel",
        "shortDescription": "Boutique stay near Syntagma Square",
        "currency": "EUR",
        "priceStrategy": "absolute",
        "priceAmountMinor": 18900,
        "amenityKeys": ["wifi", "breakfast"],
        "mediaSetRef": "media_set_123"
      }
    }'
  ```

  ```javascript Node.js theme={null}
  const res = await fetch("https://api.voyantcloud.com/v1/products/prod_123/lodging", {
    method: "PUT",
    headers: {
      Authorization: `Bearer ${process.env.VOYANT_API_KEY}`,
      "content-type": "application/json",
    },
    body: JSON.stringify({
      propertyId: "prop_987",
      roomTypeId: "room_001",
      active: true,
    }),
  })
  const payload = await res.json()
  ```

  ```python Python theme={null}
  import os, requests

  payload = {
    "propertyId": "prop_987",
    "active": True,
    "override": {
      "currency": "EUR",
      "priceStrategy": "inherit"
    }
  }

  resp = requests.put(
    "https://api.voyantcloud.com/v1/products/prod_123/lodging",
    headers={
      "Authorization": f"Bearer {os.environ['VOYANT_API_KEY']}",
      "content-type": "application/json",
    },
    json=payload,
  )
  result = resp.json()
  ```
</RequestExample>

## Response

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "data": {
      "link": {
        "id": "pll_001",
        "productId": "prod_123",
        "propertyId": "prop_987",
        "departureId": null,
        "ratePlanId": "rate_456",
        "roomTypeId": "room_001",
        "active": "true"
      },
      "override": {
        "id": "plo_001",
        "name": "Voyant Athens Hotel",
        "currency": "EUR",
        "priceStrategy": "absolute",
        "priceAmountMinor": 18900,
        "amenityKeys": ["wifi", "breakfast"],
        "mediaSetRef": "media_set_123"
      }
    }
  }
  ```
</ResponseExample>

<Tip>
  If the specified rate plan no longer exists, the API automatically retries with `ratePlanId` set to `null` to preserve the link.
</Tip>
