# Self-Service Mapping

To use this capability, add `octo/mappings` to your `Octo-Capabilities` header.

This capability allows you to send a "mapping sheet" of products that you need to map. This is then given to the supplier in a user-friendly form they can select which product each item maps to in their Ventrata system. Once the mapping has been set a webhook URL is called to notify your system of the change.

The mappings endpoints are available under `/octo`.

{% openapi src="<https://221588849-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M7bgGIyO7QYNOfUMfxh%2Fuploads%2Fgit-blob-fa2d8cb1d7297d352c2639e6c4c6a990f2add6d7%2Fopenapi.yaml?alt=media>" path="/mappings" method="put" %}
[openapi.yaml](https://221588849-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M7bgGIyO7QYNOfUMfxh%2Fuploads%2Fgit-blob-fa2d8cb1d7297d352c2639e6c4c6a990f2add6d7%2Fopenapi.yaml?alt=media)
{% endopenapi %}

Body must be a JSON array of mapping rows.

See the `PUT /mappings` operation above for request schema examples.

`resellerReference` is required on each item. Items are upserted by `resellerReference`, and any existing mappings not included in the array are removed.

Whenever a product in your system for this supplier has been changed, updated or deleted, you should repeat this request with all mappings. `PUT` synchronizes the full set for the connection.

After you make the request and new mappings are added, Ventrata sends a notification to the supplier to complete them.

Once the supplier chooses a product and option for a mapping, Ventrata sends a `POST` request to the URL provided in `webhookUrl` for that mapping row. The webhook body follows the mapping object schema and includes resolved `productId`, `optionId`, and `unitId` values.

The `unitId` and `optionId` will be null in the webhook request body if we set `unitRequired` and `optionRequired` to false respectively on the original mappings request.

Your response to this request must be `2XX` (for example `200 OK`), otherwise we retry until we receive a `2XX` response.

{% openapi src="<https://221588849-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M7bgGIyO7QYNOfUMfxh%2Fuploads%2Fgit-blob-fa2d8cb1d7297d352c2639e6c4c6a990f2add6d7%2Fopenapi.yaml?alt=media>" path="/mappings" method="get" %}
[openapi.yaml](https://221588849-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M7bgGIyO7QYNOfUMfxh%2Fuploads%2Fgit-blob-fa2d8cb1d7297d352c2639e6c4c6a990f2add6d7%2Fopenapi.yaml?alt=media)
{% endopenapi %}

#### Query Parameters

If both `productId` and `productIds[]` are provided, `productId` is used. If both `optionId` and `optionIds[]` are provided, `optionId` is used. Use repeated query keys for arrays, for example `productIds[]=id1&productIds[]=id2`. `DEFAULT` on `optionId`/`optionIds[]` filters for mappings without a stored option.

`optionId` and `unitId` may be `null` when no mapping has been selected yet, or when `optionRequired` / `unitRequired` is `false`.

## Booking and Availability Responses

When this capability is enabled, booking and availability responses include a `mappings` field. The array contains mappings for the response product/option combination.

* Booking responses include `booking.mappings`.
* Availability responses include `availability[].mappings`.

Each `mappings[]` item uses the same schema as the mappings list response.

## Schema Additions (JSON)

These are additive fragments showing only fields introduced by this capability.

### `Availability`

```json
{
  "// ...rest of availability object": "...",
  "mappings": [
    {
      "resellerReference": "RES-BOOK-10045",
      "optionId": "94cdd032-3d32-416d-b0a4-abf8b7495b8b",
      "productId": "e7cc8bb4-8d1c-4848-8824-5dbedb718681",
      "resellerStatus": "CONFIRMED"
    }
  ]
}
```

### `AvailabilityBatchRow`

```json
{
  "// ...rest of availability batch row object": "...",
  "mappings": [
    {
      "resellerReference": "RES-BOOK-10045",
      "optionId": "94cdd032-3d32-416d-b0a4-abf8b7495b8b",
      "productId": "e7cc8bb4-8d1c-4848-8824-5dbedb718681",
      "resellerStatus": "CONFIRMED"
    }
  ]
}
```

### `Booking`

```json
{
  "// ...rest of booking object": "...",
  "mappings": [
    {
      "resellerReference": "RES-BOOK-10045",
      "optionId": "94cdd032-3d32-416d-b0a4-abf8b7495b8b",
      "resellerStatus": "CONFIRMED",
      "resellerProduct": "grand-canyon-day-tour",
      "productId": "e7cc8bb4-8d1c-4848-8824-5dbedb718681",
      "unitId": "unit_adult",
      "optionRequired": true,
      "unitRequired": true,
      "validityDays": 2,
      "webhookUrl": "https://www.city-sightseeing.com"
    }
  ]
}
```

### `MappingUpsertRequest`

```json
{
  "// ...rest of mapping upsert request object": "...",
  "mappings": [
    {
      "resellerReference": "RES-BOOK-10045",
      "productId": "e7cc8bb4-8d1c-4848-8824-5dbedb718681",
      "optionId": "94cdd032-3d32-416d-b0a4-abf8b7495b8b"
    }
  ]
}
```

### `PackageAvailability`

```json
{
  "// ...rest of package availability object": "...",
  "mappings": [
    {
      "resellerReference": "RES-BOOK-10045",
      "optionId": "94cdd032-3d32-416d-b0a4-abf8b7495b8b",
      "productId": "e7cc8bb4-8d1c-4848-8824-5dbedb718681",
      "resellerStatus": "CONFIRMED"
    }
  ]
}
```
