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

# inventory.duplicate.resolved

> Fires when a duplicate hotel report on a reference hotel is closed — including duplicates you didn't personally report.

`inventory.duplicate.resolved` is the broad fan-out event. When we close a duplicate report on hotel **X**, every Pro+ organization with **at least one active mapping** pointing at X is notified, regardless of who originally filed the duplicate.

If your downstream system caches the hotel id you mapped to, this is your signal to invalidate that cache.

## When it fires

When a `ReferenceHotelDuplicateReport` is resolved by our team. The same event id may be delivered to many subscriptions (one per receiving org).

## Required plan

Pro and above.

## Recipients

Every organization with at least one `partner_mapping_result` whose `matchedReferenceHotelId` is either the **original** or the **duplicate** hotel id.

## Payload

```json theme={null} theme={null}
{
  "id": "del_…",
  "eventId": "evt_…",
  "type": "inventory.duplicate.resolved",
  "apiVersion": "2026-06-01",
  "occurredAt": "2026-06-01T12:34:56Z",
  "organizationId": "org_…",
  "data": {
    "reportId": "rep_…",
    "originalHotelId": "ref_canonical_…",
    "duplicateHotelId": "ref_removed_…",
    "resolution": "FIXED",
    "resolvedAt": "2026-06-01T12:34:56Z"
  }
}
```

## Fields

| Field                   | Type                       | Notes                                                                                                                    |
| ----------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `data.reportId`         | UUID                       | The duplicate report that was closed.                                                                                    |
| `data.originalHotelId`  | UUID                       | The canonical reference hotel we kept.                                                                                   |
| `data.duplicateHotelId` | UUID                       | The reference hotel that was merged or dismissed.                                                                        |
| `data.resolution`       | `"FIXED"` \| `"DISMISSED"` | `FIXED` means the duplicate was real and merged. `DISMISSED` means we determined the two hotels are genuinely different. |
| `data.resolvedAt`       | ISO timestamp              | When the report transitioned.                                                                                            |

## What to do

* If `resolution = FIXED` and any of your mappings point to `duplicateHotelId`, those mappings will be redirected to `originalHotelId` server-side. You should invalidate any cached reference data and consider re-fetching the mapping result.
* If `resolution = DISMISSED`, no mapping changes — but you may still want to record that we explicitly considered and rejected the duplicate.

## Example: cache invalidation (Python)

```python theme={null} theme={null}
@app.post("/hooks/mapping")
def receive(request):
    if not verify_webhook(request.headers["X-Webhook-Signature"], request.body, SECRET):
        return Response(status=401)
    payload = json.loads(request.body)
    if payload["type"] != "inventory.duplicate.resolved":
        return Response(status=204)

    data = payload["data"]
    if data["resolution"] == "FIXED":
        cache.delete_many([
            f"hotel:{data['duplicateHotelId']}",
            f"hotel:{data['originalHotelId']}",
        ])
    return Response(status=200)
```
