> ## 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.

# Bulk Upsert Lodging Links

> Link a product to multiple properties (and optional departure/rate plan scopes) in a single request.

## Method

`PATCH` `/v1/products/:id/lodging/links`

## Path Parameters

<ParamField path="id" type="uuid">Product ID for the links.</ParamField>

## Body Parameters

<ParamField name="propertyIds" type="array" required>Array of property IDs to link (must contain at least one ID).</ParamField>
<ParamField name="departureId" type="uuid">Scope links to a specific departure.</ParamField>
<ParamField name="ratePlanId" type="uuid">Scope links to a specific rate plan.</ParamField>

## 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 PATCH "https://api.voyantcloud.com/v1/products/prod_123/lodging/links" \
    -H "Authorization: Bearer $VOYANT_API_KEY" \
    -H "content-type: application/json" \
    -d '{
      "propertyIds": ["prop_987", "prop_654"],
      "departureId": "dep_456"
    }'
  ```

  ```javascript Node.js theme={null}
  await fetch("https://api.voyantcloud.com/v1/products/prod_123/lodging/links", {
    method: "PATCH",
    headers: {
      Authorization: `Bearer ${process.env.VOYANT_API_KEY}`,
      "content-type": "application/json",
    },
    body: JSON.stringify({
      propertyIds: ["prop_987"],
      ratePlanId: "rate_002",
    }),
  })
  ```

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

  payload = {
    "propertyIds": ["prop_987", "prop_654"],
    "departureId": "dep_456",
    "ratePlanId": "rate_002"
  }

  resp = requests.patch(
    "https://api.voyantcloud.com/v1/products/prod_123/lodging/links",
    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": [
      {
        "id": "pll_001",
        "property_id": "prop_987",
        "departure_id": "dep_456",
        "rate_plan_id": "rate_002",
        "active": "true"
      },
      {
        "id": "pll_002",
        "property_id": "prop_654",
        "departure_id": "dep_456",
        "rate_plan_id": "rate_002",
        "active": "true"
      }
    ]
  }
  ```
</ResponseExample>

<Info>
  If a property is already linked with the same scope, it is returned unchanged. When a rate plan no longer exists, the API retries with `ratePlanId` set to `null` to maintain the link.
</Info>
