# Developer Platform

Cover Genius is the global insurtech for embedded protection. Licensed or authorised in over 60 countries and all 50 US states, you can embed and sell multiple lines of insurance and other types of protection. Our modularity offers seamless integration with our platforms for an integrated customer experience.

<a href="https://partner-docs.covergenius.com/offers" class="button primary">Get started</a>

## Browse by vertical

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="image">Cover image</th></tr></thead><tbody><tr><td><strong>Travel</strong></td><td>Tailor protection with bundled and unbundled products such as Comprehensive, Cancel For Any Reason (CFAR) and more.</td><td><a href="https://partner-docs.covergenius.com/offers/vertical-examples/travel-accomodation">https://partner-docs.covergenius.com/offers/vertical-examples/travel-accomodation</a></td><td><a href="https://3873421260-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEBqbGpgaWCnTt7sv0Rhu%2Fuploads%2FPkM5jeZiHeYXAzmxiUZk%2Fcover-genius-xcover-travel.png?alt=media&amp;token=9ddaa5a0-cf96-4108-8c5d-ef0c8e8b628f">cover-genius-xcover-travel.png</a></td></tr><tr><td><strong>Ticketing</strong></td><td>Get solutions optimised for customer utility through AI-backed deductibles and pricing.</td><td><a href="https://partner-docs.covergenius.com/offers/vertical-examples/events-tickets">https://partner-docs.covergenius.com/offers/vertical-examples/events-tickets</a></td><td><a href="https://3873421260-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEBqbGpgaWCnTt7sv0Rhu%2Fuploads%2FLScnKbF8iW7B2YYWlOzf%2Fcover-genius-xcover-ticketing.png?alt=media&amp;token=8f243348-22d4-4743-a530-1518eba2be19">cover-genius-xcover-ticketing.png</a></td></tr><tr><td><strong>Retail</strong></td><td>Offer warranties and return protection with omnichannel integration for retailers and marketplaces.</td><td><a href="https://partner-docs.covergenius.com/offers/vertical-examples/product-retail">https://partner-docs.covergenius.com/offers/vertical-examples/product-retail</a></td><td><a href="https://3873421260-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEBqbGpgaWCnTt7sv0Rhu%2Fuploads%2F6vNgTcHwlGWFlk54CI4E%2Fcover-genius-xcover-retail.png?alt=media&amp;token=50de0365-caaf-4cf2-be95-06dd089a95d2">cover-genius-xcover-retail.png</a></td></tr><tr><td><strong>Logistics</strong></td><td>Get solutions that are up to 20% cheaper and 20 days faster than carrier insurance.</td><td><a href="https://partner-docs.covergenius.com/offers/vertical-examples/parcel-shipping">https://partner-docs.covergenius.com/offers/vertical-examples/parcel-shipping</a></td><td><a href="https://3873421260-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEBqbGpgaWCnTt7sv0Rhu%2Fuploads%2FGVVTvG8iYX0wsnk8XVQu%2Fcover-genius-xcover-logistics.png?alt=media&amp;token=9a372a2e-f8c9-4b3f-ac02-3fd919385a7d">cover-genius-xcover-logistics.png</a></td></tr></tbody></table>

## Browse by platforms

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="image">Cover image</th></tr></thead><tbody><tr><td><strong>XCover</strong></td><td>Our award-winning distribution platform that delivers personalised protection in any country, language and currency with global capabilities from a single API call.</td><td><a href="broken://spaces/dHv5DyJX33AxnvgIK8bR/pages/LThc2RqOxBKU56Qt3TMy">Broken link</a></td><td><a href="https://3873421260-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEBqbGpgaWCnTt7sv0Rhu%2Fuploads%2FwFnDYTI8fkEWN5OAF1O4%2Fcover-genius-xcover-documentation.png?alt=media&amp;token=d30de12a-7b6e-4135-92e5-3b960b660b6c">cover-genius-xcover-documentation.png</a></td></tr><tr><td><strong>RentalCover</strong></td><td>Our global distribution platform for rental car insurance that enables you to sell rental car insurance to your customers for any vehicle, anywhere in the world.</td><td><a href="https://partner-docs.covergenius.com/rentalcover/">Rental Cover</a></td><td><a href="https://3873421260-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEBqbGpgaWCnTt7sv0Rhu%2Fuploads%2FHf17BNtCx4FchwzcK0rz%2Fcover-genius-rental-cover-documentation.png?alt=media&amp;token=0d98dd85-1553-49a4-88ed-c09a6a4963f8">cover-genius-rental-cover-documentation.png</a></td></tr></tbody></table>

## System performance

<a href="https://status.covergenius.com/" class="button primary">Status Page</a>


# Introduction

The Offers platform includes an easy-to-use API integration to promote, sell, and manage insurance and non-insurance products provided by Cover Genius underwriting partners. It is designed to seamlessly integrate with any platform and sell any line of insurance and non-insurance products.

This is made possible by the Offers API, a flexible interface based on [REST](http://en.wikipedia.org/wiki/Representational_State_Transfer) that returns standard HTTP response codes and [JSON](http://www.json.org/)-encoded responses.

Please, [follow us on LinkedIn](https://www.linkedin.com/company/cover-genius/) for the latest updates.

## Integration outline

This outline is intended to provide an overview of the integration workflows for anyone working with an Offers API integration, including (but not limited to): Product & Project Managers, Software Engineers, and Business Analysts.

Each of these concepts are explored in more detail via the **Offers Guide, API Specification** and **Integration Guides.**

### Offer

An offer is the complete proposition used to display protection products to a customer. It's the central concept of the Offers API, bundling together one or more insurance/non-insurance products with their associated content, rules, and pricing into a single, cohesive unit. This is returned to the partner as a structured API response.

### Confirm Offer

After successful checkout, call the Offers API to notify about the offer purchased and provides the policyholder information. Offers API will inform customers about all the insurance product features, offer to create an account on to the XCover.com website where they can modify, renew, cancel the purchased policies, or lodge a claim. We take care of registering the purchased policies with the underwriting partners as well.

### Modifications

If booking Modifications are allowed by the underwriting partner Offers allows booking modification by customers via XCover.com. Alternatively, booking modifications can be triggered by one of the partner's platforms via Offers API.

### Cancellation

It can happen that the customer is not happy with the product purchased and wants to return it. Offers API offers cancellation workflows that allow the previously issued policy to be canceled and refunded automatically in this case.


# Summary

#### What is the Personalisation Engine

{% hint style="info" %}
The Offer API is how partners make use of the Cover Genius Personalisation Engine
{% endhint %}

At its core, the Personalisation Engine is designed to be the single, definitive source of truth for what protection offer a customer sees, when they see it, and why.

Cover Genius has built this engine based on our decades plus of experience and is built to be vertical, platform and partner agnostic. Its primary job is to deliver the most relevant and tailored offer to a customer in real time, regardless of whether they are on your website, in a mobile app, or interacting with a marketing campaign. By centralizing the decision-making process, we can ensure consistency and rapidly test new strategies aimed at improving key metrics like conversion rates, retention, and the average value of a subscription or purchase.

The Personalisation Engine is the cornerstone of our digital strategy into the next decade and beyond at Cover Genius.

#### High level flow

When a partner application needs to display an offer for instance, on a checkout page, you would send a single API request to the engine. This request is bundled with crucial Context data (like the user's ID, device type, location, and previous engagement attributes).

The engine then executes a **real-time** process:

1. Evaluate: It takes the provided Context and evaluates it against all available Products and Strategies in our system.
2. Decide: Based on a set of defined eligibility rules and available machine learning models, the engine selects the single optimal Offer for your customer.
3. Respond: The client receives a clean, complete response object called an Offer, which includes all the necessary product details, pricing, and specific content ready for presentation to the customer.

This unified approach separates the business logic (what to show) from the display logic (how to show it). Your client application remains lightweight, relying on the engine to deliver the complete package, which makes testing and deployment of new pricing or content strategies fast and safe whilst driving growth.


# Key Concepts

Before diving into API calls, it is crucial to establish a common language. The Personalisation Engine operates several core concepts that serve as its building blocks, which are explained below.

### Offer

The Offer is the single most important concept in our system. It is the complete, final decision returned by the Personalisation Engine. When we talk about an Offer, we mean the complete package that a customer sees: [#products](#products "mention"), [#product-rules](#product-rules "mention"), and the [#content](#content "mention") that dictates how it should be displayed.

There are four key components to the Offer Response that are outlined in detail via the API [Reference](/offers/api/reference) documentation but are shown below in an example API response from the engine

<figure><img src="https://3062128269-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMuGidY91cJqNK5u33H8e%2Fuploads%2FWOz4ENP4fzdvDgGENoWk%2Fimage.png?alt=media&amp;token=e02d650d-6a41-42fa-ba9c-387dbb21a1a1" alt=""><figcaption></figcaption></figure>

### Offer Schema

{% hint style="info" %}
Unless you have a complex integration, Cover Genius will configure one schema for you to use for all of your Offers.
{% endhint %}

The Offer Schema is an attribute that you set in your API request to [Create Offer](/offers/guides/purchase-workflow-overview/create-offer).

A partner can have one or more configured Offer Schema's in our system and we will inform you at integration time what Schema is relevant for you.

The Offer Schema will drive what fields you need to send us in the [#offer-context](#offer-context "mention") object of a request and is typically per business line or vertical.

### Offer Context

{% hint style="info" %}
The more information you send via the Context object the more personalised experiences we can provide to your customers into the future

Even if we aren't using all of the data you are sending us **today**, we may want to enhance customer experiences **in the future** and this would mean no re-work for you if you're already sending us this data.
{% endhint %}

The Offer Context is the essential data you provide to the engine in your [Create Offer](/offers/guides/purchase-workflow-overview/create-offer) API request. Think of it as the information that paints a picture of the customer and the environment they are in. The engine uses this data to inform its decision. In the travel vertical for example, Context may include trip duration, destination, information about flights and trip cost.

The structure of the Context is dictated by the chosen Offer Schema where you'll be provided with the necessary fields needing to be sent in order for us to provide the relevant Offer to customers.

### Products

{% hint style="info" %}
Products are platform and type agnostic. Whilst most integrations will see Insurance products be displayed to customers, the platform is capable of handling non-insurance products from many providers and mixing these together to form a coherent Offer.
{% endhint %}

Products are foundational elements of the Personalisation Engine, representing the actual insurance or non-insurance products that collectively make up a complete Offer.

An Offer may contain one or more Products in its response, and where multiple Products are returned, [#product-rules](#product-rules "mention") dictate how these individual components interact with each other. The Product itself will contain all the underlying insurance or non-insurance data, which can be used to inform backend processing and determine what is displayed to the customer.

By integrating with the Personalisation Engine's Product system, we establish a pathway to push different insurance and non-insurance products through the customer pipeline in the future without requiring any re-integration work on the partner end.

### Product Rules

Product rules enable dynamic, event-driven Offer flows including upsells, cross-sells, second chance Offers, and complex multi-product configurations. This structure provides partners with a powerful, declarative way to define product relationships and conditional visibility rules.

Most integrations will make use of a single Product per Offer. If a partner integration is planned to use multiple Offer types then a deep integration with the Product Rules concept and functionality is a requisite.

<figure><img src="https://3062128269-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMuGidY91cJqNK5u33H8e%2Fuploads%2FJY9D7bDC7UBGTubz7XiV%2Fimage.png?alt=media&amp;token=ce3ef710-67f8-4129-a95d-8409c921eb4a" alt=""><figcaption></figcaption></figure>

### Content

Content in the Personalisation Engine is structured to enhance the personalization and presentation of Offers to customers.

1. Content Management
   * The Personalisation Engine includes a dedicated section for Offer Content structured according to a presentation JSON Schema. This schema defines how content is organized and should be presented.
   * Content includes both product content (specific to individual products) and offer content (specific to the Offer panel). This content is localized, ensuring it is relevant to the user's language and context they are viewing it in.
2. Content Integration
   * The Offer Engine uses models `OfferContent` and `ProductContent` to manage content dynamically. These models allow for automated linking and synchronization with our CMS, supporting flexible content structures and multi-language support
3. API and Content Delivery
   * The API response includes decoupled content blocks (e.g., `headline`, `benefits`, `cta_text`), allowing partners to render dynamic panels without custom front-end work. Dynamic variables can be injected into the content to personalize Offers further.

Overall, the content in the Personalisation Engine is designed to provide a seamless and personalized experience for users, leveraging structured data and dynamic content delivery to enhance the presentation and relevance of Offers.


# Reference

Offers API Specs

The Offers API is a RESTful API that enables partners to create, manage, and confirm product offerings. It uses resource-oriented URLs, standard HTTP methods, and returns JSON-encoded responses with conventional HTTP status codes.

The complete OpenAPI specification below provides generic examples, and validation rules for all endpoints.


# Create Offer

## Create Offer

> The Create Offer endpoint generates product offerings based on your business context and customer information. This endpoint uses a schema-driven approach to validate requests and returns one or more products with detailed pricing, product information, and content for display.

```json
{"openapi":"3.0.0","info":{"title":"Offers API","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n* **Example:** `X-Api-Key: YOUR_API_KEY_HERE`\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n* **Example:** `Date: Sun, 09 Nov 2025 04:04:00 GMT`\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** The cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\n**Signature Generation Logic:**\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}},"parameters":{"ApiErrorVersion":{"name":"X-API-Error-Version","in":"header","required":false,"description":"Opt-in selector for the shape of non-2xx response bodies. `v1` (the default) returns the legacy error body. `v2` returns the structured error body described by `ErrorV2`. Matched case-insensitively. An absent, empty or unrecognised value falls back to `v1` and never fails an otherwise-valid request.","schema":{"type":"string","enum":["v1","v2"],"default":"v1"}}},"schemas":{"ErrorV1":{"type":"object","description":"Legacy error body. Returned unless `X-API-Error-Version: v2` is sent.","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object","nullable":true,"description":"Field-keyed validation errors, when applicable."}}},"ErrorV2":{"type":"object","description":"Structured error body, returned when `X-API-Error-Version: v2` is sent. `code`, `error_id`, `errors` and `metadata` are always present, the last two as an empty array/object when there is nothing to report, so they can be read unconditionally. `error_id` is null when the failing path minted no id (an auth or throttle rejection, say). Any field-keyed errors the `v1` body would have carried are preserved under `metadata.field_errors`.\n\nOne limit: an error that produces no framework response (a server-rendered 500) is not reshaped and stays in the `v1` form.","properties":{"type":{"type":"string"},"message":{"type":"string"},"code":{"type":"string","description":"Machine-readable error code for the response as a whole."},"error_id":{"type":"string","nullable":true,"description":"Identifier for this failure, null when none was minted."},"errors":{"type":"array","description":"Structured error entries. Empty when there is nothing to itemise.","items":{"$ref":"#/components/schemas/ErrorItemV2"}},"metadata":{"type":"object","description":"Supplementary context. Empty object when there is nothing to report. Field-keyed errors from the `v1` shape appear here under `field_errors`."}}},"ErrorItemV2":{"type":"object","description":"A single structured error entry.","properties":{"product_config_id":{"type":"string","nullable":true,"description":"Product configuration the error relates to, when applicable."},"quote_id":{"type":"string","nullable":true,"description":"Quote the error relates to, when applicable."},"code":{"type":"string","description":"Machine-readable error code for this item."},"details":{"type":"array","description":"Human-readable detail messages.","items":{"type":"string"}}}}}},"paths":{"/partners/{partner_code}/offers/":{"post":{"summary":"Create Offer","description":"The Create Offer endpoint generates product offerings based on your business context and customer information. This endpoint uses a schema-driven approach to validate requests and returns one or more products with detailed pricing, product information, and content for display.","tags":["Create Offer"],"parameters":[{"$ref":"#/components/parameters/ApiErrorVersion"},{"name":"active_only","in":"query","required":false,"description":"When using a test API key, only return active offers","schema":{"type":"boolean","default":false}},{"name":"include_content","in":"query","required":false,"description":"Include localized content in the response","schema":{"type":"boolean","default":true}},{"name":"extra_fields","in":"query","required":false,"description":"Comma-separated list of specific extra fields to include. Available fields: tax, commission, benefits, surcharge","schema":{"type":"string"}},{"name":"exclude_offer_ids","in":"query","required":false,"description":"Comma-separated list of Offer Config IDs to exclude from the response","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","headers":{"Date":{"schema":{"type":"string"}},"Transfer-Encoding":{"schema":{"type":"string"}},"Connection":{"schema":{"type":"string"}},"CF-Ray":{"schema":{"type":"integer"}},"CF-Cache-Status":{"schema":{"type":"string"}},"Allow":{"schema":{"type":"string"}},"Server":{"schema":{"type":"string"}},"Strict-Transport-Security":{"schema":{"type":"string"}},"cross-origin-opener-policy":{"schema":{"type":"string"}},"referrer-policy":{"schema":{"type":"string"}},"Vary":{"schema":{"type":"string"}},"Content-Encoding":{"schema":{"type":"string"}},"Server-Timing":{"schema":{"type":"string"}},"Cf-Team":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"session_id":{"type":"string"},"offer_config_id":{"type":"string"},"offer_schema":{"type":"string"},"currency":{"type":"string"},"products":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"product_config_id":{"type":"string"},"type":{"type":"string"},"schema_url":{"type":"string"},"details":{"type":"object","properties":{"policy_version_id":{"type":"string"},"start_date":{"type":"string","format":"date-time"},"end_date":{"type":"string","format":"date-time"},"finance":{"type":"object","properties":{"price":{"type":"object","properties":{"total_amount":{"type":"number"},"total_amount_without_tax":{"type":"number"},"total_amount_formatted":{"type":"string"},"total_amount_without_tax_formatted":{"type":"string"}}},"tax":{"type":"object","properties":{"total_amount":{"type":"number"},"total_amount_formatted":{"type":"string"},"breakdown":{"type":"array","nullable":true,"description":"Per-tax breakdown of the total tax amount. Only populated when the tax extra field is requested (e.g. extra_fields=tax); null otherwise.","items":{"type":"object","properties":{"tax_code":{"type":"string"},"tax_amount":{"type":"number"},"tax_amount_formatted":{"type":"string"}}}}}},"surcharge":{"type":"object","properties":{"total_amount":{"nullable":true},"total_amount_formatted":{"nullable":true}}},"commission":{"type":"object","properties":{"total_amount":{"type":"number"},"total_amount_formatted":{"type":"string"}}}}},"pds_url":{"type":"string","format":"uri"},"files":{"type":"array","items":{}},"extra_fields":{"type":"object"},"experiment":{"type":"object"}}}}}},"product_rules":{"type":"array","description":"Product display and selection rules. Optional: the field is omitted entirely when there are no rules, so clients must not assume it is always present.","items":{"type":"object","properties":{"slug":{"type":"string","description":"Unique rule identifier"},"product_ids":{"type":"array","description":"Array of product IDs in this rule","items":{"type":"string"}},"initial_state":{"type":"string","enum":["show","hide","disable"],"description":"Initial display state"},"min_select":{"type":"integer","description":"Minimum number of products to select"},"max_select":{"type":"integer","description":"Maximum number of products to select"},"events":{"type":"array","description":"Event-driven rules. Can be empty array for terminal rules or single product rules.","items":{"type":"object","properties":{"on":{"type":"string","enum":["select","deselect","accept","decline"],"description":"Trigger event"},"action":{"type":"string","enum":["show","hide","enable","disable"],"description":"Action to perform"},"target_rule":{"type":"string","description":"Target rule slug"}}}}}}},"content":{"type":"object","properties":{"schema_version":{"type":"string","description":"Content schema version"},"locale":{"type":"string","description":"Content locale (e.g., en-AU, en-US)"},"slug":{"type":"string","description":"Content slug identifier for the offer"},"title":{"type":"string","description":"Main title for the offer"},"heading":{"type":"string","description":"Heading text"},"sub_heading":{"type":"string","description":"Sub-heading text"},"disclaimer":{"type":"string","description":"Legal disclaimer text"},"disclaimer_html":{"type":"string","description":"HTML formatted disclaimer"},"price_unit":{"type":"string","description":"Price unit descriptor (e.g., per person)"},"description":{"type":"string","description":"Offer description"},"positive_cta":{"type":"string","description":"Text for accept/yes button"},"negative_cta":{"type":"string","description":"Text for decline/no button"},"negative_cta_warning":{"type":"string","description":"Warning shown when user declines"},"required_message":{"type":"string","description":"Message shown when selection is required"},"credibility_message":{"type":"string","description":"Trust/credibility message (deprecated, use credibility)"},"credibility":{"type":"string","description":"Credibility message text"},"credibility_sales_count":{"type":"integer","description":"Number for credibility metric"},"products":{"type":"array","description":"Content for each product","items":{"type":"object","properties":{"id":{"type":"string","description":"Product content identifier"},"product_config_id":{"type":"string","description":"Product configuration identifier"},"slug":{"type":"string","description":"Content slug identifier for this product"},"locale":{"type":"string","description":"Content locale"},"title":{"type":"string","description":"Product title"},"description":{"type":"string","description":"Product description"},"benefits":{"type":"object","description":"Product benefits with dynamic keys (benefit_1, benefit_2, etc.)","additionalProperties":{"type":"string"}},"exclusions":{"type":"object","description":"Product exclusions with dynamic keys (exclusion_1, exclusion_2, etc.)","additionalProperties":{"type":"string"}},"inclusions":{"type":"object","description":"Product inclusions with dynamic keys (inclusion_1, inclusion_2, etc.)","additionalProperties":{"type":"string"}},"disclaimer":{"type":"string","description":"Product-specific disclaimer"},"disclaimer_html":{"type":"string","description":"HTML formatted product disclaimer"},"credibility_badge":{"type":"string","description":"Credibility badge content (e.g., Most Popular)"}}}}}},"errors":{"type":"object","description":"Any errors encountered during offer creation"},"metadata":{"type":"object","description":"Supplementary response context, such as experiment assignment data. Optional: the field is omitted entirely when there is nothing to report."}}}}}},"403":{"description":"Forbidden","headers":{"Date":{"schema":{"deprecated":false}},"Transfer-Encoding":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}},"Content-Encoding":{"schema":{"deprecated":false}},"Server-Timing":{"schema":{"deprecated":false}},"Cf-Team":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorV1"},{"$ref":"#/components/schemas/ErrorV2"}]}}}},"422":{"description":"Unprocessable Entity","headers":{"Date":{"schema":{"deprecated":false}},"Content-Length":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}},"Server-Timing":{"schema":{"deprecated":false}},"Cf-Team":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object","properties":{"schema":{"type":"array","items":{"type":"string","format":"style"}}}}}},{"$ref":"#/components/schemas/ErrorV2"}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"schema":{"type":"string","description":"Schema identifier for the offer type. If omitted, the default schema will be used (if one is configured). If no default schema is configured and this field is omitted, the request will fail with a validation error. Contact your Client Solutions Engineer (CSE) to confirm your schema configuration."},"customer":{"type":"object","description":"Customer information","properties":{"currency":{"type":"string","description":"Currency code (e.g., USD, AUD, EUR, GBP)"},"language":{"type":"string","description":"Customer's preferred language (e.g., en)"},"country":{"type":"string","description":"Customer's country code (e.g., US, AU, GB)"},"region":{"type":"string","description":"Customer's region or state"},"email":{"type":"string","format":"email","description":"Customer's email address"},"ip":{"type":"string","description":"Customer's IP address"},"postcode":{"type":"string","description":"Customer's postal code"}},"required":["currency","language","country"]},"context":{"type":"object","description":"Business context data required for offer selection and pricing. The specific fields required will be defined through the offer schema with the Client Solutions Engineer (CSE).","additionalProperties":true},"partner":{"type":"object","description":"Partner information","properties":{"subsidiary":{"type":"string","description":"Partner subsidiary identifier"},"transaction_id":{"type":"string","description":"Partner transaction identifier"},"customer_id":{"type":"string","description":"Partner customer identifier"},"metadata":{"type":"object","description":"Additional partner metadata","properties":{"session_id":{"type":"string","description":"Optional unique session identifier passed by the partner"},"touchpoint":{"type":"string","description":"Optional touchpoint slug identifying where in the partner's flow the offer is presented (e.g., checkout)"}}}}}},"required":["customer","context"]}}}}}}}}
```


# Opt Out Offer

## Opt-out Offer

> The Insurance opt-out workflow describes the API call that must be made in the case that XCover insurance is offered but not selected by the customer. The purpose of utilising the opt-out workflow is so Cover Genius can demonstrate conversion rate to the regulators ensuring the product and pricing is fit for purpose. It also enables XCover machine learning platform Brightwrite to deliver the optimal products at the optimal prices.

```json
{"openapi":"3.0.0","info":{"title":"Offers API","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n* **Example:** `X-Api-Key: YOUR_API_KEY_HERE`\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n* **Example:** `Date: Sun, 09 Nov 2025 04:04:00 GMT`\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** The cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\n**Signature Generation Logic:**\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}},"parameters":{"ApiErrorVersion":{"name":"X-API-Error-Version","in":"header","required":false,"description":"Opt-in selector for the shape of non-2xx response bodies. `v1` (the default) returns the legacy error body. `v2` returns the structured error body described by `ErrorV2`. Matched case-insensitively. An absent, empty or unrecognised value falls back to `v1` and never fails an otherwise-valid request.","schema":{"type":"string","enum":["v1","v2"],"default":"v1"}}},"schemas":{"ErrorV1":{"type":"object","description":"Legacy error body. Returned unless `X-API-Error-Version: v2` is sent.","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object","nullable":true,"description":"Field-keyed validation errors, when applicable."}}},"ErrorV2":{"type":"object","description":"Structured error body, returned when `X-API-Error-Version: v2` is sent. `code`, `error_id`, `errors` and `metadata` are always present, the last two as an empty array/object when there is nothing to report, so they can be read unconditionally. `error_id` is null when the failing path minted no id (an auth or throttle rejection, say). Any field-keyed errors the `v1` body would have carried are preserved under `metadata.field_errors`.\n\nOne limit: an error that produces no framework response (a server-rendered 500) is not reshaped and stays in the `v1` form.","properties":{"type":{"type":"string"},"message":{"type":"string"},"code":{"type":"string","description":"Machine-readable error code for the response as a whole."},"error_id":{"type":"string","nullable":true,"description":"Identifier for this failure, null when none was minted."},"errors":{"type":"array","description":"Structured error entries. Empty when there is nothing to itemise.","items":{"$ref":"#/components/schemas/ErrorItemV2"}},"metadata":{"type":"object","description":"Supplementary context. Empty object when there is nothing to report. Field-keyed errors from the `v1` shape appear here under `field_errors`."}}},"ErrorItemV2":{"type":"object","description":"A single structured error entry.","properties":{"product_config_id":{"type":"string","nullable":true,"description":"Product configuration the error relates to, when applicable."},"quote_id":{"type":"string","nullable":true,"description":"Quote the error relates to, when applicable."},"code":{"type":"string","description":"Machine-readable error code for this item."},"details":{"type":"array","description":"Human-readable detail messages.","items":{"type":"string"}}}}}},"paths":{"/partners/{partner_code}/offers/{offer_id}/opt_out/":{"post":{"summary":"Opt-out Offer","description":"The Insurance opt-out workflow describes the API call that must be made in the case that XCover insurance is offered but not selected by the customer. The purpose of utilising the opt-out workflow is so Cover Genius can demonstrate conversion rate to the regulators ensuring the product and pricing is fit for purpose. It also enables XCover machine learning platform Brightwrite to deliver the optimal products at the optimal prices.","tags":["Opt-out Offer"],"parameters":[{"$ref":"#/components/parameters/ApiErrorVersion"}],"responses":{"204":{"description":"No Content","headers":{"Date":{"schema":{"type":"string"}},"Connection":{"schema":{"type":"string"}},"CF-Ray":{"schema":{"type":"integer"}},"CF-Cache-Status":{"schema":{"type":"string"}},"Allow":{"schema":{"type":"string"}},"Server":{"schema":{"type":"string"}},"Strict-Transport-Security":{"schema":{"type":"string"}},"cross-origin-opener-policy":{"schema":{"type":"string"}},"referrer-policy":{"schema":{"type":"string"}},"Vary":{"schema":{"type":"string"}},"Server-Timing":{"schema":{"type":"string"}},"Cf-Team":{"schema":{"type":"integer"}}}},"403":{"description":"Forbidden","headers":{"Date":{"schema":{"deprecated":false}},"Transfer-Encoding":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}},"Content-Encoding":{"schema":{"deprecated":false}},"Server-Timing":{"schema":{"deprecated":false}},"Cf-Team":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorV1"},{"$ref":"#/components/schemas/ErrorV2"}]}}}},"404":{"description":"Not Found","headers":{"Date":{"schema":{"deprecated":false}},"Transfer-Encoding":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}},"Content-Encoding":{"schema":{"deprecated":false}},"Server-Timing":{"schema":{"deprecated":false}},"Cf-Team":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorV1"},{"$ref":"#/components/schemas/ErrorV2"}]}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}}}}}}
```


# Confirm Offer

## Confirm Offer

> The Confirm Offer endpoint is used to finalize the purchase of products from a previously created Offer. This endpoint converts the selected Offer into a confirmed booking after payment has been successfully collected.\
> \### Idempotency\
> This endpoint supports idempotency keys via the \`x-idempotency-key\` header to prevent duplicate transactions. Provide a unique operation identifier (e.g., UUID) to ensure safe retries. Duplicate requests return:\
> \- \*\*409 Conflict\*\*: The request was already processed; response contains\
> &#x20; the cached original result (handle as success)\
> \- \*\*423 Locked\*\*: The original request is still processing; retry after\
> &#x20; a short delay

```json
{"openapi":"3.0.0","info":{"title":"Offers API","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n* **Example:** `X-Api-Key: YOUR_API_KEY_HERE`\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n* **Example:** `Date: Sun, 09 Nov 2025 04:04:00 GMT`\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** The cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\n**Signature Generation Logic:**\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}},"parameters":{"ApiErrorVersion":{"name":"X-API-Error-Version","in":"header","required":false,"description":"Opt-in selector for the shape of non-2xx response bodies. `v1` (the default) returns the legacy error body. `v2` returns the structured error body described by `ErrorV2`. Matched case-insensitively. An absent, empty or unrecognised value falls back to `v1` and never fails an otherwise-valid request.","schema":{"type":"string","enum":["v1","v2"],"default":"v1"}}},"schemas":{"ErrorV1":{"type":"object","description":"Legacy error body. Returned unless `X-API-Error-Version: v2` is sent.","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object","nullable":true,"description":"Field-keyed validation errors, when applicable."}}},"ErrorV2":{"type":"object","description":"Structured error body, returned when `X-API-Error-Version: v2` is sent. `code`, `error_id`, `errors` and `metadata` are always present, the last two as an empty array/object when there is nothing to report, so they can be read unconditionally. `error_id` is null when the failing path minted no id (an auth or throttle rejection, say). Any field-keyed errors the `v1` body would have carried are preserved under `metadata.field_errors`.\n\nOne limit: an error that produces no framework response (a server-rendered 500) is not reshaped and stays in the `v1` form.","properties":{"type":{"type":"string"},"message":{"type":"string"},"code":{"type":"string","description":"Machine-readable error code for the response as a whole."},"error_id":{"type":"string","nullable":true,"description":"Identifier for this failure, null when none was minted."},"errors":{"type":"array","description":"Structured error entries. Empty when there is nothing to itemise.","items":{"$ref":"#/components/schemas/ErrorItemV2"}},"metadata":{"type":"object","description":"Supplementary context. Empty object when there is nothing to report. Field-keyed errors from the `v1` shape appear here under `field_errors`."}}},"ErrorItemV2":{"type":"object","description":"A single structured error entry.","properties":{"product_config_id":{"type":"string","nullable":true,"description":"Product configuration the error relates to, when applicable."},"quote_id":{"type":"string","nullable":true,"description":"Quote the error relates to, when applicable."},"code":{"type":"string","description":"Machine-readable error code for this item."},"details":{"type":"array","description":"Human-readable detail messages.","items":{"type":"string"}}}}}},"paths":{"/partners/{partner_code}/offers/{offer_id}/confirm/":{"post":{"summary":"Confirm Offer","description":"The Confirm Offer endpoint is used to finalize the purchase of products from a previously created Offer. This endpoint converts the selected Offer into a confirmed booking after payment has been successfully collected.\n### Idempotency\nThis endpoint supports idempotency keys via the `x-idempotency-key` header to prevent duplicate transactions. Provide a unique operation identifier (e.g., UUID) to ensure safe retries. Duplicate requests return:\n- **409 Conflict**: The request was already processed; response contains\n  the cached original result (handle as success)\n- **423 Locked**: The original request is still processing; retry after\n  a short delay","tags":["Confirm Offer"],"parameters":[{"$ref":"#/components/parameters/ApiErrorVersion"},{"name":"x-idempotency-key","in":"header","required":false,"description":"A unique identifier to ensure idempotent request processing. If a request with the same idempotency key and body has already been processed, the cached response is returned with a `409` Conflict status code (which can be treated as successful). Keys are stored for 48 hours.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","headers":{"Date":{"schema":{"deprecated":false}},"Transfer-Encoding":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"content-security-policy":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}},"Content-Encoding":{"schema":{"deprecated":false}},"Server-Timing":{"schema":{"deprecated":false}},"Cf-Team":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"partner_transaction_id":{"nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"pds_url":{"type":"string","format":"uri"},"security_token":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"policy_start_date":{"type":"string","format":"date-time"},"policy_end_date":{"type":"string","format":"date-time"},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"policy":{"type":"object","properties":{"policy_type":{"type":"string"},"policy_type_version":{"type":"string","format":"utc-millisec"},"policy_type_slug":{"type":"string"},"policy_type_group_name":{"type":"string"},"policy_name":{"type":"string"},"policy_code":{"type":"string"},"policy_version":{"type":"string"},"category":{"type":"string"},"content":{"type":"object","properties":{"title":{"type":"string"},"header":{"nullable":true},"description":{"type":"string"},"optout_msg":{"type":"string"},"inclusions":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"}}}},"exclusions":{"type":"array","items":{}},"disclaimer":{"type":"string","format":"style"},"disclaimer_html":{"type":"string","format":"style"},"payment_disclaimer":{"type":"string"},"in_path_disclaimer":{"type":"string"},"extra_content":{"type":"object"}}},"underwriter":{"type":"object","properties":{"disclaimer":{"type":"string"},"name":{"type":"string"}}},"claim_selector_id":{"nullable":true},"policy_currency":{"type":"string"}}},"insured":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"region":{"nullable":true}}}},"tax":{"type":"object","properties":{"total_tax":{"type":"number"},"total_amount_without_tax":{"type":"number"},"taxes":{"type":"array","items":{"type":"object","properties":{"tax_amount":{"type":"number"},"tax_code":{"type":"string"},"tax_amount_formatted":{"type":"string"}}}},"total_tax_formatted":{"type":"string"},"total_amount_without_tax_formatted":{"type":"string"}}},"duration":{"type":"string","format":"style"},"benefits":{"type":"array","items":{"type":"object","properties":{"benefit_content_id":{"type":"string"},"description":{"type":"string"},"extra_content":{"type":"object","properties":{"benefit-text-test":{"type":"string"},"benefit_rich_text_test":{"type":"string"}}},"limit":{"type":"integer"},"limit_policy_currency":{"type":"integer"},"limit_formatted":{"type":"string"},"limit_policy_currency_formatted":{"type":"string"},"excess":{"type":"integer"},"excess_policy_currency":{"type":"integer"},"excess_formatted":{"type":"string"},"excess_policy_currency_formatted":{"type":"string"}}}},"commission":{"type":"object","properties":{"partner_commission":{"type":"number"},"surcharge_commission":{"type":"integer"},"total_commission":{"type":"number"},"partner_commission_formatted":{"type":"string"},"surcharge_commission_formatted":{"type":"string"},"total_commission_formatted":{"type":"string"}}},"created_at":{"type":"string","format":"date-time"},"confirmed_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"cancelled_at":{"nullable":true},"cancelled_from":{"nullable":true},"is_renewable":{"type":"boolean"},"is_pricebeat_enabled":{"nullable":true},"cover_amount":{"type":"integer"},"cover_amount_formatted":{"type":"string"},"pds_url":{"type":"string","format":"uri"},"attachments":{"type":"array","items":{}},"files":{"type":"array","items":{}},"custom_documents":{"nullable":true},"extra_fields":{"type":"object","properties":{"destination_region":{"type":"string"},"seller_entity":{"type":"string"},"age_brackets":{"type":"string"},"desitnation_sanctions":{"type":"array","items":{}},"sanctioned_distination_countries":{"type":"array","items":{"type":"string"}},"test_underwrting_rule":{"type":"boolean"}}},"surcharge":{"type":"object","properties":{"total_amount":{"nullable":true},"surcharges":{"nullable":true},"total_amount_formatted":{"type":"string"}}},"parent_quote_status":{"nullable":true},"experiment":{"nullable":true},"next_renewal":{"nullable":true},"can_be_cancelled":{"type":"boolean"},"third_party_admins":{"type":"array","items":{}},"ombudsman_list":{"type":"array","items":{}},"cancellation_info":{"type":"object","properties":{"reason_for_cancellation":{"type":"string"}}}}}},"coi":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"pdf":{"type":"string","format":"uri"}}},"account_url":{"type":"string","format":"uri"},"sign_up_url":{"type":"string","format":"uri"},"policyholder":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"nullable":true},"address1":{"nullable":true},"address2":{"nullable":true},"postcode":{"type":"string","format":"utc-millisec"},"company":{"nullable":true},"company_reg_id":{"nullable":true},"middle_name":{"nullable":true},"country":{"type":"string"},"age":{"type":"integer"},"city":{"nullable":true},"region":{"type":"string"},"secondary_email":{"nullable":true},"birth_date":{"nullable":true},"allow_updates":{"type":"boolean"},"fields_allowed_to_update":{"type":"array","items":{}}}},"total_tax":{"type":"number"},"total_tax_formatted":{"type":"string"},"total_premium":{"type":"number"},"total_premium_formatted":{"type":"string"},"fnol_link":{"type":"string","format":"uri"},"booking_agent":{"nullable":true}}}}}},"403":{"description":"Forbidden","headers":{"Date":{"schema":{"deprecated":false}},"Transfer-Encoding":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}},"Content-Encoding":{"schema":{"deprecated":false}},"Server-Timing":{"schema":{"deprecated":false}},"Cf-Team":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorV1"},{"$ref":"#/components/schemas/ErrorV2"}]}}}},"404":{"description":"Not Found","headers":{"Date":{"schema":{"type":"string"}},"Transfer-Encoding":{"schema":{"type":"string"}},"Connection":{"schema":{"type":"string"}},"CF-Ray":{"schema":{"type":"integer"}},"CF-Cache-Status":{"schema":{"type":"string"}},"Allow":{"schema":{"type":"string"}},"Server":{"schema":{"type":"string"}},"Strict-Transport-Security":{"schema":{"type":"string"}},"cross-origin-opener-policy":{"schema":{"type":"string"}},"referrer-policy":{"schema":{"type":"string"}},"Vary":{"schema":{"type":"string"}},"Content-Encoding":{"schema":{"type":"string"}},"Server-Timing":{"schema":{"type":"string"}},"Cf-Team":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorV1"},{"$ref":"#/components/schemas/ErrorV2"}]}}}},"409":{"description":"Conflict - Duplicate Request (Idempotent)","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"partner_transaction_id":{"nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"pds_url":{"type":"string","format":"uri"},"security_token":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"policy_start_date":{"type":"string","format":"date-time"},"policy_end_date":{"type":"string","format":"date-time"},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"policy":{"type":"object","properties":{"policy_type":{"type":"string"},"policy_type_version":{"type":"string","format":"utc-millisec"},"policy_type_slug":{"type":"string"},"policy_type_group_name":{"type":"string"},"policy_name":{"type":"string"},"policy_code":{"type":"string"},"policy_version":{"type":"string"},"category":{"type":"string"},"content":{"type":"object","properties":{"title":{"type":"string"},"header":{"nullable":true},"description":{"type":"string"},"optout_msg":{"type":"string"},"inclusions":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"}}}},"exclusions":{"type":"array","items":{}},"disclaimer":{"type":"string","format":"style"},"disclaimer_html":{"type":"string","format":"style"},"payment_disclaimer":{"type":"string"},"in_path_disclaimer":{"type":"string"},"extra_content":{"type":"object"}}},"underwriter":{"type":"object","properties":{"disclaimer":{"type":"string"},"name":{"type":"string"}}},"claim_selector_id":{"nullable":true},"policy_currency":{"type":"string"}}},"insured":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"region":{"nullable":true}}}},"tax":{"type":"object","properties":{"total_tax":{"type":"number"},"total_amount_without_tax":{"type":"number"},"taxes":{"type":"array","items":{"type":"object","properties":{"tax_amount":{"type":"number"},"tax_code":{"type":"string"},"tax_amount_formatted":{"type":"string"}}}},"total_tax_formatted":{"type":"string"},"total_amount_without_tax_formatted":{"type":"string"}}},"duration":{"type":"string","format":"style"},"benefits":{"type":"array","items":{"type":"object","properties":{"benefit_content_id":{"type":"string"},"description":{"type":"string"},"extra_content":{"type":"object","properties":{"benefit-text-test":{"type":"string"},"benefit_rich_text_test":{"type":"string"}}},"limit":{"type":"integer"},"limit_policy_currency":{"type":"integer"},"limit_formatted":{"type":"string"},"limit_policy_currency_formatted":{"type":"string"},"excess":{"type":"integer"},"excess_policy_currency":{"type":"integer"},"excess_formatted":{"type":"string"},"excess_policy_currency_formatted":{"type":"string"}}}},"commission":{"type":"object","properties":{"partner_commission":{"type":"number"},"surcharge_commission":{"type":"integer"},"total_commission":{"type":"number"},"partner_commission_formatted":{"type":"string"},"surcharge_commission_formatted":{"type":"string"},"total_commission_formatted":{"type":"string"}}},"created_at":{"type":"string","format":"date-time"},"confirmed_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"cancelled_at":{"nullable":true},"cancelled_from":{"nullable":true},"is_renewable":{"type":"boolean"},"is_pricebeat_enabled":{"nullable":true},"cover_amount":{"type":"integer"},"cover_amount_formatted":{"type":"string"},"pds_url":{"type":"string","format":"uri"},"attachments":{"type":"array","items":{}},"files":{"type":"array","items":{}},"custom_documents":{"nullable":true},"extra_fields":{"type":"object","properties":{"destination_region":{"type":"string"},"seller_entity":{"type":"string"},"age_brackets":{"type":"string"},"desitnation_sanctions":{"type":"array","items":{}},"sanctioned_distination_countries":{"type":"array","items":{"type":"string"}},"test_underwrting_rule":{"type":"boolean"}}},"surcharge":{"type":"object","properties":{"total_amount":{"nullable":true},"surcharges":{"nullable":true},"total_amount_formatted":{"type":"string"}}},"parent_quote_status":{"nullable":true},"experiment":{"nullable":true},"next_renewal":{"nullable":true},"can_be_cancelled":{"type":"boolean"},"third_party_admins":{"type":"array","items":{}},"ombudsman_list":{"type":"array","items":{}},"cancellation_info":{"type":"object","properties":{"reason_for_cancellation":{"type":"string"}}}}}},"coi":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"pdf":{"type":"string","format":"uri"}}},"account_url":{"type":"string","format":"uri"},"sign_up_url":{"type":"string","format":"uri"},"policyholder":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"nullable":true},"address1":{"nullable":true},"address2":{"nullable":true},"postcode":{"type":"string","format":"utc-millisec"},"company":{"nullable":true},"company_reg_id":{"nullable":true},"middle_name":{"nullable":true},"country":{"type":"string"},"age":{"type":"integer"},"city":{"nullable":true},"region":{"type":"string"},"secondary_email":{"nullable":true},"birth_date":{"nullable":true},"allow_updates":{"type":"boolean"},"fields_allowed_to_update":{"type":"array","items":{}}}},"total_tax":{"type":"number"},"total_tax_formatted":{"type":"string"},"total_premium":{"type":"number"},"total_premium_formatted":{"type":"string"},"fnol_link":{"type":"string","format":"uri"},"booking_agent":{"nullable":true}}}}}},"422":{"description":"Unprocessable Entity","headers":{"Date":{"schema":{"type":"string"}},"Content-Length":{"schema":{"type":"integer"}},"Connection":{"schema":{"type":"string"}},"CF-Ray":{"schema":{"type":"integer"}},"CF-Cache-Status":{"schema":{"type":"string"}},"Allow":{"schema":{"type":"string"}},"Server":{"schema":{"type":"string"}},"Strict-Transport-Security":{"schema":{"type":"string"}},"cross-origin-opener-policy":{"schema":{"type":"string"}},"referrer-policy":{"schema":{"type":"string"}},"Vary":{"schema":{"type":"string"}},"Server-Timing":{"schema":{"type":"string"}},"Cf-Team":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"array","items":{"type":"string"}}}},{"$ref":"#/components/schemas/ErrorV2"}]}}}},"423":{"description":"Locked - Request In Progress","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorV1"},{"$ref":"#/components/schemas/ErrorV2"}]}}}},"429":{"description":"Too Many Requests","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ErrorV1"},{"$ref":"#/components/schemas/ErrorV2"}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"quotes":{"type":"array","description":"Array of quote objects to confirm","items":{"type":"object","properties":{"id":{"type":"string","description":"The product ID (quote ID) from the offer response"},"insured":{"type":"array","description":"List of insured persons if required by the policy","items":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"birth_date":{"type":"string","format":"date"},"country":{"type":"string"},"city":{"type":"string"},"postcode":{"type":"string"},"region":{"type":"string"},"age":{"type":"integer"}}}},"instalment_plan":{"type":"string","description":"Selected instalment plan name"},"first_instalment_paid":{"type":"boolean","description":"Whether first instalment has been paid"}},"required":["id"]}},"policyholder":{"type":"object","description":"Policyholder information","properties":{"first_name":{"type":"string","description":"Policyholder's first name"},"last_name":{"type":"string","description":"Policyholder's last name"},"email":{"type":"string","format":"email","description":"Policyholder's email address"},"phone":{"type":"string","description":"Policyholder's phone number"},"country":{"type":"string","description":"Policyholder's country code"},"region":{"type":"string","description":"Policyholder's region or state"},"city":{"type":"string","description":"Policyholder's city"},"postcode":{"type":"string","description":"Policyholder's postal code"},"address1":{"type":"string","description":"Policyholder's address line 1"},"address2":{"type":"string","description":"Policyholder's address line 2"}},"required":["first_name","last_name","email","phone","country"]},"require_payment_confirmation":{"type":"boolean","default":false,"description":"Enables two-step confirmation. If `true`, the booking is left in `PENDING_PAYMENT` until you call `Confirm booking` endpoint. Defaults to `false`, confirming in one step."},"partner_transaction_id":{"type":"string","description":"Your internal transaction identifier"},"partner_transaction_ref":{"type":"string","maxLength":255,"description":"An additional partner-side reference for this transaction."},"payment_details":{"type":"object","description":"Payment information","properties":{"provider":{"type":"string","description":"Payment provider name (e.g., stripe, paypal, xpay)"},"transaction_id":{"type":"string","description":"Payment transaction ID"},"xpay_charge_id":{"type":"string","description":"XPay charge ID if using XPay"},"xpay_customer_id":{"type":"string","description":"XPay customer ID if using XPay"},"customer_token_id":{"type":"string","description":"Customer token for payment authorization"}}},"booking_agent":{"type":"object","description":"Agent information if booked through an agent"}},"required":["quotes","policyholder"]}}}}}}}}
```


# Modify Booking

## Get Booking

> Retrieve detailed information about an existing booking including policy details, quotes, policyholder information, and current status. This is typically the first step in the modification workflow to retrieve current booking state before making changes. Use this endpoint to obtain the INS number (booking ID), quote IDs, price paid, or current policy details for subsequent operations like modifications or cancellations.

```json
{"openapi":"3.0.0","info":{"title":"Offers API","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n* **Example:** `X-Api-Key: YOUR_API_KEY_HERE`\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n* **Example:** `Date: Sun, 09 Nov 2025 04:04:00 GMT`\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** The cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\n**Signature Generation Logic:**\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/":{"get":{"summary":"Get Booking","description":"Retrieve detailed information about an existing booking including policy details, quotes, policyholder information, and current status. This is typically the first step in the modification workflow to retrieve current booking state before making changes. Use this endpoint to obtain the INS number (booking ID), quote IDs, price paid, or current policy details for subsequent operations like modifications or cancellations.","tags":["Modify Booking"],"responses":{"200":{"description":"OK","headers":{"Date":{"schema":{"type":"string"}},"Transfer-Encoding":{"schema":{"type":"string"}},"Connection":{"schema":{"type":"string"}},"CF-Ray":{"schema":{"type":"integer"}},"CF-Cache-Status":{"schema":{"type":"string"}},"Allow":{"schema":{"type":"string"}},"Server":{"schema":{"type":"string"}},"Strict-Transport-Security":{"schema":{"type":"string"}},"cross-origin-opener-policy":{"schema":{"type":"string"}},"referrer-policy":{"schema":{"type":"string"}},"Vary":{"schema":{"type":"string"}},"Content-Encoding":{"schema":{"type":"string"}},"Server-Timing":{"schema":{"type":"string"}},"Cf-Team":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"partner_transaction_id":{"nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"pds_url":{"type":"string","format":"uri"},"security_token":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"policy_start_date":{"type":"string","format":"date-time"},"policy_end_date":{"type":"string","format":"date-time"},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"policy":{"type":"object","properties":{"policy_type":{"type":"string"},"policy_type_version":{"type":"string","format":"utc-millisec"},"policy_type_slug":{"type":"string"},"policy_type_group_name":{"type":"string"},"policy_name":{"type":"string"},"policy_code":{"type":"string"},"policy_version":{"type":"string"},"category":{"type":"string"},"content":{"type":"object","properties":{"title":{"type":"string"},"header":{"nullable":true},"description":{"type":"string"},"optout_msg":{"type":"string"},"inclusions":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"}}}},"exclusions":{"type":"array","items":{}},"disclaimer":{"type":"string","format":"style"},"disclaimer_html":{"type":"string","format":"style"},"payment_disclaimer":{"type":"string"},"in_path_disclaimer":{"type":"string"},"extra_content":{"type":"object"}}},"underwriter":{"type":"object","properties":{"disclaimer":{"type":"string"},"name":{"type":"string"}}},"claim_selector_id":{"nullable":true},"policy_currency":{"type":"string"}}},"insured":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"region":{"nullable":true}}}},"tax":{"type":"object","properties":{"total_tax":{"type":"number"},"total_amount_without_tax":{"type":"number"},"taxes":{"type":"array","items":{"type":"object","properties":{"tax_amount":{"type":"number"},"tax_code":{"type":"string"},"tax_amount_formatted":{"type":"string"}}}},"total_tax_formatted":{"type":"string"},"total_amount_without_tax_formatted":{"type":"string"}}},"duration":{"type":"string","format":"style"},"benefits":{"type":"array","items":{"type":"object","properties":{"benefit_content_id":{"type":"string"},"description":{"type":"string"},"extra_content":{"type":"object"},"limit":{"type":"integer"},"limit_policy_currency":{"type":"integer"},"limit_formatted":{"type":"string"},"limit_policy_currency_formatted":{"type":"string"},"excess":{"type":"integer"},"excess_policy_currency":{"type":"integer"},"excess_formatted":{"type":"string"},"excess_policy_currency_formatted":{"type":"string"}}}},"commission":{"type":"object","properties":{"partner_commission":{"type":"number"},"surcharge_commission":{"type":"integer"},"total_commission":{"type":"number"},"partner_commission_formatted":{"type":"string"},"surcharge_commission_formatted":{"type":"string"},"total_commission_formatted":{"type":"string"}}},"created_at":{"type":"string","format":"date-time"},"confirmed_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"cancelled_at":{"nullable":true},"cancelled_from":{"nullable":true},"is_renewable":{"type":"boolean"},"is_pricebeat_enabled":{"nullable":true},"cover_amount":{"type":"integer"},"cover_amount_formatted":{"type":"string"},"pds_url":{"type":"string","format":"uri"},"attachments":{"type":"array","items":{}},"files":{"type":"array","items":{}},"custom_documents":{"nullable":true},"extra_fields":{"type":"object"},"surcharge":{"type":"object","properties":{"total_amount":{"nullable":true},"surcharges":{"nullable":true},"total_amount_formatted":{"type":"string"}}},"parent_quote_status":{"nullable":true},"experiment":{"nullable":true},"next_renewal":{"nullable":true},"can_be_cancelled":{"type":"boolean"},"third_party_admins":{"type":"array","items":{}},"ombudsman_list":{"type":"array","items":{}},"cancellation_info":{"type":"object","properties":{"reason_for_cancellation":{"type":"string"}}}}}},"coi":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"pdf":{"type":"string","format":"uri"}}},"account_url":{"type":"string","format":"uri"},"sign_up_url":{"type":"string","format":"uri"},"policyholder":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"nullable":true},"address1":{"nullable":true},"address2":{"nullable":true},"postcode":{"type":"string"},"company":{"nullable":true},"company_reg_id":{"nullable":true},"middle_name":{"nullable":true},"country":{"type":"string"},"age":{"type":"integer"},"city":{"nullable":true},"region":{"type":"string"},"secondary_email":{"nullable":true},"birth_date":{"nullable":true},"allow_updates":{"type":"boolean"},"fields_allowed_to_update":{"type":"array","items":{}}}},"total_tax":{"type":"number"},"total_tax_formatted":{"type":"string"},"total_premium":{"type":"number"},"total_premium_formatted":{"type":"string"},"fnol_link":{"type":"string","format":"uri"},"booking_agent":{"nullable":true}}}}}},"403":{"description":"Forbidden","headers":{"Date":{"schema":{"deprecated":false}},"Transfer-Encoding":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}},"Content-Encoding":{"schema":{"deprecated":false}},"Server-Timing":{"schema":{"deprecated":false}},"Cf-Team":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","headers":{"Date":{"schema":{"type":"string"}},"Transfer-Encoding":{"schema":{"type":"string"}},"Connection":{"schema":{"type":"string"}},"CF-Ray":{"schema":{"type":"integer"}},"CF-Cache-Status":{"schema":{"type":"string"}},"Allow":{"schema":{"type":"string"}},"Server":{"schema":{"type":"string"}},"Strict-Transport-Security":{"schema":{"type":"string"}},"cross-origin-opener-policy":{"schema":{"type":"string"}},"referrer-policy":{"schema":{"type":"string"}},"Vary":{"schema":{"type":"string"}},"Content-Encoding":{"schema":{"type":"string"}},"Server-Timing":{"schema":{"type":"string"}},"Cf-Team":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}
```

## Modify booking

> The modification workflow is used when a customer wants to make changes to their existing policy. This endpoint allows you to update policy details which may result in price adjustments, refunds, or additional fees.

```json
{"openapi":"3.0.0","info":{"title":"Offers API","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n* **Example:** `X-Api-Key: YOUR_API_KEY_HERE`\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n* **Example:** `Date: Sun, 09 Nov 2025 04:04:00 GMT`\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** The cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\n**Signature Generation Logic:**\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/":{"patch":{"summary":"Modify booking","description":"The modification workflow is used when a customer wants to make changes to their existing policy. This endpoint allows you to update policy details which may result in price adjustments, refunds, or additional fees.","tags":["Modify Booking"],"responses":{"200":{"description":"OK","headers":{"Date":{"schema":{"type":"string"}},"Transfer-Encoding":{"schema":{"type":"string"}},"Connection":{"schema":{"type":"string"}},"CF-Ray":{"schema":{"type":"integer"}},"CF-Cache-Status":{"schema":{"type":"string"}},"Allow":{"schema":{"type":"string"}},"Server":{"schema":{"type":"string"}},"Strict-Transport-Security":{"schema":{"type":"string"}},"content-security-policy":{"schema":{"type":"string"}},"cross-origin-opener-policy":{"schema":{"type":"string"}},"referrer-policy":{"schema":{"type":"string"}},"Vary":{"schema":{"type":"string"}},"Content-Encoding":{"schema":{"type":"string"}},"Server-Timing":{"schema":{"type":"string"}},"Cf-Team":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"partner_transaction_id":{"nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"pds_url":{"type":"string","format":"uri"},"security_token":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"policy_start_date":{"type":"string","format":"date-time"},"policy_end_date":{"type":"string","format":"date-time"},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"policy":{"type":"object","properties":{"policy_type":{"type":"string"},"policy_type_version":{"type":"string","format":"utc-millisec"},"policy_type_slug":{"type":"string"},"policy_type_group_name":{"type":"string"},"policy_name":{"type":"string"},"policy_code":{"type":"string"},"policy_version":{"type":"string"},"category":{"type":"string"},"content":{"type":"object","properties":{"title":{"type":"string"},"header":{"nullable":true},"description":{"type":"string"},"optout_msg":{"type":"string"},"inclusions":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"}}}},"exclusions":{"type":"array","items":{}},"disclaimer":{"type":"string","format":"style"},"disclaimer_html":{"type":"string","format":"style"},"payment_disclaimer":{"type":"string"},"in_path_disclaimer":{"type":"string"},"extra_content":{"type":"object"}}},"underwriter":{"type":"object","properties":{"disclaimer":{"type":"string"},"name":{"type":"string"}}},"claim_selector_id":{"nullable":true},"policy_currency":{"type":"string"}}},"insured":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"region":{"nullable":true}}}},"tax":{"type":"object","properties":{"total_tax":{"type":"number"},"total_amount_without_tax":{"type":"number"},"taxes":{"type":"array","items":{"type":"object","properties":{"tax_amount":{"type":"number"},"tax_code":{"type":"string"},"tax_amount_formatted":{"type":"string"}}}},"total_tax_formatted":{"type":"string"},"total_amount_without_tax_formatted":{"type":"string"}}},"duration":{"type":"string","format":"style"},"benefits":{"type":"array","items":{"type":"object","properties":{"benefit_content_id":{"type":"string"},"description":{"type":"string"},"extra_content":{"type":"object","properties":{"benefit-text-test":{"type":"string"},"benefit_rich_text_test":{"type":"string"}}},"limit":{"type":"integer"},"limit_policy_currency":{"type":"integer"},"limit_formatted":{"type":"string"},"limit_policy_currency_formatted":{"type":"string"},"excess":{"type":"integer"},"excess_policy_currency":{"type":"integer"},"excess_formatted":{"type":"string"},"excess_policy_currency_formatted":{"type":"string"}}}},"commission":{"type":"object","properties":{"partner_commission":{"type":"number"},"surcharge_commission":{"type":"integer"},"total_commission":{"type":"number"},"partner_commission_formatted":{"type":"string"},"surcharge_commission_formatted":{"type":"string"},"total_commission_formatted":{"type":"string"}}},"created_at":{"type":"string","format":"date-time"},"confirmed_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"cancelled_at":{"nullable":true},"cancelled_from":{"nullable":true},"is_renewable":{"type":"boolean"},"is_pricebeat_enabled":{"nullable":true},"cover_amount":{"type":"integer"},"cover_amount_formatted":{"type":"string"},"pds_url":{"type":"string","format":"uri"},"attachments":{"type":"array","items":{}},"files":{"type":"array","items":{}},"custom_documents":{"nullable":true},"extra_fields":{"type":"object","properties":{"destination_region":{"type":"string"},"seller_entity":{"type":"string"},"age_brackets":{"type":"string"},"desitnation_sanctions":{"type":"array","items":{}},"sanctioned_distination_countries":{"type":"array","items":{"type":"string"}},"test_underwrting_rule":{"type":"boolean"}}},"surcharge":{"type":"object","properties":{"total_amount":{"nullable":true},"surcharges":{"nullable":true},"total_amount_formatted":{"type":"string"}}},"parent_quote_status":{"nullable":true},"experiment":{"nullable":true},"next_renewal":{"nullable":true},"can_be_cancelled":{"type":"boolean"},"third_party_admins":{"type":"array","items":{}},"ombudsman_list":{"type":"array","items":{}},"cancellation_info":{"type":"object","properties":{"reason_for_cancellation":{"type":"string"}}}}}},"coi":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"pdf":{"type":"string","format":"uri"}}},"account_url":{"type":"string","format":"uri"},"sign_up_url":{"type":"string","format":"uri"},"policyholder":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"nullable":true},"address1":{"nullable":true},"address2":{"nullable":true},"postcode":{"type":"string","format":"utc-millisec"},"company":{"nullable":true},"company_reg_id":{"nullable":true},"middle_name":{"nullable":true},"country":{"type":"string"},"age":{"type":"integer"},"city":{"nullable":true},"region":{"type":"string"},"secondary_email":{"nullable":true},"birth_date":{"nullable":true},"allow_updates":{"type":"boolean"},"fields_allowed_to_update":{"type":"array","items":{}}}},"total_tax":{"type":"number"},"total_tax_formatted":{"type":"string"},"total_premium":{"type":"number"},"total_premium_formatted":{"type":"string"},"fnol_link":{"type":"string","format":"uri"},"booking_agent":{"nullable":true}}}}}},"403":{"description":"Forbidden","headers":{"Date":{"schema":{"deprecated":false}},"Transfer-Encoding":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}},"Content-Encoding":{"schema":{"deprecated":false}},"Server-Timing":{"schema":{"deprecated":false}},"Cf-Team":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","headers":{"Date":{"schema":{"type":"string"}},"Content-Length":{"schema":{"type":"integer"}},"Connection":{"schema":{"type":"string"}},"CF-Ray":{"schema":{"type":"integer"}},"CF-Cache-Status":{"schema":{"type":"string"}},"Allow":{"schema":{"type":"string"}},"Server":{"schema":{"type":"string"}},"Strict-Transport-Security":{"schema":{"type":"string"}},"cross-origin-opener-policy":{"schema":{"type":"string"}},"referrer-policy":{"schema":{"type":"string"}},"Vary":{"schema":{"type":"string"}},"Server-Timing":{"schema":{"type":"string"}},"Cf-Team":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"array","items":{"type":"string"}}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"policy_start_date":{"type":"string"},"update_fields":{"type":"object","properties":{"insured":{"type":"array","items":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string"}}}}}}},"required":["id","update_fields"]}}}}}}}}}}}
```

## Modify Booking - preview

> Preview the price impact of proposed changes to a booking before committing them. This endpoint calculates the price difference (refund or additional charge) for the requested modifications without applying them. Use this to show customers the financial impact before they confirm. The response includes an \`update\_id\` that must be used with the Confirm Update endpoint to apply the changes.

```json
{"openapi":"3.0.0","info":{"title":"Offers API","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n* **Example:** `X-Api-Key: YOUR_API_KEY_HERE`\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n* **Example:** `Date: Sun, 09 Nov 2025 04:04:00 GMT`\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** The cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\n**Signature Generation Logic:**\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/quote_for_update":{"patch":{"summary":"Modify Booking - preview","description":"Preview the price impact of proposed changes to a booking before committing them. This endpoint calculates the price difference (refund or additional charge) for the requested modifications without applying them. Use this to show customers the financial impact before they confirm. The response includes an `update_id` that must be used with the Confirm Update endpoint to apply the changes.","tags":["Modify Booking"],"responses":{"200":{"description":"OK","headers":{"Date":{"schema":{"deprecated":false}},"Transfer-Encoding":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"content-security-policy":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}},"Content-Encoding":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"partner_transaction_id":{"nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"pds_url":{"type":"string","format":"uri"},"security_token":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"policy_start_date":{"type":"string","format":"date-time"},"policy_end_date":{"type":"string","format":"date-time"},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"policy":{"type":"object","properties":{"policy_type":{"type":"string"},"policy_type_version":{"type":"string","format":"utc-millisec"},"policy_type_slug":{"type":"string"},"policy_type_group_name":{"type":"string"},"policy_name":{"type":"string"},"policy_code":{"type":"string"},"policy_version":{"type":"string"},"category":{"type":"string"},"content":{"type":"object","properties":{"title":{"type":"string"},"header":{"nullable":true},"description":{"type":"string"},"optout_msg":{"type":"string"},"inclusions":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"}}}},"exclusions":{"type":"array","items":{}},"disclaimer":{"type":"string","format":"style"},"disclaimer_html":{"type":"string","format":"style"},"payment_disclaimer":{"type":"string"},"in_path_disclaimer":{"type":"string"},"extra_content":{"type":"object"}}},"underwriter":{"type":"object","properties":{"disclaimer":{"type":"string"},"name":{"type":"string"}}},"claim_selector_id":{"nullable":true},"policy_currency":{"type":"string"}}},"insured":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"region":{"nullable":true}}}},"tax":{"type":"object","properties":{"total_tax":{"type":"number"},"total_amount_without_tax":{"type":"number"},"taxes":{"type":"array","items":{"type":"object","properties":{"tax_amount":{"type":"number"},"tax_code":{"type":"string"},"tax_amount_formatted":{"type":"string"}}}},"total_tax_formatted":{"type":"string"},"total_amount_without_tax_formatted":{"type":"string"}}},"duration":{"type":"string","format":"style"},"benefits":{"type":"array","items":{"type":"object","properties":{"benefit_content_id":{"type":"string"},"description":{"type":"string"},"extra_content":{"type":"object","properties":{"benefit-text-test":{"type":"string"},"benefit_rich_text_test":{"type":"string"}}},"limit":{"type":"integer"},"limit_policy_currency":{"type":"integer"},"limit_formatted":{"type":"string"},"limit_policy_currency_formatted":{"type":"string"},"excess":{"type":"integer"},"excess_policy_currency":{"type":"integer"},"excess_formatted":{"type":"string"},"excess_policy_currency_formatted":{"type":"string"}}}},"commission":{"type":"object","properties":{"partner_commission":{"type":"number"},"surcharge_commission":{"type":"integer"},"total_commission":{"type":"number"},"partner_commission_formatted":{"type":"string"},"surcharge_commission_formatted":{"type":"string"},"total_commission_formatted":{"type":"string"}}},"created_at":{"type":"string","format":"date-time"},"confirmed_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"cancelled_at":{"nullable":true},"cancelled_from":{"nullable":true},"is_renewable":{"type":"boolean"},"is_pricebeat_enabled":{"nullable":true},"cover_amount":{"type":"integer"},"cover_amount_formatted":{"type":"string"},"pds_url":{"type":"string","format":"uri"},"attachments":{"type":"array","items":{}},"files":{"type":"array","items":{}},"custom_documents":{"nullable":true},"extra_fields":{"type":"object","properties":{"destination_region":{"type":"string"},"seller_entity":{"type":"string"},"age_brackets":{"type":"string"},"desitnation_sanctions":{"type":"array","items":{}},"sanctioned_distination_countries":{"type":"array","items":{"type":"string"}},"test_underwrting_rule":{"type":"boolean"}}},"surcharge":{"type":"object","properties":{"total_amount":{"nullable":true},"surcharges":{"nullable":true},"total_amount_formatted":{"type":"string"}}},"parent_quote_status":{"nullable":true},"experiment":{"nullable":true},"next_renewal":{"nullable":true},"can_be_cancelled":{"type":"boolean"},"third_party_admins":{"type":"array","items":{}},"ombudsman_list":{"type":"array","items":{}},"cancellation_info":{"type":"object","properties":{"reason_for_cancellation":{"type":"string"}}},"price_diff":{"type":"integer"},"price_diff_formatted":{"type":"string"}}}},"coi":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"pdf":{"type":"string","format":"uri"}}},"account_url":{"type":"string","format":"uri"},"sign_up_url":{"type":"string","format":"uri"},"policyholder":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"address1":{"nullable":true},"address2":{"nullable":true},"postcode":{"type":"string","format":"color"},"company":{"nullable":true},"company_reg_id":{"nullable":true},"middle_name":{"nullable":true},"country":{"type":"string"},"age":{"type":"integer"},"city":{"nullable":true},"region":{"type":"string"},"secondary_email":{"nullable":true},"birth_date":{"nullable":true},"allow_updates":{"type":"boolean"},"fields_allowed_to_update":{"type":"array","items":{}}}},"total_tax":{"type":"number"},"total_tax_formatted":{"type":"string"},"total_premium":{"type":"number"},"total_premium_formatted":{"type":"string"},"fnol_link":{"type":"string","format":"uri"},"booking_agent":{"nullable":true},"total_price_diff":{"type":"integer"},"total_price_diff_formatted":{"type":"string"},"update_id":{"type":"string"}}}}}},"403":{"description":"Forbidden","headers":{"Date":{"schema":{"deprecated":false}},"Transfer-Encoding":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}},"Content-Encoding":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","headers":{"Date":{"schema":{"deprecated":false}},"Content-Length":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object","properties":{"_non_field_errors":{"type":"array","items":{"type":"string"}}}}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"policy_start_date":{"type":"string"},"update_fields":{"type":"object","properties":{"insured":{"type":"array","items":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string"}}}}}}},"required":["id","update_fields"]}}}}}}}}}}}
```

## Modify Booking - confirm

> Confirm and apply previously previewed booking modifications. This endpoint finalizes the changes calculated by the Preview endpoint. You must provide the \`update\_id\` returned from the Preview endpoint. If there is an additional charge, include the \`xpay\_charge\_id\` from the payment transaction.

```json
{"openapi":"3.0.0","info":{"title":"Offers API","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n* **Example:** `X-Api-Key: YOUR_API_KEY_HERE`\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n* **Example:** `Date: Sun, 09 Nov 2025 04:04:00 GMT`\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** The cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\n**Signature Generation Logic:**\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/confirm_update/{update_id}/":{"post":{"summary":"Modify Booking - confirm","description":"Confirm and apply previously previewed booking modifications. This endpoint finalizes the changes calculated by the Preview endpoint. You must provide the `update_id` returned from the Preview endpoint. If there is an additional charge, include the `xpay_charge_id` from the payment transaction.","tags":["Modify Booking"],"responses":{"201":{"description":"Created","headers":{"Date":{"schema":{"deprecated":false}},"Content-Length":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"content-security-policy":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"partner_transaction_id":{"nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"pds_url":{"type":"string","format":"uri"},"security_token":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"policy_start_date":{"type":"string","format":"date-time"},"policy_end_date":{"type":"string","format":"date-time"},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"policy":{"type":"object","properties":{"policy_type":{"type":"string"},"policy_type_version":{"type":"string","format":"utc-millisec"},"policy_type_slug":{"type":"string"},"policy_type_group_name":{"type":"string"},"policy_name":{"type":"string"},"policy_code":{"type":"string"},"policy_version":{"type":"string"},"category":{"type":"string"},"content":{"type":"object","properties":{"title":{"type":"string"},"header":{"nullable":true},"description":{"type":"string"},"optout_msg":{"type":"string"},"inclusions":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"}}}},"exclusions":{"type":"array","items":{}},"disclaimer":{"type":"string","format":"style"},"disclaimer_html":{"type":"string","format":"style"},"payment_disclaimer":{"type":"string"},"in_path_disclaimer":{"type":"string"},"extra_content":{"type":"object"}}},"underwriter":{"type":"object","properties":{"disclaimer":{"type":"string"},"name":{"type":"string"}}},"claim_selector_id":{"nullable":true},"policy_currency":{"type":"string"}}},"insured":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"region":{"nullable":true}}}},"tax":{"type":"object","properties":{"total_tax":{"type":"number"},"total_amount_without_tax":{"type":"number"},"taxes":{"type":"array","items":{"type":"object","properties":{"tax_amount":{"type":"number"},"tax_code":{"type":"string"},"tax_amount_formatted":{"type":"string"}}}},"total_tax_formatted":{"type":"string"},"total_amount_without_tax_formatted":{"type":"string"}}},"duration":{"type":"string","format":"style"},"benefits":{"type":"array","items":{"type":"object","properties":{"benefit_content_id":{"type":"string"},"description":{"type":"string"},"extra_content":{"type":"object","properties":{"benefit-text-test":{"type":"string"},"benefit_rich_text_test":{"type":"string"}}},"limit":{"type":"integer"},"limit_policy_currency":{"type":"integer"},"limit_formatted":{"type":"string"},"limit_policy_currency_formatted":{"type":"string"},"excess":{"type":"integer"},"excess_policy_currency":{"type":"integer"},"excess_formatted":{"type":"string"},"excess_policy_currency_formatted":{"type":"string"}}}},"commission":{"type":"object","properties":{"partner_commission":{"type":"number"},"surcharge_commission":{"type":"integer"},"total_commission":{"type":"number"},"partner_commission_formatted":{"type":"string"},"surcharge_commission_formatted":{"type":"string"},"total_commission_formatted":{"type":"string"}}},"created_at":{"type":"string","format":"date-time"},"confirmed_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"cancelled_at":{"nullable":true},"cancelled_from":{"nullable":true},"is_renewable":{"type":"boolean"},"is_pricebeat_enabled":{"nullable":true},"cover_amount":{"type":"integer"},"cover_amount_formatted":{"type":"string"},"pds_url":{"type":"string","format":"uri"},"attachments":{"type":"array","items":{}},"files":{"type":"array","items":{}},"custom_documents":{"nullable":true},"extra_fields":{"type":"object","properties":{"destination_region":{"type":"string"},"seller_entity":{"type":"string"},"age_brackets":{"type":"string"},"desitnation_sanctions":{"type":"array","items":{}},"sanctioned_distination_countries":{"type":"array","items":{"type":"string"}},"test_underwrting_rule":{"type":"boolean"}}},"surcharge":{"type":"object","properties":{"total_amount":{"nullable":true},"surcharges":{"nullable":true},"total_amount_formatted":{"type":"string"}}},"parent_quote_status":{"nullable":true},"experiment":{"nullable":true},"next_renewal":{"nullable":true},"can_be_cancelled":{"type":"boolean"},"third_party_admins":{"type":"array","items":{}},"ombudsman_list":{"type":"array","items":{}},"cancellation_info":{"type":"object","properties":{"reason_for_cancellation":{"type":"string"}}},"price_diff":{"type":"integer"},"price_diff_formatted":{"type":"string"}}}},"coi":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"pdf":{"type":"string","format":"uri"}}},"account_url":{"type":"string","format":"uri"},"sign_up_url":{"type":"string","format":"uri"},"policyholder":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"address1":{"nullable":true},"address2":{"nullable":true},"postcode":{"type":"string","format":"color"},"company":{"nullable":true},"company_reg_id":{"nullable":true},"middle_name":{"nullable":true},"country":{"type":"string"},"age":{"type":"integer"},"city":{"nullable":true},"region":{"type":"string"},"secondary_email":{"nullable":true},"birth_date":{"nullable":true},"allow_updates":{"type":"boolean"},"fields_allowed_to_update":{"type":"array","items":{}}}},"total_tax":{"type":"number"},"total_tax_formatted":{"type":"string"},"total_premium":{"type":"number"},"total_premium_formatted":{"type":"string"},"fnol_link":{"type":"string","format":"uri"},"booking_agent":{"nullable":true},"total_price_diff":{"type":"integer"},"total_price_diff_formatted":{"type":"string"}}}}}},"403":{"description":"Forbidden","headers":{"Date":{"schema":{"deprecated":false}},"Transfer-Encoding":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}},"Content-Encoding":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","headers":{"Date":{"schema":{"deprecated":false}},"Transfer-Encoding":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}},"Content-Encoding":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","headers":{"Date":{"schema":{"deprecated":false}},"Content-Length":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"xpay_charge_id":{"type":"string"}}}}}}}}}}
```


# Confirm Booking

## Confirm Booking

> Completes the second step of the two-step booking flow. Use this endpoint after confirming an Offer with \`require\_payment\_confirmation\` set to \`true\`, which leaves the booking in \`PENDING\_PAYMENT\`. Once payment has been collected, call this endpoint to move the booking to \`CONFIRMED\` and issue the policies.\
> The booking must be in \`PENDING\_PAYMENT\` status; any other status returns \`422\`.\
> \### Idempotency\
> This endpoint supports idempotency keys via the \`x-idempotency-key\` header to prevent duplicate transactions. Provide a unique operation identifier (e.g., UUID) to ensure safe retries. Duplicate requests return:\
> \- \*\*409 Conflict\*\*: The request was already processed; response contains\
> &#x20; the cached original result (handle as success)\
> \- \*\*423 Locked\*\*: The original request is still processing; retry after\
> &#x20; a short delay

```json
{"openapi":"3.0.0","info":{"title":"Offers API","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n* **Example:** `X-Api-Key: YOUR_API_KEY_HERE`\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n* **Example:** `Date: Sun, 09 Nov 2025 04:04:00 GMT`\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** The cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\n**Signature Generation Logic:**\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/confirm":{"put":{"summary":"Confirm Booking","description":"Completes the second step of the two-step booking flow. Use this endpoint after confirming an Offer with `require_payment_confirmation` set to `true`, which leaves the booking in `PENDING_PAYMENT`. Once payment has been collected, call this endpoint to move the booking to `CONFIRMED` and issue the policies.\nThe booking must be in `PENDING_PAYMENT` status; any other status returns `422`.\n### Idempotency\nThis endpoint supports idempotency keys via the `x-idempotency-key` header to prevent duplicate transactions. Provide a unique operation identifier (e.g., UUID) to ensure safe retries. Duplicate requests return:\n- **409 Conflict**: The request was already processed; response contains\n  the cached original result (handle as success)\n- **423 Locked**: The original request is still processing; retry after\n  a short delay","tags":["Confirm Booking"],"parameters":[{"name":"x-idempotency-key","in":"header","required":false,"description":"A unique identifier to ensure idempotent request processing. If a request with the same idempotency key and body has already been processed, the cached response is returned with a `409` Conflict status code (which can be treated as successful). Keys are stored for 48 hours.","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"payment_details":{"type":"object","description":"Payment information for the collected payment","properties":{"provider":{"type":"string","description":"Payment provider name (e.g., stripe, paypal, xpay)"},"transaction_id":{"type":"string","description":"Payment transaction ID"},"xpay_charge_id":{"type":"string","description":"XPay charge ID if using XPay"},"xpay_customer_id":{"type":"string","description":"XPay customer ID if using XPay"},"customer_token_id":{"type":"string","description":"Customer token for payment authorization"}}},"xpay_charge_id":{"type":"string","deprecated":true,"description":"Deprecated. Use `payment_details.xpay_charge_id` instead."}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","description":"The confirmed booking. Payload is identical to the Confirm Offer response.","properties":{"id":{"type":"string"},"status":{"type":"string"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"partner_transaction_id":{"nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"pds_url":{"type":"string","format":"uri"},"security_token":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"policy_start_date":{"type":"string","format":"date-time"},"policy_end_date":{"type":"string","format":"date-time"},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"insured":{"type":"array","items":{"type":"object"}},"can_be_cancelled":{"type":"boolean"}}}},"coi":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"pdf":{"type":"string","format":"uri"}}},"account_url":{"type":"string","format":"uri"},"sign_up_url":{"type":"string","format":"uri"},"policyholder":{"type":"object"},"total_tax":{"type":"number"},"total_tax_formatted":{"type":"string"},"total_premium":{"type":"number"},"total_premium_formatted":{"type":"string"},"fnol_link":{"type":"string","format":"uri"},"booking_agent":{"nullable":true}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"409":{"description":"Conflict - Duplicate Request (Idempotent)","content":{"application/json":{"schema":{"type":"object","description":"The cached response from the original request. Handle as a success."}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"array","items":{"type":"string"}}}}}}},"423":{"description":"Locked - Request In Progress","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}
```


# Cancel Booking

## Cancel Booking

> Cancel a policy booking when a customer no longer requires coverage. This endpoint supports two modes controlled by the \`preview\` field:\
> \- \*\*Preview mode\*\* (\`preview: true\`): Calculate the refund amount without\
> &#x20; cancelling. Returns a \`cancellation\_id\` for use with the Confirm\
> &#x20; Cancellation endpoint.\
> \
> \- \*\*Immediate cancellation\*\* (\`preview: false\` or omitted): Cancel the\
> &#x20; booking immediately and process any applicable refunds.\
> \
> Use preview mode when you need customer confirmation before finalizing the cancellation.

```json
{"openapi":"3.0.0","info":{"title":"Offers API","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n* **Example:** `X-Api-Key: YOUR_API_KEY_HERE`\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n* **Example:** `Date: Sun, 09 Nov 2025 04:04:00 GMT`\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** The cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\n**Signature Generation Logic:**\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/cancel":{"post":{"summary":"Cancel Booking","description":"Cancel a policy booking when a customer no longer requires coverage. This endpoint supports two modes controlled by the `preview` field:\n- **Preview mode** (`preview: true`): Calculate the refund amount without\n  cancelling. Returns a `cancellation_id` for use with the Confirm\n  Cancellation endpoint.\n\n- **Immediate cancellation** (`preview: false` or omitted): Cancel the\n  booking immediately and process any applicable refunds.\n\nUse preview mode when you need customer confirmation before finalizing the cancellation.","tags":["Cancel Booking"],"responses":{"200":{"description":"OK - cancelled","headers":{"Date":{"schema":{"deprecated":false}},"Transfer-Encoding":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"content-security-policy":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}},"Content-Encoding":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"policy_start_date":{"type":"string","format":"date-time"},"policy_end_date":{"type":"string","format":"date-time"},"policy_cancellation_date":{"type":"string","format":"date-time"},"policy_coolingoff_date":{"type":"string","format":"date-time"},"status":{"type":"string"},"price":{"type":"number"},"refund_value":{"type":"number"},"adjustment_fee":{"type":"integer"},"policy":{"type":"object","properties":{"policy_type":{"type":"string"},"policy_type_version":{"type":"string","format":"utc-millisec"},"policy_type_slug":{"type":"string"},"policy_type_group_name":{"type":"string"},"policy_name":{"type":"string"},"policy_code":{"type":"string"},"policy_version":{"type":"string"},"category":{"type":"string"},"content":{"type":"object","properties":{"title":{"type":"string"},"header":{"nullable":true},"description":{"type":"string"},"optout_msg":{"type":"string"},"inclusions":{"type":"array","items":{}},"exclusions":{"type":"array","items":{}},"disclaimer":{"type":"string"},"disclaimer_html":{"type":"string"},"payment_disclaimer":{"type":"string"},"in_path_disclaimer":{"type":"string"}}},"underwriter":{"type":"object","properties":{"disclaimer":{"type":"string"},"name":{"type":"string"}}},"claim_selector_id":{"nullable":true},"policy_currency":{"type":"string"}}},"insured":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"region":{"nullable":true}}}},"created_at":{"type":"string","format":"date-time"},"confirmed_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"cancelled_at":{"type":"string","format":"date-time"},"cancelled_from":{"type":"string","format":"date-time"},"commission":{"nullable":true}}}},"policyholder":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"address1":{"nullable":true},"address2":{"nullable":true},"postcode":{"type":"string","format":"color"},"company":{"nullable":true},"company_reg_id":{"nullable":true},"middle_name":{"nullable":true},"country":{"type":"string"},"age":{"type":"integer"},"city":{"nullable":true},"region":{"type":"string"},"secondary_email":{"nullable":true},"birth_date":{"nullable":true},"allow_updates":{"type":"boolean"},"fields_allowed_to_update":{"type":"array","items":{}}}},"pds_url":{"type":"string","format":"uri"},"coi":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"pdf":{"type":"string","format":"uri"}}},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"total_price":{"type":"integer"},"total_price_formatted":{"type":"string"},"total_refund":{"type":"number"},"total_refund_formatted":{"type":"string"},"total_tax":{"type":"integer"},"total_tax_formatted":{"type":"string"},"total_premium":{"type":"integer"},"total_premium_formatted":{"type":"string"},"currency":{"type":"string"},"cancellation_id":{"nullable":true},"confirm_before":{"nullable":true},"partner":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"title":{"type":"string"},"logo":{"type":"string","format":"uri"},"contact_url":{"type":"string","format":"uri"},"partner_url":{"type":"string","format":"uri"},"help_center_url":{"type":"string","format":"uri"},"updated_at":{"type":"string","format":"date-time"},"xpay_payment_enabled":{"type":"boolean"},"xpay_b2c_payment_enabled":{"type":"boolean"},"xpay_refund_enabled":{"type":"boolean"},"automatic_refund_by_xcore":{"type":"boolean"},"allow_policy_modifications_on_xcover":{"type":"boolean"},"emails":{"type":"array","items":{}},"attributes":{"type":"object"},"signup_method_on_xcover":{"nullable":true},"use_standard_region":{"nullable":true},"allow_payout_customer":{"type":"boolean"},"eligible_for_xpay_charge_retry":{"type":"boolean"},"subsidiary":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"title":{"type":"string"},"logo":{"type":"string","format":"uri"},"contact_url":{"type":"string","format":"uri"},"partner_url":{"type":"string","format":"uri"},"help_center_url":{"type":"string","format":"uri"},"updated_at":{"type":"string","format":"date-time"},"xpay_payment_enabled":{"type":"boolean"},"xpay_b2c_payment_enabled":{"type":"boolean"},"xpay_refund_enabled":{"type":"boolean"},"automatic_refund_by_xcore":{"type":"boolean"},"allow_policy_modifications_on_xcover":{"type":"boolean"},"emails":{"type":"array","items":{}},"attributes":{"type":"object"},"signup_method_on_xcover":{"nullable":true},"use_standard_region":{"nullable":true},"allow_payout_customer":{"type":"boolean"},"eligible_for_xpay_charge_retry":{"type":"boolean"}}}}},"refund_amount":{"type":"number"},"refund_amount_formatted":{"type":"string"},"cancellation_payout_url":{"nullable":true}}}}}},"403":{"description":"Forbidden","headers":{"Date":{"schema":{"deprecated":false}},"Transfer-Encoding":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}},"Content-Encoding":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","headers":{"Date":{"schema":{"type":"string"}},"Transfer-Encoding":{"schema":{"type":"string"}},"Connection":{"schema":{"type":"string"}},"CF-Ray":{"schema":{"type":"integer"}},"CF-Cache-Status":{"schema":{"type":"string"}},"Allow":{"schema":{"type":"string"}},"Server":{"schema":{"type":"string"}},"Strict-Transport-Security":{"schema":{"type":"string"}},"cross-origin-opener-policy":{"schema":{"type":"string"}},"referrer-policy":{"schema":{"type":"string"}},"Vary":{"schema":{"type":"string"}},"Content-Encoding":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Modify booking Copy","headers":{"Date":{"schema":{"deprecated":false}},"Content-Length":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"array","items":{"type":"string"}}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"preview":{"type":"boolean"},"refund_required":{"type":"boolean"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"reason_for_cancellation":{"type":"string"}},"required":["id"]}}}}}}}}}}}
```

## Cancel Booking - confirm

> Confirm and finalize a previously previewed cancellation. This endpoint completes the cancellation process initiated by calling Cancel Booking with \`preview: true\`. You must provide the \`cancellation\_id\` returned from the preview request. The cancellation will be processed and any applicable refunds will be issued.

```json
{"openapi":"3.0.0","info":{"title":"Offers API","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n* **Example:** `X-Api-Key: YOUR_API_KEY_HERE`\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n* **Example:** `Date: Sun, 09 Nov 2025 04:04:00 GMT`\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** The cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\n**Signature Generation Logic:**\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/confirm_cancellation/{cancellation_id}/":{"post":{"summary":"Cancel Booking - confirm","description":"Confirm and finalize a previously previewed cancellation. This endpoint completes the cancellation process initiated by calling Cancel Booking with `preview: true`. You must provide the `cancellation_id` returned from the preview request. The cancellation will be processed and any applicable refunds will be issued.","tags":["Cancel Booking"],"responses":{"200":{"description":"OK","headers":{"Date":{"schema":{"type":"string"}},"Transfer-Encoding":{"schema":{"type":"string"}},"Connection":{"schema":{"type":"string"}},"CF-Ray":{"schema":{"type":"integer"}},"CF-Cache-Status":{"schema":{"type":"string"}},"Allow":{"schema":{"type":"string"}},"Server":{"schema":{"type":"string"}},"Strict-Transport-Security":{"schema":{"type":"string"}},"content-security-policy":{"schema":{"type":"string"}},"cross-origin-opener-policy":{"schema":{"type":"string"}},"referrer-policy":{"schema":{"type":"string"}},"Vary":{"schema":{"type":"string"}},"Content-Encoding":{"schema":{"type":"string"}}}},"403":{"description":"Forbidden","headers":{"Date":{"schema":{"deprecated":false}},"Transfer-Encoding":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}},"Content-Encoding":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","headers":{"Date":{"schema":{"deprecated":false}},"Transfer-Encoding":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}},"Content-Encoding":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","headers":{"Date":{"schema":{"deprecated":false}},"Content-Length":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"array","items":{"type":"string"}}}}}}}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"reason_for_cancellation":{"type":"string"}}}}}}}}}}
```


# Responses

Offers API uses conventional HTTP response codes to indicate the success or failure of API requests. Error codes ranging from 200 to 299 indicate successful operations. Error code 308 indicates that the requested resource has been permanently moved to a different URL. Error codes ranging from 400 to 499 represent various error codes. Errors that can be resolved programmatically will result in an error code that briefly explains the error type and the reason for failure. 5xx codes indicate an unexpected error within the Offers API application. In the unlikely event of a 5xx error, our engineering team will automatically receive a notification and will fix the issue as fast as possible.

| Status                             | Description                                                                                       |
| ---------------------------------- | ------------------------------------------------------------------------------------------------- |
| 200 - OK                           | Everything worked as expected                                                                     |
| 201 - Created                      | The request has been fulfilled and has resulted in one or more new resources being created        |
| 308 - Permanent Redirect           | The requested resource has been permanently moved to a different URL                              |
| 400 - Bad Request                  | The request was not accepted, often due to the wrong format of the request                        |
| 401 - Unauthorized                 | No valid API key was provided                                                                     |
| 404 - Not Found                    | The requested resource doesn't exist                                                              |
| 409 - Conflict                     | The request conflicts with another request, perhaps due to the usage of the same idempotency key  |
| 422 - Unprocessable Entity         | Validation failed or logical error                                                                |
| 429 - Too Many Requests            | Too many requests hit the API too quickly. We recommend an exponential back-off of your requests. |
| 500, 502, 503, 504 - Server Errors | Something went wrong on Offers API side                                                           |

### Error response bodies

The structure of an error body differs between endpoints and between failure modes, so parsing them generically requires defensive handling.

The Create Offer, Confirm Offer and Opt-out Offer endpoints support an opt-in header, `X-API-Error-Version: v2`, that returns every error response in a single consistent shape with a fixed set of top-level fields, including a machine-readable `code`, an `error_id` for support requests, and an `errors` array of per-product and per-quote detail. All fields are always present, so one error handler can parse every error response from those endpoints.

We recommend all new integrations send this header. See [Error Versioning](/offers/api/responses/error-versioning) for the full shape, the error code list and examples.


# Offer Status

An Offer and individual Products within an Offer can transition between several different statuses. Below is a state diagram of these transitions and their conditions.

<figure><img src="https://3062128269-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMuGidY91cJqNK5u33H8e%2Fuploads%2FceS2LE2CyyDkoRKKm99u%2Fimage.png?alt=media&amp;token=c5d7c830-e1f1-4cfb-8d92-9016afa775f1" alt=""><figcaption></figcaption></figure>

\
The Offer API operates with a set number of states that an Offer can rest in.\
\
**RECEIVED**: The initial creation state for an Offer. This is not a live policy and requires confirmation to proceed.\
\
**CONFIRMED**: A successful and active Booking (or confirmed Offer). This is a live, paid-for policy that may be active or expired. This may be cancellable or modifiable, and can be claimed against.

\
**CANCELLED**: A Booking or confirmed Offer that has been formally cancelled. It cannot be claimed against, or modified.\
\
**DELETED**: A rare, final state indicating the Offer or Booking record has been removed (e.g., purged for data retention).

\
**PENDING\_PAYMENT**: An Offer that has been accepted but requires final payment confirmation before transitioning to CONFIRMED. Only relevant for Offers that are confirmed using the `require_payment_confirmation` flag during a `confirm offer` request (usually followed by the `confirm booking` request) end state if confirmed will be CONFIRMED.\
\
**FAILED**: An Offer or Booking attempt that could not be completed due to a payment failure, system refusal, or technical error.\
\
**RENEWED**: A state used to depict a prior Booking that has been successfully renewed (e.g., after an annual renewal payment is confirmed).

```
OfferStatus:
    RECEIVED
    CONFIRMED
    CANCELLED
    DELETED
    PENDING_PAYMENT
    FAILED
    RENEWED 
```


# Error Management

General error management

### **Error Handling**

Offers uses conventional HTTP response codes to indicate the success or failure of an API request. Error codes ranging from 400 to 499 represent various error codes.

Errors that can be resolved programmatically will result in an error code that briefly explains the type of error or reason for the error.

In the unlikely event of a 5xx error, our engineering team will automatically receive a report and will fix any issue as fast as possible.

Note the below workflow for error handling:

<figure><picture><source srcset="/files/1wNm40Dpv9CKgUsDKfRI" media="(prefers-color-scheme: dark)"><img src="https://3062128269-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMuGidY91cJqNK5u33H8e%2Fuploads%2Fgit-blob-254e193ea97bd7ad3b298f2c13962a1ea04764d7%2FCopy%20of%20%5BNEW%5D%20Gitbook%20Flows.png?alt=media" alt=""></picture><figcaption></figcaption></figure>

We strongly recommend the following mechanisms for error handling:

#### **Retry Mechanism**

The request/response goes through various hops between partners and Cover Genius. These may include various networks and servers.

If at any point, the request fails due to network issue for example (e.g. a timeout), partners should try to resend the request at least twice to rule out any intermittent issue.

For asynchronous request situations, retries may be spaced comfortably, ideally 2-5 mins apart before sending out an alert for someone to manually check any issues.

We recommend at least 5 second timeout for confirming Offers, and setting it to 10 seconds or more should be more reliable and not be a problem for customers.

If requests fail, they should be retried with exponential backoff. In case the Offer confirmation failed 5 times, partners should flag and raise with Cover Genius. Similar logic should apply for cancellations.

#### **Alert Mechanism**

If, after the second try partners fail to receive the expected response (received, confirmed etc), it is recommended to establish alert mechanisms that notify responsible teams of the failure.

#### **Logging Mechanism**

Irrespective of a correct or a failed request/response, it is highly recommended for partners to log requests and responses all centrally. These assist investigation where besides direct issue itself, patterns may become visible, helping to identify overarching issues.


# Error Types

Error type and management

### API Errors

(Stated in headers): see the status code reference, global environment based\
\
Basic approach:\
“Does the API respond with a 20X response?”\
\
Useful for:\
\- General API function\
\- Confirmation of actions\
\- Basic operation validation

Example of use:\
\- Was a Create Offer request received?\
\- Was a Confirm Offer request received?\
\- Was there any full failures

### Logic Errors

Logic errors are present in API response body, are case by case, and policy based.\
They are often the indicator of a problem with the Offer creation or confirmation, and may represent a partial booking failure. Always look for the `errors` array.\
\
Basic approach:\
“Does the request contain any content concerns, or logical failures?”\
\
Useful for:\
\- Calculation issues\
\- Confirmation over various state actions\
(does a booking match an Offer expectation)\
\- In depth rule validation\
\
Example of use:\
\- Was a create offer request valid?\
\- Was a confirm offer request complete, were there any partial failures?

\
Logic error management:

1. All products in a create Offer or Confirm Offer request should be confirmed individually (not just package, or package status).\
   An erroneous Offer will return a "null" response for the object.\
   \
   Example:\
   Create Offer request

   **Ensure there is no error field in response (flag if there is, may be a miss-offer or partial offer)**\
   **Other Offer stage errors include "no policy available for these parameters" etc.**<br>
2. Confirm offer request items should be confirmed similarly\
   Example, basic elements present, first quote id sent also present
3. Confirm Offer request shouldn't have errors, mismatched values, or null quote responses

In the below example, the Offer confirmation failed due to a validation error.

Understanding and monitoring for these response variations and errors will greatly reduce misaligned bookings and improve customer satisfaction.

### Consistent error bodies with `X-API-Error-Version`

The response variations described above are the reason the Offers API supports an opt-in error shape. Sending the header `X-API-Error-Version: v2` on Create Offer, Confirm Offer or Opt-out Offer returns every error response from those endpoints in one consistent structure, so both API errors and logic errors can be handled by a single code path instead of being matched case by case.

The `v2` body always contains the same top-level fields: `type`, `message`, `code`, `error_id`, `errors` and `metadata` and `errors` is always an array whose entries identify the failing product and quote:

```json
{
  "product_config_id": "8f2b41c9-6d7e-4a15-b3c8-1e9f0a2d5b76",
  "quote_id": "3c7d9e21-5b48-4f0a-8d16-2a9c4e7b0f53",
  "code": "booking_quote_failed",
  "details": ["Policyholder country is not eligible for this product"]
}
```

This makes the per-product checks described above straightforward: rather than inspecting each product object for a `null` quote or an ad-hoc error field, read `errors[]` and match on `product_config_id` and `quote_id`.

The header is opt-in and affects the shape of error bodies only. An omitted or unrecognised value never fails the request.

See Error Versioning for the full field reference, the error code list, worked examples and known limitations.


# Error Versioning

Opting into the versioned error response shape

## Error Versioning

Error responses from the Offers API can be returned in a consistent, versioned shape by sending the `X-API-Error-Version` header. This is opt-in: the header changes the shape of error response bodies only and has no effect on successful responses or on any business logic.

Without the header, the structure of an error body varies between endpoints and between failure modes, which makes error handling difficult to implement generically. Sending `X-API-Error-Version: v2` guarantees a single shape with a fixed set of top-level fields on every error response, so a single error handler can parse all of them.

We recommend all new integrations send `X-API-Error-Version: v2`.

#### Supported endpoints

| Endpoint          | Method and path                                          |
| ----------------- | -------------------------------------------------------- |
| **Create Offer**  | `POST /partners/{partner_id}/offers/`                    |
| **Confirm Offer** | `POST /partners/{partner_id}/offers/{offer_id}/confirm/` |
| **Opt-out Offer** | `POST /partners/{partner_id}/offers/{offer_id}/opt_out/` |

On these endpoints the header applies to **every** error response, that is, every response with a status code of 400 or above.

#### The `v2` error shape

Every `v2` error response body contains the following top-level fields.

| Field      | Type   | Description                                                                                                       |
| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------- |
| `type`     | string | Broad error category: `validation_error`, `invalid_request_error`, `auth_error` or `api_error`.                   |
| `message`  | string | Human-readable summary of the failure. Intended for logs and diagnostics, not for display to customers.           |
| `code`     | string | Machine-readable code for the failure as a whole. See Error codes.                                                |
| `error_id` | string | Identifier for this failure, for use when raising a support request.                                              |
| `errors`   | array  | Per-item detail of what failed. An empty array when the failure is not attributable to specific items. See below. |
| `metadata` | object | Supplementary context. An empty object when there is none.                                                        |

**The `errors` array**

Each entry in `errors` is an object with these four fields:

| Field               | Type           | Description                                                                                                                                |
| ------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `product_config_id` | string \| null | The product configuration the failed item belongs to. `null` when the failure is not specific to one product.                              |
| `quote_id`          | string \| null | The quote the failed item relates to. `null` when no quote had been created at the point of failure, or when the failure is request-level. |
| `code`              | string         | Machine-readable code for this specific item. See Error codes.                                                                             |
| `details`           | array          | Array of strings describing this item's failure.                                                                                           |

#### Examples

Create Offer, where every quote failed to price (`422 Unprocessable Entity`):

```json
{
  "type": "validation_error",
  "message": "Offer could not be created due to quote generation errors",
  "code": "offer_quote_generation_failed",
  "error_id": "b9c1f0d2-3a4e-4c6b-9f21-7d8e5a0b1c34",
  "errors": [
    {
      "product_config_id": "8f2b41c9-6d7e-4a15-b3c8-1e9f0a2d5b76",
      "quote_id": "3c7d9e21-5b48-4f0a-8d16-2a9c4e7b0f53",
      "code": "offer_quote_pricing_error",
      "details": ["No rate available for the supplied parameters"]
    },
    {
      "product_config_id": "a41e9c72-8b05-4d63-9f18-6c2a7e0d4b95",
      "quote_id": null,
      "code": "quote_creation_failure",
      "details": ["Upstream pricing service unavailable"]
    }
  ],
  "metadata": {
    "selected_offer_id": "5d8a2f61-9c04-4e73-b1a8-3f6e7c0d9b42"
  }
}
```

Confirm Offer, where none of the requested quotes could be booked (`422 Unprocessable Entity`). Note that `error_id` is the Offer ID:

```json
{
  "type": "validation_error",
  "message": "None of the requested quotes were successful.",
  "code": "booking_quotes_unsuccessful",
  "error_id": "5d8a2f61-9c04-4e73-b1a8-3f6e7c0d9b42",
  "errors": [
    {
      "product_config_id": "8f2b41c9-6d7e-4a15-b3c8-1e9f0a2d5b76",
      "quote_id": "3c7d9e21-5b48-4f0a-8d16-2a9c4e7b0f53",
      "code": "booking_quote_failed",
      "details": ["Policyholder country is not eligible for this product"]
    }
  ],
  "metadata": {}
}
```

A request-level validation failure, where the failure cannot be attributed to a product or quote. Note that `message` here is generic and that the field-keyed detail is preserved under `metadata.field_errors`:

```json
{
  "type": "validation_error",
  "message": "An API error occurred.",
  "code": "offer_validation_request_invalid",
  "error_id": "7e4c1a80-2f39-4b6d-95e1-8a0c3d7b6f14",
  "errors": [
    {
      "product_config_id": null,
      "quote_id": null,
      "code": "offer_validation_request_invalid",
      "details": ["Quote does not exist"]
    }
  ],
  "metadata": {
    "field_errors": {
      "quotes": ["Quote does not exist"]
    }
  }
}
```

#### Error codes

Codes appear in the top-level `code` and in each `errors[].code`. Treat the list as open-ended: new codes may be added, so always handle an unrecognised code by falling back to the HTTP status.

| Code                                       | Typical status | Meaning                                                                           |
| ------------------------------------------ | -------------- | --------------------------------------------------------------------------------- |
| `offer_partner_not_found`                  | 404            | The partner in the request path does not exist.                                   |
| `offer_not_found_no_offers`                | 404            | No Offers are configured for this partner.                                        |
| `offer_no_products`                        | 404            | The selected Offer has no products available.                                     |
| `offer_not_found_no_match_context`         | 422            | No Offer matches the supplied request context.                                    |
| `offer_quote_generation_failed`            | 422            | Package level: no quote in the Offer could be generated.                          |
| `offer_quote_pricing_error`                | 422            | Item level: a quote was created but could not be priced.                          |
| `quote_creation_failure`                   | 422            | Item level: the quote could not be created at all.                                |
| `offer_quote_multiple_per_product`         | 422            | More than one quote was produced for a product that permits one.                  |
| `offer_validation_request_invalid`         | 422            | The request body failed validation.                                               |
| `offer_validation_schema_required`         | 422            | No schema was supplied and the partner has no default schema.                     |
| `offer_validation_schema_invalid`          | 422            | The supplied schema identifier is not valid for this partner.                     |
| `offer_schema_validation_failed`           | 422            | The request did not validate against the partner's Offer Schema.                  |
| `offer_enrichment_failed`                  | 422            | Enrichment of the request data failed.                                            |
| `expression_evaluation_failed`             | 422            | An Offer configuration expression could not be evaluated.                         |
| `too_many_instances`                       | 422            | The resolved quantity exceeds the permitted number of instances.                  |
| `quantity_expression_invalid_output`       | 422            | A quantity expression returned an unusable value.                                 |
| `too_many_variants`                        | 422            | The resolved variants exceed the permitted number.                                |
| `variant_expression_invalid_output`        | 422            | A variant expression returned an unusable value.                                  |
| `variant_config_expression_failed`         | 422            | A variant configuration expression could not be evaluated.                        |
| `variant_config_expression_invalid_output` | 422            | A variant configuration expression returned an unusable value.                    |
| `booking_quotes_unsuccessful`              | 422            | Package level: none of the requested quotes could be booked.                      |
| `booking_quote_failed`                     | 422            | Item level: the per-quote reason inside a `booking_quotes_unsuccessful` response. |
| `booking_quote_not_found`                  | 404            | A quote ID in the confirm request does not belong to this Offer.                  |
| `offer_request_failed`                     | any            | Generic fallback where no more specific code applies.                             |
| `offer_unexpected_error`                   | 500            | Unexpected server-side failure.                                                   |

#### Limitations

Two cases are not covered by the versioned shape and should be handled defensively:

1. **Unhandled server errors.** An unexpected failure that produces no structured API response rendered as a generic `500`  is returned as-is and will not carry the `v2` fields.
2. **Partial successes.** A response that carries a success payload alongside a non-2xx status is left unchanged, because its body is not an error body. Continue to inspect the `errors` field of the payload in these cases, as described in Error Types.


# Authentication

All HTTP requests sent to the Offer API must be signed with a special signature. The signature must be provided in the `Authorization` header. In order to generate signature partners need to have a valid API key and a secret signing key. Please note, a new signature must be generated for every request.

## Generate HMAC Signature

Offers API uses [HMAC-based](https://en.wikipedia.org/wiki/HMAC) authentication.

To authenticate API request the client application needs to perform the following steps:

1. Prepare request data for signing.
2. Sign data using one of the HMAC algorithms such as **`SHA1`** (dprecated), **`SHA256`** , **`SHA384`** or **`SHA512`** algorithms.
3. Encode the signature using **`Base64`** encoding.
4. URL encode the result of the previous step.
5. Prepare **`Authorization`** header containing the Base64 and URL encoded signature string, API Key and the algorithm used, for example **`hmac-sha512`**.

{% hint style="warning" %}
Please note the date string to be signed should be in [RFC 822 Section 5.1 format](https://datatracker.ietf.org/doc/html/rfc822#section-5.1) e.g. Thu, 04 Nov 2021 18:07:11 GMT

The date must be padded e.g. 04.
{% endhint %}

{% hint style="warning" %}
Please note the signature must be a base64 encoded strictly matching RFC 4648. Some programming languages will URL safe base64 encode which will replace the "+" and "/" characters with "-" and "\_" respectively. This will cause a "Signature string does not match!" error.
{% endhint %}

Below you can see an example code implementing these steps, this code can be used as a pre-request script in Postman.

{% tabs %}
{% tab title="Python" %}
{% code expandable="true" %}

```python
import requests
# Module defined below
from auth import SignatureAuth

# Prodivded by the assigned Client Solutions Engineer (CSE)
API_KEY = ""
API_SECRET = ""

def _apply_auth(request):
    request.headers.update(
        SignatureAuth(API_KEY,
                      API_SECRET).sign()
    )
    return request

session = requests.Session()
request = requests.Request('POST', url, json=payload, headers=headers)
response = session.send(_apply_auth(request.prepare()))

print(response.status_code)
    
# auth.py
"""
Authentication related module.
"""
from __future__ import unicode_literals
​
from base64 import b64encode
from hashlib import sha512
import hmac
from urllib.parse import quote
​
from datetime import datetime
from time import mktime
from wsgiref.handlers import format_date_time
​
def http_date():
    now = datetime.utcnow()
    return format_date_time(mktime(now.timetuple()))
​
​
class SignatureAuth:
    """Class for basic authentication support."""
​
    def __init__(self, key, secret):
        self._key = key
        self._secret = secret
        self._headers = None
​
    def create_signature(self, date):
        raw = 'date: {date}'.format(date=date)
        hashed = hmac.new(self._secret.encode('utf-8'), raw.encode('utf-8'), sha512).digest()
        return quote(b64encode(hashed), safe='')
​
    def build_signature(self, signature, key):
        template = ('Signature keyId="%(key)s",algorithm="hmac-sha512",'
                    'signature="%(signature)s"')
​
        return template % {
            'key': key,
            'signature': signature
        }
​
    def sign(self):
        date = http_date()
        auth = self.build_signature(signature=self.create_signature(date), key=self._key)
​
        return {
            'Date': date,
            'Authorization': auth,
            'X-Api-Key': self._key,
        }

```

{% endcode %}
{% endtab %}

{% tab title="JavaScript (Postman)" %}

```javascript
var apiKey = environment.api_key,
    apiSecret = environment.api_secret,
    date = (new Date()).toUTCString(),
    sigContent = 'date: ' + date,
    sig = CryptoJS.HmacSHA512(sigContent, apiSecret).toString(CryptoJS.enc.Base64),
    authHeader = 'Signature keyId="' + apiKey + '",algorithm="hmac-sha512",signature="' + encodeURIComponent(sig) + '"';

pm.environment.set("authHeader", authHeader);  // Authorization header
pm.environment.set("date", date);  // Date header
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$apiKey = env('API_KEY'); // or however you access your environment variables
$apiSecret = env('API_SECRET');

$date = gmdate('D, d M Y H:i:s') . ' GMT';

$sigContent = 'date: ' . $date;

$sig = base64_encode(hash_hmac('sha512', $sigContent, $apiSecret, true));

$authHeader = sprintf(
    'Signature keyId="%s",algorithm="hmac-sha512",signature="%s"',
    $apiKey,
    urlencode($sig)
);

// Usage in HTTP headers:
// 'Authorization' => $authHeader
// 'Date' => $date
```

{% endtab %}

{% tab title="C#" %}

```csharp
using System;
using System.Web;
using System.Text;
using System.Security.Cryptography;

class Program {
    static void Main(string[] args) {
        String rfc1123DateString = DateTime.Now.ToString("R");
        String apiKey = "";
        String apiSecret = "";
	String signatureContentString = "date: " + rfc1123DateString;
	HMACSHA512 hmacsha512 = new HMACSHA512(Encoding.UTF8.GetBytes(apiSecret));
	byte[] bytes = hmacsha512.ComputeHash(Encoding.UTF8.GetBytes(signatureContentString));
	String signature = Convert.ToBase64String(bytes);
	String authHeader = "Signature keyId=\""+apiKey+"\",algorithm=\"hmac-sha512\",signature=\""+HttpUtility.UrlEncode(signatureString)+"\"";
	return authHeader;
    }
}
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
require "base64"
require "time"
require 'openssl'
require 'cgi/util'

def auth_header
  rfc1123_date_string = Time.now.httpdate
  api_key = ""
  api_secret = ""
  sig_content = "date: #{rfc1123_date_string}"
  sig = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha512'), api_secret, sig_content)
  encoded_sig = Base64.strict_encode64(sig)
  "Signature keyId=\"#{api_key}\",algorithm=\"hmac-sha512\",signature=\"#{CGI.escape(encoded_sig)}\""
end
```

{% endtab %}
{% endtabs %}

## Testing API Keys

To streamline your integration process, the XCover API supports Test Keys that operate directly within the production environment. This "Single Environment" approach ensures that your integration behaves exactly the same way during testing as it will in live production, without the need to manage separate staging endpoints.

#### How it Works

When you use a Test API Key, the system automatically flags the transaction. This allows you to validate your integration end-to-end—from generating offers to binding policies—without triggering real financial transactions.

* Endpoint: Use the standard production URL.
* Identification: Transactions made with these keys are marked as `test` in our backend and your partner dashboard.
* Security: Even when using test keys, all requests must be signed using the same HMAC signature process described in the [Authentication](/offers/api/authentication) section.


# Idempotency Keys

Idempotency keys are unique identifiers that API clients can provide in HTTP request headers to ensure that a specific API request is not processed multiple times even if it is accidentally sent more than once. This mechanism helps maintain data consistency and prevent undesired side effects like duplicated transactions or repeating customer notifications.

Idempotency keys can be passed to most of the non-idempotent endpoints through a custom header `x-idempotency-key`. The value of this header should be a unique operation identifier. If the request with the same idempotency key and body has already been processed in the past the response body will be stored in a temporary storage for 48 hours and returned to all subsequent requests with `409 Conflict` status code. The 409 responses can be handled by the API client as if it would be a successful response. The use of a separate response code can help API consumers identify the root cause for duplicated requests and fix the issue.

In some cases when two duplicated requests are sent within a short interval of time it is possible that a `423 Locked` response code will be returned. The 423 response indicates that the API started processing the previous request, but the response was not generated yet. The API client should retry the request after a reasonable amount of time.

Find below an example of code that illustrates implementing the idempotency keys mechanism using Python's `requests` library.

{% tabs %}
{% tab title="Python" %}
{% code overflow="wrap" %}

```python
import json
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

from logging import getLogger

logger = getLogger("xcover")

url = "https://api.xcover.com/x/partners/YOUR_PARTNER_ID/instant_booking/"

payload = json.dumps({
    # ... generated payload
})

headers = {
    # ... other required headers
    'x-idempotency-key': 'db55f986-c30c-4883-ac4f-0d2cfada6d3f'
}
retry_strategy = Retry(total=3, status_forcelist=[423, 429, 502, 503, 504], backoff_factor=5)

with requests.Session() as session:
    session.mount(url, HTTPAdapter(max_retries=retry_strategy))
    response = session.post(url, headers=headers, data=payload)
    if response.status_code in (200, 409):
        if response.status_code == 409:
            # this request is a duplicate, let's log it as a warning
            logger.warning("duplicated xcover request")

        # successfull response
        print(response.json())
    else:
        # error response
        print(response.status_code)
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript" %}

```javascript
const axios = require('axios');
const axiosRetry = require('axios-retry');

const url = "https://api.xcover.com/x/partners/YOUR_PARTNER_ID/offers/";

const payload = {
  // ... generated payload
};

const headers = {
  'Content-Type': 'application/json',
  'x-idempotency-key': 'db55f986-c30c-4883-ac4f-0d2cfada6d3f'
};

const client = axios.create();
axiosRetry(client, {
  retries: 3,
  retryCondition: (error) => 
    error.response && [423, 429, 502, 503, 504].includes(error.response.status)
});

client.post(url, payload, { headers })
  .then(response => {
    if (response.status === 409) {
      console.warn("duplicated xcover request");
    }
    console.log(response.data);
  })
  .catch(error => {
    console.log(error.response?.status || error.message);
  });
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$url = "https://api.xcover.com/x/partners/YOUR_PARTNER_ID/offers/";

$payload = json_encode([
    // ... generated payload
]);

$headers = [
    'Content-Type: application/json',
    'x-idempotency-key: db55f986-c30c-4883-ac4f-0d2cfada6d3f'
];

$retries = 0;
$maxRetries = 3;
$retryStatuses = [423, 429, 502, 503, 504];

do {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
    $response = curl_exec($ch);
    $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if (in_array($statusCode, [200, 409])) {
        if ($statusCode === 409) {
            error_log("duplicated offer request");
        }
        echo $response;
        break;
    }
    
    if (in_array($statusCode, $retryStatuses) && $retries < $maxRetries) {
        $retries++;
        sleep(5 * $retries);
    } else {
        echo $statusCode;
        break;
    }
} while ($retries <= $maxRetries);
```

{% endtab %}
{% endtabs %}


# Rate Limits

By default, the following base API rate limits apply for all partner API keys:

* Create Offer and Confirm Offer endpoints: 50 req/sec
* All other endpoints: 20 req/sec (shared across all endpoints)
* All testing API keys: 2 req/sec

Please, reach out to the Account Manager or Client Solution Engineer if you want to increase these limits.


# Data Formats

The API adheres to the REST principles and provides developer-friendly, predictable and logically organised resource-oriented structure.

### Dates

Offers API accepts `date` and `date-time` parameters in the format as defined by [RFC 3339, section 5.6](https://tools.ietf.org/html/rfc3339#section-5.6), for example `2018-01-01`, `2018-01-01T17:00:01Z`, `2018-01-01T17:00:00+01:00`, `2018-01-01T17:00:01.04399-04:00`. We encourage partners to keep the original timezone in contrast to sending all dates in UTC. Having original timezone can help Offers API to deal with potential issues with DST changes.

### Country Codes

All country codes provided in API requests must be compliant with [ISO 3166-1 Alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) standard.

### Currency

Currency must be compliant with 3-letter codes as defined by [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217).

### Languages

Language input must be compliant with 2-letter codes as defined by [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) standard.\
Variations of base languages use a variant indicator, for example: "en-us" to specify English, United States variant (where applicable).

### Telephone (Mobile Phone) numbers

Phone numbers provided (at offer confirmation stage) should predominantly be of personal mobile/cell type, with the format of `+[country_code]` plus a phone number, e.g., [`+61412345678`](tel:+61412345678)\
\
In some use cases, Offers API will validate the phone number format (to allow sending SMS policy and claim communications to the customer), and return an error if an invalid format is provided.


# Webhooks

Webhooks allow partners to be notified when important events happen in Offers.

When one of those events are triggered, we will send an HTTP POST payload to the webhook's configured URL. Webhooks can be used to send a customer notification, initiate a policy renewal process or perform any custom logic.

To establish webhooks, partners can provide to their CSE:

1\. Listener URL\
2\. Authentication Key & Secret\
3\. Support URL\
4\. Requested events (CSE may propose or suggest these as part of solutioning).

We will provide an HTTP signature generated on our end in `Authorization` header and the api key itself in `X-Api-Key` header. We will base the signature on your provided key pair. You can use the same `HMAC` based algorithm for signature verification, if required. Please use the information from the signature header to check which hash algorithm is used in order to validate the request. Currently, webhook requests are signed using `sha256` algorithm.

In case of multiple failures with the webhook notification, where the partner supplied endpoint does not respond with a 200 OK, we will try the webhook for up to 3 times.

### Authentication

Your webhook API endpoint should implement HMAC authentication to verify that the API request was sent and signed by Offers.

{% tabs %}
{% tab title="Python" %}
{% code expandable="true" %}

```python
import base64
import hashlib
import hmac
from urllib.parse import unquote

# You will provide your assigned Client Solution Engineer with an API key and secret
# they will configure the Offers API
api_key = "--your-api-key--"
secret = "--your-secret--"
# This is just an example, you would obtain this from your server library
# E.g. a Flask server
# from flask import Flask, request
# app = Flask(__name__)
# @app.post('/my-offers-api-webhook')
# def offers_api_webhook():
#.   request_headers = request.headers 
#    return do_everything_below()

request_headers = {
    'X-Api-Key': '--api-key--',
    'Authorization': '--signature--',
    'Date': 'Thu, 27 Feb 2025 05:01:47 GMT'
}

# Extract signature from the request headers
auth_header = request_headers.get('Authorization', '')
if not auth_header.startswith('Signature '):
    raise ValueError("Invalid Authorization header")

auth_parts = dict(
    part.split('=', 1) for part in 
    auth_header.replace('Signature ', '').split(',')
)
received_signature = unquote(auth_parts.get('signature', '').strip('"'))

# Compute the expected signature
date_header = request_headers.get('Date')
if not date_header:
    raise ValueError("Missing Date header")

raw = f"date: {date_header}"

expected_hash = hmac.new(
    secret.encode("utf-8"),
    raw.encode("utf-8"),
    hashlib.sha256
).digest()

expected_signature = base64.b64encode(expected_hash).decode('utf-8')

is_valid = hmac.compare_digest(expected_signature, received_signature)
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript" %}
{% code overflow="wrap" expandable="true" %}

```javascript
const crypto = require('crypto');

// You will provide your assigned Client Solution Engineer with an API key and secret
// they will configure the Offers API
const apiKey = "--your-api-key--";
const secret = "--your-secret--";

// This is just an example, you would obtain this from your server library
// E.g. an Express server
// const express = require('express');
// const app = express();
// app.post('/my-offers-api-webhook', (req, res) => {
//   const requestHeaders = req.headers;
//   return doEverythingBelow();
// });

const requestHeaders = {
  'X-Api-Key': '--api-key--',
  'Authorization': '--signature--',
  'Date': 'Thu, 27 Feb 2025 05:01:47 GMT'
};

// Extract signature from the request headers
const authHeader = requestHeaders['Authorization'] || '';
if (!authHeader.startsWith('Signature ')) {
  throw new Error("Invalid Authorization header");
}

// Parse the Authorization header
const authString = authHeader.replace('Signature ', '');
const authParts = {};
authString.split(',').forEach(part => {
  const [key, value] = part.split('=', 2);
  authParts[key.trim()] = value;
});

const receivedSignature = decodeURIComponent(
  (authParts['signature'] || '').replace(/^"|"$/g, '')
);

// Compute the expected signature
const dateHeader = requestHeaders['Date'];
if (!dateHeader) {
  throw new Error("Missing Date header");
}

const raw = `date: ${dateHeader}`;

// Create HMAC-SHA256 hash
const expectedHash = crypto
  .createHmac('sha256', secret)
  .update(raw, 'utf8')
  .digest();

const expectedSignature = expectedHash.toString('base64');

// Timing-safe comparison
const isValid = crypto.timingSafeEqual(
  Buffer.from(expectedSignature),
  Buffer.from(receivedSignature)
);

console.log('Is valid:', isValid);
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}

```php
<?php

// You will provide your assigned Client Solution Engineer with an API key and secret
// they will configure the Offers API
$apiKey = "--your-api-key--";
$secret = "--your-secret--";

// This is just an example, you would obtain this from your server library
// E.g. a Laravel controller
// public function offersApiWebhook(Request $request)
// {
//     $requestHeaders = $request->headers->all();
//     return $this->doEverythingBelow();
// }

$requestHeaders = [
    'X-Api-Key' => '--api-key--',
    'Authorization' => '--signature--',
    'Date' => 'Thu, 27 Feb 2025 05:01:47 GMT'
];

// Extract signature from the request headers
$authHeader = $requestHeaders['Authorization'] ?? '';
if (!str_starts_with($authHeader, 'Signature ')) {
    throw new InvalidArgumentException("Invalid Authorization header");
}

// Parse the Authorization header
$authString = str_replace('Signature ', '', $authHeader);
$authParts = [];
foreach (explode(',', $authString) as $part) {
    [$key, $value] = explode('=', $part, 2);
    $authParts[trim($key)] = $value;
}

$receivedSignature = urldecode(
    trim($authParts['signature'] ?? '', '"')
);

// Compute the expected signature
$dateHeader = $requestHeaders['Date'] ?? null;
if (!$dateHeader) {
    throw new InvalidArgumentException("Missing Date header");
}

$raw = "date: {$dateHeader}";

// Create HMAC-SHA256 hash
$expectedHash = hash_hmac('sha256', $raw, $secret, true);
$expectedSignature = base64_encode($expectedHash);

// Timing-safe comparison
$isValid = hash_equals($expectedSignature, $receivedSignature);

var_dump($isValid);
```

{% endtab %}
{% endtabs %}

### BOOKING\_CREATED

*Description*: The payload is sent in a webhook to the Partner whenever the Offer is Confirmed through an API Request.

```json
{
  "event": "BOOKING_CREATED",
  "payload": {
    "id": "8AMKH-KQ8NR-INS",
    "status": "CONFIRMED",
    "currency": "USD",
    "total_price": 68.71,
    "total_price_formatted": "US$68.71",
    "partner_transaction_id": null,
    "quotes": [
      {
        "id": "8bfb48ab-6947-4f34-a932-c4dcede958f6",
        "policy_start_date": "2023-10-08T00:00:49.751227+00:00",
        "policy_end_date": "2023-10-13T00:00:49.751247+00:00",
        "status": "CONFIRMED",
        "price": 68.71,
        "price_formatted": "US$68.71",
        "policy": {
          "policy_type": "travel_medical",
          "policy_name": "PolicyVersion 0",
          "policy_version": "e94df011-ee0b-44a1-bdb1-1dd05cb67fc7"
        },
        "duration": "5 00:00:00.000020",
        "total_renewed_times": 0
      }
    ]
  }
}
```

### BOOKING\_UPDATED

*Description*: The payload is sent to the Partner whenever the Confirmed Offer is Updated through an API Request

```json
{
  "event": "BOOKING_UPDATED",
  "payload": {
    "id": "TKBZN-XGPAX-INS",
    "status": "CONFIRMED",
    "currency": "USD",
    "total_price": 68.71,
    "total_price_formatted": "US$68.71",
    "partner_transaction_id": null,
    "quotes": [
      {
        "id": "4d3b7919-9372-4c54-bdaf-05f770ffc2fc",
        "policy_start_date": "2023-10-08T01:09:19.649112+00:00",
        "policy_end_date": "2023-10-13T01:09:19.649133+00:00",
        "status": "CONFIRMED",
        "price": 68.71,
        "price_formatted": "US$68.71",
        "policy": {
          "policy_type": "travel_medical",
          "policy_name": "PolicyVersion 0",
          "policy_version": "1637bc92-0299-4624-8f38-c9b9e15d379e"
        },
        "duration": "5 00:00:00.000021",
        "total_renewed_times": 0
      }
    ]
  }
}  
```

### BOOKING\_CANCELLED

*Description*: The payload is sent to the Partner whenever the Confirmed Offer is cancelled through an API Request

```json
{
  "event": "BOOKING_CANCELLED",
  "payload": {
    "id": "HMZZ8-3YYHZ-INS",
    "status": "CANCELLED",
    "currency": "USD",
    "total_price": 0.0,
    "total_price_formatted": "US$0.00",
    "partner_transaction_id": null,
    "quotes": [
      {
        "id": "e0925616-824d-4216-bd18-450fb669c017",
        "policy_start_date": "2023-10-08T01:19:41.766661+00:00",
        "policy_end_date": "2023-10-13T01:19:41.766719+00:00",
        "status": "CANCELLED",
        "price": 68.71,
        "price_formatted": "US$68.71",
        "policy": {
          "policy_type": "travel_medical",
          "policy_name": "PolicyVersion 0",
          "policy_version": "dd5aef78-5ce5-4f19-a455-968780b89ea2"
        },
        "duration": "5 00:00:00.000058",
        "total_renewed_times": 0,
        "refund_value": 68.71
      }
    ]
  }
}
```

### RENEWAL\_CREATED

*Description*: Used to notify partner that the policy has been renewed.

*Example*:

```json
{
    "event": "RENEWAL_CREATED",
    "payload": {
        "id": "daSJp-fwdoj-REN",
        "package_id": "GKDK9-CECQU-INS",
        "quote_id": "c8ddb161-e3d9-455b-9621-96df90f17acb",
        "status": "ACTIVE",
        "start_date": "2019-02-25T13:00:00Z",
        "notification_date": "2018-11-22T00:21:41Z",
        "due_date": "2019-02-25T13:00:00Z",
        "expiry_date": "2018-11-21T22:56:01Z",
        "cancelled_on": null,
        "paid_on": "2019-02-25T13:00:00Z",
        "created_at": "2018-11-21T04:15:12.175468Z"
    }
}
```

### RENEWAL\_NOTIFICATION

*Description*: Used to notify partner about approaching renewal.

*Example*:

```json
{
    "event": "RENEWAL_NOTIFICATION",
    "payload": {
        "id": "daSJp-fwdoj-REN",
        "package_id": "GKDK9-CECQU-INS",
        "quote_id": "c8ddb161-e3d9-455b-9621-96df90f17acb",
        "status": "ACTIVE",
        "start_date": "2019-02-25T13:00:00Z",
        "notification_date": "2018-11-22T00:21:41Z",
        "due_date": "2019-02-25T13:00:00Z",
        "expiry_date": "2018-11-21T22:56:01Z",
        "cancelled_on": null,
        "paid_on": null,
        "created_at": "2018-11-21T04:15:12.175468Z"
    }
}
```

### RENEWAL\_DUE

*Description*: Sent on the renewal due date, the customer policy will be active until the end of the grace period (`expiry_date`).

*Example*:

```json
{
    "event": "RENEWAL_DUE",
    "payload": {
        "id": "daSJp-fwdoj-REN",
        "package_id": "GKDK9-CECQU-INS",
        "quote_id": "c8ddb161-e3d9-455b-9621-96df90f17acb",
        "status": "DUE",
        "start_date": "2019-02-25T13:00:00Z",
        "notification_date": "2018-11-22T00:21:41Z",
        "due_date": "2019-02-25T13:00:00Z",
        "expiry_date": "2018-11-21T22:56:01Z",
        "cancelled_on": null,
        "paid_on": null,
        "created_at": "2018-11-21T04:15:12.175468Z"
    }
}
```

### RENEWAL\_EXPIRED

*Description*: Sent on the renewal expiry date, the customer policy is no longer renewable after this event is triggered.

*Example*:

```json
{
    "event": "RENEWAL_DUE",
    "payload": {
        "id": "daSJp-fwdoj-REN",
        "package_id": "GKDK9-CECQU-INS",
        "quote_id": "c8ddb161-e3d9-455b-9621-96df90f17acb",
        "status": "DUE",
        "start_date": "2019-02-25T13:00:00Z",
        "notification_date": "2018-11-22T00:21:41Z",
        "due_date": "2019-02-25T13:00:00Z",
        "expiry_date": "2018-11-21T22:56:01Z",
        "cancelled_on": null,
        "paid_on": null,
        "created_at": "2018-11-21T04:15:12.175468Z"
    }
}
```


# Performance Benchmarks & Latency Targets

To assist with your integration planning and timeout configurations, we publish the following performance targets for the Offers API.

These metrics reflect our internal benchmarks for **server-side processing time** under standard operating conditions.

{% hint style="info" %}
Please note that these figures are intended for technical guidance only and differ from the binding Service Level Agreements (SLAs) defined in your commercial contract. For guaranteed availability and support commitments, please refer to your Account Manager or Client Solution Engineer.
{% endhint %}

| Endpoint      | P90 (Target) | P95 (Target) | P99 (Target) |
| ------------- | ------------ | ------------ | ------------ |
| Create Offer  | 150ms        | 170ms        | 600ms        |
| Confirm Offer | 500ms        | 650ms        | 1100ms       |
| Opt Out Offer | 140ms        | 160ms        | 300ms        |

{% hint style="info" %}
**Integration Recommendations:** For rate limit errors and retries, please refer to [Error Management](/offers/api/responses/error-management)
{% endhint %}


# Integration Checklist

The following checklist describes the high level tasks that need to be completed in order to completely integrate the Offer API and begin selling insurance policies.

* [ ] Choose the right workflow based on nature of business
  * [ ] [Events / Tickets](/offers/vertical-examples/events-tickets)
  * [ ] [Travel / Accommodation](/offers/vertical-examples/travel-accomodation)
  * [ ] [Parcel / Shipping](/offers/vertical-examples/parcel-shipping)
  * [ ] [Product / Retail](/offers/vertical-examples/product-retail)
* [ ] Obtain Sandbox access credentials from Cover Genius CSE (Client Solutions Engineer)
* [ ] [Implement the Purchase Workflow](/offers/guides/purchase-workflow-overview)
* [ ] [Implement the Cancellation Workflow](/offers/guides/purchase-workflow-overview/cancel-booking)
* [ ] [Implement the Modification Workflow](/offers/guides/purchase-workflow-overview/modify-booking)
* [ ] Test using Sandbox credentials
* [ ] Obtain Test Production credentials from CSE
* [ ] Deploy integration to Pre Production environment
* [ ] Share Pre Production access details with CSE
* [ ] CSE performs end-to-end testing in Pre Production and Cover Genius Compliance Manager signs off on integration
* [ ] Fix any issues that arise
* [ ] Final testing and sign-off carried out by CSE
* [ ] Obtain Production credentials from CSE
* [ ] Production deployment date scheduled with CSE
* [ ] Deploy integration to Production environment
* [ ] Start selling insurance policies

<picture><source srcset="/files/gTf2X2A9Z5koQma5K7bA" media="(prefers-color-scheme: dark)"><img src="https://3062128269-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMuGidY91cJqNK5u33H8e%2Fuploads%2Fgit-blob-794ab97eea7c2db9cb1e58adff77edc3727ca0cb%2FPlatforms%20%20XCover%20%20Guides%20%20Integration%20Checklist%20Light.png?alt=media" alt=""></picture>


# Workflow Overview

The Offer platform enables efficient, flexible, and compliant offer and sale of any line of insurance and non-insurance products within a partner experience. Some examples include:

* A public facing Online Travel Agent selling flight and accommodation packages, with related travel and cancellation insurance.
* A merchant facing shipping management platform selling parcel and shipping insurance.
* An ecommerce retail marketplace facilitating sales and offering warranties and or insurance policies for relevant products.

In most integrations policies are attached to one or more main products or services. An example of main product is a laptop purchased from an online store, flight tickets, hotel reservations, etc. Depending on the partner integration, the insurance offering is typically placed in the main product booking path.

<figure><picture><source srcset="/files/LB4x3nNq8anhRmqSgGdz" media="(prefers-color-scheme: dark)"><img src="https://3062128269-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMuGidY91cJqNK5u33H8e%2Fuploads%2Fgit-blob-be51dd99c589cede33fab42d1c5586a615cb578a%2FPlatforms%20%20XCover%20%20Workflow%20Overview%20Light.png?alt=media" alt=""></picture><figcaption><p>Simple insurance purchase workflow</p></figcaption></figure>

### Common Request Flow

#### 1. Create Offer

The initial step is to request personalized product offerings using the **Create Offer** endpoint. This endpoint uses a schema-driven approach to validate requests and returns one or more insurance products with detailed pricing, product information, and content for display.

**Initial Status:** After a successful Create Offer request, the Offer is created with available products ready for customer review.

**Key Points:**

* Returns an Offer ID (UUID) that can be used to confirm the purchase
* Provides product details including pricing, policy dates, benefits, and content
* Validates requests against your partner's Offer Schema
* Supports query parameters for content inclusion and extra fields

#### 2. Confirm Offer

After customers complete the checkout process and insurance premiums are collected by the partner, a request to the **Confirm Offer** endpoint must be made.

**Confirmation Status:** An Offer with status `CONFIRMED` is considered booked, sold, and provisioned. The policy confirmation will be automatically submitted to the customer via email.

**Key Points:**

* Requires the Offer ID from the Create Offers response
* Requires the Product ID of the selected product
* Payment must be collected BEFORE calling this endpoint
* Returns a booking ID (format: `XXXXX-XXXXX-INS`) for future operations

#### 3. Additional Operations

**Opt-out Offer** - Record when product is offered but not selected by the customer. This is crucial for regulatory compliance and platform optimization.

**Modify Booking** - Update existing policy details such as dates, insured persons, or coverage amounts. Modifications may result in price adjustments, refunds, or additional fees.

**Cancel Booking** - Cancel a policy when coverage is no longer required. The system calculates pro-rata refunds where applicable, and the partner is responsible for processing refunds to customers.

### Simple Insurance Purchase Workflow

1. Create Offer ↓
2. Customer Reviews Products ↓
   1. Customer Accepts → Confirm Offer → CONFIRMED Booking OR
   2. Customer Declines → Opt-out Offer → Recorded for Analytics ↓
3. Post-Purchase Operations (if confirmed)
   * Modify Booking (if changes needed)
   * Cancel Booking (if coverage no longer required)

### Important Notes

> **Schema-Driven Validation:** All Create Offer requests are validated against your partner's Offer Schema. Contact your integration team to understand your specific schema requirements.

> **Payment Collection:** Partners must collect payment from customers before calling the Confirm Offer endpoint. The endpoint records that payment has been collected but does not process payments.

> **Regulatory Compliance:** Recording opt-outs is essential for demonstrating fair insurance offerings and appropriate pricing to regulators.


# Create Offer

Sending a Quote Request

The Create Offer endpoint generates personalized product offerings based on partner business context and customer information. This endpoint uses a schema-driven approach to validate requests and returns one or more products with detailed pricing, policy information, and content for display to customers.

> For the full request/response schema, query parameters, and field definitions, see the [Create Offer API Specification](/offers/api/reference).

### What You Get in the Response

The response from the Create Offer endpoint includes:

* **Offer ID** - Unique identifier (UUID) for the offer that can be used to confirm the purchase or opt out.
* **Session ID** - Unique session identifier associated with this offer.
* **Offer Config ID** - The Offer configuration used to generate this Offer. Can be used in subsequent requests to exclude previously shown offers.
* **Currency** - The currency code for all pricing.
* **Products** - List of available products with their configurations. For each product:
  * Quote ID - Used for booking confirmation via the Confirm Offer endpoint
  * Product Type (e.g., `xcover-product`)
  * Finance Information - Price breakdown including total, tax, surcharge, and commission (each with formatted display values)
  * Policy Dates (start and end dates)
  * Policy Disclosure Statement (PDS) URL
  * Attached Files (documents related to the product)
  * Extra Fields and Experiment data (when requested)
  * Benefits from the pricing engine
* **Product Rules** - Selection rules controlling how products behave in the UI (visibility, required/optional, interactions between products). Only present when rules are configured for the offer.
* **Content** - Localized display content including:
  * Offer-level: title, description, terms URL
  * Per-product: title, description, benefits, inclusions, exclusions, extras, disclaimers
* **Metadata** - Additional response metadata such as experiment data. Only present when applicable.
* **Errors** - Empty on success.

### Making a Create Offers Request

The request structure is defined by your partner's Offer Schema, which validates all incoming data using JSON Schema Draft 7. Every request typically includes:

* **schema** - Schema identifier for the Offer type. If omitted, the default schema for the partner will be used. If the partner does not have a default schema, omitting this field will return a validation error.
* **customer** - Customer information (language, currency, country, and optional fields like email, IP address, region, postcode)
* **context** - Business context data required for offer selection and pricing (product-specific fields defined by your schema)
* **partner** (optional) - Partner-specific information such as subsidiary, transaction ID, customer ID, and metadata (including an optional `metadata.session_id`).

> For the complete field definitions, required vs. optional fields, and query parameters, see the [Create Offer API Specification](/offers/api/reference).

### Response Status Codes

<table><thead><tr><th width="241.5">Status</th><th>Description</th></tr></thead><tbody><tr><td><strong>200 OK</strong></td><td>Offer successfully created with available products</td></tr><tr><td><strong>400 Bad Request</strong></td><td>Malformed or unparseable request body</td></tr><tr><td><strong>401 Unauthorized</strong></td><td>Missing or invalid API key</td></tr><tr><td><strong>403 Forbidden</strong></td><td>Access denied</td></tr><tr><td><strong>404 Not Found</strong></td><td>Partner not found, no offers exist, no offers match the request context, or no offers pass access control</td></tr><tr><td><strong>422 Unprocessable Entity</strong></td><td>Request validation failed, all quotes failed to generate, or expression evaluation errors</td></tr><tr><td><strong>429 Too Many Requests</strong></td><td>Rate limit exceeded</td></tr><tr><td><strong>500 Internal Server Error</strong></td><td>Unexpected server error</td></tr></tbody></table>

### Error Responses

Create Offer supports the opt-in `X-API-Error-Version: v2` header, which returns every error response from this endpoint in one consistent shape. We recommend all new integrations send it.

On a `422` where no quote could be generated, for example, the body carries the code `offer_quote_generation_failed` and one entry per failed product:

```json
{
  "type": "validation_error",
  "message": "Offer could not be created due to quote generation errors",
  "code": "offer_quote_generation_failed",
  "error_id": "b9c1f0d2-3a4e-4c6b-9f21-7d8e5a0b1c34",
  "errors": [
    {
      "product_config_id": "8f2b41c9-6d7e-4a15-b3c8-1e9f0a2d5b76",
      "quote_id": "3c7d9e21-5b48-4f0a-8d16-2a9c4e7b0f53",
      "code": "offer_quote_pricing_error",
      "details": ["No rate available for the supplied parameters"]
    }
  ],
  "metadata": {
    "selected_offer_id": "5d8a2f61-9c04-4e73-b1a8-3f6e7c0d9b42"
  }
}
```

The header applies to all of the non-2xx statuses in the table above. See [Error Versioning](/offers/api/responses/error-versioning) for the full field reference and error code list.

### Important Notes

* The `id` field in each product is the quote ID that must be used when confirming the offer via the Confirm Offer endpoint.
* **Performance Tip:** For optimal performance and dynamic pricing, always request fresh offers rather than caching offer responses. Server-side configuration is cached for 5 minutes, so very recent config changes may not be reflected immediately.
* **Schema Validation:** All requests are validated against your partner's Offer Schema. Contact your integration team to understand your specific schema requirements.
* **Exclude Offers:** Use the `exclude_offer_ids` query parameter to request a different offer later in a customer journey by excluding a previously shown offer using the `offer_config_id` returned in the response.

### Next Steps

After receiving an Offer response:

1. Display the product information and pricing to your customer
2. Present the content (benefits, inclusions, exclusions, disclaimers)
3. When the customer decides to purchase, use the **Confirm Offer** endpoint with:
   * The offer `id` from the response
   * The quote `id` (from each product) of the selected product(s)
   * Policyholder details (first name, last name, country)
4. If the customer declines, use the **Opt-Out** endpoint with the offer `id` for conversion tracking


# Confirm Offer

Booking process overview

The Confirm Offer endpoint is used to finalize the purchase of Product(s) from a previously created Offer. This endpoint converts the selected offer into a confirmed booking after payment has been successfully collected.

<figure><picture><source srcset="/files/mH09eYmWjjclhQ05RvN4" media="(prefers-color-scheme: dark)"><img src="https://3062128269-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMuGidY91cJqNK5u33H8e%2Fuploads%2Fgit-blob-0da83c067e95636c79463cf4f991fdea450d68e2%2FPlatforms%20%20XCover%20%20Workflow%20Overview%20%20Confirm%20Offer%20Light.png?alt=media" alt=""></picture><figcaption></figcaption></figure>

### When to Use Confirm Offer

After a customer has:

1. Received an Offer from the Create Offer endpoint
2. Reviewed the Product details, pricing, and policy information
3. Completed the checkout process with payment successfully collected

You must make a request to the Confirm Offer endpoint to provision the product and distribute confirmation to the customer.

### Making a Confirm Offer Request

The Confirm Offer endpoint requires:

#### Path Parameters

* `partner_code` - Your partner identifier
* `offer_id` - The Offer ID returned from the Create Offer response

#### Request Body

* **quotes** (required) - Array of quote objects to confirm, each containing:
  * `id` (required) - The product ID (quote ID) from the Offer response
  * `insured` (optional) - List of insured persons if required by the policy
  * `instalment_plan` (optional) - Selected instalment plan name
  * `first_instalment_paid` (optional) - Whether first instalment has been paid
* **policyholder** (required) - Policyholder information:
  * `email` (required) - Policyholder's email address
  * `phone` (required) - Policyholder's phone number
  * `first_name` (required) - Policyholder's first name
  * `last_name` (required) - Policyholder's last name
  * `country` (required) - Policyholder's country code
  * Additional fields as required by the policy (e.g., city, postcode, region)
* **partner\_transaction\_id** (optional) - Your internal transaction identifier
* **payment\_details** (optional) - Payment information:
  * `provider` - Payment provider name (e.g., "stripe", "paypal", "xpay")
  * `transaction_id` - Payment transaction ID
  * `xpay_charge_id` - XPay charge ID if using XPay
  * `xpay_customer_id` - XPay customer ID if using XPay
  * `customer_token_id` - Customer token for payment authorization
* **booking\_agent** (optional) - Agent information if booked through an agent

### Validations

When confirming an Offer, the following validations are performed:

1. **Status Validation:** The Offer must be in a valid state for confirmation. The expected status after a successful confirmation is `CONFIRMED`.
2. **Price Validation:** The final price is validated to ensure it matches the price from the Create Offer stage. Any price discrepancies will result in an error.
3. **Error Detection:** The presence of an `errors` object in the response payload indicates an important logic error during booking that should be investigated.

### Response Status Codes

* **HTTP 200 OK** - Offer successfully confirmed and policy provisioned
* **HTTP 400 BAD REQUEST** - Invalid request format
* **HTTP 404 NOT FOUND** - Offer not found or partner not found
* **HTTP 409 CONFLICT** - Offer already confirmed
* **HTTP 422 UNPROCESSABLE ENTITY** - Validation error or booking failed
* **HTTP 423 LOCKED** - Resource is locked (concurrent modification)

### Important Notes

> **Policy Confirmation:** An Offer with status `CONFIRMED` is considered booked, sold, and provisioned. The policy confirmation will be automatically submitted to the customer via email.

> **Payment Collection:** You must collect payment from the customer BEFORE calling this endpoint. The Confirm Offer endpoint does not process payments—it only records that payment has been collected.

> **Quote ID Usage:** The `id` field in the quotes array must match the product `id` from the Create Offer response. This is the quote ID, not the Offer ID.
>
> If the integration involves multiple quotes per product, then we have to make sure to send through every product `id` sharing the same `product_config_id` from the Create Offer response.

### Relationship to Fast Booking

The Confirm Offer endpoint uses the same underlying logic as the Fast Booking endpoint. The key difference is:

* **Fast Booking** - Confirms quotes from a Fast Quote request
* **Confirm Offer** - Confirms quotes from a Create Offer request

Both endpoints accept the same request structure and return the same response format.

### Error Handling

If the confirmation fails:

* Check the `errors` field in the response for specific error details
* Verify that the Offer ID is valid and not expired
* Ensure all required fields are provided in the request
* Confirm that payment was successfully collected before calling this endpoint
* Check that the quote IDs match those returned in the Create Offer response

### **Consistent error bodies**

Confirm Offer supports the opt-in `X-API-Error-Version: v2` header, which returns every error response from this endpoint in one consistent shape. We recommend all new integrations send it.

For example, when none of the requested quotes could be booked, the response is a `422` with the package-level code `booking_quotes_unsuccessful` and one `booking_quote_failed` entry per quote. `error_id` is the Offer ID:

```json
{
  "type": "validation_error",
  "message": "None of the requested quotes were successful.",
  "code": "booking_quotes_unsuccessful",
  "error_id": "5d8a2f61-9c04-4e73-b1a8-3f6e7c0d9b42",
  "errors": [
    {
      "product_config_id": "8f2b41c9-6d7e-4a15-b3c8-1e9f0a2d5b76",
      "quote_id": "3c7d9e21-5b48-4f0a-8d16-2a9c4e7b0f53",
      "code": "booking_quote_failed",
      "details": ["Policyholder country is not eligible for this product"]
    }
  ],
  "metadata": {}
}
```

See [Error Versioning](/offers/api/responses/error-versioning) for the full field reference and error code list.

### Next Steps

After successful confirmation:

1. Store the booking ID (`id` field with format `XXXXX-XXXXX-INS`) for future reference
2. Display the confirmation to the customer
3. The customer will receive a confirmation email with policy documents
4. Use the booking ID for any future operations (cancellations, modifications, etc.)


# Opt-out Offer

The Offer opt-out workflow describes the API call that must be made when an Offer is offered but not selected by the customer.

The purpose of utilising the opt-out workflow is so Cover Genius can demonstrate conversion rate to the regulators ensuring the product and pricing is fit for purpose. It also enables XCover machine learning platform Brightwrite to deliver the optimal products at the optimal prices.

<figure><picture><source srcset="/files/RWspiQHeXhmBiTql66Hs" media="(prefers-color-scheme: dark)"><img src="https://3062128269-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMuGidY91cJqNK5u33H8e%2Fuploads%2Fgit-blob-a1853f96b8668c5c0e5bfdd22076e74ad2b2e0a9%2FPlatforms%20%20XCover%20%20Workflow%20Overview%20%20Opt-out%20Offer%20Light.png?alt=media" alt=""></picture><figcaption><p>Opt-Out Workflow</p></figcaption></figure>

### Purpose

Utilizing the opt-out workflow serves two critical functions:

1. **Regulatory Compliance** - Enables Cover Genius to demonstrate conversion rates to regulators, ensuring the product and pricing is fit for purpose
2. **Platform Optimization** - Powers XCover's machine learning platform BrightWrite to deliver optimal products at optimal prices through data-driven insights

### When to Use Opt-out

Call this endpoint when:

* An Offer has been presented to the customer (via Create Offer endpoint)
* The customer has chosen NOT to purchase the Offer
* You need to record the customer's decision to decline coverage

### Making an Opt-out Request

#### Path Parameters

* `partner_code` - Your partner identifier
* `offer_id` - The Offer ID from the Create Offer response that was declined

#### Request Body

The request body is optional and can include:

* `partner_metadata` - Additional metadata about the opt-out decision
* Custom fields as defined by your integration

### Response

* **HTTP 204 No Content** - Opt-out successfully recorded
* **HTTP 403 Forbidden** - Authentication or authorization error
* **HTTP 404 Not Found** - Offer not found

A successful opt-out returns `204` with no body, so there is nothing to parse on the success path.

#### Error Responses

Opt-out Offer supports the opt-in `X-API-Error-Version: v2` header, which returns every error response from this endpoint in one consistent shape. We recommend all new integrations send it.

Opt-out failures are request-level rather than per-product, so the `errors` array carries a single entry with `product_config_id` and `quote_id` set to `null`:

```json
{
  "type": "api_error",
  "message": "Quote not found.",
  "code": "offer_request_failed",
  "error_id": "5d8a2f61-9c04-4e73-b1a8-3f6e7c0d9b42",
  "errors": [
    {
      "product_config_id": null,
      "quote_id": null,
      "code": "offer_request_failed",
      "details": ["Quote not found."]
    }
  ],
  "metadata": {}
}
```

See [Error Versioning](/offers/api/responses/error-versioning) for the full field reference and error code list.

### Important Notes

> **Regulatory Requirement:** Recording opt-outs is essential for demonstrating that insurance offerings are presented fairly and that pricing is appropriate for the market.

> **Data Analytics:** Opt-out data feeds into BrightWrite's machine learning algorithms to continuously improve product offerings and pricing strategies.

> **No Impact on Customer:** Calling this endpoint does not affect the customer in any way - it simply records their decision for analytics and compliance purposes.

### Best Practices

* Call this endpoint as soon as the customer declines the Offer
* Include relevant metadata to help understand opt-out patterns
* Ensure opt-out is called for every Offer that is presented but not purchased


# Modify Booking

Modifying an existing booked policy

The modification workflow is used when a customer wants to make changes to their existing policy. This endpoint allows you to update policy details which may result in price adjustments, refunds, or additional fees.

<figure><picture><source srcset="/files/SQU9mJkRnt3F7mKpeync" media="(prefers-color-scheme: dark)"><img src="https://3062128269-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMuGidY91cJqNK5u33H8e%2Fuploads%2Fgit-blob-623a8d1ce245478bdbe47fcae3d5c5d03e7cb02f%2FPlatforms%20%20XCover%20%20Workflow%20Overview%20%20Modify%20Booking%20Light.png?alt=media" alt=""></picture><figcaption></figcaption></figure>

### Use Cases

Common modification scenarios include:

* **Travel Insurance** - Changing the date of an overseas vacation
* **Product Insurance** - Increasing the item value or value of goods
* **Event Insurance** - Changing the date of an event
* **General Updates** - Modifying insured persons, coverage amounts, or policy dates

### Modification Workflow

#### Step 1: Booking Retrieval

First, obtain information about the customer's purchased insurance. This step can be skipped if you have stored all relevant information such as:

* INS number (booking ID)
* Quote IDs
* Price paid
* Current policy details

Use the GET `/partners/{partner_code}/bookings/{booking_id}` endpoint to retrieve current booking details if needed.

#### Step 2: Preview Modification (Optional but Recommended)

Before applying changes, use the **Modify booking - preview** endpoint (`/partners/{partner_code}/bookings/{booking_id}/quote_for_update`) to:

* See the new price after modifications
* Calculate any refund or additional fee
* Validate that the modification is possible
* Display the price difference to the customer for approval

#### Step 3: Apply Modification

Once the customer approves the changes, call this endpoint to apply the modification.

### Making a Modify Booking Request

#### Path Parameters

* `partner_code` - Your partner identifier
* `booking_id` - The booking ID (INS number) to modify

#### Request Body

* **quotes** (required) - Array of quote modifications, each containing:
  * `id` (required) - The quote ID to modify
  * `policy_start_date` (optional) - New policy start date
  * `update_fields` (required) - Object containing fields to update:
    * `insured` - Updated list of insured persons
    * Other policy-specific fields that can be modified

### Price Changes

Modifications may result in:

* **Additional Fee** - If the new coverage costs more (customer pays the difference)
* **Refund** - If the new coverage costs less (customer receives pro-rata refund)
* **No Change** - If the modification doesn't affect pricing

The response will include `price_diff` and `price_diff_formatted` fields showing the price adjustment.

### Response Status Codes

* **HTTP 200 OK** - Modification successfully applied
* **HTTP 403 Forbidden** - Authentication or authorization error
* **HTTP 422 Unprocessable Entity** - Validation error or modification not allowed

### Important Notes

> **Policy Restrictions:** Not all policies support modifications. Check the policy terms and the `fields_allowed_to_update` field in the booking response.

> **Price Validation:** Always preview the modification first to show the customer any price changes before applying.

> **Refund Handling:** If a refund is due, the partner may need to process the refund to the customer depending on the payment method and policy cooling-off period.

> **Modification Limits:** Some modifications may not be allowed after certain time periods or once the policy has started.

### Best Practices

1. Always use the preview endpoint before applying modifications
2. Display price changes clearly to the customer
3. Obtain customer confirmation before applying changes that increase the price
4. Store the modification history for customer service purposes
5. Handle refunds promptly according to your payment provider's processes


# Cancel Booking

Cancel a specific policy booking

Cancelling a policy booking is used when a customer no longer requires coverage and has contacted the partner directly to cancel the policy. This endpoint handles the cancellation process and calculates any applicable refunds.

<figure><picture><source srcset="/files/mVHzF449IXiEjWuZ2tEl" media="(prefers-color-scheme: dark)"><img src="https://3062128269-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMuGidY91cJqNK5u33H8e%2Fuploads%2Fgit-blob-2e4461feff429764dd0471e88d97fe0f95bec325%2FPlatforms%20%20XCover%20%20Workflow%20Overview%20Cancel%20Booking%20Light.png?alt=media" alt=""></picture><figcaption><p>Cancellation Workflow</p></figcaption></figure>

### Use Cases

Common cancellation scenarios include:

* **Product Insurance** - Product is on-sold or no longer needed
* **Travel Insurance** - Trip is cancelled or postponed indefinitely
* **Event Insurance** - Event is cancelled
* **General Cancellation** - Customer no longer requires coverage for any reason

### Cancellation Workflow

#### Step 1: Booking Retrieval

First, obtain information about the customer's purchased insurance. This step can be skipped if you have stored all relevant information such as:

* INS number (booking ID)
* Quote IDs
* Price paid
* Policy start and end dates

Use the GET `/partners/{partner_code}/bookings/{booking_id}` endpoint to retrieve current booking details if needed.

#### Step 2: Preview Cancellation (Optional but Recommended)

Before cancelling, you can preview the cancellation by calling this endpoint with `preview: true` in the request body to:

* Calculate the pro-rata refund amount (if applicable)
* Validate that cancellation is allowed
* Display refund information to the customer

#### Step 3: Process Cancellation

Call this endpoint with `preview: false` (or omit the preview field) to process the actual cancellation.

### Making a Cancel Booking Request

#### Path Parameters

* `partner_code` - Your partner identifier
* `booking_id` - The booking ID (INS number) to cancel

#### Request Body

* **preview** (optional, boolean) - Set to `true` to preview cancellation without actually cancelling
* **reason\_for\_cancellation** (optional, string) - Reason for the cancellation
* **quotes** (optional, array) - Specific quotes to cancel (if not provided, all quotes in the booking will be cancelled)
  * `id` - Quote ID to cancel

### Refund Calculation

When a refund is due, the response includes:

* **Calculated Pro-rata Refund** - Based on unused coverage period
* **Refund Amount** - The amount to be refunded to the customer
* **Cancellation Fee** - Any applicable cancellation fees (policy-dependent)

The partner is responsible for processing the refund to the customer, depending on:

* Method of payment collection
* Policy cooling-off period
* Policy terms and conditions

### Response

The cancellation response includes:

* Updated booking status (`CANCELLED`)
* Refund calculation details
* Cancellation timestamp
* Updated quote statuses

### Response Status Codes

* **HTTP 200 OK** - Cancellation successful (or preview successful)
* **HTTP 403 Forbidden** - Authentication or authorization error
* **HTTP 404 Not Found** - Booking not found
* **HTTP 422 Unprocessable Entity** - Cancellation not allowed or validation error

### Important Notes

> **Refund Responsibility:** The partner must process refunds to the customer. XCover calculates the refund amount but does not process the payment.

> **Cooling-off Period:** Some policies have a cooling-off period during which full refunds are available. After this period, pro-rata refunds may apply.

> **Cancellation Restrictions:** Check the `can_be_cancelled` field in the booking response to determine if cancellation is allowed.

> **Preview First:** Always preview the cancellation to show the customer the refund amount before processing the actual cancellation.

> **Irreversible Action:** Once a booking is cancelled (with `preview: false`), it cannot be un-cancelled. The customer would need to create a new booking.

### Best Practices

1. Always preview cancellations before processing to show refund amounts
2. Clearly communicate refund amounts and timelines to customers
3. Record the reason for cancellation for analytics and customer service
4. Process refunds promptly according to your payment provider's processes
5. Send cancellation confirmation to the customer
6. Store cancellation records for compliance and auditing purposes


# Payment Process

How will customers pay for their policy premium?

We support multiple payment integration methods to accommodate different regulatory requirements and partner preferences. The payment method you use depends on your market, regulatory environment, and business model.

### Single Payment

Most of our partners operate their own shopping cart, checkout, and payment collection processes. From a customer experience perspective, a single itemized purchase transaction is preferable (for example a travel booking along with the insurance policy).

**This is the recommended approach** as it offers:

* Simplified customer experience (one transaction)
* Higher payment approval rates
* Reduced payment processing complexity
* Lower transaction fees

Please refer to the **Single Payment** section below for more information.

### Dual Payment

In rare circumstances, Partners and us may agree to operate a dual payment integration approach. This results in two transactions against the same payment method of the user in quick succession:

* The merchant of record for the product/service remains the Partner
* The merchant of record for Insurance remains XCover (Cover Genius)

If this is your preferred integration method, please speak to your Partnerships manager or Client Solutions Engineer.

Please refer to the **Dual Payment** section below for details on implementing this workflow.

### Split Payment

In some circumstances, Partners may choose to integrate split payments (by using an approved payment provider) to split the transaction after payment collection:

* One payment from the customer
* Two merchants (Partner and XCover)
* Two settlements (Partner and XCover)

If this is your preferred integration method, please speak to your Partnerships manager or Client Solutions Engineer.


# Single Payment

Overview of the payment process where the partner is the Merchant of Record (MoR)

Partners operating in markets that allow the collection of insurance premiums by non-insurance companies may use this method of premium collection. This is the most common approach for XCover partner integrations, and offers significant efficiency, process, and approval rate benefits.

### Regulatory Considerations

#### United States of America

If you are planning to sell insurance products to residents of the United States of America then it is likely the integration would use the **Dual Payment** method unless the insurance products are travel or warranty related, in which case you might be eligible for a Travel Retailers or general warranty exemption. Please contact your assigned Client Solutions Engineer (CSE) for more information.

#### European Union

For partners planning to sell insurance products solely to residents of the European Union you might be eligible to become an Approved Representative of Cover Genius allowing you to collect premium. Otherwise you must use the **Dual Payment** method. Please contact your assigned CSE for more information.

#### Other Markets

For partners planning to sell insurance products to residents elsewhere please contact your assigned CSE for more information on how to collect premiums if you wish to remain the Merchant of Record.

### Implementation

**No integration steps are required for a single payment implementation approach.** The partner collects payment for both the main product and insurance in a single transaction.

### Workflow

1. **Create Offers** - Request insurance product offerings using the Create Offers endpoint
2. **Customer Reviews** - Display insurance products and pricing to the customer
3. **Checkout** - Customer proceeds to checkout with main product + insurance
4. **Payment Collection** - Partner collects payment for the entire transaction (product + insurance)
5. **Confirm Offer** - Partner calls the Confirm Offer endpoint to provision the insurance policy

### Tracking Payment Information (Optional)

Partners may choose to track the payment/checkout item using metadata fields in the **Confirm Offer** request:

```json
{
  "quotes": [...],
  "policyholder": {...},
  "partner_transaction_id": "XZY123",
  "payment_details": {
    "provider": "stripe",
    "transaction_id": "ch_1234567890"
  },
  "partner_metadata": {
    "trip_name": "Holiday trip",
    "primary_contact": "Dana Skulky",
    "primary_contact_number": "+123123123",
    "primary_contact_email": "dana_skulky[themail.com",](cci:4://file://themail.com",:0:0-0:0)
    "custom_platform_transaction_reference": "XZY123"
  }
}
```

### Important Notes

> **Payment Before Confirmation:** You must collect payment from the customer BEFORE calling the Confirm Offer endpoint. The endpoint records that payment has been collected but does not process payments.

> **Partner as Merchant of Record:** In single payment integrations, the partner remains the merchant of record for the entire transaction, including the insurance premium.

> **Settlement:** XCover will invoice the partner for collected insurance premiums according to the agreed settlement terms.


# Dual Payment using XPay Token

Overview of the dual payment process where Cover Genius is the Merchant of Record

Partners that are at a minimum of **PCI DSS SAQ A compliant** are able to utilize the XPay API to process the insurance transaction. This will make Cover Genius the Merchant of Record (MoR) for the insurance portion of the transaction.

<figure><picture><source srcset="/files/V6TJCPWPMXN4DVqGSqTn" media="(prefers-color-scheme: dark)"><img src="https://3062128269-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMuGidY91cJqNK5u33H8e%2Fuploads%2Fgit-blob-ef485d8932034035d743aa81e20b8dad6dba8492%2FPlatforms%20%20XCover%20%20Payment%20Process%20%20Dual%20Payment%20using%20XPay%20Token%20Light.png?alt=media" alt=""></picture><figcaption></figcaption></figure>

### Overview

In a dual payment integration:

1. Partner collects payment for the main product/service
2. XCover (via XPay) collects payment for the insurance separately
3. Customer experiences two transactions in quick succession
4. Partner remains MoR for product, XCover is MoR for insurance

### Workflow

#### Step 1: Create Offers

Request insurance product offerings using the **Create Offers** endpoint. Display the insurance products and pricing to the customer during the shopping experience.

#### Step 2: Collect Payment Details

After a customer selects the insurance product and proceeds to the checkout stage, the payment information (credit card details) must be collected and transmitted through the **XPay Customer Tokens** endpoint.

**Sending Payment Details:**

```
POST  /xpay/customer_tokens
```

The XPay API uses a long-lived JSON Web Token (JWT) which will be provided to you by the assigned Client Solutions Engineer (CSE).

#### Step 3: Process Main Product Payment

Process the payment for the main product/service through your own payment provider.

#### Step 4: Confirm Offer with XPay Details

Call the **Confirm Offer** endpoint with the XPay payment details:

```json
{
  "quotes": [
    {
      "id": "quote-uuid-from-offer"
    }
  ],
  "policyholder": {
    "first_name": "John",
    "last_name": "Doe",
    "email": "john.doe@example.com",
    "phone": "+1234567890",
    "country": "US"
  },
  "payment_details": {
    "provider": "xpay",
    "xpay_customer_id": "customer_token_from_step_2",
    "customer_token_id": "customer_token_from_step_2"
  }
}
```

#### Step 5: XPay Processes Insurance Payment

XPay will automatically process the insurance payment using the provided customer token. The insurance transaction will appear as a separate charge on the customer's payment method.

### Authentication

The XPay API requires authentication using a JWT token:

```
Authorization: Bearer <your_xpay_jwt_token>
```

Your assigned CSE will provide you with the long-lived JWT token for XPay API access.

### Important Notes

> **PCI Compliance:** Partners must be at minimum PCI DSS SAQ A compliant to use XPay token-based payments.

> **Customer Experience:** Inform customers that they will see two separate charges on their payment method - one for the main product and one for insurance.

> **Merchant of Record:** Cover Genius is the merchant of record for the insurance transaction when using XPay.

> **Token Security:** Store XPay JWT tokens securely and never expose them in client-side code.

### Error Handling

If the XPay payment fails during the Confirm Offer request:

* The response will include error details in the `errors` object
* The booking will not be confirmed
* You may need to retry with a different payment method or customer token
* Inform the customer that the insurance payment failed and offer to retry

### Testing

Use the XPay sandbox environment for testing:

* Test JWT tokens will be provided by your CSE
* Use test credit card numbers provided in the XPay documentation
* Sandbox transactions will not result in actual charges


# Rendering an Offer Panel

Partners will often present an Offer after customers have selected a core product (such as a laptop, travel booking, event tickets, etc.). The Offer presentation combines dynamic data from the Create Offer API response with static branding and content elements.

### Key Components of an Offer

There are key components to presenting an Offer:

#### Dynamic Components (from Create Offer API Response)

1. **Price** - Product pricing and financial details
2. **Disclaimer** - Legal disclaimers and policy information
3. **Policy Wording Link** - Link to the Policy Disclosure Statement (PDS)
4. **Product Details** - Product name, benefits, inclusions, and exclusions

#### Static Components (provided or approved by Cover Genius CSE)

* Trustpilot banner and ratings
* Graphical elements and branding
* Layout and design structure
* Additional marketing copy

The following examples are for Single Product cases. You want to make sure for multiple products we are displaying price, disclaimer and pds urls accordingly to not a signle product but multiple.

### Design Structure

Cover Genius offers a standard or customized design structure optimized for the partner-specific use case (e.g., Travel, Parcel, Ticket, Retail, etc.). A Travel example is presented below:

**Travel Protection Offer Panel Example**

<figure><img src="https://3062128269-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMuGidY91cJqNK5u33H8e%2Fuploads%2FYA1NFXIppL4fgAIMLZVy%2Fimage.png?alt=media&amp;token=f7c45b81-cfa4-4375-8ce3-0cb6b0fa6fe8" alt=""><figcaption></figcaption></figure>

### API Response Mapping

#### 1. Price Display

**Source:** Create Offer response → `products[].details.finance.price`

```json
{
  "products": [
    {
      "id": "1846ae80-bda8-4288-aeea-4ad130a4de6a",
      "details": {
        "finance": {
          "price": {
            "total_amount": 18.61,
            "total_amount_formatted": "€18.61",
            "total_amount_without_tax": null,
            "total_amount_without_tax_formatted": null
          }
        }
      }
    }
  ]
}
```

**Display Options:**

* **Total Price:** Display `products[0].details.finance.price.total_amount_formatted`
  * Example: "€18.61"
* **Per Unit Price:** Divide `total_amount` by number of travelers/units
  * Example: "€9.31 per traveler" (if €18.61 total for 2 travelers)
* **In Button:** Use in the CTA button from `content.positive_cta`
  * Example: "Yes, add Travel Protection for €18.61"

#### 2. Disclaimer

**Source:** Create Offers response → `content.disclaimer` or `content.disclaimer_html`

{% code overflow="wrap" %}

```json
{
  "content": {
    "disclaimer": "This protection is sold by Cover Genius. Lorem ipsum dolor sit amet...",
    "disclaimer_html": "<p>This protection is sold by Cover Genius. Lorem ipsum...</p>"
  }
}
```

{% endcode %}

**Display:** Show the disclaimer text prominently near the price or at the bottom of the offer panel. Use `disclaimer_html` if you want to render HTML formatting, but make sure to apply HTML sanitization before rendering to mitigate XSS attacks.

#### 3. Policy Wording Link

**Source:** Create Offer response → `products[].details.pds_url`

{% code overflow="wrap" %}

```json
{
  "products": [
    {
      "details": {
        "pds_url": "https://staging.xcover.com/en/pds/fe92ecc3-fe4c-408a-b678-a80e5a073c65?policy_type=travel_ticket_cover_v1"
      }
    }
  ]
}
```

{% endcode %}

**Display:** Render as a hyperlink with text such as:

* "View Wording"
* "Read Policy Details"
* "Policy Disclosure Statement"

**Example:**

```html
<a href="{{ products[0].details.pds_url }}" target="_blank">
  View Policy Wording
</a>
```

#### 4. Offer Heading and Product Content

**Source:** Create Offer response → `content.heading` and `content.products[]`

{% code overflow="wrap" %}

```json
{
  "content": {
    "title": "Trip Cancelation",
    "heading": "Protect your trip",
    "sub_heading": "Make your flights and other prepaid travel costs reimbursable...",
    "products": [
      {
        "id": "6684446b-61bd-4039-b753-a4837643671c",
        "title": "Trip cancellation",
        "description": "Protection for trip cancellations"
      }
    ]
  }
}
```

{% endcode %}

**Display:**

* **Main Title:** Use `content.heading`
* **Sub-heading:** Use `content.sub_heading` for additional context
* **Product Title:** Use `content.products[0].title` for specific product name

#### 5. Benefits

**Source:** Create Offers response → `content.products[].benefits`

{% code overflow="wrap" %}

```json
{
  "content": {
    "products": [
      {
        "benefits": {
          "benefit_1": "Get up to 100% of your flight and prepaid travel costs reimbursed if you have to cancel or cut your trip short due to illness or injury",
          "benefit_2": "Money back for emergency medical costs and access to 24/7 medical assistance",
          "benefit_3": "Protection for your baggage if it is lost, stolen or delayed"
        }
      }
    ]
  }
}
```

{% endcode %}

**Display:** Iterate through the benefits object and display as bullet points:

{% code overflow="wrap" %}

```javascript
const benefits = offerData.content.products[0].benefits;
Object.values(benefits).forEach(benefitText => {
  // Display each benefit as a list item
  console.log(`✓ ${benefitText}`);
});
```

{% endcode %}

#### 6. Call-to-Action Buttons

**Source:** Create Offers response → `content.positive_cta` and `content.negative_cta`

{% code overflow="wrap" %}

```json
{
  "content": {
    "positive_cta": "Yes, add Travel Protection for  per traveler",
    "negative_cta": "No, don't protect my trip",
    "negative_cta_warning": "Are you sure? Without protection you risk having to pay significant medical expenses..."
  }
}
```

{% endcode %}

**Display:**

* **Accept Button:** Use `positive_cta` (may need to inject price)
* **Decline Button:** Use `negative_cta`
* **Warning Modal:** Show `negative_cta_warning` when user clicks decline

#### 7. Trust and Credibility

**Source:** Create Offers response → `content.credibility_message`

{% code overflow="wrap" %}

```json
{
  "content": {
    "credibility_message": "8,000 travellers choose XCover to protect their trips each week"
  }
}
```

{% endcode %}

**Display:** Show near the offer to build trust.


# Product Rules

Product rules enable dynamic, event-driven offer flows including upsells, cross-sells, second chance offers, and complex multi-product configurations. This structure provides partners with a powerful, declarative way to define product relationships and conditional visibility rules.

### Structure

The `product_rules` array is returned in the Create Offer response and defines how products should be displayed, grouped, and made interactive based on user actions.

#### Root Object

```json
{
  "product_rules": [
    {
      "slug": "group_id",
      "product_ids": ["product_id_1"],
      "initial_state": "show",
      "min_select": 1,
      "max_select": 1,
      "events": []
    }
  ]
}
```

#### Field Definitions

**Group Object**

| Field           | Type           | Required | Description                                                                            |
| --------------- | -------------- | -------- | -------------------------------------------------------------------------------------- |
| `slug`          | string         | Yes      | Unique slug for the ProductRules. Used for event targeting and reference in UI/booking |
| `product_ids`   | array\<string> | Yes      | Array of product/quote IDs included in this group                                      |
| `initial_state` | enum           | Yes      | Initial visibility/interaction state: `"show"`, `"hide"`, or `"disable"`               |
| `min_select`    | integer        | Yes      | Minimum number of products the customer must select from this group (0 = optional)     |
| `max_select`    | integer        | Yes      | Maximum number of products the customer can select from this group                     |
| `events`        | array\<Event>  | No       | Array of event-driven rules. Can be empty or omitted for terminal groups               |

**Event Object**

| Field         | Type   | Required | Description                                                                                |
| ------------- | ------ | -------- | ------------------------------------------------------------------------------------------ |
| `on`          | enum   | Yes      | User action that triggers this event: `"select"`, `"deselect"`, `"accept"`, or `"decline"` |
| `action`      | enum   | Yes      | Action to perform on target group: `"show"`, `"hide"`, `"enable"`, or `"disable"`          |
| `target_rule` | string | Yes      | ProductRules Slug to apply action to (must reference existing ProductRules)                |

**Event Triggers**

| Trigger    | When It Fires                                | Use Case                                             |
| ---------- | -------------------------------------------- | ---------------------------------------------------- |
| `select`   | User selects product(s) meeting `min_select` | Show upsells immediately when user picks a product   |
| `deselect` | User's selection drops below `min_select`    | Hide/cleanup dependent groups when selection removed |
| `accept`   | User explicitly accepts the group            | Show next step after accepting Offer                 |
| `decline`  | User explicitly declines the entire group    | Show second chance Offer when user opts out          |

**Event Actions**

| Action    | Effect                                  | Use Case                                   |
| --------- | --------------------------------------- | ------------------------------------------ |
| `show`    | Make group visible and interactive      | Reveal upsell after main product selected  |
| `hide`    | Make group invisible                    | Hide alternative when user makes selection |
| `enable`  | Make group interactive (if disabled)    | Unlock addon after main product accepted   |
| `disable` | Make group non-interactive (grayed out) | Disable competing option in XOR scenario   |

**Initial State**

| State     | Description                               | Use Case                                  |
| --------- | ----------------------------------------- | ----------------------------------------- |
| `show`    | Visible and interactive from start        | Primary Offer, always available options   |
| `hide`    | Not visible until triggered by event      | Upsells, second chance Offer              |
| `disable` | Visible but non-interactive until enabled | Show addon but require main product first |

### Common use cases

#### Single Product

Simple single product Offer with no events.

```json
{
  "product_rules": [
    {
      "slug": "primary",
      "product_ids": ["product_A"],
      "initial_state": "show",
      "min_select": 1,
      "max_select": 1,
      "events": []
    }
  ]
}
```

**Use Case:** Standard single product offer where user must select the product to proceed.

**Implementation:**

* Display the product immediately
* User must select exactly 1 product
* No conditional behavior

***

#### Multiple Products (XOR - One-of)

User must pick exactly one of multiple products.

```json
{
  "product_rules": [
    {
      "slug": "plan_options",
      "product_ids": ["product_A", "product_B"],
      "initial_state": "show",
      "min_select": 1,
      "max_select": 1,
      "events": []
    }
  ]
}
```

**Use Case:** Tiered pricing where user selects one plan from multiple options (e.g., Basic vs Premium, Bronze vs Silver vs Gold).

**Implementation:**

* Display all products in the group simultaneously
* User must select exactly 1 product
* Typically rendered as radio buttons or tabs

***

#### Multiple Product Rules (Second Chance Offer)

Show alternative product when user declines primary offer.

```json
{
  "product_rules": [
    {
      "slug": "primary",
      "product_ids": ["premium_product"],
      "initial_state": "show",
      "min_select": 1,
      "max_select": 1,
      "events": [
        {
          "on": "decline",
          "action": "show",
          "target_rule": "second_chance"
        },
        {
          "on": "select",
          "action": "hide",
          "target_rule": "second_chance"
        }
      ]
    },
    {
      "slug": "second_chance",
      "product_ids": ["budget_product"],
      "initial_state": "hide",
      "min_select": 1,
      "max_select": 1,
      "events": []
    }
  ]
}
```

**Use Case:** Offer a lower-priced alternative when user declines the primary offer to maximize conversion.

**Flow:**

1. User sees primary offer (premium product at higher price)
2. User clicks "No thanks" → `decline` event fires
3. Primary group hides, second chance group shows (budget product at lower price)
4. If user changes mind and selects primary → second chance hides

**Example with Real Data:**

{% code overflow="wrap" expandable="true" %}

```json
{
  "id": "offer_123",
  "currency": "AUD",
  "products": [
    {
      "id": "quote_id_1",
      "type": "insurance",
      "details": {
        "policy_start_date": "2025-10-29T10:00:00+00:00",
        "policy_end_date": "2025-11-28T10:00:00+00:00",
        "finance": {
          "price": {
            "total_amount": 16,
            "total_amount_formatted": "A$16.00"
          }
        },
        "pds_url": "https://www.xcover.com/en/pds/..."
      }
    },
    {
      "id": "quote_id_2",
      "type": "insurance",
      "details": {
        "policy_start_date": "2025-10-29T10:00:00+00:00",
        "policy_end_date": "2025-11-28T10:00:00+00:00",
        "finance": {
          "price": {
            "total_amount": 10,
            "total_amount_formatted": "A$10.00"
          }
        },
        "pds_url": "https://www.xcover.com/en/pds/..."
      }
    }
  ],
  "product_rules": [
    {
      "slug": "primary",
      "product_ids": ["quote_id_1"],
      "initial_state": "show",
      "min_select": 1,
      "max_select": 1,
      "events": [
        {
          "on": "decline",
          "action": "show",
          "target_rule": "second_chance"
        },
        {
          "on": "select",
          "action": "hide",
          "target_rule": "second_chance"
        }
      ]
    },
    {
      "slug": "second_chance",
      "product_ids": ["quote_id_2"],
      "initial_state": "hide",
      "min_select": 1,
      "max_select": 1,
      "events": []
    }
  ],
  "content": {
    "heading": "Protect Your Trip",
    "positive_cta": "Add to booking",
    "negative_cta": "No thanks",
    "extras": {
        "second_chance_heading": "Your last chance!",
        "second_chance_subheading": "Don't leave empty-handed—grab this special deal."
    },
    "products": [
      {
        "id": "quote_id_1",
        "title": "Essential Travel Protection",
        "benefits": {
          "benefit_1": "Up to $2,000,000 in emergency medical expenses",
          "benefit_2": "Cover for unexpected trip disruptions"
        },
        "credibility_badge": "Most Popular"
      },
      {
        "id": "quote_id_2",
        "title": "Cancel For Any Reason",
        "benefits": {
          "benefit_1": "Receive up to 75% of your trip costs back",
          "benefit_2": "Cancel for reasons not covered by standard policy"
        }
      }
    ]
  }
}
```

{% endcode %}

### Business Rules & Validation

#### Event Processing Rules

1. **Events fire only on user interactions**, not on programmatic state changes from other events
2. **Events are processed synchronously** in the order they appear in the `events` array
3. **State changes are idempotent** - showing a visible group or hiding a hidden group has no effect
4. **Cleanup must be explicit** - system does not auto-reverse actions; partners must configure bidirectional events

### Best Practices

1. **Use `initial_state: "show"` for primary offers** - Always display the main offer immediately
2. **Use `initial_state: "hide"` for secondary offers** - Hide upsells, cross-sells, and second chance offers until triggered
3. **Configure bidirectional events** - If `select` shows a group, `deselect` should hide it
4. **Provide rule-specific content** - Use `content.extras` to customize messaging for second chance offers
5. **Set appropriate min/max values** - Use `min_select: 1, max_select: 1` for required single selection
6. **Handle opt-out** - Record opt-out when user declines all visible groups


# Multi-Step Session Tracking

## Overview

When building multi-step booking journeys such as offering coverage at search, updating options at checkout, and repricing before payment, each interaction typically generates a unique offer instance `id`.

Without session tracking, every request appears as an isolated event. This forces you to maintain external tracking maps and distorts reporting by counting a single customer's journey as multiple separate offer requests.

The Session Tracking capability introduces `session_id`, a single correlation ID maintained across your entire customer flow.

{% stepper %}
{% step %}
**Omit on Initial Request**

Send your initial `/offers` without a `session_id`. Offers generates a unique `session_id` and returns it in the response payload.
{% endstep %}

{% step %}
**Echo Back on Subsequent Requests**

Pass the returned `session_id` in `partner.metadata.session_id` on every subsequent API call for that customer journey (e.g., checkout, repricing).
{% endstep %}

{% step %}
**Maintain Independent Selection Logic**

Offers dynamically evaluates the current business context on each step, returning refreshed pricing or updated offers while binding all calls under one session.
{% endstep %}
{% endstepper %}

## How It Works

Understanding how identifiers interact throughout a multi-step journey helps ensure proper implementation:

| **Identifier**    | **Uniqueness Scope**         | **Description**                                                                  |
| ----------------- | ---------------------------- | -------------------------------------------------------------------------------- |
| `session_id`      | Stable across entire journey | Correlates all `/offers` calls belonging to a single customer flow.              |
| `id`              | New per `/offers` call       | Identifies a specific offer instance and keys the temporary stored quote record. |
| `offer_config_id` | Reused across sessions       | Identifies the underlying product rule configuration selected for display.       |

## Technical Integration

#### 1. Starting a New Session

Omit `partner.metadata.session_id` on your initial `create_offer` call (e.g., on the search or flight selection page). This signals the start of a new session.

```
POST /partners/{partner_code}/offers/
```

```json

{
  "schema": "travel_insurance_v1",
  "customer": {
    "currency": "USD",
    "language": "en",
    "country": "US"
  },
  "context": {
    "placement": "search",
    "trip_cost": 1200
  }
}
```

**Response (200 OK):**

Offers returns a newly generated `session_id` alongside the unique offer `id` for this specific step.

```json
{
  "id": "off_01H123456789ABCDEF",
  "session_id": "sess_9876543210",
  "offer_config_id": "cfg_travel_standard",
  "currency": "USD",
  "products": [ ... ]
}
```

#### 2. Continuing an Existing Session

On subsequent steps (e.g., moving from search to checkout, or repricing at payment), include the `session_id` received from the previous response in `partner.metadata.session_id`.

```
POST /partners/{partner_code}/offers/
```

```json
{
  "schema": "travel_insurance_v1",
  "customer": {
    "currency": "USD",
    "language": "en",
    "country": "US"
  },
  "context": {
    "placement": "checkout",
    "trip_cost": 1200
  },
  "partner": {
    "metadata": {
      "session_id": "sess_9876543210"
    }
  }
}
```

**Response (200 OK):**

Offers echoes the exact same `session_id` back, while issuing a fresh offer `id` for the updated step.

```json
{
  "id": "off_02H987654321FEDCBA",
  "session_id": "sess_9876543210",
  "offer_config_id": "cfg_travel_standard",
  "currency": "USD",
  "products": [ ... ]
}
```

## End-to-End Journey Workflow

Below is a typical multi-step integration lifecycle:

<pre class="language-mermaid"><code class="lang-mermaid">---
config:
  theme: base
---
<strong>sequenceDiagram
</strong>    participant Customer as Customer
    participant Partner as Partner Backend
    participant Offers as Offers API

    %% Step 1: Search
    note over Customer, Offers: Step 1: Initial Offer (Search / Flight Selection)
    Customer->>Partner: Selects flight/search
    Partner->>Offers: POST /offers/ (no session_id)
    note over Offers: Generates new session_id (S1)&#x3C;br/>Runs selection logic -> offer id (O1)
    Offers-->>Partner: Returns offer id: O1, session_id: S1
    Partner-->>Customer: Displays offer O1

    %% Step 2: Checkout
    note over Customer, Offers: Step 2: Journey Continuation (Checkout)
    Customer->>Partner: Navigates to checkout
    Partner->>Offers: POST /offers/ (partner.metadata.session_id: S1)
    note over Offers: Uses session_id (S1)&#x3C;br/>Runs selection for checkout -> offer id (O2)
    Offers-->>Partner: Returns offer id: O2, session_id: S1
    Partner-->>Customer: Displays offer O2

    %% Step 3: Payment / Reprice
    note over Customer, Offers: Step 3: Reprice / Final Review
    Customer->>Partner: Proceeds to payment page
    Partner->>Offers: POST /offers/ (partner.metadata.session_id: S1)
    note over Offers: Uses session_id (S1)&#x3C;br/>Refreshes pricing for context -> offer id (O3)
    Offers-->>Partner: Returns offer id: O3, session_id: S1
    Partner-->>Customer: Displays final offer O3

    %% Step 4: Final Outcome (Confirm or Opt-Out)
    note over Customer, Offers: Step 4: Final Action (Purchase OR Decline)
    alt Customer Accepts Offer
        Customer->>Partner: Completes booking &#x26; pays for coverage
        Partner->>Offers: POST /offers/O3/confirm/
        Offers-->>Partner: Booking confirmed (Bound to session S1)
    else Customer Declines Offer
        Customer->>Partner: Completes booking without coverage
        Partner->>Offers: POST /offers/O3/opt_out/
        Offers-->>Partner: 204 No Content (Opt-out recorded for session S1)
    end

</code></pre>

1. Step 1 (Search): Request sent without `session_id`. Response returns `id: O1` and creates `session_id: S1`.
2. Step 2 (Checkout): Request includes `session_id: S1`. Response returns `id: O2` and echoes `session_id: S1`.
3. Step 3 (Payment / Reprice): Request includes `session_id: S1`. Context remains identical to Step 2, so Offers API returns the same offer refreshed with current pricing under a new `id: O3` and `session_id: S1`.
4. Step 4 (Final Action):
   * If Accepted: Call `POST /offers/O3/confirm/` using the latest offer `id`.
   * If Declined: Call `POST /offers/O3/opt_out/` using the latest `id`.

## Key Behaviors & Best Practices

#### Final Action Handling (Confirm vs. Opt-Out)

Just as you confirm the purchase using the latest offer `id` (`O3` in the flow above), when a customer actively declines coverage, call the Opt-Out endpoint using the most recent offer `id`. This ensures accurate conversion and attach-rate tracking for the session.

#### Partner-Supplied Session IDs

If you already maintain internal session tracking (e.g., a checkout session or cart ID), you may pass your own ID in `partner.metadata.session_id` on the first request. Offers API will adopt and preserve your supplied ID throughout the funnel.

> Integrity Requirement: When supplying your own IDs, ensure they are uniquely scoped per customer flow. Reusing a single ID across multiple distinct customers will merge separate user journeys into a single session in reporting.

#### Stateless Continuity

Passing `session_id` on request payloads allows Offers API to maintain stateless continuation. Every request triggers real-time offer evaluation and re-pricing against the provided context rather than serving stale, cached quotes.

#### Dynamic Offer Selection

Providing `session_id` does not force rotation or auto-exclude previously shown offers. Offers API continues using context-driven selection rules to return the optimal offer for each step.

* To explicitly suppress specific offer configurations across journey steps (e.g., preventing a previously shown offer from appearing again), continue using the standard `exclude_offer_ids` query parameter.

#### Boundary Handling

* Omitted Mid-Journey: If `session_id` is omitted on a subsequent call, Offers API interprets the request as a new boundary and generates a fresh `session_id`.
* Malformed or Unrecognized IDs: Offers API accepts provided IDs as valid session keys without strict database lookup validation; an unrecognized ID simply initializes a new tracked journey without throwing an API error.


# Events / Tickets

Event cancellation insurance or warranties - Offered via event or ticket booking platforms

Ticket and event sales services can present relevant cancellation insurance or ticket warranty policies in the event purchase booking path. Commonly, partners will integrate XCover using two key purchase process API calls: [create offer](https://partner-docs.covergenius.com/offers/api/reference/create-offer#post-partners-partner_code-offers) and [confirm offer](https://partner-docs.covergenius.com/offers/api/reference/confirm-offer#post-partners-partner_code-offers-offer_id-confirm).\
\
See a collection of common requests for this integration type, by contacting your CSE.\
\
Most integrations follow the below high level flow of events:

<figure><picture><source srcset="/files/2yfJM6IXmsi2FwL0M7Pi" media="(prefers-color-scheme: dark)"><img src="https://3062128269-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMuGidY91cJqNK5u33H8e%2Fuploads%2Fgit-blob-d66b54f6662b848d445e59d036081925dc07b6d0%2FPlatforms%20%20XCover%20%20Events%20%20Tickets%20Light.png?alt=media" alt=""></picture><figcaption></figcaption></figure>

1\. User browses event options and\
2\. Selects a event/ticket package\
3\. Partner platform sends an [offer payload](https://partner-docs.covergenius.com/offers/api/reference/create-offer#post-partners-partner_code-offers) to the create offer endpoint\
4\. User selects offer products\
5\. User pays for tickets and offer products at checkout\
6\. [Payment collection](/offers/guides/payment-process)\
7\. Partner sends a [confirmation request](https://partner-docs.covergenius.com/offers/api/reference/confirm-offer#post-partners-partner_code-offers-offer_id-confirm) to the confirm offer endpoint\
8\. XCover sends confirmation email including policy details and partner sends purchase confirmation and tax invoice.

#### Post sale processes

[Modification](/offers/guides/purchase-workflow-overview/modify-booking) - Only non financial modifications are applicable for this policy type.

[Cancellation](/offers/guides/purchase-workflow-overview/cancel-booking) - Due to the nature of event/cancellation policies cancellations are restricted in line with relevant regulations.

#### [Opt-out process](/offers/guides/purchase-workflow-overview/opt-out-offer)

In circumstances where a customer chooses to purchase tickets, but not the insurance offer. An opt-out request is used to notify XCover of a non-opted insurance quote. This assists with pricing and product offer data analysis and ultimately improved offers and sales results.


# Create Offer

## Create Offer

> The Create Offer endpoint generates event ticket protection offerings based on the events and tickets being purchased. Multiple events may be quoted in a single request; the response returns one or more protection products with pricing.

```json
{"openapi":"3.0.0","info":{"title":"Offers API - Event Ticket Protection","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nRequires three mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** Cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/offers/":{"post":{"summary":"Create Offer","description":"The Create Offer endpoint generates event ticket protection offerings based on the events and tickets being purchased. Multiple events may be quoted in a single request; the response returns one or more protection products with pricing.","tags":["Create Offer"],"parameters":[{"name":"active_only","in":"query","required":false,"description":"When using a test API key, only return active offers","schema":{"type":"boolean","default":false}},{"name":"include_content","in":"query","required":false,"description":"Include localized content in the response","schema":{"type":"boolean","default":true}},{"name":"extra_fields","in":"query","required":false,"description":"Comma-separated list of specific extra fields to include. Available fields: tax, commission, benefits, surcharge","schema":{"type":"string"}},{"name":"exclude_offer_ids","in":"query","required":false,"description":"Comma-separated list of Offer Config IDs to exclude from the response","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"schema":{"type":"string","description":"Schema identifier for the offer type. Optional. If not provided, the default schema for your partner will be used."},"customer":{"type":"object","description":"Customer information","properties":{"currency":{"type":"string","description":"Currency code (e.g., USD, AUD, EUR, GBP)"},"country":{"type":"string","description":"Customer's country code (e.g., US, AU, GB)"},"region":{"type":"string","description":"Customer's region or state"},"postcode":{"type":"string","description":"Customer's postal code"},"language":{"type":"string","description":"Customer's preferred language tag (e.g., en-us)"},"email":{"type":"string","format":"email"},"ip":{"type":"string"}},"required":["currency","country","language"]},"partner":{"type":"object","description":"Partner information","properties":{"transaction_id":{"type":"string","description":"Partner transaction identifier"},"customer_id":{"type":"string","description":"Partner customer identifier"},"subsidiary":{"type":"string","description":"Partner subsidiary identifier (e.g., regional subsidiary, white-label brand)."},"metadata":{"type":"object","description":"Additional partner metadata","additionalProperties":true}}},"context":{"type":"object","description":"Event-ticketing context.","properties":{"events":{"type":"array","description":"Events whose tickets are being protected.","items":{"type":"object","properties":{"id":{"type":"string","description":"Partner's event identifier."},"name":{"type":"string","description":"Event name."},"start_date":{"type":"string","format":"date-time","description":"Event start date and time."},"end_date":{"type":"string","format":"date-time","nullable":true,"description":"Event end date and time. May be omitted for single-day events; for multi-day events this should be set."},"venue":{"type":"string","description":"Venue name."},"city":{"type":"string"},"country":{"type":"string"},"multiday_event":{"type":"boolean","description":"Whether the event spans multiple days."},"duration_days":{"type":"integer","description":"Event duration in days."},"category":{"type":"string","description":"Event category (e.g., Music, Comedy, Sports)."},"total_amount":{"type":"number","description":"Total ticket amount for this event in the customer currency."},"ticket_count":{"type":"integer","description":"Number of tickets being purchased for this event."},"tickets":{"type":"array","description":"Individual tickets being purchased.","items":{"type":"object","properties":{"id":{"type":"string","description":"Partner's ticket identifier."},"type":{"type":"string","description":"Ticket type / tier (e.g., GA, VIP, Meet & Greet)."},"status":{"type":"string","description":"Ticket status (e.g., purchased, layaway, layaway - void)."},"price":{"type":"number","description":"Face value of the ticket."},"total_paid":{"type":"number","description":"Amount the customer has paid so far for this ticket (useful for layaway)."}},"required":["id","price"]}}},"required":["id","name","start_date","country"]}}},"additionalProperties":true}},"required":["customer","context"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"Event ticket protection offer responses are wrapped in a top-level `data` object.","properties":{"data":{"type":"object","properties":{"id":{"type":"string","description":"Offer ID"},"currency":{"type":"string"},"products":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Product (quote) ID"},"product_config_id":{"type":"string"},"type":{"type":"string","nullable":true},"schema_url":{"type":"string","format":"uri","nullable":true},"details":{"type":"object","properties":{"policy_version_id":{"type":"string"},"start_date":{"type":"string","format":"date-time","nullable":true},"end_date":{"type":"string","format":"date-time","nullable":true},"finance":{"type":"object","properties":{"price":{"type":"object","properties":{"total_amount":{"type":"number","nullable":true},"total_amount_without_tax":{"type":"number","nullable":true},"total_amount_formatted":{"type":"string","nullable":true},"total_amount_without_tax_formatted":{"type":"string","nullable":true}}},"tax":{"type":"object","properties":{"total_amount":{"type":"number","nullable":true},"total_amount_formatted":{"type":"string","nullable":true}}},"surcharge":{"type":"object","properties":{"total_amount":{"type":"number","nullable":true},"total_amount_formatted":{"type":"string","nullable":true}}},"commission":{"type":"object","properties":{"total_amount":{"type":"number","nullable":true},"total_amount_formatted":{"type":"string","nullable":true}}}}},"pds_url":{"type":"string","format":"uri"},"files":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"url":{"type":"string","format":"uri"},"type":{"type":"string"}}}},"extra_fields":{"type":"object","description":"Event-ticketing-specific computed fields about the resulting policy.","properties":{"seller_entity":{"type":"string","description":"Legal selling entity for the insurance product."},"event_datetime":{"type":"string","format":"date-time","nullable":true,"description":"Resolved primary event date and time."},"policy_start_date":{"type":"string","format":"date-time","nullable":true},"policy_start_calculated":{"type":"string","format":"date-time","nullable":true},"event_id":{"type":"string","nullable":true},"customer_id":{"type":"string","nullable":true},"esim_eligible":{"type":"boolean","description":"Whether the customer is eligible for a bundled travel eSIM perk."},"esimid":{"type":"string","nullable":true,"description":"eSIM identifier when provisioned."},"same_day":{"type":"boolean","description":"Whether the offer is being purchased on the same day as the event."}},"additionalProperties":true},"experiment":{"type":"array","description":"Experiment metadata. Returned as an array (may be empty).","items":{"type":"object","additionalProperties":true}},"benefits":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"content":{"type":"object","properties":{"schema_version":{"type":"string"},"locale":{"type":"string"}}},"provider_reference":{"type":"string","description":"Provider reference identifier for downstream tracking and reconciliation."}}}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object","additionalProperties":true}}}}}}}}}}}
```


# Confirm Offer

## Confirm Offer

> Finalize the purchase of event ticket protection. Converts the selected Offer into a confirmed booking after payment.\
> \
> \## Idempotency\
> \
> Supports \`x-idempotency-key\` header for safe retries.

```json
{"openapi":"3.0.0","info":{"title":"Offers API - Event Ticket Protection","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nRequires three mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** Cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/offers/{offer_id}/confirm/":{"post":{"summary":"Confirm Offer","description":"Finalize the purchase of event ticket protection. Converts the selected Offer into a confirmed booking after payment.\n\n## Idempotency\n\nSupports `x-idempotency-key` header for safe retries.","tags":["Confirm Offer"],"parameters":[{"name":"x-idempotency-key","in":"header","required":false,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"}},"required":["id"]}},"policyholder":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"address1":{"type":"string"},"city":{"type":"string"},"region":{"type":"string"},"postcode":{"type":"string"},"country":{"type":"string"}},"required":["first_name","last_name","email","country"]}},"required":["quotes","policyholder"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"partner_transaction_id":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"pds_url":{"type":"string","format":"uri"},"security_token":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"policy_start_date":{"type":"string","format":"date-time"},"policy_end_date":{"type":"string","format":"date-time","nullable":true},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"policy":{"type":"object","properties":{"policy_type":{"type":"string"},"policy_type_version":{"type":"string"},"policy_type_slug":{"type":"string"},"policy_type_group_name":{"type":"string"},"policy_name":{"type":"string"},"policy_code":{"type":"string"},"policy_version":{"type":"string"},"category":{"type":"string"},"policy_currency":{"type":"string"}}},"tax":{"type":"object","properties":{"total_tax":{"type":"number","nullable":true},"total_amount_without_tax":{"type":"number","nullable":true},"total_tax_formatted":{"type":"string","nullable":true},"total_amount_without_tax_formatted":{"type":"string","nullable":true}}},"benefits":{"type":"array","items":{"type":"object","additionalProperties":true}},"commission":{"type":"object","properties":{"partner_commission":{"type":"number","nullable":true},"total_commission":{"type":"number","nullable":true},"partner_commission_formatted":{"type":"string","nullable":true},"total_commission_formatted":{"type":"string","nullable":true}}},"created_at":{"type":"string","format":"date-time"},"confirmed_at":{"type":"string","format":"date-time"},"pds_url":{"type":"string","format":"uri"},"can_be_cancelled":{"type":"boolean"}}}},"coi":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"pdf":{"type":"string","format":"uri"}}},"policyholder":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"country":{"type":"string"}}},"total_tax":{"type":"number"},"total_tax_formatted":{"type":"string"},"total_premium":{"type":"number"},"total_premium_formatted":{"type":"string"},"fnol_link":{"type":"string","format":"uri"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"409":{"description":"Conflict - Duplicate Request (Idempotent)","content":{"application/json":{"schema":{"type":"object"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"array","items":{"type":"string"}}}}}}},"423":{"description":"Locked - Request In Progress","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}
```


# Opt Out Offer

## Opt-out Offer

> Record when a customer declines an event ticket protection offer.

```json
{"openapi":"3.0.0","info":{"title":"Offers API - Event Ticket Protection","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nRequires three mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** Cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/offers/{offer_id}/opt_out/":{"post":{"summary":"Opt-out Offer","description":"Record when a customer declines an event ticket protection offer.","tags":["Opt-out Offer"],"responses":{"204":{"description":"No Content - Opt-out recorded successfully"},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}
```


# Modify Booking

## Modify Booking

> Modify an existing event ticket protection booking. Typical modifications include event reschedules (updating event start/end dates) or adjusting ticket counts.

```json
{"openapi":"3.0.0","info":{"title":"Offers API - Event Ticket Protection","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nRequires three mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** Cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/":{"patch":{"summary":"Modify Booking","description":"Modify an existing event ticket protection booking. Typical modifications include event reschedules (updating event start/end dates) or adjusting ticket counts.","tags":["Modify Booking"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"update_fields":{"type":"object","description":"Fields to update on the quote. For event ticket protection, common fields are nested `events` updates (e.g., new start_date/end_date) or ticket-level changes.","additionalProperties":true}},"required":["id","update_fields"]}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"price_diff":{"type":"number"},"price_diff_formatted":{"type":"string"}}}},"total_price_diff":{"type":"number"},"total_price_diff_formatted":{"type":"string"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"array","items":{"type":"string"}}}}}}}}}}}}
```

## Modify Booking - Preview

> Preview the price changes that would result from a modification without applying them. The response includes an \`update\_id\` that can be used to confirm the modification.

```json
{"openapi":"3.0.0","info":{"title":"Offers API - Event Ticket Protection","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nRequires three mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** Cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/quote_for_update":{"patch":{"summary":"Modify Booking - Preview","description":"Preview the price changes that would result from a modification without applying them. The response includes an `update_id` that can be used to confirm the modification.","tags":["Modify Booking"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"update_fields":{"type":"object","additionalProperties":true}},"required":["id","update_fields"]}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"price_diff":{"type":"number"},"price_diff_formatted":{"type":"string"}}}},"total_price_diff":{"type":"number"},"total_price_diff_formatted":{"type":"string"},"update_id":{"type":"string"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object"}}}}}}}}}}}
```

## Modify Booking - Confirm

> Finalize a previewed modification.

```json
{"openapi":"3.0.0","info":{"title":"Offers API - Event Ticket Protection","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nRequires three mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** Cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/confirm_update/{update_id}/":{"post":{"summary":"Modify Booking - Confirm","description":"Finalize a previewed modification.","tags":["Modify Booking"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"xpay_charge_id":{"type":"string"}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"price_diff":{"type":"number"},"price_diff_formatted":{"type":"string"}}}},"total_price_diff":{"type":"number"},"total_price_diff_formatted":{"type":"string"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}
```


# Cancel Booking

## Cancel Booking

> Cancel an event ticket protection booking. Typical cancellation reasons include the event being cancelled by the organizer, the customer being unable to attend, or a duplicate booking.\
> \
> When \`preview\` is \`true\`, returns a refund preview with a \`cancellation\_id\`. When \`preview\` is \`false\` (or omitted), the cancellation is applied immediately.

```json
{"openapi":"3.0.0","info":{"title":"Offers API - Event Ticket Protection","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nRequires three mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** Cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/cancel":{"post":{"summary":"Cancel Booking","description":"Cancel an event ticket protection booking. Typical cancellation reasons include the event being cancelled by the organizer, the customer being unable to attend, or a duplicate booking.\n\nWhen `preview` is `true`, returns a refund preview with a `cancellation_id`. When `preview` is `false` (or omitted), the cancellation is applied immediately.","tags":["Cancel Booking"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"preview":{"type":"boolean"},"refund_required":{"type":"boolean"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"reason_for_cancellation":{"type":"string"}},"required":["id"]}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"policy_start_date":{"type":"string","format":"date-time"},"policy_end_date":{"type":"string","format":"date-time","nullable":true},"policy_cancellation_date":{"type":"string","format":"date-time","nullable":true},"status":{"type":"string"},"price":{"type":"number"},"refund_value":{"type":"number"},"adjustment_fee":{"type":"number"}}}},"policyholder":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"country":{"type":"string"}}},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"total_refund":{"type":"number"},"total_refund_formatted":{"type":"string"},"currency":{"type":"string"},"cancellation_id":{"type":"string","nullable":true},"confirm_before":{"type":"string","format":"date-time","nullable":true},"refund_amount":{"type":"number"},"refund_amount_formatted":{"type":"string"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"array","items":{"type":"string"}}}}}}}}}}}}
```

## Cancel Booking - Confirm

> Finalize a previewed cancellation.

```json
{"openapi":"3.0.0","info":{"title":"Offers API - Event Ticket Protection","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nRequires three mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** Cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/confirm_cancellation/{cancellation_id}/":{"post":{"summary":"Cancel Booking - Confirm","description":"Finalize a previewed cancellation.","tags":["Cancel Booking"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"reason_for_cancellation":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"price":{"type":"number"},"refund_value":{"type":"number"},"cancelled_at":{"type":"string","format":"date-time"}}}},"total_refund":{"type":"number"},"total_refund_formatted":{"type":"string"},"refund_amount":{"type":"number"},"refund_amount_formatted":{"type":"string"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"array","items":{"type":"string"}}}}}}}}}}}}
```


# Travel / Accomodation

Travel Insurance such as Comprehensive, Medical,  Baggage, Cancellation, Smart Delay, Insolvency, and more - Offered via Online Travel Agents and other platforms.

Online Travel Agents (OTA's) and Accommodation platforms selling flights, hotel bookings, experiences and travel packages can seamlessly present relevant travel insurance policies in the purchase booking path. Commonly, partners will integrate XCover using two key purchase process API calls: [create offer](https://partner-docs.covergenius.com/offers/vertical-examples/travel-accomodation/create-offer#post-partners-partner_code-offers) and [confirm offer](https://partner-docs.covergenius.com/offers/vertical-examples/travel-accomodation/confirm-offer).\
\
:bulb: See a collection of common requests for this integration type\
\
Most integrations follow the below high level flow of events:

<figure><picture><source srcset="/files/KAfa3wgdPMOzspoRv97G" media="(prefers-color-scheme: dark)"><img src="https://3062128269-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMuGidY91cJqNK5u33H8e%2Fuploads%2Fgit-blob-b883dea66c29ad67080d5b834a1978ef2283abb2%2FPlatforms%20%20XCover%20Travel%20%20Accomodation%20Light.png?alt=media" alt=""></picture><figcaption></figcaption></figure>

1\. User browses travel options and;\
2\. Selects a travel offer\
3\. Partner platform sends an [offer payload](https://partner-docs.covergenius.com/offers/vertical-examples/travel-accomodation/create-offer#post-partners-partner_code-offers) to the create offer endpoint\
4\. User selects offer products\
5\. User pays for travel and offer products at checkout\
6\. [Payment collection](/offers/guides/payment-process)\
7\. Partner sends a [confirmation request](https://partner-docs.covergenius.com/offers/vertical-examples/travel-accomodation/confirm-offer#post-partners-partner_code-offers-offer_id-confirm) to the confirm offer endpoint\
8\. XCover sends confirmation email including policy details, Partner sends purchase confirmation and tax invoice.

#### Post sale processes

[Modification](/offers/guides/purchase-workflow-overview/modify-booking)\
Where a partner operates a management service for booked travel services, modifications to policies may be submitted to adjust for trip length (financial adjustment), or basic updates such as address changes for a policy profile (non-financial adjustment)

<figure><picture><source srcset="/files/SQU9mJkRnt3F7mKpeync" media="(prefers-color-scheme: dark)"><img src="https://3062128269-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMuGidY91cJqNK5u33H8e%2Fuploads%2Fgit-blob-623a8d1ce245478bdbe47fcae3d5c5d03e7cb02f%2FPlatforms%20%20XCover%20%20Workflow%20Overview%20%20Modify%20Booking%20Light.png?alt=media" alt=""></picture><figcaption></figcaption></figure>

\
[Cancellation](/offers/guides/purchase-workflow-overview/cancel-booking)\
Should a partner need to facilitate travel and policy cancellation (note that this differs from trip cancellation policies, which due to their nature, may not be cancelled), the below workflow should be referenced.

<figure><picture><source srcset="/files/mVHzF449IXiEjWuZ2tEl" media="(prefers-color-scheme: dark)"><img src="https://3062128269-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMuGidY91cJqNK5u33H8e%2Fuploads%2Fgit-blob-2e4461feff429764dd0471e88d97fe0f95bec325%2FPlatforms%20%20XCover%20%20Workflow%20Overview%20Cancel%20Booking%20Light.png?alt=media" alt=""></picture><figcaption></figcaption></figure>

#### Opt-out process

In circumstances where a customer chooses to purchase travel, but not the insurance offer. An opt-out request is used to notify XCover of a non-opted insurance offer. This assists with pricing and product offer data analysis and ultimately improved offers and sales results.

<figure><picture><source srcset="/files/RWspiQHeXhmBiTql66Hs" media="(prefers-color-scheme: dark)"><img src="https://3062128269-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMuGidY91cJqNK5u33H8e%2Fuploads%2Fgit-blob-a1853f96b8668c5c0e5bfdd22076e74ad2b2e0a9%2FPlatforms%20%20XCover%20%20Workflow%20Overview%20%20Opt-out%20Offer%20Light.png?alt=media" alt=""></picture><figcaption></figcaption></figure>


# Create Offer

## Create Offer

> The Create Offer endpoint generates product offerings based on your business context and customer information. This endpoint uses a schema-driven approach to validate requests and returns one or more products with detailed pricing, product information, and content for display.

```json
{"openapi":"3.0.0","info":{"title":"Offers API","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n* **Example:** `X-Api-Key: a1b2c3d4e5f6g7h8`\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n* **Example:** `Date: Sun, 09 Nov 2025 04:04:00 GMT`\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** The cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\n**Signature Generation Logic:**\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/offers/":{"post":{"summary":"Create Offer","description":"The Create Offer endpoint generates product offerings based on your business context and customer information. This endpoint uses a schema-driven approach to validate requests and returns one or more products with detailed pricing, product information, and content for display.","tags":["Create Offer"],"parameters":[{"name":"active_only","in":"query","required":false,"description":"When using a test API key, only return active offers","schema":{"type":"boolean","default":false}},{"name":"include_content","in":"query","required":false,"description":"Include localized content in the response","schema":{"type":"boolean","default":true}},{"name":"extra_fields","in":"query","required":false,"description":"Comma-separated list of specific extra fields to include. Available fields: tax, commission, benefits, surcharge","schema":{"type":"string"}},{"name":"exclude_offer_ids","in":"query","required":false,"description":"Comma-separated list of Offer Config IDs to exclude from the response","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"schema":{"type":"string","description":"Schema identifier for the offer type. If not provided, the default schema for your partner will be used. The Client Solutions Engineer (CSE) will provide the appropriate schema identifier during integration."},"customer":{"type":"object","description":"Customer information","properties":{"currency":{"type":"string","description":"Currency code (e.g., USD, AUD, EUR, GBP)"},"language":{"type":"string","description":"Customer's preferred language (e.g., en)"},"country":{"type":"string","description":"Customer's country code (e.g., US, AU, GB)"},"region":{"type":"string","description":"Customer's region or state"},"email":{"type":"string","format":"email","description":"Customer's email address"},"ip":{"type":"string","description":"Customer's IP address"},"postcode":{"type":"string","description":"Customer's postal code"}},"required":["currency","language","country"]},"context":{"type":"object","description":"Business context data required for offer selection and pricing. The specific fields required will be defined through the offer schema with the Client Solutions Engineer (CSE).","additionalProperties":true},"partner":{"type":"object","description":"Partner information","properties":{"subsidiary":{"type":"string","description":"Partner subsidiary identifier"},"transaction_id":{"type":"string","description":"Partner transaction identifier"},"customer_id":{"type":"string","description":"Partner customer identifier"},"metadata":{"type":"object","description":"Additional partner metadata"}}}},"required":["schema","customer","context"]}}}},"responses":{"200":{"description":"OK","headers":{"Date":{"schema":{"type":"string"}},"Transfer-Encoding":{"schema":{"type":"string"}},"Connection":{"schema":{"type":"string"}},"CF-Ray":{"schema":{"type":"integer"}},"CF-Cache-Status":{"schema":{"type":"string"}},"Allow":{"schema":{"type":"string"}},"Server":{"schema":{"type":"string"}},"Strict-Transport-Security":{"schema":{"type":"string"}},"cross-origin-opener-policy":{"schema":{"type":"string"}},"referrer-policy":{"schema":{"type":"string"}},"Vary":{"schema":{"type":"string"}},"Content-Encoding":{"schema":{"type":"string"}},"Server-Timing":{"schema":{"type":"string"}},"Cf-Team":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"offer_config_id":{"type":"string"},"offer_schema":{"type":"string"},"currency":{"type":"string"},"products":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"product_config_id":{"type":"string"},"type":{"type":"string"},"details":{"type":"object","properties":{"policy_version_id":{"type":"string"},"start_date":{"type":"string","format":"date-time"},"end_date":{"type":"string","format":"date-time"},"finance":{"type":"object","properties":{"price":{"type":"object","properties":{"total_amount":{"type":"number"},"total_amount_without_tax":{"type":"number"},"total_amount_formatted":{"type":"string"},"total_amount_without_tax_formatted":{"type":"string"}}},"tax":{"type":"object","properties":{"total_amount":{"type":"number"},"total_amount_formatted":{"type":"string"}}},"surcharge":{"type":"object","properties":{"total_amount":{"nullable":true},"total_amount_formatted":{"nullable":true}}},"commission":{"type":"object","properties":{"total_amount":{"type":"number"},"total_amount_formatted":{"type":"string"}}}}},"pds_url":{"type":"string","format":"uri"},"files":{"type":"array","items":{}},"extra_fields":{"type":"object"},"experiment":{"type":"object"}}}}}},"product_rules":{"type":"array","description":"Product display and selection rules","items":{"type":"object","properties":{"slug":{"type":"string","description":"Unique rule identifier"},"product_ids":{"type":"array","description":"Array of product IDs in this rule","items":{"type":"string"}},"initial_state":{"type":"string","enum":["show","hide","disable"],"description":"Initial display state"},"min_select":{"type":"integer","description":"Minimum number of products to select"},"max_select":{"type":"integer","description":"Maximum number of products to select"},"events":{"type":"array","description":"Event-driven rules. Can be empty array for terminal rules or single product rules.","items":{"type":"object","properties":{"on":{"type":"string","enum":["select","deselect","accept","decline"],"description":"Trigger event"},"action":{"type":"string","enum":["show","hide","enable","disable"],"description":"Action to perform"},"target_rule":{"type":"string","description":"Target rule slug"}}}}}}},"content":{"type":"object","properties":{"schema_version":{"type":"string","description":"Content schema version"},"locale":{"type":"string","description":"Content locale (e.g., en-AU, en-US)"},"slug":{"type":"string","description":"Content slug identifier for the offer"},"title":{"type":"string","description":"Main title for the offer"},"heading":{"type":"string","description":"Heading text"},"sub_heading":{"type":"string","description":"Sub-heading text"},"disclaimer":{"type":"string","description":"Legal disclaimer text"},"disclaimer_html":{"type":"string","description":"HTML formatted disclaimer"},"price_unit":{"type":"string","description":"Price unit descriptor (e.g., per person)"},"description":{"type":"string","description":"Offer description"},"positive_cta":{"type":"string","description":"Text for accept/yes button"},"negative_cta":{"type":"string","description":"Text for decline/no button"},"negative_cta_warning":{"type":"string","description":"Warning shown when user declines"},"required_message":{"type":"string","description":"Message shown when selection is required"},"credibility_message":{"type":"string","description":"Trust/credibility message (deprecated, use credibility)"},"credibility":{"type":"string","description":"Credibility message text"},"credibility_sales_count":{"type":"integer","description":"Number for credibility metric"},"products":{"type":"array","description":"Content for each product","items":{"type":"object","properties":{"id":{"type":"string","description":"Product content identifier"},"product_config_id":{"type":"string","description":"Product configuration identifier"},"slug":{"type":"string","description":"Content slug identifier for this product"},"locale":{"type":"string","description":"Content locale"},"title":{"type":"string","description":"Product title"},"description":{"type":"string","description":"Product description"},"benefits":{"type":"object","description":"Product benefits with dynamic keys (benefit_1, benefit_2, etc.)","additionalProperties":{"type":"string"}},"exclusions":{"type":"object","description":"Product exclusions with dynamic keys (exclusion_1, exclusion_2, etc.)","additionalProperties":{"type":"string"}},"inclusions":{"type":"object","description":"Product inclusions with dynamic keys (inclusion_1, inclusion_2, etc.)","additionalProperties":{"type":"string"}},"disclaimer":{"type":"string","description":"Product-specific disclaimer"},"disclaimer_html":{"type":"string","description":"HTML formatted product disclaimer"},"credibility_badge":{"type":"string","description":"Credibility badge content (e.g., Most Popular)"}}}}}},"errors":{"type":"object","description":"Any errors encountered during offer creation"}}}}}},"403":{"description":"Forbidden","headers":{"Date":{"schema":{"deprecated":false}},"Transfer-Encoding":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}},"Content-Encoding":{"schema":{"deprecated":false}},"Server-Timing":{"schema":{"deprecated":false}},"Cf-Team":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","headers":{"Date":{"schema":{"deprecated":false}},"Content-Length":{"schema":{"deprecated":false}},"Connection":{"schema":{"deprecated":false}},"CF-Ray":{"schema":{"deprecated":false}},"CF-Cache-Status":{"schema":{"deprecated":false}},"Allow":{"schema":{"deprecated":false}},"Server":{"schema":{"deprecated":false}},"Strict-Transport-Security":{"schema":{"deprecated":false}},"cross-origin-opener-policy":{"schema":{"deprecated":false}},"referrer-policy":{"schema":{"deprecated":false}},"Vary":{"schema":{"deprecated":false}},"Server-Timing":{"schema":{"deprecated":false}},"Cf-Team":{"schema":{"deprecated":false}}},"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object","properties":{"schema":{"type":"array","items":{"type":"string","format":"style"}}}}}}}}}}}}}}
```


# Confirm Offer

## Confirm Offer

> The Confirm Offer endpoint is used to finalize the purchase of products from a previously created Offer. This endpoint converts the selected Offer into a confirmed booking after payment has been successfully collected.\
> \
> \## Idempotency\
> \
> This endpoint supports idempotency keys via the \`x-idempotency-key\` header to prevent duplicate transactions. Provide a unique operation identifier (e.g., UUID) to ensure safe retries. Duplicate requests return:\
> \- \*\*409 Conflict\*\*: The request was already processed; response contains\
> &#x20; the cached original result (handle as success)\
> \
> \- \*\*423 Locked\*\*: The original request is still processing; retry after\
> &#x20; a short delay

```json
{"openapi":"3.0.0","info":{"title":"Offers API","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n* **Example:** `X-Api-Key: a1b2c3d4e5f6g7h8`\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n* **Example:** `Date: Sun, 09 Nov 2025 04:04:00 GMT`\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** The cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\n**Signature Generation Logic:**\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/offers/{offer_id}/confirm/":{"post":{"summary":"Confirm Offer","description":"The Confirm Offer endpoint is used to finalize the purchase of products from a previously created Offer. This endpoint converts the selected Offer into a confirmed booking after payment has been successfully collected.\n\n## Idempotency\n\nThis endpoint supports idempotency keys via the `x-idempotency-key` header to prevent duplicate transactions. Provide a unique operation identifier (e.g., UUID) to ensure safe retries. Duplicate requests return:\n- **409 Conflict**: The request was already processed; response contains\n  the cached original result (handle as success)\n\n- **423 Locked**: The original request is still processing; retry after\n  a short delay","tags":["Confirm Offer"],"parameters":[{"name":"x-idempotency-key","in":"header","required":false,"description":"A unique identifier to ensure idempotent request processing. If a request with the same idempotency key and body has already been processed, the cached response is returned with a 409 Conflict status code (which can be treated as successful). Keys are stored for 48 hours.","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"quotes":{"type":"array","description":"Array of quote objects to confirm","items":{"type":"object","properties":{"id":{"type":"string","description":"The product ID (quote ID) from the offer response"},"insured":{"type":"array","description":"List of insured persons if required by the policy","items":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"birth_date":{"type":"string","format":"date"},"age":{"type":"integer"}}}}},"required":["id"]}},"policyholder":{"type":"object","description":"Policyholder information","properties":{"first_name":{"type":"string","description":"Policyholder's first name"},"last_name":{"type":"string","description":"Policyholder's last name"},"email":{"type":"string","format":"email","description":"Policyholder's email address"},"address1":{"type":"string","description":"Policyholder's address line 1"},"city":{"type":"string","description":"Policyholder's city"},"country":{"type":"string","description":"Policyholder's country code"}},"required":["first_name","last_name","email","country"]}},"required":["quotes","policyholder"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Booking ID"},"status":{"type":"string","description":"Booking status"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"partner_transaction_id":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"pds_url":{"type":"string","format":"uri"},"security_token":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"policy_start_date":{"type":"string","format":"date-time"},"policy_end_date":{"type":"string","format":"date-time"},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"policy":{"type":"object","properties":{"policy_type":{"type":"string"},"policy_type_version":{"type":"string"},"policy_type_slug":{"type":"string"},"policy_type_group_name":{"type":"string"},"policy_name":{"type":"string"},"policy_code":{"type":"string"},"policy_version":{"type":"string"},"category":{"type":"string"},"policy_currency":{"type":"string"}}},"insured":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"age":{"type":"integer"},"birth_date":{"type":"string","format":"date"}}}},"tax":{"type":"object","properties":{"total_tax":{"type":"number"},"total_amount_without_tax":{"type":"number"},"taxes":{"type":"array","items":{"type":"object","properties":{"tax_amount":{"type":"number"},"tax_code":{"type":"string"},"tax_amount_formatted":{"type":"string"}}}},"total_tax_formatted":{"type":"string"},"total_amount_without_tax_formatted":{"type":"string"}}},"benefits":{"type":"array","items":{"type":"object","properties":{"benefit_content_id":{"type":"string"},"description":{"type":"string"},"limit":{"type":"number"},"limit_formatted":{"type":"string"},"excess":{"type":"number"},"excess_formatted":{"type":"string"}}}},"commission":{"type":"object","properties":{"partner_commission":{"type":"number"},"total_commission":{"type":"number"},"partner_commission_formatted":{"type":"string"},"total_commission_formatted":{"type":"string"}}},"created_at":{"type":"string","format":"date-time"},"confirmed_at":{"type":"string","format":"date-time"},"pds_url":{"type":"string","format":"uri"},"can_be_cancelled":{"type":"boolean"}}}},"coi":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"pdf":{"type":"string","format":"uri"}}},"policyholder":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"country":{"type":"string"}}},"total_tax":{"type":"number"},"total_tax_formatted":{"type":"string"},"total_premium":{"type":"number"},"total_premium_formatted":{"type":"string"},"fnol_link":{"type":"string","format":"uri"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"409":{"description":"Conflict - Duplicate Request (Idempotent)","content":{"application/json":{"schema":{"type":"object","description":"Returns the cached response from the original successful request. This response can be handled identically to a 200 OK response."}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"array","items":{"type":"string"}}}}}}},"423":{"description":"Locked - Request In Progress","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}
```


# Opt Out Offer

## Opt-out Offer

> The Opt-out Offer endpoint is used to record when a customer declines an offer. This helps track conversion rates and customer preferences.

```json
{"openapi":"3.0.0","info":{"title":"Offers API","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n* **Example:** `X-Api-Key: a1b2c3d4e5f6g7h8`\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n* **Example:** `Date: Sun, 09 Nov 2025 04:04:00 GMT`\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** The cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\n**Signature Generation Logic:**\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/offers/{offer_id}/opt_out/":{"post":{"summary":"Opt-out Offer","description":"The Opt-out Offer endpoint is used to record when a customer declines an offer. This helps track conversion rates and customer preferences.","tags":["Opt-out Offer"],"responses":{"204":{"description":"No Content - Opt-out recorded successfully"},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}
```


# Modify Booking

## Modify Booking

> The Modify Booking endpoint is used when a customer wants to make changes to their existing policy. This endpoint allows you to update policy details which may result in price adjustments, refunds, or additional fees. The modification is applied directly.

```json
{"openapi":"3.0.0","info":{"title":"Offers API","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n* **Example:** `X-Api-Key: a1b2c3d4e5f6g7h8`\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n* **Example:** `Date: Sun, 09 Nov 2025 04:04:00 GMT`\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** The cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\n**Signature Generation Logic:**\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/":{"patch":{"summary":"Modify Booking","description":"The Modify Booking endpoint is used when a customer wants to make changes to their existing policy. This endpoint allows you to update policy details which may result in price adjustments, refunds, or additional fees. The modification is applied directly.","tags":["Modify Booking"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The quote ID to modify"},"update_fields":{"type":"object","description":"Fields to update on the quote","additionalProperties":true}},"required":["id","update_fields"]}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"price_diff":{"type":"number"},"price_diff_formatted":{"type":"string"}}}},"total_price_diff":{"type":"number"},"total_price_diff_formatted":{"type":"string"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"array","items":{"type":"string"}}}}}}}}}}}}
```

## Modify Booking - Preview

> The Modify Booking Preview endpoint allows you to preview the price changes that would result from a modification without actually applying them. The response includes an update\_id that can be used to confirm the modification.

```json
{"openapi":"3.0.0","info":{"title":"Offers API","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n* **Example:** `X-Api-Key: a1b2c3d4e5f6g7h8`\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n* **Example:** `Date: Sun, 09 Nov 2025 04:04:00 GMT`\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** The cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\n**Signature Generation Logic:**\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/quote_for_update":{"patch":{"summary":"Modify Booking - Preview","description":"The Modify Booking Preview endpoint allows you to preview the price changes that would result from a modification without actually applying them. The response includes an update_id that can be used to confirm the modification.","tags":["Modify Booking"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The quote ID to modify"},"update_fields":{"type":"object","description":"Fields to update on the quote","additionalProperties":true}},"required":["id","update_fields"]}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"price_diff":{"type":"number"},"price_diff_formatted":{"type":"string"}}}},"total_price_diff":{"type":"number"},"total_price_diff_formatted":{"type":"string"},"update_id":{"type":"string","description":"The update ID to use when confirming this modification via the Confirm Update endpoint."}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object"}}}}}}}}}}}
```

## Modify Booking - Confirm

> The Confirm Update endpoint finalizes a previewed modification. Use the update\_id returned from the Modify Booking Preview endpoint.

```json
{"openapi":"3.0.0","info":{"title":"Offers API","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n* **Example:** `X-Api-Key: a1b2c3d4e5f6g7h8`\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n* **Example:** `Date: Sun, 09 Nov 2025 04:04:00 GMT`\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** The cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\n**Signature Generation Logic:**\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/confirm_update/{update_id}/":{"post":{"summary":"Modify Booking - Confirm","description":"The Confirm Update endpoint finalizes a previewed modification. Use the update_id returned from the Modify Booking Preview endpoint.","tags":["Modify Booking"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"xpay_charge_id":{"type":"string","description":"XPay charge ID if additional payment is required"}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"price_diff":{"type":"number"},"price_diff_formatted":{"type":"string"}}}},"total_price_diff":{"type":"number"},"total_price_diff_formatted":{"type":"string"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}
```


# Cancel Booking

## Cancel Booking

> The Cancel Booking endpoint is used when a customer no longer requires coverage and has contacted the partner directly to cancel the policy. This endpoint handles the cancellation process and calculates any applicable refunds.\
> \
> When \`preview\` is set to \`true\`, the cancellation is not applied but a preview of the refund is returned along with a \`cancellation\_id\` that can be used to confirm the cancellation.\
> \
> When \`preview\` is set to \`false\` (or omitted), the cancellation is applied immediately.

```json
{"openapi":"3.0.0","info":{"title":"Offers API","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n* **Example:** `X-Api-Key: a1b2c3d4e5f6g7h8`\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n* **Example:** `Date: Sun, 09 Nov 2025 04:04:00 GMT`\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** The cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\n**Signature Generation Logic:**\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/cancel":{"post":{"summary":"Cancel Booking","description":"The Cancel Booking endpoint is used when a customer no longer requires coverage and has contacted the partner directly to cancel the policy. This endpoint handles the cancellation process and calculates any applicable refunds.\n\nWhen `preview` is set to `true`, the cancellation is not applied but a preview of the refund is returned along with a `cancellation_id` that can be used to confirm the cancellation.\n\nWhen `preview` is set to `false` (or omitted), the cancellation is applied immediately.","tags":["Cancel Booking"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"preview":{"type":"boolean","description":"When true, returns a preview of the cancellation without applying it. Use the returned cancellation_id to confirm."},"refund_required":{"type":"boolean","description":"Whether a refund is required for this cancellation"},"quotes":{"type":"array","description":"Array of quotes to cancel. Required when preview is true.","items":{"type":"object","properties":{"id":{"type":"string","description":"The quote ID to cancel"},"reason_for_cancellation":{"type":"string","description":"Reason for cancelling this quote"}},"required":["id"]}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"policy_start_date":{"type":"string","format":"date-time"},"policy_end_date":{"type":"string","format":"date-time"},"policy_cancellation_date":{"type":"string","format":"date-time","nullable":true},"status":{"type":"string"},"price":{"type":"number"},"refund_value":{"type":"number"},"adjustment_fee":{"type":"number"}}}},"policyholder":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"country":{"type":"string"}}},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"total_refund":{"type":"number"},"total_refund_formatted":{"type":"string"},"currency":{"type":"string"},"cancellation_id":{"type":"string","nullable":true,"description":"Present when preview=true. Use this ID to confirm the cancellation."},"confirm_before":{"type":"string","format":"date-time","nullable":true,"description":"Deadline to confirm the cancellation preview"},"refund_amount":{"type":"number"},"refund_amount_formatted":{"type":"string"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"array","items":{"type":"string"}}}}}}}}}}}}
```

## Cancel Booking - Confirm

> The Confirm Cancellation endpoint finalizes a previewed cancellation. Use the cancellation\_id returned from the Cancel Booking endpoint when preview was set to true.

```json
{"openapi":"3.0.0","info":{"title":"Offers API","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n* **Example:** `X-Api-Key: a1b2c3d4e5f6g7h8`\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n* **Example:** `Date: Sun, 09 Nov 2025 04:04:00 GMT`\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** The cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\n**Signature Generation Logic:**\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/confirm_cancellation/{cancellation_id}/":{"post":{"summary":"Cancel Booking - Confirm","description":"The Confirm Cancellation endpoint finalizes a previewed cancellation. Use the cancellation_id returned from the Cancel Booking endpoint when preview was set to true.","tags":["Cancel Booking"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"reason_for_cancellation":{"type":"string","description":"Reason for the cancellation"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"price":{"type":"number"},"refund_value":{"type":"number"},"cancelled_at":{"type":"string","format":"date-time"}}}},"total_refund":{"type":"number"},"total_refund_formatted":{"type":"string"},"refund_amount":{"type":"number"},"refund_amount_formatted":{"type":"string"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"array","items":{"type":"string"}}}}}}}}}}}}
```


# Parcel / Shipping

Total Shipping Insurance - Offered to Merchants or Consumers

Shipping services and platforms offering parcel shipping, or marketplaces connected to 3rd party logistics services (3PL's) can enable the offer and or attachment of parcel insurance policies in the purchase path. Commonly, partners will integrate XCover using two key purchase process API calls: [create offer](https://partner-docs.covergenius.com/offers/api/reference/create-offer#post-partners-partner_code-offers) and [confirm offer](https://partner-docs.covergenius.com/offers/api/reference/confirm-offer#post-partners-partner_code-offers-offer_id-confirm).\
\
:bulb: See a collection of common requests for this integration type, by contacting your CSE.\
\
Many integrations follow the below high level flow of events:

<figure><picture><source srcset="/files/MFs0WzXq7i0NnVEI1M4u" media="(prefers-color-scheme: dark)"><img src="https://3062128269-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMuGidY91cJqNK5u33H8e%2Fuploads%2Fgit-blob-ce62b77cbe8429e56da896a41eedfc5c039f9992%2FPlatforms%20%20XCover%20%20Vertical%20Examples%20%20ParcelShipping%20Offers%20Light.png?alt=media" alt=""></picture><figcaption></figcaption></figure>

1\. User creates a shipment order\
3\. Partner platform sends an [offer payload](https://partner-docs.covergenius.com/offers/api/reference/create-offer#post-partners-partner_code-offers) to the create offer endpoint\
4\. User selects offer product/s\
5\. User pays for shipment and offer - this is often a debit of merchants shipping account wallet\
6\. Partner sends a [confirmation request payload](https://partner-docs.covergenius.com/offers/api/reference/confirm-offer#post-partners-partner_code-offers-offer_id-confirm) to the confirm offer endpoint\
7\. Confirmation of the coverage is presented to the user

#### Post sale processes

[Cancellation](/offers/guides/purchase-workflow-overview/cancel-booking)\
In the event that a shipment label is not collected, and rendered void by the platform (within appropriate timeframes) the policy booking may be cancelled.


# Create Offer

## Create Offer

> The Create Offer endpoint generates shipping protection offerings for one or more parcels. The request describes the order, the packages being shipped, the carrier, and the sender/receiver. The response returns one or more products with pricing and policy details.

```json
{"openapi":"3.0.0","info":{"title":"Offers API - Logistics","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** Cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/offers/":{"post":{"summary":"Create Offer","description":"The Create Offer endpoint generates shipping protection offerings for one or more parcels. The request describes the order, the packages being shipped, the carrier, and the sender/receiver. The response returns one or more products with pricing and policy details.","tags":["Create Offer"],"parameters":[{"name":"active_only","in":"query","required":false,"description":"When using a test API key, only return active offers","schema":{"type":"boolean","default":false}},{"name":"include_content","in":"query","required":false,"description":"Include localized content in the response","schema":{"type":"boolean","default":true}},{"name":"extra_fields","in":"query","required":false,"description":"Comma-separated list of specific extra fields to include. Available fields: tax, commission, benefits, surcharge","schema":{"type":"string"}},{"name":"exclude_offer_ids","in":"query","required":false,"description":"Comma-separated list of Offer Config IDs to exclude from the response","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"schema":{"type":"string","description":"Schema identifier for the offer type. If not provided, the default schema for your partner will be used. The Client Solutions Engineer (CSE) will provide the appropriate schema identifier during integration."},"placement":{"type":"string","description":"Where the offer is being displayed in the partner flow (e.g., checkout, cart, post-purchase)."},"customer":{"type":"object","description":"Customer information","properties":{"currency":{"type":"string","description":"Currency code (e.g., USD, AUD, EUR, GBP)"},"country":{"type":"string","description":"Customer's country code (e.g., US, AU, GB)"},"region":{"type":"string","description":"Customer's region or state"},"language":{"type":"string","description":"Customer's preferred language (e.g., en)"},"email":{"type":"string","format":"email"},"ip":{"type":"string"},"postcode":{"type":"string"}},"required":["currency","country","language"]},"partner":{"type":"object","description":"Partner information","properties":{"transaction_id":{"type":"string","description":"Partner transaction identifier"},"customer_id":{"type":"string","description":"Partner customer identifier"},"subsidiary":{"type":"string","description":"Partner subsidiary identifier"},"metadata":{"type":"object","description":"Additional partner metadata","properties":{"merchant_id":{"type":"string","description":"Merchant identifier"},"merchant_name":{"type":"string","description":"Human-readable merchant name"}},"additionalProperties":true}}},"context":{"type":"object","description":"Logistics-specific context describing the order, shipment, packages, sender, and receiver.","properties":{"order_total":{"type":"integer","description":"Total order amount in the minor unit of the customer currency (e.g., cents for USD)."},"shipping_cost":{"type":"integer","description":"Shipping cost charged to the customer (minor units)."},"declared_value":{"type":"integer","description":"Total declared value of the shipment (minor units). Used to derive coverage."},"lot_url":{"type":"string","format":"uri","description":"URL to the product listing or order summary, used for downstream verification."},"carrier":{"type":"string","description":"Shipping carrier (e.g., UPS, FedEx, USPS, DHL)."},"carrier_service_name":{"type":"string","description":"Specific carrier service (e.g., UPS Ground, FedEx Express)."},"shipping_date":{"type":"string","format":"date-time","description":"Date the shipment is dispatched."},"shipping_method":{"type":"string","description":"How the package is handed to the carrier (e.g., drop off, pickup)."},"frontend_distr":{"type":"boolean","description":"True when the offer is presented directly to the end customer (frontend distribution)."},"dual_coverage":{"type":"boolean","description":"True when the shipment is already partially covered by the carrier (used to avoid double coverage)."},"packages":{"type":"array","description":"Packages being shipped under this offer.","items":{"type":"object","properties":{"type":{"type":"string","description":"Package type (e.g., Parcel, Pallet, Envelope)."},"width":{"type":"number","description":"Package width."},"height":{"type":"number","description":"Package height."},"length":{"type":"number","description":"Package length."},"weight":{"type":"number","description":"Package weight."},"description":{"type":"string","description":"Free-text description of the package contents."},"declared_value":{"type":"integer","description":"Declared value of this package (minor units)."},"items":{"type":"array","description":"Individual items contained in the package.","items":{"type":"object","properties":{"sku":{"type":"string"},"hs_code":{"type":"string","description":"Harmonized System (HS) tariff code."},"brand":{"type":"string"},"model":{"type":"string"},"description":{"type":"string"},"quantity":{"type":"integer"},"price":{"type":"integer","description":"Item price (minor units)."}},"required":["sku","quantity","price"]}}},"required":["type","declared_value"]}},"receiver":{"type":"object","description":"Recipient of the shipment.","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"address1":{"type":"string"},"address2":{"type":"string"},"city":{"type":"string"},"postcode":{"type":"string"},"region":{"type":"string"},"country":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"}},"required":["first_name","last_name","address1","city","postcode","country"]},"sender":{"type":"object","description":"Sender / fulfillment origin.","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"company_name":{"type":"string"},"address1":{"type":"string"},"address2":{"type":"string"},"city":{"type":"string"},"postcode":{"type":"string"},"region":{"type":"string"},"country":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"}}}},"additionalProperties":true}},"required":["schema","customer","context"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Offer ID"},"offer_config_id":{"type":"string"},"offer_schema":{"type":"string"},"currency":{"type":"string"},"products":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"product_config_id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","nullable":true},"schema_url":{"type":"string","nullable":true,"format":"uri"},"details":{"type":"object","properties":{"policy_version_id":{"type":"string"},"start_date":{"type":"string","format":"date-time","nullable":true},"end_date":{"type":"string","format":"date-time","nullable":true},"finance":{"type":"object","properties":{"price":{"type":"object","properties":{"total_amount":{"type":"number","nullable":true},"total_amount_without_tax":{"type":"number","nullable":true},"total_amount_min":{"type":"number","nullable":true},"total_amount_max":{"type":"number","nullable":true},"total_amount_formatted":{"type":"string","nullable":true},"total_amount_without_tax_formatted":{"type":"string","nullable":true},"total_amount_min_formatted":{"type":"string","nullable":true},"total_amount_max_formatted":{"type":"string","nullable":true}}},"tax":{"type":"object","properties":{"total_amount":{"type":"number","nullable":true},"total_amount_formatted":{"type":"string","nullable":true}}},"surcharge":{"type":"object","properties":{"total_amount":{"type":"number","nullable":true},"total_amount_formatted":{"type":"string","nullable":true}}},"commission":{"type":"object","properties":{"total_amount":{"type":"number","nullable":true},"total_amount_formatted":{"type":"string","nullable":true}}}}},"pds_url":{"type":"string","format":"uri"},"files":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"url":{"type":"string","format":"uri"},"type":{"type":"string"}}}},"extra_fields":{"type":"object","description":"Logistics-specific computed fields about the resulting policy.","properties":{"shipping_type":{"type":"string","description":"Computed shipment classification (e.g., domestic, international)."},"address_computed":{"type":"string","description":"Receiver address concatenated for verification."},"policy_end_date":{"type":"string","format":"date-time","nullable":true},"policy_duration":{"type":"integer","description":"Coverage duration in days."},"partner_subsidiary":{"type":"string","nullable":true}},"additionalProperties":true},"experiment":{"type":"object","additionalProperties":true},"benefits":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"content":{"type":"object","properties":{"schema_version":{"type":"string"},"locale":{"type":"string"}}},"errors":{"type":"object","additionalProperties":true}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object","properties":{"schema":{"type":"array","items":{"type":"string"}}}}}}}}}}}}}}
```


# Confirm Offer

## Confirm Offer

> Finalize the purchase of shipping protection from a previously created Offer. Converts the selected Offer into a confirmed booking after payment has been collected.\
> \
> \## Idempotency\
> \
> This endpoint supports idempotency keys via the \`x-idempotency-key\` header to prevent duplicate transactions.

```json
{"openapi":"3.0.0","info":{"title":"Offers API - Logistics","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** Cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/offers/{offer_id}/confirm/":{"post":{"summary":"Confirm Offer","description":"Finalize the purchase of shipping protection from a previously created Offer. Converts the selected Offer into a confirmed booking after payment has been collected.\n\n## Idempotency\n\nThis endpoint supports idempotency keys via the `x-idempotency-key` header to prevent duplicate transactions.","tags":["Confirm Offer"],"parameters":[{"name":"x-idempotency-key","in":"header","required":false,"description":"A unique identifier to ensure idempotent request processing. Keys are stored for 48 hours.","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"quotes":{"type":"array","description":"Array of quote objects to confirm","items":{"type":"object","properties":{"id":{"type":"string","description":"The product ID (quote ID) from the offer response"}},"required":["id"]}},"policyholder":{"type":"object","description":"Policyholder information. For logistics, this is typically the shipment receiver.","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"address1":{"type":"string"},"address2":{"type":"string"},"city":{"type":"string"},"postcode":{"type":"string"},"region":{"type":"string"},"country":{"type":"string"}},"required":["first_name","last_name","email","country"]}},"required":["quotes","policyholder"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"partner_transaction_id":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"pds_url":{"type":"string","format":"uri"},"security_token":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"policy_start_date":{"type":"string","format":"date-time"},"policy_end_date":{"type":"string","format":"date-time","nullable":true},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"policy":{"type":"object","properties":{"policy_type":{"type":"string"},"policy_type_version":{"type":"string"},"policy_type_slug":{"type":"string"},"policy_type_group_name":{"type":"string"},"policy_name":{"type":"string"},"policy_code":{"type":"string"},"policy_version":{"type":"string"},"category":{"type":"string"},"policy_currency":{"type":"string"}}},"tax":{"type":"object","properties":{"total_tax":{"type":"number","nullable":true},"total_amount_without_tax":{"type":"number","nullable":true},"total_tax_formatted":{"type":"string","nullable":true},"total_amount_without_tax_formatted":{"type":"string","nullable":true}}},"benefits":{"type":"array","items":{"type":"object","additionalProperties":true}},"commission":{"type":"object","properties":{"partner_commission":{"type":"number","nullable":true},"total_commission":{"type":"number","nullable":true},"partner_commission_formatted":{"type":"string","nullable":true},"total_commission_formatted":{"type":"string","nullable":true}}},"created_at":{"type":"string","format":"date-time"},"confirmed_at":{"type":"string","format":"date-time"},"pds_url":{"type":"string","format":"uri"},"can_be_cancelled":{"type":"boolean"}}}},"coi":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"pdf":{"type":"string","format":"uri"}}},"policyholder":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"country":{"type":"string"}}},"total_tax":{"type":"number"},"total_tax_formatted":{"type":"string"},"total_premium":{"type":"number"},"total_premium_formatted":{"type":"string"},"fnol_link":{"type":"string","format":"uri"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"409":{"description":"Conflict - Duplicate Request (Idempotent)","content":{"application/json":{"schema":{"type":"object"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"array","items":{"type":"string"}}}}}}},"423":{"description":"Locked - Request In Progress","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}
```


# Opt Out Offer

## Opt-out Offer

> Record when a customer declines a shipping protection offer. Helps track conversion rates and customer preferences.

```json
{"openapi":"3.0.0","info":{"title":"Offers API - Logistics","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** Cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/offers/{offer_id}/opt_out/":{"post":{"summary":"Opt-out Offer","description":"Record when a customer declines a shipping protection offer. Helps track conversion rates and customer preferences.","tags":["Opt-out Offer"],"responses":{"204":{"description":"No Content - Opt-out recorded successfully"},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}
```


# Modify Booking

## Modify Booking

> Modify an existing shipping protection booking. Typical logistics modifications include updating the shipping date when dispatch slips, or adjusting carrier details. The modification is applied directly and may produce a small price adjustment.

```json
{"openapi":"3.0.0","info":{"title":"Offers API - Logistics","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** Cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/":{"patch":{"summary":"Modify Booking","description":"Modify an existing shipping protection booking. Typical logistics modifications include updating the shipping date when dispatch slips, or adjusting carrier details. The modification is applied directly and may produce a small price adjustment.","tags":["Modify Booking"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The quote ID to modify"},"update_fields":{"type":"object","description":"Fields to update on the quote. For logistics, common fields include shipping_date, carrier, and carrier_service_name.","additionalProperties":true}},"required":["id","update_fields"]}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"price_diff":{"type":"number"},"price_diff_formatted":{"type":"string"}}}},"total_price_diff":{"type":"number"},"total_price_diff_formatted":{"type":"string"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"array","items":{"type":"string"}}}}}}}}}}}}
```

## Modify Booking - Preview

> Preview the price changes that would result from a modification without applying them. The response includes an \`update\_id\` that can be used to confirm the modification.

```json
{"openapi":"3.0.0","info":{"title":"Offers API - Logistics","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** Cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/quote_for_update":{"patch":{"summary":"Modify Booking - Preview","description":"Preview the price changes that would result from a modification without applying them. The response includes an `update_id` that can be used to confirm the modification.","tags":["Modify Booking"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"update_fields":{"type":"object","additionalProperties":true}},"required":["id","update_fields"]}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"price_diff":{"type":"number"},"price_diff_formatted":{"type":"string"}}}},"total_price_diff":{"type":"number"},"total_price_diff_formatted":{"type":"string"},"update_id":{"type":"string"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"object"}}}}}}}}}}}
```

## Modify Booking - Confirm

> Finalize a previewed modification. Use the \`update\_id\` returned from the Modify Booking Preview endpoint.

```json
{"openapi":"3.0.0","info":{"title":"Offers API - Logistics","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** Cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/confirm_update/{update_id}/":{"post":{"summary":"Modify Booking - Confirm","description":"Finalize a previewed modification. Use the `update_id` returned from the Modify Booking Preview endpoint.","tags":["Modify Booking"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"xpay_charge_id":{"type":"string","description":"XPay charge ID if additional payment is required"}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"currency":{"type":"string"},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"price":{"type":"number"},"price_formatted":{"type":"string"},"price_diff":{"type":"number"},"price_diff_formatted":{"type":"string"}}}},"total_price_diff":{"type":"number"},"total_price_diff_formatted":{"type":"string"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}
```


# Cancel Booking

## Cancel Booking

> Cancel a shipping protection booking. Common logistics cancellation reasons include the shipment being cancelled before dispatch, the order being returned, or a duplicate booking.\
> \
> When \`preview\` is \`true\`, returns a refund preview with a \`cancellation\_id\`. When \`preview\` is \`false\` (or omitted), the cancellation is applied immediately.

```json
{"openapi":"3.0.0","info":{"title":"Offers API - Logistics","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** Cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/cancel":{"post":{"summary":"Cancel Booking","description":"Cancel a shipping protection booking. Common logistics cancellation reasons include the shipment being cancelled before dispatch, the order being returned, or a duplicate booking.\n\nWhen `preview` is `true`, returns a refund preview with a `cancellation_id`. When `preview` is `false` (or omitted), the cancellation is applied immediately.","tags":["Cancel Booking"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"preview":{"type":"boolean"},"refund_required":{"type":"boolean"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"reason_for_cancellation":{"type":"string"}},"required":["id"]}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"policy_start_date":{"type":"string","format":"date-time"},"policy_end_date":{"type":"string","format":"date-time","nullable":true},"policy_cancellation_date":{"type":"string","format":"date-time","nullable":true},"status":{"type":"string"},"price":{"type":"number"},"refund_value":{"type":"number"},"adjustment_fee":{"type":"number"}}}},"policyholder":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string","format":"email"},"country":{"type":"string"}}},"total_price":{"type":"number"},"total_price_formatted":{"type":"string"},"total_refund":{"type":"number"},"total_refund_formatted":{"type":"string"},"currency":{"type":"string"},"cancellation_id":{"type":"string","nullable":true},"confirm_before":{"type":"string","format":"date-time","nullable":true},"refund_amount":{"type":"number"},"refund_amount_formatted":{"type":"string"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"array","items":{"type":"string"}}}}}}}}}}}}
```

## Cancel Booking - Confirm

> Finalize a previewed cancellation. Use the \`cancellation\_id\` returned from the Cancel Booking preview endpoint.

```json
{"openapi":"3.0.0","info":{"title":"Offers API - Logistics","version":"1.0.0"},"servers":[{"url":"https://api.xcover.com/x"}],"security":[{"CustomAPISignature":[]}],"components":{"securitySchemes":{"CustomAPISignature":{"type":"apiKey","name":"Authorization","in":"header","description":"**Composite Authentication Scheme (Client Key, Date, and Signature)**\n\nThis scheme requires the client to provide **three** mandatory headers in every request:\n\n### 1. X-Api-Key (Client Key)\n* **Purpose:** Public identifier for the API consumer.\n\n### 2. Date (Timestamp)\n* **Purpose:** Timestamp used for generating the signature and preventing replay attacks.\n* **Format:** RFC 7231 format (e.g., in GMT).\n\n### 3. Authorization (Computed Signature)\n* **Purpose:** Cryptographic signature that verifies the request's authenticity and integrity.\n* **Format:** `SIGNATURE [authHeader]`\n\nThe `authHeader` value is derived from a cryptographic hash (e.g., HMAC-SHA256) of canonical request components (HTTP Method, Path, and the contents of the `Date` header), signed with the private **Client Secret**.\n"}}},"paths":{"/partners/{partner_code}/bookings/{booking_id}/confirm_cancellation/{cancellation_id}/":{"post":{"summary":"Cancel Booking - Confirm","description":"Finalize a previewed cancellation. Use the `cancellation_id` returned from the Cancel Booking preview endpoint.","tags":["Cancel Booking"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"reason_for_cancellation":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"quotes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"price":{"type":"number"},"refund_value":{"type":"number"},"cancelled_at":{"type":"string","format":"date-time"}}}},"total_refund":{"type":"number"},"total_refund_formatted":{"type":"string"},"refund_amount":{"type":"number"},"refund_amount_formatted":{"type":"string"}}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"}}}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string"},"message":{"type":"string"},"errors":{"type":"array","items":{"type":"string"}}}}}}}}}}}}
```


# XCover

XCover is Cover Genius's insurance product distribution service that delivers ready-to-sell insurance products through the Offers API. When you integrate with the Offers API, XCover handles product selection, underwriting, pricing, policy administration, and claims management, enabling you to offer insurance without becoming an insurance company.

The Offers API connects your application to XCover's insurance product catalog:

1. **Create Offer** - Send customer and business context to XCover via the Offers API
2. **Receive Products** - XCover returns relevant insurance products with pricing and content
3. **Present to Customer** - Display the insurance offer using the provided content and pricing
4. **Confirm Offer** - When customer accepts, confirm the purchase through the API
5. **Policy Issued** - XCover issues the policy and handles all administration

### What XCover Handles

When you use XCover through the Offers API, the service manages:

**Product Management**

* Insurance product catalog and availability
* Product configuration and rules
* Coverage terms and conditions
* Policy wording and documentation

**Pricing & Underwriting**

* Real-time pricing calculations
* Risk assessment and underwriting
* Dynamic pricing optimization
* Multi-currency support

**Policy Administration**

* Policy issuance and confirmation
* Certificate of Insurance (COI) generation
* Policy modifications and endorsements
* Cancellations and refunds

**Regulatory Compliance**

* Insurance licensing and regulations
* Jurisdiction-specific requirements
* Consumer protection compliance
* Data privacy and security

**Claims Management**

* Claims intake and processing
* Customer support for claims
* Settlement and payouts
* Claims reporting


# Claims

How are users able to view and understand policy details, and initiate claims?

## Claims Handling

Due to their regulated nature, claims are solely handled by Cover Genius.\
Cover Genius is responsible for all communications with users, claims assessment and claims payments.\
Users can lodge the claim on [XCover.com/claims](https://xcover.com/en/account/claims/) by completing an online, pre-filled form, provide a description of the situation/event and provide any supporting information or documents required.\
Generally, in situations where customers contact your platform in regards to claims, they should be redirected to [XCover.com](https://xcover.com).

## First Notice of Loss (FNOL)

Users will need to submit a first notice of loss form (FNOL) in order for claims to be assessed.\
Generally, this is completed by a logged in user at [XCover.com/claims](https://www.xcover.com/en/account/claims/).

## Claim Assessment

Claims will be assessed by Cover Genius via our in-house claims assessment system.\
We leverage our technology and existing policy data to provide efficient and automated approval process, and fast electronic claims payment.

## Medical and Emergency Claims

Medical assistance and medical-related claims may be handled by our underwriting partners directly.\
Cover Genius works with our underwriters to create a user-centric workflow to ensure a smooth process relevant to your use case.

## Can we integrate claims submission ourselves?

Generally, claims are solely managed by Cover Genius.\
If you wish to discuss integrating claims submission into your experience, please contact your partnership manager.


# Policy Management

Most users will manage policies on XCover.com

After booking and over the course of using a policy, users may need to manage their policy, to view and reference their policy inclusions, limits, or terms and conditions, and to update their account information. In most instances, this is performed on [XCover.com](https://www.xcover.com/en/login).

Partners may wish to include a link to this page in their experience, and often a specific policy URL will be appropriate to include, such as:

* Claims:\
  [https://xcover.com/en/account/claims/fnol?bookingID=1ABCD-VWXYZ-INS](https://staging.xcover.com/en/account/claims/fnol?bookingID=7XPGF-LMCQK-INS)
* Modification:\
  <https://xcover.com/en/modify/1ABCD-VWXYZ-INS>
* Certificate of Insurance (COI):\
  [https://xcover.com/en/coi/1ABCD-VWXYZ-INS](https://xcover.com/en/modify/1ABCD-VWXYZ-INS)
* Policy Disclosure Statement / Policy Wording (PDS):\
  [https://xcover.com/en/pds/1ABCD-VWXYZ-INS](https://xcover.com/en/modify/1ABCD-VWXYZ-INS)

Users will also need to have created an account before using these links.\
In most cases, users will receive an account creation email containing a specific login URL shared with them after booking, usually via a policy confirmation email.


# FAQs

Frequently asked questions by developers, devops, business analysts

## Common FAQs by Insurance Vertical

[Events / Tickets](/offers/faqs/events-tickets-faqs)

Travel / Accommodation

Property / Renters

Parcel / Shipping

Product / Retail

## General API FAQs

<details>

<summary>How long does a typical partner integration take?</summary>

Integrations typically take between 4 to 8 weeks. There are several factors affecting this timeline:

* Partner developer resources, in regards to availability, capacity and numbers.
* Customisations to the API
* Testing
* Pricing and bundle experimentation
* Premium collection method (payment processing)

</details>

<details>

<summary>Offers API p99 and p95 latencies</summary>

Find our endpoints p95 and p99 on our [Performance Benchmarks & Latency Targets](/offers/api/performance-benchmarks-and-latency-targets)

</details>

<details>

<summary>Can you provide a Sandbox environment?</summary>

A sandboxed environment will be provided to the partner once a commercial agreement is in place.

The sandbox allows partners to create and modify quotes, create bookings, create. customers, test API responses and perform various other activities.

</details>


# Events / Tickets FAQs

FAQs specific to insurance policies in the events space

<details>

<summary><strong>What happens if the event is cancelled, does the customer get a refund on insurance, do we cancel the insurance?</strong></summary>

If the event is cancelled then it is recommended to send a /cancellation request including the `reason_for_cancellation` as `"Event cancelled"`. A refund will be issued to the customer only within the cooling off period. This period depends on region. For this reason it is recommended to perform a cancellation preview and confirmation and refund the amount returned in the preview response.

</details>


# Overview

RentalCover provides rental vehicle protection that partners embed directly into their booking flow. Customers purchase cover at the point of vehicle rental, reducing their financial exposure to excess charges in the event of an accident or theft.

## What's the typical integration process?

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="103.5675048828125">Step</th><th>Action</th><th>Endpoint</th></tr></thead><tbody><tr><td>1</td><td><strong>Authenticate:</strong> include your API key in every request header.</td><td>N/A</td></tr><tr><td>2</td><td><strong>Quote:</strong> retrieve a price and a Reference based on the customer's booking details.</td><td><code>POST /insurances/quote</code></td></tr><tr><td>3</td><td><strong>Display the offer:</strong> retrieve localised copy, logos, and UI components.</td><td><code>POST /insurances/content</code></td></tr><tr><td>4</td><td><strong>Record consent:</strong> record the customer's decision, whether they accept or decline.</td><td><code>POST /insurances/coverOptOut/&#x3C;reference></code></td></tr><tr><td>5</td><td><strong>Purchase:</strong> confirm and pay for the policy.</td><td><code>POST /insurances/purchase</code></td></tr><tr><td>6</td><td><strong>Manage:</strong> handle post-purchase changes.</td><td><code>Update</code>, <code>Cancel</code>, <code>UpdateCustomer</code></td></tr><tr><td>7</td><td><strong>Receive updates:</strong> get real-time notifications for RentalCover-originated events.</td><td>Webhooks</td></tr></tbody></table>

{% hint style="info" %}
To skip the separate Quote and Purchase steps, use [InstantBooking](/rentalcover/endpoints/instantbooking). It combines both into a single call.
{% endhint %}

## Base URLs

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Environment</th><th>Base URL</th></tr></thead><tbody><tr><td>Staging</td><td>https://api-staging.rentalcover.com </td></tr><tr><td>Production</td><td>https://api.rentalcover.com </td></tr></tbody></table>

**Use staging for all development and testing.** It behaves identically to production but does not process real payments or issue live policies.

## Endpoint Index

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Phase</th><th width="149.84521484375">Method</th><th>Path</th><th>Description</th></tr></thead><tbody><tr><td>Quoting</td><td><code>POST</code></td><td><code>/insurances/quote</code></td><td>Generate a price quote.</td></tr><tr><td>Quoting</td><td><code>POST</code></td><td><code>/insurances/content</code></td><td>Retrieve localised marketing copy and UI components.</td></tr><tr><td>Quoting</td><td><code>POST</code></td><td><code>/insurances/coverOptOut/&#x3C;reference></code></td><td>Record customer opt-in or opt-out.</td></tr><tr><td>Quoting</td><td><code>POST</code></td><td><code>/insurances/instantBooking</code></td><td>Quote and purchase in one call.</td></tr><tr><td>Purchase</td><td><code>POST</code></td><td><code>/insurances/purchase</code></td><td>Confirm a quoted policy.</td></tr><tr><td>Purchase</td><td><code>GET</code></td><td><code>/insurances/status/&#x3C;reference></code></td><td>Check booking status and details.</td></tr><tr><td>Policy management</td><td><code>POST</code></td><td><code>/insurances/update/&#x3C;reference></code></td><td>Modify dates, cover, or customer details.</td></tr><tr><td>Policy management</td><td><code>POST</code></td><td><code>/insurances/updateCustomer</code></td><td>Update customer personal information.</td></tr><tr><td>Policy management</td><td><code>POST</code>/<code>DELETE</code></td><td><code>/insurances/cancel/&#x3C;reference></code></td><td>Cancel a policy before its start date.</td></tr><tr><td>Notifications</td><td><code>GET</code></td><td><code>/notifications/list</code></td><td>Poll for booking events (invoicing partners only).</td></tr><tr><td>Notifications</td><td><code>POST</code></td><td><code>/notifications/update/event/&#x3C;eventid></code></td><td>Acknowledge a processed event.</td></tr><tr><td>Reporting</td><td><code>POST</code></td><td><code>/insurances/getAllPurchasedPolicies</code></td><td>List all purchased and cancelled policies.</td></tr><tr><td>Reporting</td><td><code>POST</code></td><td><code>/insurances/getAllCancelledPolicies</code></td><td>List cancelled policies.</td></tr><tr><td>Reporting</td><td><code>GET</code></td><td><code>/insurances/invoice/&#x3C;reference></code></td><td>Download a PDF invoice.</td></tr></tbody></table>

For troubleshooting or integration support, contact your Cover Genius Client Solutions Engineer (CSE).

<br>


# Quick Start

## Before you begin

You need the following before making your first API call:

* **API credentials:** contact your Cover Genius Client Solutions Engineer (CSE) to receive your staging API key.
* **HTTPS:** all API requests must use HTTPS. HTTP calls are rejected in production.

A server-side environment: the RentalCover API is a server-to-server integration. Never expose your API key in client-side code.

## End-to-end test walkthrough

Walk through the steps below to validate your integration before going live. Confirm you receive the expected response at each step before continuing.

### Step 1. Get a quote

```shellscript
curl -i -X POST \
  -H "X_API_KEY: your_staging_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "FromDate": "2025-08-01 00:00:00",
    "ToDate": "2025-08-08 00:00:00",
    "CustomerAge": 32,
    "DestinationCountry": "IE",
    "Country": "US",
    "FirstName": "Jane",
    "LastName": "Smith",
    "Email": "jane@example.com"
  }' \
  https://api-staging.rentalcover.com/insurances/quote
```

✅ Expect a `200` response containing a `Reference` (e.g. `AB12-345C-INS`) and a `TotalAmount`. **Save the Reference -** you'll use it as `AgentReference` in all subsequent steps.

### Step 2. Retrieve content

```shellscript
curl -i -X POST \
  -H "X_API_KEY: your_staging_api_key" \
  -H "Content-Type: application/json" \
  -d '{"AgentReference": "AB12-345C-INS", "LanguageCode": "en"}' \
  https://api-staging.rentalcover.com/insurances/content
```

✅ Expect marketing copy, logos, and comparison table data.

### Step 3. Record opt-in

```shellscript
curl -i -X POST \
  -H "X_API_KEY: your_staging_api_key" \
  -H "Content-Type: application/json" \
  -d '{"CoverOptIn": 1, "PartnerReference": "PARTNER-REF-001"}' \
  https://api-staging.rentalcover.com/insurances/coverOptOut/AB12-345C-INS
```

✅ Expect `{"success": "..."}`.

### Step 4. Purchase protection

```shellscript
curl -i -X POST \
  -H "X_API_KEY: your_staging_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "AgentReference": "AB12-345C-INS",
    "PolicyCode": "<Policy.Code from Quote response>",
    "FromDate": "2025-08-01 00:00:00",
    "ToDate": "2025-08-08 00:00:00",
    "CustomerAge": 32,
    "DestinationCountry": "IE",
    "Country": "US",
    "FirstName": "Jane",
    "LastName": "Smith",
    "Email": "jane@example.com",
    "Address1": "123 Main St",
    "City": "New York",
    "PostalCode": "10001",
    "CardHolder": "JANE SMITH",
    "CardNumber": "4242424242424242",
    "CardExpiry": "0828",
    "CardSecurityCode": "123"
  }' \
  https://api-staging.rentalcover.com/insurances/purchase
```

✅ Expect Status: `PendingConfirm`.

### Step 5. Verify confirmation

```shellscript
curl -i -X GET \
  -H "X_API_KEY: your_staging_api_key" \
  https://api-staging.rentalcover.com/insurances/status/AB12-345C-INS
```

✅ Expect Status: `Confirmed`.

### Step 6. Cancel protection

```shellscript
curl -i -X POST \
  -H "X_API_KEY: your_staging_api_key" \
  -H "Content-Type: application/json" \
  -d '{"CancelReason": "Test cancellation"}' \
  https://api-staging.rentalcover.com/insurances/cancel/AB12-345C-INS
```

✅ Expect Status: `Confirmed`.

## Test payment cards

Use these card details in the Purchase step above. Do not use real card numbers.

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Card number</th><th width="121.7047119140625">Cardholder</th><th width="147.6776123046875">Expiry</th><th width="80.610595703125">CVV</th><th>Result</th></tr></thead><tbody><tr><td>4242 4242 4242 4242</td><td>Any name</td><td>Any future date</td><td>Any</td><td>Successful payment</td></tr><tr><td>4012 8888 8888 1881</td><td>Any name</td><td>Any future date</td><td>Any</td><td>Successful payment (alternate)</td></tr></tbody></table>

For additional test scenarios including declined cards and 3D Secure flows, see the [Stripe test cards reference](https://stripe.com/docs/testing#cards).


# Authentication

Every request must include a valid API key. Requests without one, or with an invalid key, return `HTTP 401 Unauthorized`.

## Your API key

Your API key is provisioned by your Cover Genius CSE. You receive separate keys for staging and production. **Do not use your production key while testing**.

Your API key is sent in the `X_API_KEY` header of your request.

```shellscript
curl --location 'https://api-staging.rentalcover.com/insurances/quote' \
--header 'Content-Type: application/json' \
--header 'x-api-key: XXXXXXXXXXXXXXXXXXXXXXXXXX' \
--data-raw '
{
    "FromDate": "2027-08-01 23:59:59",
    "ToDate": "2027-08-01 23:59:59",
    "DestinationCountry": "GB",
    "CustomerAge": 52,
    "FirstName": "John",
    "LastName": "Doe",
    "Email": "andy.t+testbooking@covergenius.com",
    "Country": "FR",
    "LanguageCode": "fr",
    "Currency": "GBP"
}
```

## Security requirements

* Use HTTPS for all requests. HTTP calls fail in production.
* Store your API key in an environment variable or secrets manager. Never hard-code it.
* Do not expose your API key in client-side JavaScript, public repositories, or logs.
* Contact your CSE immediately if you believe your key has been compromised.


# Shared Reference

This section defines the building blocks used across multiple endpoints: [parameter groups](/rentalcover/shared-reference/parameter-groups), [response objects](/rentalcover/shared-reference/response-objects), [booking status values](/rentalcover/shared-reference/booking-statuses-and-errors#booking-statuses), and [error codes](/rentalcover/shared-reference/booking-statuses-and-errors#errors). Endpoint pages reference these by name rather than redefining them.


# Parameter Groups

Request parameters are organised into six named groups. [Quote](/rentalcover/endpoints/quote) accepts all six; other endpoints accept specific subsets, listed on each endpoint's page.

## **Group A. Core booking**

Required by: Quote, InstantBooking, Purchase, Update

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="235.1019287109375">Parameter</th><th width="149.6624755859375">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>FromDate</code></td><td>datetime</td><td>Vehicle pickup date/time. Format: <code>yyyy-mm-dd hh:mm:ss</code>.</td></tr><tr><td><code>ToDate</code></td><td>datetime</td><td>Vehicle drop-off date/time. Format: <code>yyyy-mm-dd hh:mm:ss</code>.</td></tr><tr><td><code>DestinationCountry</code></td><td>string(2)</td><td>ISO 3166-1 alpha-2 country code for the country of travel.</td></tr><tr><td><code>CustomerAge</code></td><td>integer</td><td>Age of the primary driver.</td></tr><tr><td><code>Email</code></td><td>string</td><td>Customer email address.</td></tr><tr><td><code>FirstName</code></td><td>string</td><td>Customer first name. Pass <code>NULL</code> if unknown.</td></tr><tr><td><code>LastName</code></td><td>string</td><td>Customer last name. Pass <code>NULL</code> if unknown.</td></tr><tr><td><code>Country</code></td><td>string(2)</td><td>ISO 3166-1 alpha-2 country code for the customer's country of residence or IP geolocation.</td></tr></tbody></table>

## **Group B. Customer**

Optional

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="235.3321533203125">Parameter</th><th width="149.94189453125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>Region</code></td><td>string</td><td>Customer's state, region, or territory code (2–3 letters). <strong>Required for AU, BR, CA, and US customers.</strong> See <a href="/rentalcover/supported-regions">Supported Regions</a>.</td></tr><tr><td><code>Address1</code></td><td>string(50)</td><td>Customer street address line 1.</td></tr><tr><td><code>Address2</code></td><td>string(50)</td><td>Customer street address line 2.</td></tr><tr><td><code>City</code></td><td>string</td><td>Customer city or suburb.</td></tr><tr><td><code>PostalCode</code></td><td>string</td><td>Customer postcode or zip code.</td></tr><tr><td><code>Phone</code></td><td>string</td><td>Customer phone number.</td></tr><tr><td><code>OtherEmail</code></td><td>string</td><td>Secondary email address.</td></tr><tr><td><code>OtherDriveAge1</code></td><td>integer</td><td>Age of second driver.</td></tr><tr><td><code>OtherDriveAge2</code></td><td>integer</td><td>Age of third driver.</td></tr></tbody></table>

## **Group C. Vehicle**

Optional. Not accepted by InstantBooking.

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="234.8515625">Parameter</th><th width="149.5672607421875">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>VehicleCode</code></td><td>string</td><td>Vehicle SIPP code.</td></tr><tr><td><code>VehicleName</code></td><td>string</td><td>Vehicle name.</td></tr><tr><td><code>VehicleCategory</code></td><td>string</td><td>Vehicle category (use when SIPP code is not available).</td></tr><tr><td><code>VehicleClass</code></td><td>string</td><td>Vehicle class.</td></tr><tr><td><code>VehicleBerths</code></td><td>string</td><td>Number of berths (for motorhomes/campervans).</td></tr><tr><td><code>VehicleOffroad4x4</code></td><td>boolean</td><td>Whether the vehicle is an off-road 4WD. Default: <code>false</code>.</td></tr><tr><td><code>VehicleTypes</code></td><td>string(100)</td><td>Comma-separated vehicle types. Values: <code>car</code>, <code>motorhome</code>, <code>campervan</code>, <code>4x4, minibus</code>, <code>lighttruck</code>, <code>bus</code>.</td></tr><tr><td><code>VehicleSupplierId</code></td><td>string</td><td>Vehicle supplier ID.</td></tr><tr><td><code>VehicleSupplierIdTwo</code></td><td>string</td><td>Second vehicle supplier ID.</td></tr><tr><td><code>VehicleSupplierName</code></td><td>string</td><td>Vehicle supplier name.</td></tr><tr><td><code>VehicleSupplierCountryId</code></td><td>string(2)</td><td>Vehicle supplier country code.</td></tr><tr><td><code>VehiclePickupTime</code></td><td>datetime (UTC Atom)</td><td>Local pickup time with UTC offset. Example: <code>2025-08-01T10:00:00+02:00</code>. Determines the cancellation grace period (pickup time + 15 minutes).</td></tr><tr><td><code>VehiclePickupCity</code></td><td>string(50)</td><td>Pickup city. Pass your own identifier, unstructured.</td></tr><tr><td><code>VehiclePickupCountry</code></td><td>string(2)</td><td>Pickup country code.</td></tr><tr><td><code>VehiclePickupRegion</code></td><td>string(50)</td><td>State, region, or territory code for the pickup location. Example: <code>NY</code> for New York.</td></tr><tr><td><code>VehicleDropoffTime</code></td><td>datetime (UTC Atom)</td><td>Drop-off time with UTC offset.</td></tr><tr><td><code>VehicleDropoffCity</code></td><td>string(50)</td><td>Drop-off city.</td></tr><tr><td><code>VehicleDropoffCountry</code></td><td>string(2)</td><td>Drop-off country code.</td></tr><tr><td><code>FromLocationName</code></td><td>string</td><td>Full geographical pickup location. Comma-separated values in order of increasing specificity; append a colon and IATA code for airports. Example: <code>Paris,Paris Le Bourget Airport:LBG</code>.</td></tr><tr><td><code>ToLocationName</code></td><td>string</td><td>Full geographical drop-off location. Same format as <code>FromLocationName</code>.</td></tr></tbody></table>

## **Group D. Pricing & coverage**

Optional

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="235.314697265625">Parameter</th><th width="150.3258056640625">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>VehicleStdLiabilityHigh</code></td><td>float</td><td>Higher standard excess for the vehicle. Use this field if only one excess level is available.</td></tr><tr><td><code>VehicleStdLiabilityLow</code></td><td>float</td><td>Lower standard excess. Used to determine cover required. If omitted, <code>CoverAmount</code> is used.</td></tr><tr><td><code>VehicleStdLiabilityCurrency</code></td><td>string(3)</td><td>Currency of the vehicle's standard excess.</td></tr><tr><td><code>VehicleNettPrice</code></td><td>float</td><td>Wholesale price of the vehicle paid by the online travel agent (OTA).</td></tr><tr><td><code>VehicleRentalGross</code></td><td>float</td><td>Retail price of the vehicle.</td></tr><tr><td><code>CoverAmount</code></td><td>float</td><td>Amount of cover required.</td></tr><tr><td><code>PolicyPrice</code></td><td>float</td><td>Partner-set protection price. If less than the RentalCover price, the partner price is used.</td></tr><tr><td><code>LDWIncluded</code></td><td>boolean [0|1]</td><td>Whether Loss Damage Waiver (LDW) is included in the rental. Removes theft from the comparison table in the Content response.</td></tr><tr><td><code>CDWIncluded</code></td><td>boolean [0|1]</td><td>Whether Collision Damage Waiver (CDW) is included. Default: <code>0</code>.</td></tr><tr><td><code>SLIIncluded</code></td><td>boolean [0|1]</td><td>Whether Supplementary Liability Insurance (SLI) is included.</td></tr></tbody></table>

## **Group E. Display & behaviour**

Optional

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="235.2098388671875">Parameter</th><th width="150.069091796875">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>Type</code></td><td>string</td><td>Requested protection type. Values: <code>ExcessReduction</code>, <code>CDW</code>, <code>Comprehensive</code>, <code>RoadsideAssistance</code>, <code>FullProtection</code>. Defaults to <code>ExcessReduction</code> and <code>Comprehensive</code>. Use <code>RoadsideAssistance</code> for customers travelling to the US; CDW for US residents travelling elsewhere.</td></tr><tr><td><code>Currency</code></td><td>string(3)</td><td>ISO 4217 currency code. If passed, all amounts in the response and in subsequent calls use this currency. See <a href="/rentalcover/supported-currencies">Supported Currencies</a>.</td></tr><tr><td><code>LanguageCode</code></td><td>string(2)</td><td>Two-character language code. Default: <code>en</code>. See <a href="/rentalcover/supported-languages">Supported Languages</a>.</td></tr><tr><td><code>ContactCustomer</code></td><td>boolean [0|1]</td><td>Whether RentalCover may contact the customer by email. Default: <code>1</code>.</td></tr><tr><td><code>ExpressCode</code></td><td>string(50)</td><td>Requests a specific product for experiments. Provided by your CSE. Disabled by default.</td></tr><tr><td><code>RoadSideAssistanceCoverOption</code></td><td>boolean [0|1]</td><td>Requests a roadside assistance cover option.</td></tr></tbody></table>

## **Group F. Partner & integration**

Optional

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="235.0218505859375">Parameter</th><th width="149.73046875">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>PartnerSite</code></td><td>string(50)</td><td>Partner subdomain identifier for partners with multiple sites. Format: <code>yoursitecom</code> (no dots).</td></tr><tr><td><code>PartnerCollectingPayment</code></td><td>boolean</td><td>Whether the partner is collecting payment.</td></tr><tr><td><code>UserIpAddress</code></td><td>string(20)</td><td>End user's IP address.</td></tr><tr><td><code>BWCookie</code></td><td>string</td><td>BW Cookie ID.</td></tr><tr><td><code>MetaData</code></td><td>JSON object</td><td>Additional user-defined data. Structure is entirely defined by the client.</td></tr></tbody></table>


# Response Objects

Several endpoints return the same nested objects. Each is defined once here. When an endpoint's response table lists a field as a named object type, refer to this section.

## Policy object

Returned by: Quote, InstantBooking (subset), Purchase, Status, Update.

{% hint style="info" %}
**InstantBooking subset:** Returns `Code`, `Name`, `Type`, and `PdsUrl` only.
{% endhint %}

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="234.5244140625">Field</th><th width="150.257080078125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>Name</code></td><td>string</td><td>Product display name.</td></tr><tr><td><code>Code</code></td><td>string</td><td>Product code. Pass this as <code>PolicyCode</code> in the Purchase request.</td></tr><tr><td><code>Type</code></td><td>string</td><td>Product type.</td></tr><tr><td><code>Excess</code></td><td>float</td><td>Excess amount.</td></tr><tr><td><code>GapCoverAmount</code></td><td>float</td><td>Gap cover amount included in the product.</td></tr><tr><td><code>Inclusions</code></td><td>string</td><td>Product inclusions (HTML).</td></tr><tr><td><code>Description</code></td><td>string</td><td>Full product description (HTML).</td></tr><tr><td><code>SellingPoints</code></td><td>string</td><td>Key selling points (HTML).</td></tr><tr><td><code>PdsUrl</code></td><td>string</td><td>URL to the Product Disclosure Statement (PDS) PDF.</td></tr><tr><td><code>SupplierName</code></td><td>string</td><td>Insurer/supplier name.</td></tr><tr><td><code>ModifyUrl</code></td><td>string</td><td>URL to modify the policy on RentalCover.com (non-API).</td></tr><tr><td><code>CancelUrl</code></td><td>string</td><td>URL to cancel the protection on RentalCover.com (non-API).</td></tr><tr><td><code>ExpressCode</code></td><td>string</td><td><code>ExpressCode</code> from the request, if provided.</td></tr><tr><td><code>RoadsideAssistanceBlob</code></td><td>string</td><td>Roadside assistance instructions for CRM systems and email templates. Returned by Purchase only.</td></tr></tbody></table>

## Customer object

Returned by: Quote, InstantBooking, Purchase, Status, Update, UpdateCustomer.

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="234.7486572265625">Field</th><th width="150.0093994140625">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>CustomerId</code></td><td>integer</td><td>Internal RentalCover customer ID.</td></tr><tr><td><code>FirstName</code></td><td>string</td><td>Customer first name.</td></tr><tr><td><code>LastName</code></td><td>string</td><td>Customer last name.</td></tr><tr><td><code>Email</code></td><td>string</td><td>Customer email address.</td></tr><tr><td><code>Phone</code></td><td>string</td><td>Customer phone number.</td></tr><tr><td><code>Age</code></td><td>integer</td><td>Customer age.</td></tr><tr><td><code>DateOfBirth</code></td><td>string</td><td>Customer date of birth (<code>yyyy-mm-dd</code>), if provided.</td></tr><tr><td><code>Country</code></td><td>string</td><td>Customer country code (ISO 3166-1 alpha-2).</td></tr><tr><td><code>CountryId</code></td><td>integer</td><td>Internal country ID corresponding to <code>Country</code>.</td></tr><tr><td><code>Region</code></td><td>string</td><td>Customer state/region/territory code, if provided.</td></tr><tr><td><code>Address1</code></td><td>string</td><td>Customer street address line 1.</td></tr><tr><td><code>Address2</code></td><td>string</td><td>Customer street address line 2.</td></tr><tr><td><code>City</code></td><td>string</td><td>Customer city or suburb.</td></tr><tr><td><code>PostalCode</code></td><td>string</td><td>Customer postcode or zip code.</td></tr><tr><td><code>Coupons</code></td><td>object</td><td>Available coupons keyed by coupon code. Omitted if no coupons are available. See <a href="#customer-coupons">Customer Coupons</a> below.</td></tr></tbody></table>

## Customer coupons

The `Coupons` field within the Customer object is a JSON object keyed by coupon code:

```json
{
  "SUMMER10": {
    "Title": "Summer discount",
    "Value": 10,
    "ValueType": "percent",
    "AmountRemaining": 10.00,
    "EffectiveFrom": "2025-06-01 00:00:00",
    "EffectiveTo": "2025-08-31 23:59:59",
    "Terms": "Valid on bookings over 5 days."
  }
}
```

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="235.20458984375">Field</th><th width="150.2333984375">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>Title</code></td><td>string</td><td>Display name of the coupon.</td></tr><tr><td><code>Value</code></td><td>float</td><td>Discount value.</td></tr><tr><td><code>ValueType</code></td><td>string</td><td>How the value is applied: <code>percent</code> or <code>amount</code>.</td></tr><tr><td><code>AmountRemaining</code></td><td>float</td><td>Remaining balance (for partial-use coupons).</td></tr><tr><td><code>EffectiveFrom</code></td><td>datetime</td><td>Date from which the coupon is valid.</td></tr><tr><td><code>EffectiveTo</code></td><td>datetime</td><td>Date on which the coupon expires.</td></tr><tr><td><code>Terms</code></td><td>string</td><td>Terms and conditions text.</td></tr></tbody></table>

## Commission object

Returned by: Quote, Purchase.

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="235.0670166015625">Field</th><th width="149.96435546875">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>TotalCommission</code></td><td>string</td><td>Partner commission amount (includes discounts and markups).</td></tr><tr><td><code>TotalCommissionFormatted</code></td><td>string</td><td>Formatted partner commission.</td></tr></tbody></table>

## SettlementCurrency object

Returned by: Quote. Contains the protection amount in the settlement currency agreed between the partner and RentalCover.

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="234.7962646484375">Field</th><th width="150.1148681640625">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>SettlementCurrency</code></td><td>string</td><td>Settlement currency code (ISO 4217).</td></tr><tr><td><code>SettlementAmount</code></td><td>float</td><td>Protection amount in the settlement currency.</td></tr></tbody></table>

## DestinationCountry object

**DestinationCountryObject**

Returned by: Quote and Status as DestinationCountryObject. Also returned by UpdateCustomer as the Country field, same structure.

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="235.0670166015625">Field</th><th width="149.94287109375">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>Code</code></td><td>string</td><td>ISO 3166-1 alpha-2 country code.</td></tr><tr><td><code>Name</code></td><td>string</td><td>Full country name.</td></tr><tr><td><code>PhoneCode</code></td><td>string</td><td>Country phone prefix.</td></tr></tbody></table>

## Booking responses

The canonical response shape returned by Quote, Purchase, Status, and Update. Purchase, Status, and Update each reference this object and document only the fields that differ.

```json
{
  "Reference":                "AB12-345C-INS",
  "BookingId":                12345,
  "SupplierReference":        "RC-POL-98765",
  "Status":                   "Received",
  "Expired":                  false,
  "FromDate":                 "2025-08-01 00:00:00",
  "ToDate":                   "2025-08-08 00:00:00",
  "CoveredDays":              7,
  "TotalAmount":              45.00,
  "TotalAmountFormatted":     "US$45.00",
  "InsuranceCoverAmount":     3000.00,
  "InsuranceCoverAmountFormatted": "US$3,000.00",
  "DailyAmountFormatted":     "US$6.43",
  "DiscountFormatted":        "US$0.00",
  "Currency":                 "USD",
  "DestinationCountry":       "Ireland",
  "VehiclePickupRegion":      "",
  "QuoteUrl":                 "https://rentalcover.com/...",
  "PoweredByLogo":            "https://...",
  "Documentation": { "Ipid": "https://..." },
  "Disclaimer":               "...",
  "EsimCouponEligible":       "false",
  "Policy":                   { ... },
  "Customer":                 { ... },
  "Commission":               { ... },
  "SettlementCurrencyObject": { ... },
  "DestinationCountryObject": { ... }
}
```

### Scalar fields

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="235.069580078125">Field</th><th width="151.3917236328125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>Reference</code></td><td>string</td><td>Unique booking reference ending in <code>-INS</code>. Use this in all subsequent calls. Customers receive this in their confirmation email.</td></tr><tr><td><code>BookingId</code></td><td>integer</td><td>Internal booking ID (primary key).</td></tr><tr><td><code>SupplierReference</code></td><td>string</td><td>The insurer's own policy reference. Populated after the policy is confirmed with the underwriter.</td></tr><tr><td><code>Status</code></td><td>string</td><td>Current booking status. See <a href="https://docs.google.com/document/d/1ivu-Eknbpw9WESHc0Q0s-kUylfRtrV0s-G9S89I8wEg/edit#43-booking-statuses">Booking Statuses</a>.</td></tr><tr><td><code>Expired</code></td><td>boolean</td><td>Whether the quote has expired.</td></tr><tr><td><code>FromDate</code></td><td>datetime</td><td>Protection start date/time.</td></tr><tr><td><code>ToDate</code></td><td>datetime</td><td>Protection end date/time.</td></tr><tr><td><code>CoveredDays</code></td><td>integer</td><td>Number of days the customer is covered.</td></tr><tr><td><code>TotalAmount</code></td><td>float</td><td>Total premium the customer pays (includes discounts and markups).</td></tr><tr><td><code>TotalAmountFormatted</code></td><td>string</td><td>Formatted <code>TotalAmount</code>.</td></tr><tr><td><code>InsuranceCoverAmount</code></td><td>float</td><td>Total amount of coverage the product provides.</td></tr><tr><td><code>InsuranceCoverAmountFormatted</code></td><td>string</td><td>Formatted <code>InsuranceCoverAmount</code>.</td></tr><tr><td><code>DailyAmountFormatted</code></td><td>string</td><td>TotalAmount divided by <code>CoveredDays</code>, formatted.</td></tr><tr><td><code>DiscountFormatted</code></td><td>string</td><td>Discount applied, formatted.</td></tr><tr><td><code>Currency</code></td><td>string(3)</td><td>ISO 4217 currency code for the booking.</td></tr><tr><td><code>DestinationCountry</code></td><td>string</td><td>Full name of the destination country.</td></tr><tr><td><code>VehiclePickupRegion</code></td><td>string</td><td>State/region/territory code for the vehicle pickup location, echoed from the request.</td></tr><tr><td><code>QuoteUrl</code></td><td>string</td><td>URL to the payment page on RentalCover.com. Embed in confirmation emails for customers who decline at checkout.</td></tr><tr><td><code>PoweredByLogo</code></td><td>string</td><td>URL of the RentalCover "Powered By" logo.</td></tr><tr><td><code>Documentation.Ipid</code></td><td>string</td><td>URL to the Insurance Product Information Document (IPID). Returned only when applicable.</td></tr><tr><td><code>Disclaimer</code></td><td>string</td><td>Policy disclaimer text to display to the customer.</td></tr><tr><td><code>EsimCouponEligible</code></td><td>string</td><td><code>true</code> if the partner and destination are eligible for an eSIM coupon.</td></tr></tbody></table>

### Nested objects

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Field</th><th>Object type</th><th>Reference</th></tr></thead><tbody><tr><td>Policy</td><td>Policy object</td><td>See <a href="#policy-object">Policy object</a>.</td></tr><tr><td>Customer</td><td>Customer object</td><td>See <a href="#customer-object">Customer object</a>.</td></tr><tr><td>Commission</td><td>Commission object</td><td>See <a href="#commission-object">Commission object</a>.</td></tr><tr><td>SettlementCurrency</td><td>SettlementCurrency object</td><td>See <a href="#settlementcurrency-object">SettlementCurrency object</a>.</td></tr><tr><td>DestinationCountry</td><td>DestinationCountry object</td><td>See <a href="#destinationcountry-object">DestinationCountry object</a>.</td></tr></tbody></table>


# Booking Statuses & Errors

## Booking Statuses

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Status</th><th>Meaning</th></tr></thead><tbody><tr><td><code>Received</code></td><td>Quote created; payment has not yet been taken.</td></tr><tr><td><code>PendingConfirm</code></td><td>Payment has been taken; final confirmation from the insurer is pending.</td></tr><tr><td><code>Confirmed</code></td><td>Protection is active and confirmed by the insurer.</td></tr><tr><td><code>Cancelled</code></td><td>Protection has been cancelled.</td></tr></tbody></table>

## Errors

The RentalCover API uses standard HTTP status codes. When a request fails, the response body contains a JSON object describing the error.

### **HTTP status codes**

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="120.1185302734375">Code</th><th width="194.63623046875">Meaning</th><th>What to do</th></tr></thead><tbody><tr><td><code>200</code></td><td>Success</td><td>The request completed successfully.</td></tr><tr><td><code>400</code></td><td>Bad request</td><td>A required parameter is missing, invalid, or the request conflicts with the current booking state. Read the error message in the response body.</td></tr><tr><td><code>401</code></td><td>Unauthorised</td><td>Your API key is missing or invalid. Check the <code>X_API_KEY</code> header.</td></tr><tr><td><code>404</code></td><td>Not found</td><td>The endpoint or resource does not exist. Check the URL and booking reference.</td></tr><tr><td><code>500</code></td><td>Internal server error</td><td>An unexpected error occurred on the RentalCover server. Contact your CSE if this persists.</td></tr></tbody></table>

### Error response body

```json
// Single-field validation error
{
  "errors": {
    "email": ["Email cannot be blank."]
  }
}

// General request error
{
  "errors": ["Policy cannot be purchased or modified after the date of travel"]
}
```

### Common error scenarios

General errors typically return `HTTP 400`.

#### Quote errors

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="335.20849609375">Scenario</th><th>Example error</th></tr></thead><tbody><tr><td>Required field missing</td><td>"Email cannot be blank." / "FromDate: must be in the future"</td></tr><tr><td>Invalid country code</td><td>"Country is too long (maximum is 2 characters)."</td></tr><tr><td>Invalid language code</td><td>"Language Code is too long (maximum is 5 characters)."</td></tr><tr><td>SIPP code not covered by underwriters</td><td>"No policies available for SIPP code."</td></tr><tr><td>Region without trading licence</td><td>"No policies are available for the requested state, province or territory."</td></tr></tbody></table>

#### Purchase errors

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="335.4342041015625">Scenario</th><th>Example error</th></tr></thead><tbody><tr><td>Booking details differ from quote</td><td>"Policy not found"</td></tr><tr><td>Purchase attempted after travel date</td><td>"Policy cannot be purchased or modified after the date of travel"</td></tr><tr><td>Booking not found</td><td>"Booking details not found"</td></tr><tr><td>Payment failure</td><td>"Payment validation failed, please make sure your credit card details are correct or try another card"</td></tr><tr><td>Invalid or expired coupon</td><td>"Invalid or expired coupon, please try again or remove coupon"</td></tr></tbody></table>

#### Cancel errors

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="335.0452880859375">Scenario</th><th>Example error</th></tr></thead><tbody><tr><td>Invalid booking reference</td><td>"Booking not found"</td></tr><tr><td>Already cancelled</td><td>"Booking AB12-345C-INS can not be cancelled, already been cancelled on 2024-01-23"</td></tr><tr><td>Claim in progress</td><td>"Booking 98PD-SEQN-INS can not be cancelled, claim in progress"</td></tr><tr><td>Charge dispute raised</td><td>"Booking F8TU-62C6-INS can not be cancelled as it has been disputed"</td></tr></tbody></table>

For further troubleshooting, please contact your CSE.


# Endpoints

Production API URL: https\://api.rentalcover.com

{% hint style="info" %}
**Production API URL:** <https://api.rentalcover.com>

**Staging API URL:** <https://api-staging.rentalcover.com>
{% endhint %}

**Authentication:** Every request requires an `X_API_KEY` header. This is not repeated on each endpoint page. See [Authentication](/rentalcover/authentication).

* [Quote](/rentalcover/endpoints/quote): Returns a quote based on the customer's booking details. Call this during checkout when the customer has selected a vehicle.
* [Content](/rentalcover/endpoints/content): Returns localised marketing copy and UI modules for a given booking reference. Use this to display the product offer and opt-out option.
* [CoverOptOut](/rentalcover/endpoints/coveroptout): Records whether the customer opted in or out of RentalCover coverage. Must be called for every customer who is shown the offer.
* [InstantBooking](/rentalcover/endpoints/instantbooking): Creates a quote and confirms the booking in a single request. Use this when you want to skip the separate Quote and Purchase steps.
* [Purchase](/rentalcover/endpoints/purchase): Confirms and books a quote. Call this after the customer accepts the quote and provides payment details.
* [Status](/rentalcover/endpoints/status): Returns the current status and full details of a booking by its reference. Use this to verify a purchase or check the booking state.
* [Update](/rentalcover/endpoints/update): Modifies a quoted or purchased protection (dates, cover amount, customer details). Requires a two-step call: preview then commit.
* [Update Customer](/rentalcover/endpoints/update-customer): Updates customer personal information on an existing protection.
* [Cancel](/rentalcover/endpoints/cancel): Cancels a quoted or purchased protection. Only available before the protection start date.
* [Notification/list](/rentalcover/endpoints/notifications-list): Returns pending booking events created directly in RentalCover (e.g. customer-initiated changes). For partners using invoicing rather than card payment.
* [Notification/update](/rentalcover/endpoints/notification-update): Acknowledges that your system has processed a notification event.
* [GetAllPurchasedPolicies](/rentalcover/endpoints/getallpurchasedpolicies): Returns a paginated list of all purchased and cancelled protection. Filtered by last-modification date.
* [GetAllCancelledPolicies](/rentalcover/endpoints/getallcancelledpolicies): Returns a paginated list of cancelled protection. Filtered by last-modification date.
* [Invoice](/rentalcover/endpoints/invoice): Returns the invoice PDF for a confirmed booking.


# Quote

**What it does:** Generates a price quote for RentalCover protection based on the customer's booking details.

**When to call it:** During checkout when the customer has selected a vehicle. Can also be called earlier (e.g. on search results) as long as the required parameters are available.

The response includes:

* A `Reference`: the identifier for all subsequent calls (Content, CoverOptOut, Purchase, Update, Cancel).
* A `QuoteUrl`: embed in confirmation emails so customers can purchase later if they decline at checkout.

```
POST /insurances/quote
```

## Example request

{% tabs %}
{% tab title="POST" %}

```shellscript
curl -i -X POST
-H "X_API_KEY: your_api_key"
-H "Content-Type: application/json"
-d '{ "FromDate": "2025-08-01 00:00:00", "ToDate": "2025-08-08 00:00:00", "CustomerAge": 32, "DestinationCountry": "IE", "Country": "US", "FirstName": "Jane", "LastName": "Smith", "Email": "jane@example.com" }'
https://api-staging.rentalcover.com/insurances/quote
```

{% endtab %}

{% tab title="Response" %}

```graphql
{
   "BookingId":"12345",
   "Reference":"AB12-345C-INS",
   "Status":"Received",
   "FromDate":"2015-06-24 00:00:00",
   "ToDate":"2015-06-25 00:00:00",
   "TotalAmount":10,
   "InsuranceCoverAmount":2000,
   "SupplierReference":null,
   "Expired":false,
   "PoweredByLogo":"https://www.rentalcover.com/poweredByRCLogo.png",
   "CoveredDays":2,
   "Discount":0,
   "DestinationCountry":"Australia",
   "DestinationCountryObject":{
      "Code":"AU",
      "Name":"Australia",
      "PhoneCode":"+61"
   },
   "Currency":"AUD",
   "TotalAmountFormatted":"GB\u00a310.00",
   "InsuranceCoverAmountFormatted":"GB\u00a32,000.00",
   "DiscountFormatted":"GB\u00a30.00",
   "DailyAmountFormatted":"GB\u00a35.00",
   "Disclaimer":"You agree that you have read, understood & accepted the terms of the <a href=\"http://files.rentalcover.com/pds/axa_PDS_usinbound.pdf\">Policy</a>.",
   "Policy":{
      "GapCoverAmount":"250.00",
      "Code":"destinationusa75",
      "Excess":"0.00",
      "Name":"Extra Cover for USA",
      "Type":"RoadsideAssistance",
      "Inclusions":"<b>Summary of Inclusions</b>\r\nGB\u00a32,000.00 is sufficient to cover any repair costs and fees that drivers are required to pay on top of LDW (Loss Damage Waiver) policies. We also includeGB\u00a3250.00 Free Gap Cover just in case there is any shortfall or unanticipated &quot;out of pocket&quot; costs. This policy includes:\r\n<li>All drivers that are nominated on the rental agreement are covered automatically for free.\r\n<li>Includes free roadside assistance from the #1 rated roadside provider in United States (usually GB\u00a35.00-GB\u00a310.00/day).\r\n<li>Covers roadside repair costs, call out fees &amp; labour costs.\r\n\r\n<li>Covers towing costs and impound storage fees.\r\n<li>Covers key loss, lock out &amp; key replacement (regardless of the cause).\r\n<li>Covers windscreen, headlights, tyre, mirror &amp; glass repairs.\r\n<li>Covers car rentals, car shares, loan cars from mechanics &amp; accident replacement vehicles. \r\n<li>Covers dropoff/relocation fees that are charged by rental companies for returning damaged vehicles to their preferred destination.\r\n<li>Covers credit card and processing fees that are applied by rental companies.</li>\r\n\r\n<b>Cancellations</b>\r\nYour policy can be cancelled up to and including the day of commencement for a full, immediate refund.",
      "Description":"<b>Policy Description</b>\r\nThis policy includes GB\u00a32,000.00 cover and can be applied to rental cars from any rental company. It includes free roadside assistance and covers damages, costs &amp; other fees that are not covered in the LDW policy from LDW has zero &quot;deductible excess&quot; (i.e. you don&#039;t have to pay an excess if there&#039;s an accident), drivers still face substantial costs for items that fall outside of the scope of the LDW. This policy covers those items for up to GB\u00a32,000.00, namely: \r\n\r\n<li>Any damages that are not covered by rental companies to recoup lost sales while their vehicle is being repaired.\r\n<li>&quot;Dropoff&quot; fees that are charged by the rental companies to relocate vehicles to their intended destination.\r\n<li>Administration costs that are charged by {{IF SUPPLIER}}{{/IF}}rental companies for processing repairs, insurance etc.\r\n<li>Credit card fees that are applied to all of the above.</li>\r\n<b>Additional Drivers</b>\r\nWe separately include GB\u00a3250.00 Free Gap Cover for peace of mind, just in case there is a shortfall.\r\n \r\n<b>Additional Drivers</b>\r\nAll drivers nominated on the rental agreement are covered automatically, free of charge. Those other drivers are also extended the benefit of the reimbursement of unused rental days resulting from a family medical emergency.\r\n\r\n<b>Claim Fee</b>\r\nThe claim fee on this policy is GB\u00a30.00. \r\n\r\n<b>Exclusions</b>\r\nThe following are not covered by this policy. Please read the <a href=&quot;http://files.rentalcover.com/pds/axa_PDS_usinbound.pdf&quot;>policy wording</a> for further information:\r\n<li>4x4s, campervans, motorhomes, mini buses with 10 seats or more.\r\n<li>Driving on unsealed roads.\r\n<li>Damages that resulted from a breach of the rental agreement or that contravened local laws.</li>",
      "SellingPoints":"<li>Covers car rentals, loan cars from mechanics &amp; accident replacement vehicles for up to GB\u00a32,000.00 of damages.\r\n<li>Cancel anytime including the day of pickup for a full, immediate refund.\r\n\r\n<li>Free roadside assistance.\r\n<li>Covers roadside repair costs.\r\n<li>Cover for towing costs and impound storage fees.\r\n<li>Key loss &amp; replacement.\r\n<li>Full cover for windscreen repairs, headlights and tyres.",
      "GapCoverAmountFormatted":"GB\u00a3250.00",
      "ExcessFormatted":"GB\u00a30.00",
      "PdsUrl":"http://files.rentalcover.com/pds/axa_PDS_usinbound.pdf",
      "SupplierName":"Axa Assistance",
      "ModifyUrl":"http://www.rentalcover.com/modify/AB12-345C-INS",
      "CancelUrl":""
   },
   "Customer":{
      "CustomerId":"12345",
      "FirstName":"Jack",
      "LastName":"Smith",
      "Email":"jacksmith@myemail.com.au",
      "Age":"21",
      "Phone":null,
      "Address1":"21 This Street",
      "Address2":null,
      "City":"Sydney",
      "Region":null,
      "PostalCode":null,
      "CountryId":"14",
      "DateOfBirth":"1995-01-01",
      "Country":"AU"
   },
   "QuoteUrl":"https://www.rentalcover.com/payment/AB12-345C-INS/?_lang=en&utm_campaign=api_quote_url&utm_medium=link&utm_source=destinationusa"
    "Documentation": {
       "Ipid": "https://files.rentalcover.com/ipid/AIL/AIL+FP+OUT/FULL+PROTECTION+AILS+OUTBOUND+IPID-EN.pdf"
    },
}
```

{% endtab %}
{% endtabs %}

## Request parameters

Quote accepts all six [parameter groups](/rentalcover/shared-reference/parameter-groups). Group A is required; Groups B–F are optional.

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Group</th><th>Parameters</th></tr></thead><tbody><tr><td><a href="/pages/WVMEVLGGGf8OHDZ9pLSL#group-a.-core-booking">A. Core booking</a> (required)</td><td><code>FromDate</code>, <code>ToDate</code>, <code>DestinationCountry</code>, <code>CustomerAge</code>, <code>Email</code>, <code>FirstName</code>, <code>LastName</code>, <code>Country</code></td></tr><tr><td><a href="/pages/WVMEVLGGGf8OHDZ9pLSL#group-b.-customer">B. Customer</a> (optional)</td><td><code>Region</code>, <code>Address1</code>/<code>2</code>, <code>City</code>, <code>PostalCode</code>, <code>Phone</code>, <code>OtherEmail</code>, <code>OtherDriveAge1</code>/<code>2</code></td></tr><tr><td><a href="/pages/WVMEVLGGGf8OHDZ9pLSL#group-c.-vehicle">C. Vehicle</a> (optional)</td><td>All <code>Vehicle*</code> and <code>*LocationName</code> fields</td></tr><tr><td><a href="/pages/WVMEVLGGGf8OHDZ9pLSL#group-d.-pricing-and-coverage">D. Pricing &#x26; coverage</a> (optional)</td><td><code>VehicleStdLiability*</code>, <code>CoverAmount</code>, <code>PolicyPrice</code>, <code>LDWIncluded</code>, etc.</td></tr><tr><td><a href="/rentalcover/shared-reference/parameter-groups#group-e-display-and-behaviour">E. Display &#x26; behaviour</a> (optional)</td><td><code>Type</code>, <code>Currency</code>, <code>LanguageCode</code>, <code>ContactCustomer</code>, <code>ExpressCode</code></td></tr><tr><td><a href="/pages/WVMEVLGGGf8OHDZ9pLSL#group-f.-partner-and-integration">F. Partner &#x26; integration</a> (optional)</td><td><code>PartnerSite</code>, <code>PartnerCollectingPayment</code>, <code>UserIpAddress</code>, <code>MetaData</code></td></tr></tbody></table>

## Response

Returns a [Booking Response](/rentalcover/shared-reference/response-objects#booking-responses). Status is `Received` on a fresh quote. No fields differ from the canonical shape.

```shellscript
{
"Status":"Received"
}
```

<br>


# Content

**What it does:** Returns localised marketing copy and UI components for a given booking reference.

**When to call it:** After [Quote](/rentalcover/endpoints/quote), to retrieve the text, logos, and comparison table data needed to display the product offer.

{% hint style="info" %}
**Logo compliance**

All logos must be loaded dynamically from the URLs returned in the response (`PoweredByLogo`, `RCLogo2`, `InsurerLogo`, etc.). Do not cache or hard-code logo URLs.
{% endhint %}

```
POST /insurances/content
```

## Example request

{% tabs %}
{% tab title="POST" %}

```shellscript
curl -i -X POST \
  -H "X_API_KEY: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"AgentReference": "AB12-345C-INS", "LanguageCode": "en"}' \
  https://api-staging.rentalcover.com/insurances/content
```

{% endtab %}

{% tab title="Response" %}

```graphql
{
   "-PartnerContent":{
      "AcceptCover":"Yes, I'd like to purchase TEST - Collision Damage Coverage for US$12.00 per day.<br>",
      "BookButton1With":"Reserve My Rental Car",
      "BookButton1Without":"Reserve My Rental Car",
      "RefuseCover":"No, thanks.",
      "SectionHeader":"Add Collision Damage Waiver (CDW) & Theft Coverage",
      "CancellationHeader":"Important: You have insurance that is valid for any rental",
      "CancellationBody":"Your insurance can be used with any rental from any rental company from 2016-09-19 to 2016-09-19. Click 'cancel' if you are no longer hiring a car",
      "ToQualify":"To qualify, I am a resident of:"
   },
   "PoweredByText":"Powered by",
   "RCLogo2":"https://www.rentalcover.com/RCLogo.png",
   "SectionHeader":"Add Collision Damage Waiver (CDW) & Theft Coverage",
   "ClaimsText":"Claims",
   "InsurerLogo":"https://s3-ap-southeast-2.amazonaws.com/welovetravel-data/suppliers/aonLogo.png",
   "Include":"Include",
   "DefaultCheck":false,
   "-Supplier":{
      "Disclaimer":"I agree to purchase Collision Damage Insurance. I have read, accept and agree to the <a href='http://staging.rentalcover.com/pds/AB12-345C-INS' target='_blank'>Terms & Conditions of Cover</a>.",
      "Disclaimer2":""
   },
   "-Policy":{
      "InsuranceCoverAmountFormatted":"US$35,000.00",
      "InsuranceCoverAmount":"35000.00",
      "DailyAmountFormatted":"US$12.00",
      "DailyAmount":12,
      "TotalAmountFormatted":"US$12.00",
      "TotalAmount":"12.00",
      "PerDayText":"per day",
      "Name":"TEST - Collision Damage Coverage",
      "Type":"RoadsideAssistance",
      "Code":"destinationusa75",
      "CoverAmountText":"US$35,000.00 cover for all types of damage",
      "BubbleText2":"95% of users add this <br>",
      "LDWIncluded":"dont_show",
      "CDWIncluded":true,
      "SLIIncluded":"dont_show",
      "WHTIncluded":"dont_show",
      "TheftIncluded":"dont_show",
      "RoadsideIncluded":"dont_show",
      "LossofuseIncluded":"dont_show",
      "CreditcardfeesIncluded":"dont_show",
      "KeylosslockouIncluded":"dont_show",
      "TowingimpoundIncluded":"dont_show",
      "MisfuelingIncluded":"dont_show",
      "ShortDescription":"Here's where we put the product Short Description",
      "MobileShortDescription":"Here's where we put the product Mobile Short Description",
      "Description":"Here's where we put the product Full Description",
      "Inclusions":[
         "Inclusion1",
         "Inclusion2",
         "Inclusion3"
      ],
      "CheckboxImage":"https://s3-ap-southeast-2.amazonaws.com/rentalcover-data/img/checkbox.png",
      "UnderwrittenBy":"Underwritten By",
      "UnderwritterLogo":"https://www.rentalcover.com/RCLogo.png",
      "PDSWordingText":"View Policy Wording",
      "PdsUrl":"http://files.rentalcover.com/pds/axa_PDS_usinbound.pdf"
   },
   "-ComparisonPolicy":{
      "SupplierName":"Hertz",
      "LDWIncludedHeader":"Loss Damage Waiver (LDW)",
      "LDWIncludedSubheader":"This rental comes with LDW so there is no deductible excess for damages, theft etc.",
      "LDWIncludedText":"LDW (Loss Damage Waiver) removes the deductible excess for damages & theft however there are 'out of pocket' costs that renters still face including towing, roadside repairs, key loss & other items below.",
      "CDWIncludedHeader":"Collision Damage Waiver (CDW)",
      "CDWIncludedSubheader":"Nil deductible excess payable for damages",
      "CDWIncludedText":"CDW (Collision Damage Waiver) removes any deductible excess so $0 is payable for damages/repairs. CDW does not cover theft or vandalism.",
      "SLIIncludedHeader":"Supplementary Liability Insurance",
      "SLIIncludedSubheader":"Insures against 3rd party claims",
      "SLIIncludedText":"SLI (Supplementary Liability Insurance) covers third party property (i.e. other cars or property damaged by your car) and injuries to other drivers, their passengers & pedestrians.",
      "WHTIncludedHeader":"Windscreen, headlight & tyre repairs/replacement",
      "WHTIncludedText":"Windscreen and tyre replacement or repair is the largest additional cost faced by renters once they leave the depot.",
      "TheftHeader":"Theft",
      "RoadsideHeader":"Roadside Repairs & Costs",
      "RoadsideIncludedText":"Roadside repairs include common costs such as battery replacement & labour costs for tyre replacement.",
      "LossofuseHeader":"Loss Of Use Fees",
      "LossofuseIncludedText":"“Loss of use” costs are commonly applied while the vehicle is off the road being repaired because the rental company is unable to rent the vehicle.",
      "CreditcardfeesHeader":"Credit Card & Admin Fees",
      "CreditcardfeesIncludedText":"Card fees are typically applied to incidentals such as towing, impound storage, loss of use, key loss etc.",
      "KeylosslockoutHeader":"Key loss & lockout costs",
      "KeylosslockoutIncludedText":"Costs from key loss can be significant as key programming is often required, plus roadside assistance, temporary keys, replacement keys etc.",
      "TowingimpoundHeader":"Towing & Impound Fees",
      "TowingimpoundIncludedText":"Towing & impound storage costs are often expensive. Average cost is $380 for towing & $120/day for impounding.",
      "MisfuelingHeader":"Misfueling",
      "AllIncludedHeader":"Car booking includes checked items only",
      "Shortname":"Damage Waiver",
      "LDWIncluded":"dont_show",
      "CDWIncluded":"dont_show",
      "SLIIncluded":"dont_show",
      "WHTIncluded":"dont_show",
      "TheftIncluded":"dont_show",
      "RoadsideIncluded":"dont_show",
      "LossofuseIncluded":"dont_show",
      "CreditcardfeesIncluded":"dont_show",
      "KeylosslockouIncluded":"dont_show",
      "TowingimpoundIncluded":"dont_show",
      "MisfuelingIncluded":"dont_show",
      "SupplierLogo":"https://s3-ap-southeast-2.amazonaws.com/welovetravel-data/suppliers/hertz.png",
      "Exclusions":"The supplier's policies do not cover loss/damages to: <ul> <li>Broken/lost keys</li> <li>Neverlost navigation</li> <li>Roadside Assistance- related costs</li> </ul> The above are covered by RentalCover.com.",
      "ExcessPayablePriceText":"Payable if cause of damage is 'excluded'",
      "FromPriceFormatted":"US$42.00",
      "FromPrice":"42.00",
      "ToPriceFormatted":"US$0.00",
      "ToPrice":"0.00"
   }
}
```

{% endtab %}
{% endtabs %}

## Request parameters

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="210.343994140625">Parameter</th><th width="149.8553466796875">Required?</th><th>Description</th></tr></thead><tbody><tr><td><code>AgentReference</code></td><td>Required</td><td>The booking <code>Reference</code> returned by Quote.</td></tr><tr><td><code>LanguageCode</code></td><td>Optional</td><td>Two-character language code. Default: <code>en</code>. See <a href="/rentalcover/supported-languages">Supported Languages</a>.</td></tr></tbody></table>

## Response

The `PartnerContent` object contains partner-specific fields configured for your account. Contact your CSE for the full list. Commonly used fields are documented below.

### UI labels

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="209.7596435546875">Field</th><th width="150.3812255859375">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>PartnerContent.SectionHeader</code></td><td>string</td><td>Heading for the product offer section.</td></tr><tr><td><code>PartnerContent.AcceptCover</code></td><td>string</td><td>Label for the positive CTA button.</td></tr><tr><td><code>PartnerContent.RefuseCover</code></td><td>string</td><td>Label for the negative CTA button.</td></tr><tr><td><code>PartnerContent.BookButton1With</code></td><td>string</td><td>Book button label when cover is included.</td></tr><tr><td><code>PartnerContent.BookButton1Without</code></td><td>string</td><td>Book button label when cover is excluded.</td></tr><tr><td><code>Include</code></td><td>string</td><td>Localised 'Include' text for the comparison table.</td></tr><tr><td><code>DefaultCheck</code></td><td>boolean</td><td>Whether the insurance checkbox should be pre-selected. <code>true</code> for non-US/non-EU markets; <code>false</code> for US/EU markets.</td></tr></tbody></table>

### Logos

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="210.4598388671875">Field</th><th width="150.1942138671875">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>RCLogo2</code></td><td>string</td><td>URL of the RentalCover logo. Load dynamically. Do not hard-code.</td></tr><tr><td><code>InsurerLogo</code></td><td>string</td><td>URL of the insurer logo. Load dynamically. Do not hard-code.</td></tr><tr><td><code>PoweredByText</code></td><td>string</td><td>'Powered by' text.</td></tr></tbody></table>

### Policy

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="224.6854248046875">Field</th><th width="149.5057373046875">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>Policy.Name</code></td><td>string</td><td>Policy display name.</td></tr><tr><td><kbd>Policy.Type</kbd></td><td>string</td><td>Policy type.</td></tr><tr><td><code>Policy.DailyAmountFormatted</code></td><td>string</td><td>Formatted daily premium.</td></tr><tr><td><code>Policy.TotalAmountFormatted</code></td><td>string</td><td>Formatted total premium.</td></tr><tr><td><code>Policy.InsuranceCoverAmountFormatted</code></td><td>string</td><td>Formatted total cover amount.</td></tr><tr><td><code>Policy.ShortDescription</code></td><td>string</td><td>Short product description for desktop display.</td></tr><tr><td><code>Policy.MobileShortDescription</code></td><td>string</td><td>Short product description for mobile display.</td></tr><tr><td><code>Policy.Inclusions</code></td><td>array</td><td>Array of benefit inclusions.</td></tr><tr><td><code>Policy.PDSWordingText</code></td><td>string</td><td>Localised 'View wording/coverage terms' text.</td></tr><tr><td><code>Policy.PdsUrl</code></td><td>string</td><td>URL to the PDS document.</td></tr><tr><td><code>Policy.UnderwrittenBy</code></td><td>string</td><td>'Underwritten by' text.</td></tr><tr><td><code>Policy.UnderwritterLogo</code></td><td>string</td><td>URL of the underwriter logo.</td></tr><tr><td><code>Policy.SpecialMessage</code></td><td>string</td><td>Any special product-related message.</td></tr><tr><td><code>Policy.CheckboxImage</code></td><td>string</td><td>Checkbox image URL for the comparison table.</td></tr></tbody></table>

### Disclaimers

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="225.23193359375">Field</th><th width="149.763916015625">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>Supplier.Disclaimer</code></td><td>string</td><td>Disclaimer text (version 1).</td></tr><tr><td><code>Supplier.Disclaimer2</code></td><td>string</td><td>Disclaimer text (version 2).</td></tr></tbody></table>

### Comparison table

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="224.926025390625">Field</th><th width="150.249267578125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>ComparisonPolicy.SupplierName</code></td><td>string</td><td>Rental company name for the comparison column.</td></tr><tr><td><code>ComparisonPolicy.SupplierLogo</code></td><td>string</td><td>Rental company logo URL.</td></tr><tr><td><code>ComparisonPolicy.Exclusions</code></td><td>string</td><td>HTML list of items not covered by the rental company's standard policy.</td></tr><tr><td><code>ComparisonPolicy.FromPriceFormatted</code></td><td>string</td><td>Formatted lower price of the rental company's excess product.</td></tr><tr><td><code>ComparisonPolicy.ToPriceFormatted</code></td><td>string</td><td>Formatted upper price of the rental company's excess product.</td></tr></tbody></table>


# CoverOptOut

**What it does:** Records whether a customer has opted in or out of RentalCover coverage.

**When to call it:** Immediately after the customer makes their decision, regardless of whether they accept or decline.

{% hint style="info" %}
**Required call**

This endpoint is mandatory for every customer shown the insurance offer. Failing to call it when a customer declines may result in compliance issues.
{% endhint %}

```
POST /insurances/coverOptOut/<reference>
```

## Example requests

### Customer opts out

```shellscript
curl -i -X POST \
  -H "X_API_KEY: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"CoverOptIn": 0, "PartnerReference": "PARTNER-REF-001"}' \
  https://api-staging.rentalcover.com/insurances/coverOptOut/AB12-345C-INS
```

### Customer opts in

```shellscript
curl -i -X POST \
  -H "X_API_KEY: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"CoverOptIn": 1, "PartnerReference": "PARTNER-REF-001"}' \
  https://api-staging.rentalcover.com/insurances/coverOptOut/AB12-345C-INS
```

## Request parameters

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="205.1732177734375">Parameter</th><th width="163.205078125">Required?</th><th>Description</th></tr></thead><tbody><tr><td><code>reference</code> (URL)</td><td>Required</td><td>The RentalCover booking reference from the Quote response.</td></tr><tr><td><code>CoverOptIn</code></td><td>Required</td><td><code>1</code> = customer accepted cover. <code>0</code> = customer declined cover.</td></tr><tr><td><code>PartnerReference</code></td><td>Optional</td><td>Your internal booking reference.</td></tr></tbody></table>

## Response

Returns a [Booking Response](https://docs.google.com/document/d/1ivu-Eknbpw9WESHc0Q0s-kUylfRtrV0s-G9S89I8wEg/edit#booking-response). Status is returned on `success`.

```graphql
{
    "Status":"success"
}
```


# InstantBooking

**What it does:** Creates a quote and confirms the booking in a single API call.

**When to call it:** When you want to purchase a policy without a separate Quote step. For example, in a streamlined checkout where the protection price is already known.

{% hint style="info" %}
**PolicyCode required**&#x20;

Because there is no separate Quote step, you must supply a `PolicyCode`. Your CSE will provide the codes available for your account.
{% endhint %}

```
POST /insurances/instantBooking
```

## Example request

{% tabs %}
{% tab title="POST" %}

```shellscript
curl -i -X POST \
  -H "X_API_KEY: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "FromDate": "2025-08-01 00:00:00",
    "ToDate": "2025-08-08 00:00:00",
    "CustomerAge": 29,
    "Email": "jane@example.com",
    "FirstName": "Jane",
    "LastName": "Smith",
    "Country": "NZ",
    "DestinationCountry": "NZ",
    "PolicyCode": "FP-NZ-ROW",
    "LanguageCode": "en",
    "Currency": "AUD",
    "PartnerCollectingPayment": true,
    "City": "Auckland",
    "Address1": "1 Queen Street",
    "PostalCode": "1010"
  }' \
  https://api-staging.rentalcover.com/insurances/instantBooking
```

{% endtab %}

{% tab title="Response" %}

```graphql
{
    "BookingId": "5805150",
    "Reference": "N7U4-A2JE-INS",
    "Status": "Confirmed",
    "FromDate": "2024-04-19 00:00:00",
    "ToDate": "2024-04-22 00:00:00",
    "TotalAmount": "21.64",
    "ConfirmedOn": "2024-04-17 23:17:41",
    "PartnerSiteCode": null,
    "InsuranceCoverAmount": "92100.00",
    "TotalAmountFormatted": "AU$21.64",
    "InsuranceCoverAmountFormatted": "AU$92,100.00",
    "Disclaimer": "By clicking the button you confirm that you have considered the terms of the <a href=\"https://staging.rentalcover.com/pds/N7U4-A2JE-INS\" target=\"_blank\">PDS</a>. Asservo Mutual (NZBN 9429051103644) is the issuer of the mutual risk products and RentalCover.com, a trading name of Cover Genius Pty Ltd (ABN 43 159 983 598, AFSL No.490058) is its' agent. As a member of Asservo Mutual, you can view the Constitution on its' <a href=\"https://asservoprotection.com/\" target=\"_blank\">website</a>.\n",
    "VehicleTypes": {
        "freecancellationcover": false,
        "freetravelinsurance": false,
        "car": true,
        "motorhome": false,
        "campervan": false,
        "4x4": false,
        "minibus": false,
        "lighttruck": false,
        "bus": false,
        "caravan": false
    },
    "Logos": {
        "DarkFontPng": {
            "Type": "png",
            "Url": "https://files.rentalcover.com/logos/RentalCover.png"
        },
        "DarkFontSvg": {
            "Type": "svg",
            "Url": "https://files.rentalcover.com/logos/RentalCover.svg"
        },
        "LightFontPng": {
            "Type": "png",
            "Url": "https://files.rentalcover.com/logos/RentalCover-inverse.png"
        },
        "LightFontSvg": {
            "Type": "svg",
            "Url": "https://files.rentalcover.com/logos/RentalCover-inverse.svg"
        }
    },
    "Policy": {
        "Code": "FP NZ ROW inc.Baggage - Asservo Mutual",
        "Name": "Full Protection",
        "Type": "FullProtection",
        "PdsUrl": "https://staging.rentalcover.com/pds/N7U4-A2JE-INS"
    },
    "Customer": {
        "CustomerId": "347568",
        "FirstName": "Test",
        "LastName": "Test",
        "Email": "email+123@covergenius.com",
        "BackupEmail": "",
        "DateOfBirth": "1995-01-01",
        "Age": "29",
        "Phone": "0432-488-899",
        "Address1": "abc street",
        "Address2": "",
        "City": "brisbane",
        "Region": "SAN FRAN",
        "PostalCode": "55555",
        "Country": "New Zealand"
    }
}
```

{% endtab %}
{% endtabs %}

## Request parameters

InstantBooking accepts [Group A (Core booking)](https://partner-docs.covergenius.com/rentalcover/endpoints/pages/WVMEVLGGGf8OHDZ9pLSL#group-a.-core-booking), [Group B (Customer)](https://partner-docs.covergenius.com/rentalcover/endpoints/pages/WVMEVLGGGf8OHDZ9pLSL#group-b.-customer), and [Group F (Partner & integration)](https://partner-docs.covergenius.com/rentalcover/endpoints/pages/WVMEVLGGGf8OHDZ9pLSL#group-f.-partner-and-integration), plus the differences listed below.

### Differences from Quote

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="184.9595947265625">Parameter</th><th width="150.32666015625">Required?</th><th>Note</th></tr></thead><tbody><tr><td><code>PolicyCode</code></td><td>Required</td><td>Policy code to purchase. No Quote step means this must be supplied explicitly. Provided by your CSE.</td></tr><tr><td><code>LanguageCode</code></td><td>Required</td><td>Required here; optional in Quote.</td></tr><tr><td><code>Currency</code></td><td>Required</td><td>Required here; optional in Quote.</td></tr><tr><td><code>AgentReference</code></td><td>Optional</td><td>Partner-supplied booking reference ending in <code>-INS</code>. Auto-generated if omitted.</td></tr><tr><td><code>PartnerReference</code></td><td>Optional</td><td>Your internal booking reference for customer service lookup.</td></tr></tbody></table>

{% hint style="info" %}
**Not accepted by InstantBooking**&#x20;

All [Group C (Vehicle)](https://partner-docs.covergenius.com/rentalcover/endpoints/pages/WVMEVLGGGf8OHDZ9pLSL#group-c.-vehicle) fields, `FromLocationName`, `ToLocationName`, `VehiclePickupTime`, `VehicleDropoffTime` and all other pickup/drop-off location fields, `LDWIncluded`, `SLIIncluded`, `OtherEmail`, `OtherDriveAge1`/`2`, `ExpressCode`, `RoadSideAssistanceCoverOption`, `BWCookie`, `UserIpAddress`, `ContactCustomer`, `CoverAmount`, `Type`.
{% endhint %}

## Response

### Booking

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="184.87646484375">Field</th><th width="150.45703125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>Reference</code></td><td>string</td><td>Unique booking reference ending in <code>-INS</code>. Use this for Update and Cancel.</td></tr><tr><td><code>BookingId</code></td><td>integer</td><td>Internal booking ID.</td></tr><tr><td><code>Status</code></td><td>string</td><td>InstantBooking returns Confirmed directly.</td></tr><tr><td><code>ConfirmedOn</code></td><td>datetime</td><td>Timestamp of when the booking was confirmed.</td></tr><tr><td><code>PartnerReference</code></td><td>string</td><td>Partner reference from the request, if supplied.</td></tr></tbody></table>

### Pricing

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="199.513916015625">Field</th><th width="149.7342529296875">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>TotalAmount</code></td><td>float</td><td>Total premium charged.</td></tr><tr><td><code>TotalAmountFormatted</code></td><td>string</td><td>Formatted total premium.</td></tr><tr><td><code>InsuranceCoverAmount</code></td><td>float</td><td>Total cover amount.</td></tr><tr><td><code>InsuranceCoverAmountFormatted</code></td><td>string</td><td>Formatted cover amount.</td></tr><tr><td><code>Disclaimer</code></td><td>string</td><td>Product disclaimer text.</td></tr></tbody></table>

### Vehicle coverage

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="200.238037109375">Field</th><th width="149.934326171875">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>VehicleTypes.*</code></td><td>boolean</td><td>Flags indicating which vehicle types this product covers. Keys: <code>car</code>, <code>motorhome</code>, <code>campervan</code>, <code>4x4</code>, <code>minibus</code>, <code>lighttruck</code>, <code>bus</code>, <code>caravan</code>, <code>freecancellationcover</code>, <code>freetravelinsurance</code>.</td></tr></tbody></table>

### Logos

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="249.5465087890625">Field</th><th width="150.365478515625">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>Logos.DarkFontPng.Url</code></td><td>string</td><td>URL to the dark-font PNG logo.</td></tr><tr><td><code>Logos.DarkFontSvg.Url</code></td><td>string</td><td>URL to the dark-font SVG logo.</td></tr><tr><td><code>Logos.LightFontPng.Url</code></td><td>string</td><td>URL to the light-font PNG logo.</td></tr><tr><td><code>Logos.LightFontSvg.Url</code></td><td>string</td><td>URL to the light-font SVG logo.</td></tr></tbody></table>

### Nested objects

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Field</th><th>Object type</th><th>Reference</th></tr></thead><tbody><tr><td><code>Policy</code></td><td>Policy object (subset)</td><td>Returns <code>Code</code>, <code>Name</code>, <code>Type</code>, and <code>PdsUrl</code> only. See <a href="/rentalcover/shared-reference/response-objects#policy-object">Policy object</a>.</td></tr><tr><td><code>Customer</code></td><td>Customer object</td><td>See <a href="/rentalcover/shared-reference/response-objects#customer-object">Customer object</a>.</td></tr></tbody></table>


# Purchase

**What it does:** Confirms and pays for a previously quote.

**When to call it:** After the customer accepts the product offer and provides payment details. A Quote must exist first. Pass its `Reference` as `AgentReference`.

{% hint style="info" %}
**Currency note**&#x20;

The Currency parameter is ignored in Purchase. Currency is set at quote time and cannot be changed.
{% endhint %}

```
POST /insurances/purchase
```

Optional variant (use when `AgentReference` uses your own reference format):

```
POST /insurances/purchase/<reference>
```

## Payment options

Use exactly one payment method per request:

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="275.2884521484375">Method</th><th>How to use</th></tr></thead><tbody><tr><td>Card payment (default)</td><td>Pass <code>CardHolder</code>, <code>CardNumber</code>, <code>CardExpiry</code>, and <code>CardSecurityCode</code>.</td></tr><tr><td>XPay tokenisation</td><td>Pass <code>XPayCustomerToken</code> instead of card fields.</td></tr><tr><td>Partner collecting payment</td><td>Set <code>PartnerCollectingPayment</code> to <code>true</code>. No card fields required.</td></tr><tr><td>Auto-rebill</td><td>Set <code>AutoRebill</code> to true for returning customers whose card is on file. No card fields required.</td></tr></tbody></table>

## Example request

{% tabs %}
{% tab title="POST" %}

```shellscript
curl -i -X POST \
  -H "X_API_KEY: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "AgentReference": "AB12-345C-INS",
    "PolicyCode": "RC001",
    "FromDate": "2025-08-01 00:00:00",
    "ToDate": "2025-08-08 00:00:00",
    "CustomerAge": 32,
    "DestinationCountry": "IE",
    "Country": "US",
    "FirstName": "Jane",
    "LastName": "Smith",
    "Email": "jane@example.com",
    "Address1": "123 Main St",
    "City": "New York",
    "PostalCode": "10001",
    "CardHolder": "JANE SMITH",
    "CardNumber": "4242424242424242",
    "CardExpiry": "0828",
    "CardSecurityCode": "123"
  }' \
  https://api-staging.rentalcover.com/insurances/purchase
```

{% endtab %}

{% tab title="Response" %}

```graphql
{
   "BookingId":"12345",
   "Reference":"AB12-345C-INS",
   "Status":"PendingConfirm",
   "FromDate":"2015-03-19 00:00:00",
   "ToDate":"2015-03-22 00:00:00",
   "TotalAmount":60,
   "InsuranceCoverAmount":3000,
   "SupplierReference":null,
   "Expired":false,
   "CoveredDays":4,
   "Discount":0,
   "DestinationCountry":"Australia",
   "DestinationCountryObject":{
      "Code":"AU",
      "Name":"Australia",
      "PhoneCode":"+61"
   },
   "Currency":"AUD",
   "TotalAmountFormatted":"AU$60.00",
   "InsuranceCoverAmountFormatted":"AU$3,000.00",
   "DiscountFormatted":"AU$0.00",
   "DailyAmountFormatted":"AU$15.00",
   "Disclaimer":"By clicking the button above you accept website <a href=\"https:\/\/www.rentalcover.com\/terms\" target=\"_blank\">terms<\/a> & the policy provided by RentalCover.com. \r\n\tYou agree that these documents have been provided to you via the links and understand that you may print copies of them. You have noted the exclusions and limitations, which include passengers with existing medical conditions. You are authorised to buy travel insurance on behalf of all passengers in this booking, and all passengers meet the eligibility criteria. \r\n",
   "Policy":{
      "GapCoverAmount":"3500.00",
      "Name":"Zero Excess Rental Cover",
      "Type":"RoadsideAssistance",
      "Code":"RC001",
      "Excess":"0.00",
      "Inclusions":"<li>Rental vehicle excess cover: $AU$3,000.00 plus $3500 Free Gap Cover. Gap cover is sold free of charge with all RentalCover.com policies. You do not need to take the optional excess reduction at the depot as $AU$3,000.00 + $3500 is sufficient to cover your standard liability).<\/li><br\/><li>Important: While the rental company will charge your credit card for the damages (up to the standard liability) you would then make a claim to RentalCover.com.<\/li><br\/>As with all other RentalCover.com policies, this policy includes the following which are typically excluded by the rental companies:<br\/><li>Windscreen, tyre, roof &amp; underbody repairs.<\/li><br\/><li>Single vehicle accidents.<\/li><br\/><li>Hitting an animal.<\/li><br\/><li>Accidents after dusk.<\/li><br\/><li>Weather-related and water damage.<\/li><br\/><li>Key loss\/replacement.<\/li><br\/><li>Additional drivers that are nominated on the rental agreement<\/li><br\/><li>Demurrage (the supplier&#039;s lost rental while a vehicle is off the road for repairs).<\/li><br\/><li>Maximum claim: $3500.<\/li><br\/><li>Claim Fee: $0<\/li><br\/><li>Cost: Free with any RentalCover.com purchase!<\/li><br\/>Exclusions:<br\/>This cover does not cover the following events:<br\/><li>Does not cover damages sustained while driving on unsealed roads.<\/li><br\/><li>Does not cover damage caused where the terms of Rental Contract have been breached.<\/li><br\/><li>Does not cover damage caused by an event that leads to a police investigation.<\/li><br\/><li>Does not cover damage caused to the Vehicle in any way by part or total water submersion or salt water. * Damage caused to the Vehicle by the renter\u2019s wilful or negligent conduct or contravention of any legislation or regulation controlling vehicular traffic<\/li><br\/><li>Does not cover damage caused due to use of incorrect or contaminated fuel.<\/li><br\/>Where required, RentalCover.com will utilise the resources of the claims team that handled the original claim application (i.e. the primary RentalCover.com policy issuer) and will exercise their discretion.",
      "Description":"This policy covers payments that you make for damages\/repairs to any rental vehicle anywhere in Australia. There is nil excess payable on a claim (whereas the rental companies charge $330-$1000 if you take their &quot;reduced&quot; excess). You do not need the supplier&#039;s excess reduction (collision damage waiver), instead you pay the supplier for repairs and claim that &quot;excess cost&quot; from RentalCover.com. Covers all drivers on the rental agreement aged 19 to 75, for travel anywhere in Australia on the dates shown. Note that there may be a refundable bond charged to your credit card when you do not take the supplier&#039;s excess reduction (card fees may apply).",
      "SellingPoints":"<li>No exclusions!<\/li><br\/><li>Includes $3500 Free Gap Cover, free with any RentalCover.com purchase.<\/li><br\/><li>Includes single vehicle accidents<\/li><br\/><li>Includes windscreens &amp; tyre damage<\/li><br\/><li>Covers you if you hit an animal or if you are driving at night.<\/li>",
      "RoadsideAssistanceBlob":"NMC Freecall Hotline is 855-613-8252 or +1-469-941-5569. Emergencies On The Road: If your car requires towing due to one of these, follow the 5 steps below: key loss, a mechanical fault, smashed windscreen/headlights or an accident... <li>Call the rental company and let them know that you have your own roadside assistance provider that includes towing. They will advise the towing dropoff point, then;</li> <li>Call NMC (see above). You will need your RentalCover.com reference number (AB12-345C-INS).</li> <li>NMC will send a tow truck &amp; you will pay NMC whilst on the call.</li> <li>You will meet the tow truck &amp; go to the delivery point with them.</li> <li>Claim all the costs that you incurred via <a href='http://www.rentalcover.com/claims'>rentalcover.com/claims</a>. Our goal is to reimburse you within 7 days.</li> Otherwise, if you have locked your keys in the car or have a flat tyre, empty fuel tank or dead battery... ? You do not need to call the rental company. Just call NMC who will arrange a vehicle to perform repairs. You will pay NMC and any related costs would be claimed via <a href='http://www.rentalcover.com'>rentalcover.com/claims</a>.",
      "GapCoverAmountFormatted":"AU$3,500.00",
      "ExcessFormatted":"AU$0.00",
      "PdsUrl":false,
      "SupplierName":"RentalCover.com",
      "ModifyUrl":"http:\/\/www.rentalcover.com\/modify\/AB12-345C-INS",
      "CancelUrl":"http:\/\/www.rentalcover.com\/cancel\/AB12-345C-INS"
   },
   "Customer":{
      "FirstName":"Jack",
      "LastName":"Smith",
      "Email":"jacksmith@myemail.com.au",
      "Age":21,
      "Country":"AU"
   }
}{
   "BookingId":"12345",
   "Reference":"AB12-345C-INS",
   "Status":"PendingConfirm",
   "FromDate":"2015-03-19 00:00:00",
   "ToDate":"2015-03-22 00:00:00",
   "TotalAmount":60,
   "InsuranceCoverAmount":3000,
   "SupplierReference":null,
   "Expired":false,
   "CoveredDays":4,
   "Discount":0,
   "DestinationCountry":"Australia",
   "DestinationCountryObject":{
      "Code":"AU",
      "Name":"Australia",
      "PhoneCode":"+61"
   },
   "Currency":"AUD",
   "TotalAmountFormatted":"AU$60.00",
   "InsuranceCoverAmountFormatted":"AU$3,000.00",
   "DiscountFormatted":"AU$0.00",
   "DailyAmountFormatted":"AU$15.00",
   "Disclaimer":"By clicking the button above you accept website <a href=\"https:\/\/www.rentalcover.com\/terms\" target=\"_blank\">terms<\/a> & the policy provided by RentalCover.com. \r\n\tYou agree that these documents have been provided to you via the links and understand that you may print copies of them. You have noted the exclusions and limitations, which include passengers with existing medical conditions. You are authorised to buy travel insurance on behalf of all passengers in this booking, and all passengers meet the eligibility criteria. \r\n",
   "Policy":{
      "GapCoverAmount":"3500.00",
      "Name":"Zero Excess Rental Cover",
      "Type":"RoadsideAssistance",
      "Code":"RC001",
      "Excess":"0.00",
      "Inclusions":"<li>Rental vehicle excess cover: $AU$3,000.00 plus $3500 Free Gap Cover. Gap cover is sold free of charge with all RentalCover.com policies. You do not need to take the optional excess reduction at the depot as $AU$3,000.00 + $3500 is sufficient to cover your standard liability).<\/li><br\/><li>Important: While the rental company will charge your credit card for the damages (up to the standard liability) you would then make a claim to RentalCover.com.<\/li><br\/>As with all other RentalCover.com policies, this policy includes the following which are typically excluded by the rental companies:<br\/><li>Windscreen, tyre, roof &amp; underbody repairs.<\/li><br\/><li>Single vehicle accidents.<\/li><br\/><li>Hitting an animal.<\/li><br\/><li>Accidents after dusk.<\/li><br\/><li>Weather-related and water damage.<\/li><br\/><li>Key loss\/replacement.<\/li><br\/><li>Additional drivers that are nominated on the rental agreement<\/li><br\/><li>Demurrage (the supplier&#039;s lost rental while a vehicle is off the road for repairs).<\/li><br\/><li>Maximum claim: $3500.<\/li><br\/><li>Claim Fee: $0<\/li><br\/><li>Cost: Free with any RentalCover.com purchase!<\/li><br\/>Exclusions:<br\/>This cover does not cover the following events:<br\/><li>Does not cover damages sustained while driving on unsealed roads.<\/li><br\/><li>Does not cover damage caused where the terms of Rental Contract have been breached.<\/li><br\/><li>Does not cover damage caused by an event that leads to a police investigation.<\/li><br\/><li>Does not cover damage caused to the Vehicle in any way by part or total water submersion or salt water. * Damage caused to the Vehicle by the renter\u2019s wilful or negligent conduct or contravention of any legislation or regulation controlling vehicular traffic<\/li><br\/><li>Does not cover damage caused due to use of incorrect or contaminated fuel.<\/li><br\/>Where required, RentalCover.com will utilise the resources of the claims team that handled the original claim application (i.e. the primary RentalCover.com policy issuer) and will exercise their discretion.",
      "Description":"This policy covers payments that you make for damages\/repairs to any rental vehicle anywhere in Australia. There is nil excess payable on a claim (whereas the rental companies charge $330-$1000 if you take their &quot;reduced&quot; excess). You do not need the supplier&#039;s excess reduction (collision damage waiver), instead you pay the supplier for repairs and claim that &quot;excess cost&quot; from RentalCover.com. Covers all drivers on the rental agreement aged 19 to 75, for travel anywhere in Australia on the dates shown. Note that there may be a refundable bond charged to your credit card when you do not take the supplier&#039;s excess reduction (card fees may apply).",
      "SellingPoints":"<li>No exclusions!<\/li><br\/><li>Includes $3500 Free Gap Cover, free with any RentalCover.com purchase.<\/li><br\/><li>Includes single vehicle accidents<\/li><br\/><li>Includes windscreens &amp; tyre damage<\/li><br\/><li>Covers you if you hit an animal or if you are driving at night.<\/li>",
      "RoadsideAssistanceBlob":"NMC Freecall Hotline is 855-613-8252 or +1-469-941-5569. Emergencies On The Road: If your car requires towing due to one of these, follow the 5 steps below: key loss, a mechanical fault, smashed windscreen/headlights or an accident... <li>Call the rental company and let them know that you have your own roadside assistance provider that includes towing. They will advise the towing dropoff point, then;</li> <li>Call NMC (see above). You will need your RentalCover.com reference number (AB12-345C-INS).</li> <li>NMC will send a tow truck &amp; you will pay NMC whilst on the call.</li> <li>You will meet the tow truck &amp; go to the delivery point with them.</li> <li>Claim all the costs that you incurred via <a href='http://www.rentalcover.com/claims'>rentalcover.com/claims</a>. Our goal is to reimburse you within 7 days.</li> Otherwise, if you have locked your keys in the car or have a flat tyre, empty fuel tank or dead battery... ? You do not need to call the rental company. Just call NMC who will arrange a vehicle to perform repairs. You will pay NMC and any related costs would be claimed via <a href='http://www.rentalcover.com'>rentalcover.com/claims</a>.",
      "GapCoverAmountFormatted":"AU$3,500.00",
      "ExcessFormatted":"AU$0.00",
      "PdsUrl":false,
      "SupplierName":"RentalCover.com",
      "ModifyUrl":"http:\/\/www.rentalcover.com\/modify\/AB12-345C-INS",
      "CancelUrl":"http:\/\/www.rentalcover.com\/cancel\/AB12-345C-INS"
   },
   "Customer":{
      "FirstName":"Jack",
      "LastName":"Smith",
      "Email":"jacksmith@myemail.com.au",
      "Age":21,
      "Country":"AU"
   }
}
```

{% endtab %}
{% endtabs %}

## Request parameters

### Booking identifiers

Required. Unique to Purchase.

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="184.6573486328125">Parameter</th><th width="150.324462890625">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>AgentReference</code></td><td>string</td><td>The <code>Reference</code> from the Quote response. Identifies which booking to purchase.</td></tr><tr><td><code>PolicyCode</code></td><td>string</td><td>The <code>Policy.Code</code> from the Quote response. Identifies the protection product to confirm.</td></tr></tbody></table>

### Payment

Required. Use one method only.

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="235.3402099609375">Parameter</th><th width="150.4383544921875">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>CardHolder</code></td><td>string</td><td>Cardholder name. Required for card payment.</td></tr><tr><td><code>CardNumber</code></td><td>string</td><td>Credit card number (digits only). Required for card payment.</td></tr><tr><td><code>CardExpiry</code></td><td>string(4)</td><td>Card expiry in <code>mmyy</code> format. Example: <code>0826</code>. Required for card payment.</td></tr><tr><td><code>CardSecurityCode</code></td><td>string</td><td>Card CVV/CVC. Required for card payment.</td></tr><tr><td><code>XPayCustomerToken</code></td><td>string</td><td>XPay token from the XPay tokenisation workflow. Use instead of card fields.</td></tr><tr><td><code>AutoRebill</code></td><td>boolean</td><td><code>true</code> to charge a returning customer's card on file. No card fields required.</td></tr><tr><td><code>PartnerCollectingPayment</code></td><td>boolean</td><td><code>true</code> when your platform collects payment. No card fields required.</td></tr></tbody></table>

### Customer & booking fields

Definitions shared with [Group A](https://partner-docs.covergenius.com/rentalcover/endpoints/pages/WVMEVLGGGf8OHDZ9pLSL#group-a.-core-booking) and [Group B](https://partner-docs.covergenius.com/rentalcover/endpoints/pages/WVMEVLGGGf8OHDZ9pLSL#group-b.-customer). Required fields must be re-passed even if provided at Quote time.

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="194.8192138671875">Parameter</th><th width="150.1187744140625">Required?</th><th>Notes</th></tr></thead><tbody><tr><td><code>FromDate</code></td><td>Required</td><td><br></td></tr><tr><td><code>ToDate</code></td><td>Required</td><td><br></td></tr><tr><td><code>DestinationCountry</code></td><td>Required</td><td><br></td></tr><tr><td><code>FirstName</code></td><td>Required</td><td><br></td></tr><tr><td><code>LastName</code></td><td>Required</td><td><br></td></tr><tr><td><code>Email</code></td><td>Required</td><td>Cannot be changed here — use <a href="/rentalcover/endpoints/update-customer">UpdateCustomer</a> after purchase.</td></tr><tr><td><code>Country</code></td><td>Required</td><td><br></td></tr><tr><td><code>Address1</code></td><td>Required</td><td>If unknown, use a placeholder such as <code>c/- Your Company Name</code>.</td></tr><tr><td><code>City</code></td><td>Required</td><td>If unknown, use a placeholder.</td></tr><tr><td><code>PostalCode</code></td><td>Required</td><td>If unknown, use a placeholder.</td></tr><tr><td><code>Address2</code></td><td>Optional</td><td><br></td></tr><tr><td><code>Region</code></td><td>Optional</td><td><br></td></tr><tr><td><code>Phone</code></td><td>Optional</td><td>Mobile preferred. Format: <code>+61413333333</code>.</td></tr><tr><td><code>OtherEmail</code></td><td>Optional</td><td><br></td></tr><tr><td><code>LanguageCode</code></td><td>Optional</td><td>Default: <code>en</code>.</td></tr><tr><td><code>CoverAmount</code></td><td>Optional</td><td><br></td></tr><tr><td><code>PolicyPrice</code></td><td>Optional</td><td><br></td></tr><tr><td><code>PartnerReference</code></td><td>Optional</td><td>Your internal booking reference for customer service.</td></tr><tr><td><code>Discount</code></td><td>Optional</td><td>Discount to apply, if available.</td></tr><tr><td><code>PartnerCardFees</code></td><td>Optional</td><td>Partner credit card fee.</td></tr></tbody></table>

## Response

Returns a [Booking Response](/rentalcover/shared-reference/response-objects#booking-responses) with the following differences.

### Fields that change after purchase

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="295.17529296875">Field</th><th width="149.9068603515625">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>Status</code></td><td>string</td><td>Typically <code>PendingConfirm</code> immediately after purchase. See <a href="/rentalcover/shared-reference/booking-statuses-and-errors#booking-statuses">Booking Statuses</a>.</td></tr><tr><td><code>SupplierReference</code></td><td>string</td><td>Insurer's policy number, issued upon confirmation.</td></tr><tr><td><code>TotalAmountOutstanding</code></td><td>float</td><td>Amount still outstanding. Usually equals <code>TotalAmount</code>; may differ after a modification.</td></tr><tr><td><code>TotalAmountOutstandingFormatted</code></td><td>string</td><td>Formatted outstanding amount.</td></tr><tr><td><code>TotalAmountRefunded</code></td><td>float</td><td>Amount refunded after a modification that reduced the price.</td></tr><tr><td><code>TotalAmountRefundedFormatted</code></td><td>string</td><td>Formatted refunded amount.</td></tr></tbody></table>

### Nested object differences

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="169.962158203125">Field</th><th width="195.3511962890625">Object type</th><th>Difference from Quote</th></tr></thead><tbody><tr><td><code>Policy</code></td><td>Policy object</td><td>Additionally, includes <code>RoadsideAssistanceBlob</code> - roadside assistance instructions for CRM systems and email templates. See <a href="/rentalcover/shared-reference/response-objects#policy-object">Policy object</a>.</td></tr><tr><td><code>Commission</code></td><td>Commission object</td><td>Unchanged. See <a href="/rentalcover/shared-reference/response-objects#commission-object">Commission object</a>.</td></tr></tbody></table>

{% hint style="info" %}
`SettlementCurrencyObject` is not returned by Purchase.
{% endhint %}


# Status

**What it does:** Returns the current booking details and status for a given reference.

**When to call it:** To verify a purchase has been confirmed, to check the booking state after an update, or to retrieve booking details for display.

```
GET /insurances/status/<reference>
```

## Example request

{% tabs %}
{% tab title="GET" %}

```shellscript
curl -i -X GET \
  -H "X_API_KEY: your_api_key" \
  https://api-staging.rentalcover.com/insurances/status/AB12-345C-INS
```

{% endtab %}

{% tab title="Response" %}

```graphql
{
   "BookingId":"12345",
   "Reference":"AB12-345C-INS",
   "Status":"PendingConfirm",
   "FromDate":"2015-03-19 00:00:00",
   "ToDate":"2015-03-22 00:00:00",
   "TotalAmount":60,
   "InsuranceCoverAmount":3000,
   "SupplierReference":null,
   "Expired":false,
   "CoveredDays":4,
   "Discount":0,
   "DestinationCountry":"Australia",
   "DestinationCountryObject":{
      "Code":"AU",
      "Name":"Australia",
      "PhoneCode":"+61"
   },
   "Currency":"AUD",
   "TotalAmountFormatted":"AU$60.00",
   "InsuranceCoverAmountFormatted":"AU$3,000.00",
   "DiscountFormatted":"AU$0.00",
   "DailyAmountFormatted":"AU$15.00",
   "Disclaimer":"By clicking the button above you accept website <a href=\"https:\/\/www.rentalcover.com\/terms\" target=\"_blank\">terms<\/a> & the policy provided by RentalCover.com. \r\n\tYou agree that these documents have been provided to you via the links and understand that you may print copies of them. You have noted the exclusions and limitations, which include passengers with existing medical conditions. You are authorised to buy travel insurance on behalf of all passengers in this booking, and all passengers meet the eligibility criteria. \r\n",
   "Policy":{
      "GapCoverAmount":"3500.00",
      "Name":"Zero Excess Rental Cover",
      "Type":"RoadsideAssistance",
      "Code":"RC001",
      "Excess":"0.00",
      "Inclusions":"<li>Rental vehicle excess cover: $AU$3,000.00 plus $3500 Free Gap Cover. Gap cover is sold free of charge with all RentalCover.com policies. You do not need to take the optional excess reduction at the depot as $AU$3,000.00 + $3500 is sufficient to cover your standard liability).<\/li><br\/><li>Important: While the rental company will charge your credit card for the damages (up to the standard liability) you would then make a claim to RentalCover.com.<\/li><br\/>As with all other RentalCover.com policies, this policy includes the following which are typically excluded by the rental companies:<br\/><li>Windscreen, tyre, roof &amp; underbody repairs.<\/li><br\/><li>Single vehicle accidents.<\/li><br\/><li>Hitting an animal.<\/li><br\/><li>Accidents after dusk.<\/li><br\/><li>Weather-related and water damage.<\/li><br\/><li>Key loss\/replacement.<\/li><br\/><li>Additional drivers that are nominated on the rental agreement<\/li><br\/><li>Demurrage (the supplier&#039;s lost rental while a vehicle is off the road for repairs).<\/li><br\/><li>Maximum claim: $3500.<\/li><br\/><li>Claim Fee: $0<\/li><br\/><li>Cost: Free with any RentalCover.com purchase!<\/li><br\/>Exclusions:<br\/>This cover does not cover the following events:<br\/><li>Does not cover damages sustained while driving on unsealed roads.<\/li><br\/><li>Does not cover damage caused where the terms of Rental Contract have been breached.<\/li><br\/><li>Does not cover damage caused by an event that leads to a police investigation.<\/li><br\/><li>Does not cover damage caused to the Vehicle in any way by part or total water submersion or salt water. * Damage caused to the Vehicle by the renter\u2019s wilful or negligent conduct or contravention of any legislation or regulation controlling vehicular traffic<\/li><br\/><li>Does not cover damage caused due to use of incorrect or contaminated fuel.<\/li><br\/>Where required, RentalCover.com will utilise the resources of the claims team that handled the original claim application (i.e. the primary RentalCover.com policy issuer) and will exercise their discretion.",
      "Description":"This policy covers payments that you make for damages\/repairs to any rental vehicle anywhere in Australia. There is nil excess payable on a claim (whereas the rental companies charge $330-$1000 if you take their &quot;reduced&quot; excess). You do not need the supplier&#039;s excess reduction (collision damage waiver), instead you pay the supplier for repairs and claim that &quot;excess cost&quot; from RentalCover.com. Covers all drivers on the rental agreement aged 19 to 75, for travel anywhere in Australia on the dates shown. Note that there may be a refundable bond charged to your credit card when you do not take the supplier&#039;s excess reduction (card fees may apply).",
      "SellingPoints":"<li>No exclusions!<\/li><br\/><li>Includes $3500 Free Gap Cover, free with any RentalCover.com purchase.<\/li><br\/><li>Includes single vehicle accidents<\/li><br\/><li>Includes windscreens &amp; tyre damage<\/li><br\/><li>Covers you if you hit an animal or if you are driving at night.<\/li>",
      "RoadsideAssistanceBlob":"NMC Freecall Hotline is 855-613-8252 or +1-469-941-5569. Emergencies On The Road: If your car requires towing due to one of these, follow the 5 steps below: key loss, a mechanical fault, smashed windscreen/headlights or an accident... <li>Call the rental company and let them know that you have your own roadside assistance provider that includes towing. They will advise the towing dropoff point, then;</li> <li>Call NMC (see above). You will need your RentalCover.com reference number (AB12-345C-INS).</li> <li>NMC will send a tow truck &amp; you will pay NMC whilst on the call.</li> <li>You will meet the tow truck &amp; go to the delivery point with them.</li> <li>Claim all the costs that you incurred via <a href='http://www.rentalcover.com/claims'>rentalcover.com/claims</a>. Our goal is to reimburse you within 7 days.</li> Otherwise, if you have locked your keys in the car or have a flat tyre, empty fuel tank or dead battery... ? You do not need to call the rental company. Just call NMC who will arrange a vehicle to perform repairs. You will pay NMC and any related costs would be claimed via <a href='http://www.rentalcover.com'>rentalcover.com/claims</a>.",
      "GapCoverAmountFormatted":"AU$3,500.00",
      "ExcessFormatted":"AU$0.00",
      "PdsUrl":false,
      "SupplierName":"RentalCover.com",
      "ModifyUrl":"http:\/\/www.rentalcover.com\/modify\/AB12-345C-INS",
      "CancelUrl":"http:\/\/www.rentalcover.com\/cancel\/AB12-345C-INS"
   },
   "Customer":{
      "FirstName":"Jack",
      "LastName":"Smith",
      "Email":"jacksmith@myemail.com.au",
      "Age":21,
      "Country":"AU"
   }
}
```

{% endtab %}
{% endtabs %}

## Request parameters

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Parameter</th><th>Required?</th><th>Description</th></tr></thead><tbody><tr><td><code>reference</code> (URL)</td><td>Required</td><td>The RentalCover booking reference.</td></tr></tbody></table>

## Response

Returns a [Booking Response](/rentalcover/shared-reference/response-objects#booking-responses). No fields differ from the canonical shape. Use Status to determine the current state of the booking. See [Booking Statuses](/rentalcover/shared-reference/booking-statuses-and-errors#booking-statuses).


# Update

**What it does:** Modifies an existing booking using a two-step preview-then-commit flow.

**When to call it:** Before the booking's `FromDate` has passed.

{% hint style="info" %}
**Restrictions**

To change the customer's email address, use [UpdateCustomer](/rentalcover/endpoints/update-customer).
{% endhint %}

## **What can be updated**

* Rental duration (`ToDate` relative to `FromDate`).
* Cover amount (`VehicleStdLiabilityLow` / `VehicleStdLiabilityHigh`).
* Customer details (`FirstName`, `LastName`, `CustomerAge`, `Address1`/`2`, `City`, `Region`, `PostalCode`, `Phone`).
* Vehicle information (`VehicleNettPrice`).

```
POST /insurances/update/<reference>
```

## Two-step flow

**Step 1. Preview (**`QuoteOnly: 1`**):** Returns the updated price without saving anything. Present the price difference to the customer before proceeding.

```shellscript
curl -i -X POST \
  -H "X_API_KEY: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "QuoteOnly": 1,
    "FromDate": "2025-08-01 00:00:00",
    "ToDate": "2025-08-10 00:00:00",
    "FirstName": "Jane",
    "LastName": "Smith",
    "Email": "jane@example.com",
    "Country": "US"
  }' \
  https://api-staging.rentalcover.com/insurances/update/AB12-345C-INS
```

**Step 2. Commit (**`QuoteOnly: 0`**):** Applies the change. RentalCover automatically refunds or charges the difference to the original card.

```shellscript
curl -i -X POST \
  -H "X_API_KEY: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "QuoteOnly": 0,
    "FromDate": "2025-08-01 00:00:00",
    "ToDate": "2025-08-10 00:00:00",
    "FirstName": "Jane",
    "LastName": "Smith",
    "Email": "jane@example.com",
    "Country": "US"
  }' \
  https://api-staging.rentalcover.com/insurances/update/AB12-345C-INS
```

## Request parameters

Update accepts fields from [Group A](https://partner-docs.covergenius.com/rentalcover/endpoints/pages/WVMEVLGGGf8OHDZ9pLSL#group-a.-core-booking), [Group B](https://partner-docs.covergenius.com/rentalcover/endpoints/pages/WVMEVLGGGf8OHDZ9pLSL#group-b.-customer), [Group D](https://partner-docs.covergenius.com/rentalcover/endpoints/pages/WVMEVLGGGf8OHDZ9pLSL#group-d.-pricing-and-coverage), and [Group F](https://partner-docs.covergenius.com/rentalcover/endpoints/pages/WVMEVLGGGf8OHDZ9pLSL#group-f.-partner-and-integration). Include only the fields you want to change, omitted fields remain unchanged.

### Update-specific parameter&#x20;

Required.

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Parameter</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code>QuoteOnly</code></td><td>boolean [0|1]</td><td><code>1</code> = preview (shows new price, saves nothing). <code>0</code> = commit the change. Always call step 1 first.</td></tr></tbody></table>

{% hint style="info" %}
`Email` is accepted as an identifier but cannot be changed here. Use [UpdateCustomer](/rentalcover/endpoints/update-customer).
{% endhint %}

## Response

Returns a [Booking Response](/rentalcover/shared-reference/response-objects#booking-responses). In preview mode (`QuoteOnly: 1`), Status and pricing fields reflect the proposed change but nothing is saved. In commit mode (`QuoteOnly: 0`), the response confirms the applied change.


# Update Customer

**What it does:** Updates customer personal information on an existing booking, including email address.

```
POST /insurances/updateCustomer
```

## Example request

{% tabs %}
{% tab title="POST" %}

```shellscript
curl -i -X POST \
  -H "X_API_KEY: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "AgentReference": "AB12-345C-INS",
    "Email": "jane@example.com",
    "NewEmail": "jane.new@example.com",
    "FirstName": "Jane",
    "LastName": "Smith",
    "Phone": "+12125551234",
    "CustomerAge": 33,
    "Address1": "456 Park Ave",
    "City": "New York",
    "PostalCode": "10022",
    "Region": "NY",
    "Country": "US"
  }' \
  https://api-staging.rentalcover.com/insurances/updateCustomer
```

{% endtab %}

{% tab title="Response" %}

```graphql
{
   "Country":{
      "Code":"AU",
      "Name":"Australia",
      "PhoneCode":"+61"
   },
   "Customer":{
      "CustomerId":"229233",
      "FirstName":"John",
      "LastName":"Doe",
      "Email":"neweemail@test.com",
      "Phone":"+6141012345678",
      "Address1":"20 Some Address",
      "Address2":"Suite 15",
      "City":"Sydney",
      "Region":"NSW",
      "PostalCode":"2014",
      "CountryId":"14",
      "DateOfBirth":"1990-01-01",
      "Age":28,
      "Coupons":{
         "bonvoyage-PAPpC":{
            "Title":"15% off your policy",
            "Value":"15",
            "ValueType":"Percentage",
            "AmountRemaining":null,
            "EffectiveFrom":"2018-06-28 00:00:00",
            "EffectiveTo":"2018-07-12 00:00:00",
            "Terms":"<ul><li>User is entitled to a 15% discount on eligible RentalCover.com policies. All policies are eligible except RentalCover.com's \"Collision Damage Coverage\" for US Residents/Citizens and \"Annual\" policies.</li><li>Payment must be conducted via RentalCover.com's website or mobile app. It is not applicable via our partner sites.</li><li>Coupon cannot be shared.</li><li>Coupon expires on: 2018-07-12. Coupon creation date: 2018-06-28.</li><li>Can only apply one coupon per paid policy.</li><li>Can only be used once per user</li></ul>"
         }
      }
   }
}
```

{% endtab %}
{% endtabs %}

## Request parameters

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="170.4169921875">Parameter</th><th width="150.1805419921875">Required?</th><th>Description</th></tr></thead><tbody><tr><td><code>AgentReference</code></td><td>Required</td><td>The booking reference (e.g. <code>AB12-345C-INS</code>).</td></tr><tr><td><code>Email</code></td><td>Required</td><td>Current customer email. Used as a unique identifier along with the booking reference.</td></tr><tr><td><code>FirstName</code></td><td>Optional</td><td>Customer first name.</td></tr><tr><td><code>LastName</code></td><td>Optional</td><td>Customer last name.</td></tr><tr><td><code>NewEmail</code></td><td>Optional</td><td>New email address. Pass this to change the customer's email.</td></tr><tr><td><code>Phone</code></td><td>Optional</td><td>Customer phone number.</td></tr><tr><td><code>CustomerAge</code></td><td>Optional</td><td>Customer age.</td></tr><tr><td><code>DateOfBirth</code></td><td>Optional</td><td>Customer date of birth (<code>yyyy-mm-dd</code>).</td></tr><tr><td><code>Address1</code></td><td>Optional</td><td>Customer street address line 1.</td></tr><tr><td><code>Address2</code></td><td>Optional</td><td>Customer street address line 2.</td></tr><tr><td><code>City</code></td><td>Optional</td><td>Customer city or suburb.</td></tr><tr><td><code>Region</code></td><td>Optional</td><td>State, region, or territory code. See <a href="/rentalcover/supported-regions">Supported Regions</a>.</td></tr><tr><td><code>PostalCode</code></td><td>Optional</td><td>Customer postcode or zip.</td></tr><tr><td><code>Country</code></td><td>Optional</td><td>ISO 3166-1 alpha-2 country code.</td></tr><tr><td><code>OtherEmail</code></td><td>Optional</td><td>Secondary email address.</td></tr></tbody></table>

## Response

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Field</th><th>Object type</th><th>Reference</th></tr></thead><tbody><tr><td><code>Country</code></td><td>DestinationCountry object</td><td>Customer's country (<code>Code</code>, <code>Name</code>, <code>PhoneCode</code>). See <a href="/rentalcover/shared-reference/response-objects#destinationcountry-object">DestinationCountry object</a>.</td></tr><tr><td><code>Customer</code></td><td>Customer object</td><td>The updated customer record. See <a href="/rentalcover/shared-reference/response-objects#customer-object">Customer object</a>.</td></tr></tbody></table>


# Cancel

**What it does:** Cancels a quote or purchased protection.

**When to call it:** Before the booking's `FromDate`. Cancellation is blocked if a claim is in progress or the customer has raised a card dispute.

Use `DELETE` to cancel without a reason. Use `POST` to include a `CancelReason` (recommended - useful for reporting and customer service).

```
DELETE /insurances/cancel/<reference>
POST   /insurances/cancel/<reference>
```

## Example request

### DELETE (no reason)

```shellscript
curl -i -X DELETE \
  -H "X_API_KEY: your_api_key" \
  https://api-staging.rentalcover.com/insurances/cancel/AB12-345C-INS
```

### POST (with reason)

```shellscript
curl -i -X POST \
  -H "X_API_KEY: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"CancelReason": "Customer trip has been cancelled"}' \
  https://api-staging.rentalcover.com/insurances/cancel/AB12-345C-INS
```

## Request parameters

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="200.0098876953125">Parameter</th><th width="169.5711669921875">Required?</th><th>Description</th></tr></thead><tbody><tr><td><code>reference</code> (URL)</td><td>Required</td><td>The RentalCover booking reference.</td></tr><tr><td><code>CancelReason</code></td><td>Required for <code>POST</code></td><td>Reason for cancellation. Max 500 characters.</td></tr></tbody></table>

## Response

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="200.0999755859375">Field</th><th width="170.3096923828125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>BookingId</code></td><td>string</td><td>Internal booking ID.</td></tr><tr><td><code>Reference</code></td><td>string</td><td>Booking reference.</td></tr><tr><td><code>Status</code></td><td>string</td><td><code>Cancelled</code> on success.</td></tr><tr><td><code>CancelMessage</code></td><td>string</td><td>Human-readable cancellation confirmation, including any refund amount.</td></tr></tbody></table>

```graphql
{
   "BookingId":"12345",
   "Reference":"AB12-345C-INS",
   "Status":"Cancelled",
   "CancelMessage":"Booking: AB12-345C-INS has been cancelled. A refund for AU$99.00 has been processed."
}
```


# Notifications/list

**What it does:** Returns pending booking events created directly in RentalCover.com. For example, date changes or cancellations initiated by RentalCover customer support.

{% hint style="info" %}
**For invoicing partners only**&#x20;

If your integration uses webhooks, you don't need to poll this endpoint. Webhooks deliver the same events in real time.
{% endhint %}

```
GET /notifications/list
```

## Example request

{% tabs %}
{% tab title="GET" %}

```shellscript
curl -i -X GET \
  -H "X_API_KEY: your_api_key" \
  https://api-staging.rentalcover.com/notifications/list
```

{% endtab %}

{% tab title="Response" %}

```graphql
[
   {
      "EventId":"evt_71jea4sjl778s24",
      "Sequence":1,
      "CreatedAt":"2018-01-19 10:38:26",
      "Category":"DirectUpdate",
      "EventStatus":"Pending",
      "Reference":"XXXX-XXXX-INS",
      "Type":"Refund",
      "Currency":"AUD",
      "Amount":-13.82,
      "CurrentAttributes":{
         "Status":"PendingUpdate",
         "Currency":"AUD",
         "TotalAmount":102.16,
         "FromDate":"2018-01-31 00:00:00",
         "ToDate":"2018-02-04 00:00:00",
         "InsuranceCoverAmount":100000,
         "DestinationCountry":"AU",
         "PartnerReference":null,
         "Policy":{
            "Code":"FULLPROTECTION1",
            "Type":"FullProtection",
            "Name":"Full Protection"
         },
         "VehicleTypes":{
            "freecancellationcover":false,
            "freetravelinsurance":false,
            "car":true,
            "motorhome":false,
            "campervan":false,
            "4x4":false,
            "minibus":false,
            "lighttruck":false,
            "bus":false
         },
         "Customer":{
            "FirstName":"Test",
            "LastName":"Test",
            "Email":"test@rentalcover.com",
            "Age":"34",
            "Country":"AU"
         }
      },
      "PreviousAttributes":{
         "Status":"Confirmed",
         "Currency":"AUD",
         "TotalAmount":115.98,
         "FromDate":"2018-01-31 00:00:00",
         "ToDate":"2018-02-05 00:00:00",
         "InsuranceCoverAmount":100000,
         "DestinationCountry":"AU",
         "PartnerReference":null,
         "Policy":{
            "Code":"FULLPROTECTION1",
            "Type":"FullProtection",
            "Name":"Full Protection"
         },
         "VehicleTypes":{
            "freecancellationcover":false,
            "freetravelinsurance":false,
            "car":true,
            "motorhome":false,
            "campervan":false,
            "4x4":false,
            "minibus":false,
            "lighttruck":false,
            "bus":false
         },
         "Customer":{
            "FirstName":"Test",
            "LastName":"Test",
            "Email":"test@rentalcover.com",
            "Age":"34",
            "Country":"AU"
         }
      }
   }
][
   {
      "EventId":"evt_71jea4sjl778s24",
      "Sequence":1,
      "CreatedAt":"2018-01-19 10:38:26",
      "Category":"DirectUpdate",
      "EventStatus":"Pending",
      "Reference":"XXXX-XXXX-INS",
      "Type":"Refund",
      "Currency":"AUD",
      "Amount":-13.82,
      "CurrentAttributes":{
         "Status":"PendingUpdate",
         "Currency":"AUD",
         "TotalAmount":102.16,
         "FromDate":"2018-01-31 00:00:00",
         "ToDate":"2018-02-04 00:00:00",
         "InsuranceCoverAmount":100000,
         "DestinationCountry":"AU",
         "PartnerReference":null,
         "Policy":{
            "Code":"FULLPROTECTION1",
            "Type":"FullProtection",
            "Name":"Full Protection"
         },
         "VehicleTypes":{
            "freecancellationcover":false,
            "freetravelinsurance":false,
            "car":true,
            "motorhome":false,
            "campervan":false,
            "4x4":false,
            "minibus":false,
            "lighttruck":false,
            "bus":false
         },
         "Customer":{
            "FirstName":"Test",
            "LastName":"Test",
            "Email":"test@rentalcover.com",
            "Age":"34",
            "Country":"AU"
         }
      },
      "PreviousAttributes":{
         "Status":"Confirmed",
         "Currency":"AUD",
         "TotalAmount":115.98,
         "FromDate":"2018-01-31 00:00:00",
         "ToDate":"2018-02-05 00:00:00",
         "InsuranceCoverAmount":100000,
         "DestinationCountry":"AU",
         "PartnerReference":null,
         "Policy":{
            "Code":"FULLPROTECTION1",
            "Type":"FullProtection",
            "Name":"Full Protection"
         },
         "VehicleTypes":{
            "freecancellationcover":false,
            "freetravelinsurance":false,
            "car":true,
            "motorhome":false,
            "campervan":false,
            "4x4":false,
            "minibus":false,
            "lighttruck":false,
            "bus":false
         },
         "Customer":{
            "FirstName":"Test",
            "LastName":"Test",
            "Email":"test@rentalcover.com",
            "Age":"34",
            "Country":"AU"
         }
      }
   }
]
```

{% endtab %}
{% endtabs %}

## Response

Returns an array of event objects. After processing each event, call [Notifications/update](/rentalcover/endpoints/notification-update) with the `EventId` to prevent it from reappearing.

### Event metadata

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="179.8988037109375">Field</th><th width="149.623291015625">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>EventId</code></td><td>string</td><td>Unique event identifier. Pass to Notifications/update to acknowledge.</td></tr><tr><td><code>Sequence</code></td><td>integer</td><td>Sequence number for ordering events.</td></tr><tr><td><code>CreatedAt</code></td><td>datetime</td><td>When the event was created.</td></tr><tr><td><code>Category</code></td><td>string</td><td><code>DirectUpdate</code>: the booking was modified or cancelled directly in RentalCover.com.</td></tr><tr><td><code>EventStatus</code></td><td>string</td><td><code>Pending</code> or <code>Processed</code>.</td></tr></tbody></table>

### Financial details

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="180.216796875">Field</th><th width="150.2254638671875">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>Reference</code></td><td>string</td><td>Booking reference.</td></tr><tr><td><code>Type</code></td><td>string</td><td>Financial event type: <code>Refund</code>, <code>Charge</code>, or <code>Cancel</code>.</td></tr><tr><td><code>Currency</code></td><td>string</td><td>Currency of the booking.</td></tr><tr><td><code>Amount</code></td><td>float</td><td>Amount to charge or refund. Negative values indicate a refund.</td></tr></tbody></table>

### Booking state

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="180.39990234375">Field</th><th width="149.904052734375">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>CurrentAttributes</code></td><td>object</td><td>Booking state after the change. Contains: <code>Status</code>, <code>Currency</code>, <code>TotalAmount</code>, <code>FromDate</code>, <code>ToDate</code>, <code>InsuranceCoverAmount</code>, <code>DestinationCountry</code>, <code>PartnerReference</code>, <code>Policy</code>, <code>VehicleTypes</code>, <code>Customer</code>.</td></tr><tr><td><code>PreviousAttributes</code></td><td>object</td><td>Booking state before the change. Same structure as <code>CurrentAttributes</code>.</td></tr></tbody></table>


# Notification/update

**What it does:** Acknowledges that your system has processed a notification event.

**When to call it:** After handling each event returned by Notifications/list.

```
POST /notifications/update/event/<eventid>
```

## Example request

```shellscript
curl -i -X POST \
  -H "X_API_KEY: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"Acknowledged": true, "ProcessedAt": "2025-08-01 09:00:00"}' \
  https://api-staging.rentalcover.com/notifications/update/event/evt_71jea4sjl778s24
```

## Request Parameters

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="189.7308349609375">Parameter</th><th width="149.6307373046875">Required?</th><th>Description</th></tr></thead><tbody><tr><td><code>eventid</code> (URL)</td><td>Required</td><td>The <code>EventId</code> from the Notifications/list response.</td></tr><tr><td><code>Acknowledged</code></td><td>Required</td><td><code>true</code> if your system processed the event successfully. <code>false</code> if processing failed.</td></tr><tr><td><code>ProcessedAt</code></td><td>Required</td><td>Timestamp of when your system processed the event. Format: <code>yyyy-mm-dd hh:mm:ss</code>.</td></tr></tbody></table>

## Response&#x20;

Returns Status string on `ok`.

```graphql
{
   "Status":"ok"
}
```


# GetAllPurchasedPolicies

**What it does:** Returns a paginated list of all bookings (purchased and cancelled) associated with your account.

{% code overflow="wrap" %}

```
POST /insurances/getAllPurchasedPolicies
```

{% endcode %}

## Example request

{% tabs %}
{% tab title="POST" %}

```shellscript
curl -i -X POST \
  -H "X_API_KEY: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"FromDate": "2025-01-01 00:00:00", "ToDate": "2025-06-30 23:59:59", "Page": 1}' \
  https://api-staging.rentalcover.com/insurances/getAllPurchasedPolicies
```

{% endtab %}

{% tab title="Response" %}

```graphql
{
   "MetaData":{
      "TotalItems":1,
      "TotalPages":1,
      "CurrentPage":1,
      "ItemsPerPage":500,
      "Links":{
         "FirstPage":"https://api-staging.rentalcover.com/insurances/getAllPurchasedPolicies/page/1"
      }
   },
   "Bookings":[
      {
         "Booking":{
            "BookingId":"1971444",
            "Status":"Cancelled",
            "Reference":"7VC1-XZ75-INS",
            "FromDate":"2018-05-08 00:00:00",
            "ToDate":"2018-05-20 00:00:00",
            "Currency":"USD",
            "Amount":"52.56",
            "ModifiedOn":"2018-11-23 14:03:56"
         }
      }
   ]
}
```

{% endtab %}
{% endtabs %}

## Request parameters

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="169.7076416015625">Parameter</th><th width="149.7652587890625">Required?</th><th>Description</th></tr></thead><tbody><tr><td><code>FromDate</code></td><td>Optional</td><td>Start of the modification-date filter.</td></tr><tr><td><code>ToDate</code></td><td>Optional</td><td>End of the modification-date filter.</td></tr><tr><td><code>Page</code></td><td>Optional</td><td>Page index. Default: <code>1</code>. Each page contains up to 500 items.</td></tr></tbody></table>

{% hint style="info" %}
**Date filter**

`FromDate` and `ToDate` filter by each booking's last-modification date, not by protection start or end date.
{% endhint %}

## Response

### Pagination metadata

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="234.7935791015625">Field</th><th width="149.7606201171875">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>MetaData.TotalItems</code></td><td>integer</td><td>Total number of matching bookings.</td></tr><tr><td><code>MetaData.TotalPages</code></td><td>integer</td><td>Total number of pages.</td></tr><tr><td><code>MetaData.CurrentPage</code></td><td>integer</td><td>Current page index.</td></tr><tr><td><code>MetaData.ItemsPerPage</code></td><td>integer</td><td>Number of items per page (500 max).</td></tr><tr><td><code>MetaData.Links.FirstPage</code></td><td>string</td><td>URL for page 1.</td></tr></tbody></table>

### Booking items

Each item in the `Bookings` array.

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="274.680419921875">Field</th><th width="150.131103515625">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>Bookings[].Booking.BookingId</code></td><td>string</td><td>Internal booking ID.</td></tr><tr><td><code>Bookings[].Booking.Status</code></td><td>string</td><td>Booking status.</td></tr><tr><td><code>Bookings[].Booking.Reference</code></td><td>string</td><td>Booking reference.</td></tr><tr><td><code>Bookings[].Booking.FromDate</code></td><td>datetime</td><td>Protection start date.</td></tr><tr><td><code>Bookings[].Booking.ToDate</code></td><td>datetime</td><td>Protection end date.</td></tr><tr><td><code>Bookings[].Booking.Currency</code></td><td>string</td><td>Booking currency.</td></tr><tr><td><code>Bookings[].Booking.Amount</code></td><td>string</td><td>Total protection amount.</td></tr><tr><td><code>Bookings[].Booking.ModifiedOn</code></td><td>datetime</td><td>Date of last modification. The <code>FromDate</code>/<code>ToDate</code> filter applies to this field.</td></tr></tbody></table>


# GetAllCancelledPolicies

**What it does:** Returns a paginated list of all cancelled policies associated with your account.

```
POST /insurances/getAllCancelledPolicies
```

## Example request

{% tabs %}
{% tab title="POST" %}

```shellscript
curl -i -X POST \
  -H "X_API_KEY: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"FromDate": "2025-01-01 00:00:00", "ToDate": "2025-06-30 23:59:59", "Page": 1}' \
  https://api-staging.rentalcover.com/insurances/getAllCancelledPolicies
```

{% endtab %}

{% tab title="Response" %}

```graphql
{
   "MetaData":{
      "TotalItems":1,
      "TotalPages":1,
      "CurrentPage":1,
      "ItemsPerPage":1000,
      "Links":{
         "FirstPage":"https://api-testing.rentalcover.com/insurances/getAllCancelledPolicies/page/1"
      }
   },
   "Bookings":[
      {
         "Booking":{
            "BookingId":"2395636",
            "Reference":"026J-88W5-INS",
            "CancelledOn":"2018-06-28 15:23:39"
         }
      }
   ]
}{
   "MetaData":{
      "TotalItems":1,
      "TotalPages":1,
      "CurrentPage":1,
      "ItemsPerPage":1000,
      "Links":{
         "FirstPage":"https://api-testing.rentalcover.com/insurances/getAllCancelledPolicies/page/1"
      }
   },
   "Bookings":[
      {
         "Booking":{
            "BookingId":"2395636",
            "Reference":"026J-88W5-INS",
            "CancelledOn":"2018-06-28 15:23:39"
         }
      }
   ]
}
```

{% endtab %}
{% endtabs %}

## Request Parameters

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="169.617431640625">Parameter</th><th width="149.5831298828125">Required?</th><th>Description</th></tr></thead><tbody><tr><td><code>FromDate</code></td><td>Optional</td><td>Start of the modification-date filter.</td></tr><tr><td><code>ToDate</code></td><td>Optional</td><td>End of the modification-date filter.</td></tr><tr><td><code>Page</code></td><td>Optional</td><td>Page index. Default: <code>1</code>. Each page contains up to 1,000 items.</td></tr></tbody></table>

{% hint style="info" %}
**Date filter**

`FromDate` and `ToDate` filter by each booking's last-modification date, not by protection start or end date.
{% endhint %}

## Response

### Pagination metadata

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="235.1817626953125">Field</th><th width="149.510498046875">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>MetaData.TotalItems</code></td><td>integer</td><td>Total number of matching cancelled bookings.</td></tr><tr><td><code>MetaData.TotalPages</code></td><td>integer</td><td>Total number of pages.</td></tr><tr><td><code>MetaData.CurrentPage</code></td><td>integer</td><td>Current page index.</td></tr><tr><td><code>MetaData.ItemsPerPage</code></td><td>integer</td><td>Number of items per page (1,000 max).</td></tr></tbody></table>

### Booking items&#x20;

Each entry in the Bookings array

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="282.330078125">Field</th><th width="149.7872314453125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>Bookings[].Booking.BookingId</code></td><td>string</td><td>Internal booking ID.</td></tr><tr><td><code>Bookings[].Booking.Reference</code></td><td>string</td><td>Booking reference.</td></tr><tr><td><code>Bookings[].Booking.CancelledOn</code></td><td>datetime</td><td>Date and time the protection was cancelled.</td></tr></tbody></table>


# Invoice

**What it does:** Returns the PDF invoice for a confirmed booking.

{% hint style="info" %}
**Confirmed bookings only.** Only bookings with Status: `Confirmed` can generate an invoice.
{% endhint %}

```
GET /insurances/invoice/reference:[A-Z0-9\-]+
```

## Example request

{% tabs %}
{% tab title="GET" %}

```shellscript
curl -i -X GET \
  -H "X_API_KEY: your_api_key" \
  https://api-staging.rentalcover.com/insurances/invoice/AB12-345C-INS
```

{% endtab %}

{% tab title="Response" %}

```graphql
The generated PDF will be attached in the response with the following name: 
Invoice_AB12-345C-INS.pdf
(Content-Type is application/pdf).
```

{% endtab %}
{% endtabs %}

## Request parameters

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Parameter</th><th>Required?</th><th>Description</th></tr></thead><tbody><tr><td><code>reference</code> (URL)</td><td>Required</td><td>The confirmed booking reference.</td></tr></tbody></table>

## **Response**

The response body is a PDF file. `Content-Type: application/pdf`. Filename format: `Invoice_<reference>.pdf` (e.g. `Invoice_AB12-345C-INS.pdf`).


# Webhook

Webhooks allow RentalCover to push booking events to your server in real time, so you don't need to poll [Notifications/list](/rentalcover/endpoints/notifications-list). When a booking is created, updated, or cancelled, RentalCover sends an HTTP POST to a URL you configure.

## Setup

1. Expose an HTTPS endpoint on your server that accepts HTTP POST requests.
2. Contact your Cover Genius CSE with your endpoint URL and the events you want to subscribe to. Your CSE configures the webhook in the RentalCover backend.
3. Verify HMAC signatures on all incoming requests (see [HMAC Verification](#hmac-verification) below).
4. Return an HTTP 2xx status code to acknowledge each event.

## Available events

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="229.633544921875">Event</th><th>Description</th></tr></thead><tbody><tr><td><code>booking.created</code></td><td>A new booking has been confirmed.</td></tr><tr><td><code>booking.updated</code></td><td>A booking has been modified (dates, cover, or customer details changed).</td></tr><tr><td><code>booking.cancelled</code></td><td>A booking has been cancelled.</td></tr></tbody></table>

RentalCover currently supports one live booking event:

* `booking.cancelled` — booking cancellation

`booking.created` and `booking.updated` are reserved for future use and are not yet sent. Do not subscribe to these until Cover Genius confirms availability.

## Acknowledging events

Your endpoint must return HTTP `2xx` to confirm receipt. If your server returns a non-2xx response, RentalCover considers delivery failed. Contact your CSE for retry behaviour details.

## HMAC verification

Each webhook request includes an HMAC-SHA256 signature in the `X-Signature` header. Verify this signature before processing the payload. It confirms the request originated from RentalCover and was not altered in transit.

{% code overflow="wrap" %}

```shellscript
curl --location '[your_server_endpoint]'
--header 'Content-Type: application/json'
--header 'X-Signature: [shared_secret]'
--data-raw '[request_payload]'
```

{% endcode %}

{% hint style="info" %}
Reject requests with an invalid signature without acknowledging them.
{% endhint %}

Your HMAC secret key is provided when your webhook is configured by your CSE.

Requests include an `X-Signature` header containing an HMAC-SHA256 signature, computed over the request body concatenated with the `Timestamp` header value. You must verify this signature using your shared secret key before processing. Reject requests with an invalid signature without acknowledging them.

```php
<?php

// Shared HMAC key provided by your CSE at webhook configuration
$secret = 'your_hmac_secret_key';

// Read the raw request body
$requestBody = file_get_contents('php://input');

// Read the HMAC signature from the request header
$receivedHMAC = $_SERVER['HTTP_X_SIGNATURE'] ?? '';
//UTC datetime the request was signed; required to verify the signature
$timestamp = $_SERVER['HTTP_TIMESTAMP'] ?? null;

//use this to check if it is a duplicate request
$idempotencyKey = $_SERVER['HTTP_IDEMPOTENCY_KEY'] ?? null;

// Calculate the expected signature
$signedPayload = $requestBody . $timestamp;
$calculatedHMAC = hash_hmac('sha256', $signedPayload, $secret);

// Compare using a timing-safe function to prevent timing attacks
if (hash_equals($calculatedHMAC, $receivedHMAC)) {
    $data = json_decode($requestBody, true);
    // ... handle $data ...
    http_response_code(200);
    echo 'Webhook verified and processed';
} else {
    http_response_code(400);
    echo 'Invalid signature';
}
```

**Headers sent with every webhook request:**

* `X-Signature` — HMAC-SHA256 signature (see above)
* `Timestamp` — UTC datetime the request was signed; required to verify the signature
* `Idempotency-Key` — unique per-delivery hash; use to de-duplicate retried/redelivered requests

## Cancellation event&#x20;

### Payload

Core fields include:

```json
{
  "Event": "BOOKING_CANCELLED",
  "Bookings": [
    {
      "BookingId": "12345",
      "Reference": "AB12-345C-INS",
      "Type": "FullProtection",
      "Code": "FULLPROTECTION11",
      "SupplierReference": "CXCSUK8F7C0U",
      "MetaData": "{\"provider_id\":\"PARTNER123\"}"
    }
  ],
  "Status": "Cancelled",
  "Currency": "USD",
  "TotalAmount": 60,
  "TotalAmountFormatted": "US$60.00",
  "PartnerReference": "PARTNER-REF-001",
  "PartnerCollectingPayment": false,
  "PartnerSiteCode": "carrentalscouk",
  "FromDate": "2025-08-01 00:00:00",
  "ToDate": "2025-08-08 00:00:00",
  "CancelledOn": "2025-07-15 10:20:25",
  "Source": "Frontend",
  "CancelReason": "Trip has been cancelled"
}
```

### Fields

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="199.60400390625">Field</th><th width="149.8304443359375">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>Event</code></td><td>string</td><td>Event type identifier. Example: <code>BOOKING_CANCELLED</code>.</td></tr><tr><td><code>Bookings</code></td><td>array</td><td>Array of affected bookings. Contains multiple entries for bundled bookings.</td></tr><tr><td><code>Bookings[].BookingId</code></td><td>string</td><td>Internal booking ID.</td></tr><tr><td><code>Bookings[].Reference</code></td><td>string</td><td>Booking reference (ends in <code>-INS</code>). Use this for all claims and support.</td></tr><tr><td><code>Bookings[].Type</code></td><td>string</td><td>Policy type.</td></tr><tr><td><code>Bookings[].Code</code></td><td>string</td><td>Policy code.</td></tr><tr><td><code>Bookings[].SupplierReference</code></td><td>string</td><td>Insurer's policy reference.</td></tr><tr><td><code>Bookings[].MetaData</code></td><td>string</td><td>JSON string of the <code>MetaData</code> passed in the original quote or purchase request.</td></tr><tr><td><code>Status</code></td><td>string</td><td>Booking status at the time of the event.</td></tr><tr><td><code>Currency</code></td><td>string</td><td>Three-letter ISO 4217 currency code.</td></tr><tr><td><code>TotalAmount</code></td><td>float</td><td>Original total protection amount.</td></tr><tr><td><code>TotalAmountFormatted</code></td><td>string</td><td>Formatted total amount.</td></tr><tr><td><code>PartnerReference</code></td><td>string</td><td>Your booking reference, if provided.</td></tr><tr><td><code>PartnerCollectingPayment</code></td><td>boolean</td><td>Whether the partner was collecting payment.</td></tr><tr><td><code>PartnerSiteCode</code></td><td>string</td><td>The partner-defined site/sub-brand identifier configured for this booking's agent site</td></tr><tr><td><code>FromDate</code></td><td>datetime</td><td>Protection start date.</td></tr><tr><td><code>ToDate</code></td><td>datetime</td><td>Protection end date.</td></tr><tr><td><code>CancelledOn</code></td><td>datetime</td><td>Date and time the booking was cancelled.</td></tr><tr><td><code>Source</code></td><td>string</td><td>Where the cancellation originated: <code>Frontend</code>, <code>Backend</code>, or <code>API</code>.</td></tr><tr><td><code>CancelReason</code></td><td>string</td><td>Reason provided for the cancellation.</td></tr></tbody></table>


# Supported Currencies

Use the `Currency` parameter on supported endpoints to specify the currency for quotes and payments. Pass a three-letter ISO 4217 code.

**Zero-decimal currencies**

For standard currencies, monetary amounts are expressed in the minor unit. For example, AUD 45.00 is passed as `4500`. For zero-decimal currencies, there is no decimal subdivision. For example, JPY 500 is passed as `500`.

Pass the currency code in Quote or InstantBooking. All subsequent calls for that booking (Purchase, Update, Cancel) use the same currency.

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="255.8985595703125">Code</th><th width="256.273193359375">Currency</th><th>Zero decimal?</th></tr></thead><tbody><tr><td><code>AED</code></td><td>Emirati Dirham</td><td>No</td></tr><tr><td><code>ARS</code></td><td>Argentina Peso</td><td>No</td></tr><tr><td><code>AUD</code></td><td>Australian Dollar</td><td>No</td></tr><tr><td><code>BGN</code></td><td>Bulgaria Leva</td><td>No</td></tr><tr><td><code>BOB</code></td><td>Bolivian Boliviano</td><td>No</td></tr><tr><td><code>BRL</code></td><td>Brazil Real</td><td>No</td></tr><tr><td><code>BSD</code></td><td>Bahamas Dollar</td><td>No</td></tr><tr><td><code>CAD</code></td><td>Canadian Dollar</td><td>No</td></tr><tr><td><code>CHF</code></td><td>Switzerland Franc</td><td>No</td></tr><tr><td><code>CLP</code></td><td>Chile Peso</td><td>Yes</td></tr><tr><td><code>CNY</code></td><td>Chinese Yuan</td><td>No</td></tr><tr><td><code>COP</code></td><td>Colombia Peso</td><td>No</td></tr><tr><td><code>CZK</code></td><td>Czech Republic Koruna</td><td>No</td></tr><tr><td><code>DKK</code></td><td>Denmark Kroner</td><td>No</td></tr><tr><td><code>DOP</code></td><td>Dominican Peso</td><td>No</td></tr><tr><td><code>EGP</code></td><td>Egypt Pound</td><td>No</td></tr><tr><td><code>EUR</code></td><td>Euro</td><td>No</td></tr><tr><td><code>GBP</code></td><td>British Pound Sterling</td><td>No</td></tr><tr><td><code>HKD</code></td><td>Hong Kong Dollar</td><td>No</td></tr><tr><td><code>HRK</code></td><td>Croatia Kuna</td><td>No</td></tr><tr><td><code>HUF</code></td><td>Hungary Forint</td><td>No</td></tr><tr><td><code>IDR</code></td><td>Indonesia Rupiah</td><td>No</td></tr><tr><td><code>ILS</code></td><td>Israel Shekel</td><td>No</td></tr><tr><td><code>INR</code></td><td>India Rupee</td><td>No</td></tr><tr><td><code>ISK</code></td><td>Iceland Kronur</td><td>Yes</td></tr><tr><td><code>JPY</code></td><td>Japan Yen</td><td>Yes</td></tr><tr><td><code>KRW</code></td><td>South Korea Won</td><td>Yes</td></tr><tr><td><code>KZT</code></td><td>Kazakhstan Tenge</td><td>No</td></tr><tr><td><code>MAD</code></td><td>Moroccan Dirham</td><td>No</td></tr><tr><td><code>MUR</code></td><td>Mauritius Rupee</td><td>No</td></tr><tr><td><code>MXN</code></td><td>Mexico Peso</td><td>No</td></tr><tr><td><code>MYR</code></td><td>Malaysia Ringgit</td><td>No</td></tr><tr><td><code>NOK</code></td><td>Norway Krone</td><td>No</td></tr><tr><td><code>NZD</code></td><td>New Zealand Dollar</td><td>No</td></tr><tr><td><code>PEN</code></td><td>Peru Nuevos Sol</td><td>No</td></tr><tr><td><code>PHP</code></td><td>Philippines Peso</td><td>No</td></tr><tr><td><code>PLN</code></td><td>Poland Zlotych</td><td>No</td></tr><tr><td><code>PYG</code></td><td>Paraguayan Guaraní</td><td>Yes</td></tr><tr><td><code>QAR</code></td><td>Qatar Rial</td><td>No</td></tr><tr><td><code>RON</code></td><td>Romania New Lei</td><td>No</td></tr><tr><td><code>RSD</code></td><td>Serbia Dinar</td><td>No</td></tr><tr><td><code>RUB</code></td><td>Russia Ruble</td><td>No</td></tr><tr><td><code>SAR</code></td><td>Saudi Arabia Riyal</td><td>No</td></tr><tr><td><code>SEK</code></td><td>Sweden Kronor</td><td>No</td></tr><tr><td><code>SGD</code></td><td>Singapore Dollar</td><td>No</td></tr><tr><td><code>THB</code></td><td>Thailand Baht</td><td>No</td></tr><tr><td><code>TRY</code></td><td>Turkey Lira</td><td>No</td></tr><tr><td><code>TWD</code></td><td>Taiwan New Dollar</td><td>No</td></tr><tr><td><code>UAH</code></td><td>Ukraine Hryvnia</td><td>No</td></tr><tr><td><code>USD</code></td><td>United States Dollar</td><td>No</td></tr><tr><td><code>UYU</code></td><td>Uruguay Peso</td><td>No</td></tr><tr><td><code>VEF</code></td><td>Bolívar Fuerte</td><td>No</td></tr><tr><td><code>VND</code></td><td>Vietnam Dong</td><td>Yes</td></tr><tr><td><code>ZAR</code></td><td>South African Rand</td><td>No</td></tr></tbody></table>


# Supported Languages

Use the `LanguageCode` parameter on supported endpoints to return response content in the customer's preferred language. Pass a two-letter ISO 639-1 code. For regional variants, append a country subtag separated by a hyphen (e.g. `en-us` for United States English).

{% hint style="info" %}
**Language fallback**&#x20;

When content is not available in the requested language, RentalCover defaults to English (`en`).
{% endhint %}

<table data-header-hidden="false" data-header-sticky><thead><tr><th>Code</th><th>Language</th></tr></thead><tbody><tr><td><code>en</code></td><td>English (default)</td></tr><tr><td><code>en-us</code></td><td>English (United States)</td></tr><tr><td><code>ar</code></td><td>Arabic</td></tr><tr><td><code>bg</code></td><td>Bulgarian</td></tr><tr><td><code>ca</code></td><td>Catalan</td></tr><tr><td><code>cs</code></td><td>Czech</td></tr><tr><td><code>da</code></td><td>Danish</td></tr><tr><td><code>de</code></td><td>German</td></tr><tr><td><code>ee</code></td><td>Estonian</td></tr><tr><td><code>el</code></td><td>Greek</td></tr><tr><td><code>es</code></td><td>Spanish</td></tr><tr><td><code>fi</code></td><td>Finnish</td></tr><tr><td><code>fr</code></td><td>French</td></tr><tr><td><code>he</code></td><td>Hebrew</td></tr><tr><td><code>hk</code></td><td>Hongkong</td></tr><tr><td><code>hr</code></td><td>Croatian</td></tr><tr><td><code>hu</code></td><td>Hungarian</td></tr><tr><td><code>id</code></td><td>Indonesian</td></tr><tr><td><code>is</code></td><td>Iceland</td></tr><tr><td><code>it</code></td><td>Italian</td></tr><tr><td><code>ja</code></td><td>Japanese</td></tr><tr><td><code>ko</code></td><td>Korean</td></tr><tr><td><code>lt</code></td><td>Lithuanian</td></tr><tr><td><code>lv</code></td><td>Latvian</td></tr><tr><td><code>my</code></td><td>Malay</td></tr><tr><td><code>nl</code></td><td>Dutch</td></tr><tr><td><code>no</code></td><td>Norwegian</td></tr><tr><td><code>pl</code></td><td>Polish</td></tr><tr><td><code>br</code></td><td>Brazilian Portuguese</td></tr><tr><td><code>pt</code></td><td>European Portuguese</td></tr><tr><td><code>ro</code></td><td>Romanian</td></tr><tr><td><code>ru</code></td><td>Russian</td></tr><tr><td><code>sk</code></td><td>Slovakian</td></tr><tr><td><code>sl</code></td><td>Slovenian</td></tr><tr><td><code>sr</code></td><td>Serbian</td></tr><tr><td><code>sv</code></td><td>Swedish</td></tr><tr><td><code>sw</code></td><td>Swahili</td></tr><tr><td><code>th</code></td><td>Thai</td></tr><tr><td><code>tr</code></td><td>Turkish</td></tr><tr><td><code>uk</code></td><td>Ukrainian</td></tr><tr><td><code>vi</code></td><td>Vietnamese</td></tr><tr><td><code>zh</code></td><td>Chinese</td></tr></tbody></table>


# Supported Regions

Some countries require a state, province, or territory code for accurate premium calculation and product eligibility. Use the `Region` parameter when the customer's address or vehicle pickup location is in one of the countries listed below. For all other countries, omit `Region`.

The region code is 2–3 characters.

{% hint style="info" %}
Countries that require a region code: Australia, Brazil, Canada, United States.
{% endhint %}

## Australia

<table><thead><tr><th width="162"></th><th></th></tr></thead><tbody><tr><td><strong>Code</strong></td><td><strong>Region</strong></td></tr><tr><td>ACT</td><td>Australian Capital Territory</td></tr><tr><td>NSW</td><td>New South Wales</td></tr><tr><td>NT</td><td>Northern Territory</td></tr><tr><td>QLD</td><td>Queensland</td></tr><tr><td>SA</td><td>South Australia</td></tr><tr><td>TAS</td><td>Tasmania</td></tr><tr><td>VIC</td><td>Victoria</td></tr><tr><td>WA</td><td>Western Australia</td></tr></tbody></table>

## Brazil

<table><thead><tr><th width="163"></th><th></th></tr></thead><tbody><tr><td><strong>Code</strong></td><td><strong>Region</strong></td></tr><tr><td>AC</td><td>Acre</td></tr><tr><td>AL</td><td>Alagoas</td></tr><tr><td>AM</td><td>Amazonas</td></tr><tr><td>AP</td><td>Amapá</td></tr><tr><td>BA</td><td>Bahia</td></tr><tr><td>CE</td><td>Ceará</td></tr><tr><td>DF</td><td>Distrito Federal</td></tr><tr><td>ES</td><td>Espírito Santo</td></tr><tr><td>GO</td><td>Goiás</td></tr><tr><td>MA</td><td>Maranhão</td></tr><tr><td>MG</td><td>Minas Gerais</td></tr><tr><td>MS</td><td>Mato Grosso do Sul</td></tr><tr><td>MT</td><td>Mato Grosso</td></tr><tr><td>PA</td><td>Pará</td></tr><tr><td>PB</td><td>Paraíba</td></tr><tr><td>PE</td><td>Pernambuco</td></tr><tr><td>PI</td><td>Piauí</td></tr><tr><td>PR</td><td>Paraná</td></tr><tr><td>RJ</td><td>Rio de Janeiro</td></tr><tr><td>RN</td><td>Rio Grande do Norte</td></tr><tr><td>RO</td><td>Rondônia</td></tr><tr><td>RR</td><td>Roraima</td></tr><tr><td>RS</td><td>Rio Grande do Sul</td></tr><tr><td>SC</td><td>Santa Catarina</td></tr><tr><td>SE</td><td>Sergipe</td></tr><tr><td>SP</td><td>São Paulo</td></tr><tr><td>TO</td><td>Tocantins</td></tr></tbody></table>

## Canada

<table><thead><tr><th width="163"></th><th></th></tr></thead><tbody><tr><td><strong>Code</strong></td><td><strong>Region</strong></td></tr><tr><td>AB</td><td>Alberta</td></tr><tr><td>BC</td><td>British Columbia</td></tr><tr><td>MB</td><td>Manitoba</td></tr><tr><td>NB</td><td>New Brunswick</td></tr><tr><td>NL</td><td>Newfoundland and Labrador</td></tr><tr><td>NS</td><td>Nova Scotia</td></tr><tr><td>NT</td><td>Northwest Territories</td></tr><tr><td>NU</td><td>Nunavut</td></tr><tr><td>ON</td><td>Ontario</td></tr><tr><td>PE</td><td>Prince Edward Island</td></tr><tr><td>QC</td><td>Quebec</td></tr><tr><td>SK</td><td>Saskatchewan</td></tr><tr><td>YT</td><td>Yukon</td></tr></tbody></table>

## United States

<table><thead><tr><th width="166"></th><th></th></tr></thead><tbody><tr><td><strong>Code</strong></td><td><strong>Region</strong></td></tr><tr><td>AK</td><td>Alaska</td></tr><tr><td>AL</td><td>Alabama</td></tr><tr><td>AR</td><td>Arkansas</td></tr><tr><td>AZ</td><td>Arizona</td></tr><tr><td>CA</td><td>California</td></tr><tr><td>CO</td><td>Colorado</td></tr><tr><td>CT</td><td>Connecticut</td></tr><tr><td>DC</td><td>District of Columbia</td></tr><tr><td>DE</td><td>Delaware</td></tr><tr><td>FL</td><td>Florida</td></tr><tr><td>GA</td><td>Georgia</td></tr><tr><td>HI</td><td>Hawaii</td></tr><tr><td>IA</td><td>Iowa</td></tr><tr><td>ID</td><td>Idaho</td></tr><tr><td>IL</td><td>Illinois</td></tr><tr><td>IN</td><td>Indiana</td></tr><tr><td>KS</td><td>Kansas</td></tr><tr><td>KY</td><td>Kentucky</td></tr><tr><td>LA</td><td>Louisiana</td></tr><tr><td>MA</td><td>Massachusetts</td></tr><tr><td>MD</td><td>Maryland</td></tr><tr><td>ME</td><td>Maine</td></tr><tr><td>MI</td><td>Michigan</td></tr><tr><td>MN</td><td>Minnesota</td></tr><tr><td>MO</td><td>Missouri</td></tr><tr><td>MS</td><td>Mississippi</td></tr><tr><td>MT</td><td>Montana</td></tr><tr><td>NC</td><td>North Carolina</td></tr><tr><td>ND</td><td>North Dakota</td></tr><tr><td>NE</td><td>Nebraska</td></tr><tr><td>NH</td><td>New Hampshire</td></tr><tr><td>NJ</td><td>New Jersey</td></tr><tr><td>NM</td><td>New Mexico</td></tr><tr><td>NV</td><td>Nevada</td></tr><tr><td>NY</td><td>New York</td></tr><tr><td>OH</td><td>Ohio</td></tr><tr><td>OK</td><td>Oklahoma</td></tr><tr><td>OR</td><td>Oregon</td></tr><tr><td>PA</td><td>Pennsylvania</td></tr><tr><td>RI</td><td>Rhode Island</td></tr><tr><td>SC</td><td>South Carolina</td></tr><tr><td>SD</td><td>South Dakota</td></tr><tr><td>TN</td><td>Tennessee</td></tr><tr><td>TX</td><td>Texas</td></tr><tr><td>UT</td><td>Utah</td></tr><tr><td>VA</td><td>Virginia</td></tr><tr><td>VT</td><td>Vermont</td></tr><tr><td>WA</td><td>Washington</td></tr><tr><td>WI</td><td>Wisconsin</td></tr><tr><td>WV</td><td>West Virginia</td></tr><tr><td>WY</td><td>Wyoming</td></tr></tbody></table>

Contact your CSE for the full list of supported region codes by country.


# Non-API Functions

These options let you surface RentalCover on your platform without using the full REST API. They suit two scenarios:

* Offering RentalCover to customers who completed a booking before API integration was available (e.g. via a My Bookings page).
* Use by meta-search sites or affiliates that don't process bookings directly.

## Pre-populated URL

Link customers directly to the RentalCover website with form fields pre-filled. If all fields are included, the form submits automatically.

Replace each `[placeholder]` with values from your booking data. Your `partner_id` is provided by your CSE.

### **Request parameters**

<table data-header-hidden="false" data-header-sticky><thead><tr><th width="216.7626953125">Parameter</th><th width="224.707275390625">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>FromDate</code></td><td>date (<code>yyyy-mm-dd</code>)</td><td>Rental start date.</td></tr><tr><td><code>ToDate</code></td><td>date (<code>yyyy-mm-dd</code>)</td><td>Rental end date.</td></tr><tr><td><code>Age</code></td><td>integer</td><td>Primary driver age.</td></tr><tr><td><code>FirstName</code></td><td>string</td><td>Customer first name.</td></tr><tr><td><code>LastName</code></td><td>string</td><td>Customer last name.</td></tr><tr><td><code>Phone</code></td><td>string</td><td>Customer phone number.</td></tr><tr><td><code>Email</code></td><td>string (URL-encoded)</td><td>Customer email address.</td></tr><tr><td><code>CountryOfTravelCode</code></td><td>string</td><td>Two-letter country code for the rental destination.</td></tr><tr><td><code>CustomerCountryCode</code></td><td>string</td><td>Two-letter country code for the customer's home country.</td></tr></tbody></table>

### Example URL

```
https://rentalcover.com/?CountryOfTravelCode=IE&CustomerCountryCode=US
  &FromDate=2025-08-01&ToDate=2025-08-08&Age=32
```

## Powered by RentalCover.com Logo

Place this logo where you offer protection. It links to RentalCover and fires a tracking impression event.

{% hint style="info" %}
**Script dependency**&#x20;

The `window.wlt_trk` function is part of the RentalCover analytics script. Ensure this script is loaded on the page before the snippet below. Contact your CSE for the script URL.
{% endhint %}

![Powered by RentalCover.com](https://597382560-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6jz0iiPyqvAgW1ZRxHtx%2Fuploads%2Fgit-blob-a1a4fff86520cf52e7c5862994cb624a2a4b7c55%2Fpowered-by-rc-oval.png?alt=media)

{% code overflow="wrap" %}

```html
<a href="https://www.rentalcover.com/?utm_source=[partner_id]&utm_medium=rc_logo&utm_campaign=rc_logo"
   target="_blank">
  <img src="[logo_url]" alt="Powered by RentalCover" />
</a>
<script type="text/javascript">
  window.wlt_trk('trackStructEvent', 'rc_logo', 'impression', 'powered-by-rc-oval.png', '', '');
</script>
```

{% endcode %}

## Promotional Buttons

Place these buttons in booking path pages or confirmation emails. Each links to the RentalCover quote page with the customer's details pre-filled.

{% hint style="info" %}
**HTTPS required**

All href and img src values must use HTTPS. Using HTTP causes mixed-content failures in modern browsers.
{% endhint %}

![Save 50% Off Insurance](https://597382560-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6jz0iiPyqvAgW1ZRxHtx%2Fuploads%2Fgit-blob-751e5883754df92065e0b2fb79cc229514876319%2Frr1.png?alt=media)

### “Save 50% Off Insurance” button

```html
<a href="http://www.rentalcover.com/?FromDate=[FromDate]&ToDate=[ToDate]&Age=[Age]&Email=[Email]&FirstName=[FirstName]&LastName=[LastName]&Phone=[Phone]&CountryOfTravelCode=[CountryOfTravelCode]&CustomerCountryCode=[CustomerCountryCode]&utm_source=[partner_id]&utm_medium=rc_button&utm_campaign=rc_button"><img src="//s3-ap-southeast-2.amazonaws.com/rentalcover-data/img/rr1.png" border="" alt="Save 50% Off Insurance"></a>
```

![](https://597382560-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6jz0iiPyqvAgW1ZRxHtx%2Fuploads%2Fgit-blob-0f1817432fe1d6508b5a9db8de6acbc0688be761%2Frr2.png?alt=media)

### “Save 50% on Cover for Rental Vehicles” button

```html
<a href="http://www.rentalcover.com/?FromDate=[FromDate]&ToDate=[ToDate]&Age=[Age]&Email=[Email]&FirstName=[FirstName]&LastName=[LastName]&Phone=[Phone]&CountryOfTravelCode=[CountryOfTravelCode]&CustomerCountryCode=[CustomerCountryCode]&utm_source=[partner_id]&utm_medium=rc_button&utm_campaign=rc_button"><img src="//s3-ap-southeast-2.amazonaws.com/rentalcover-data/img/rr2.png" border="" alt="Save 50% on Cover for Rental Vehicles"></a>
```

![](https://597382560-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6jz0iiPyqvAgW1ZRxHtx%2Fuploads%2Fgit-blob-384a879850c72e5ccb64a4659ee87aa95f3a7dc2%2Frr3.png?alt=media)

### “Don’t get stuck with a $5,000 bill” button

```html
<a href="http://www.rentalcover.com/?FromDate=[FromDate]&ToDate=[ToDate]&Age=[Age]&Email=[Email]&FirstName=[FirstName]&LastName=[LastName]&Phone=[Phone]&CountryOfTravelCode=[CountryOfTravelCode]&CustomerCountryCode=[CustomerCountryCode]&utm_source=[partner_id]&utm_medium=rc_button&utm_campaign=rc_button"><img src="//s3-ap-southeast-2.amazonaws.com/rentalcover-data/img/rr3.png" border="" alt="Don't get stuck with a $5,000 bill"></a>
```

![](https://597382560-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6jz0iiPyqvAgW1ZRxHtx%2Fuploads%2Fgit-blob-dd720012fca4a43a759f6cdf68d74dc786d95fea%2Frr4.png?alt=media)

### “Save $30 per day on Rental Vehicle Cover” button

```html
<a href="http://www.rentalcover.com/?FromDate=[FromDate]&ToDate=[ToDate]&Age=[Age]&Email=[Email]&FirstName=[FirstName]&LastName=[LastName]&Phone=[Phone]&CountryOfTravelCode=[CountryOfTravelCode]&CustomerCountryCode=[CustomerCountryCode]&utm_source=[partner_id]&utm_medium=rc_button&utm_campaign=rc_button"><img src="//s3-ap-southeast-2.amazonaws.com/rentalcover-data/img/rr4.png" border="" alt="Save $30 per day on Rental Vehicle Cover"></a>
```

![Why Pay $35 per day for Excess Reduction](https://597382560-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6jz0iiPyqvAgW1ZRxHtx%2Fuploads%2Fgit-blob-29ae9bb5ebb9cccac7dafc02d553752aba27401b%2Frr5.png?alt=media)

### “Why Pay $35 per day for Excess Reduction” button

```html
<a href="http://www.rentalcover.com/?FromDate=[FromDate]&ToDate=[ToDate]&Age=[Age]&Email=[Email]&FirstName=[FirstName]&LastName=[LastName]&Phone=[Phone]&CountryOfTravelCode=[CountryOfTravelCode]&CustomerCountryCode=[CustomerCountryCode]&utm_source=[partner_id]&utm_medium=rc_button&utm_campaign=rc_button"><img src="//s3-ap-southeast-2.amazonaws.com/rentalcover-data/img/rr5.png" border="" alt="Why Pay $35 per day for Excess Reduction"></a>
```

![Save 50% off Insurance](https://597382560-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6jz0iiPyqvAgW1ZRxHtx%2Fuploads%2Fgit-blob-f87ce9d201082dc07ac836ef2689c97e25778466%2Frr6.png?alt=media)

### “Save 50% off Insurance” button

```html
<a href="http://www.rentalcover.com/?FromDate=[FromDate]&ToDate=[ToDate]&Age=[Age]&Email=[Email]&FirstName=[FirstName]&LastName=[LastName]&Phone=[Phone]&CountryOfTravelCode=[CountryOfTravelCode]&CustomerCountryCode=[CustomerCountryCode]&utm_source=[partner_id]&utm_medium=rc_button&utm_campaign=rc_button"><img src="//s3-ap-southeast-2.amazonaws.com/rentalcover-data/img/rr6.png" border="" alt="Save 50% Off Insurance"></a>
```

![Powered by RentalCover.com](https://597382560-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6jz0iiPyqvAgW1ZRxHtx%2Fuploads%2Fgit-blob-a1a4fff86520cf52e7c5862994cb624a2a4b7c55%2Fpowered-by-rc-oval.png?alt=media)

### “Powered by RentalCover.com” button

```html
<a href="http://www.rentalcover.com/?FromDate=[FromDate]&ToDate=[ToDate]&Age=[Age]&Email=[Email]&FirstName=[FirstName]&LastName=[LastName]&Phone=[Phone]&CountryOfTravelCode=[CountryOfTravelCode]&CustomerCountryCode=[CustomerCountryCode]&utm_source=[partner_id]&utm_medium=rc_logo&utm_campaign=rc_logo"><img src="//s3-ap-southeast-2.amazonaws.com/rentalcover-data/img/rc-button.png" border="" alt="Powered By RentalCover.com"></a>
```


# Product Overview

This document outlines the integration requirements for a partner to use XCover Elements (XCE), serving as a comprehensive yet concise reference, it is designed to complement a partner-specific guide.

## Background

The current integration between Partners and XCover requires Partners to create and maintain the XCover protection panel's user interface (UI). XCE addresses these challenges and offers the following key benefits:

### Seamless Integration

XCE provides a minimal integration solution that seamlessly delivers the XCover protection panel to customers on the Partner platform via our Content Delivery Network(CDN).

### Streamlined AB Testing

XCE empowers CG Growth Product Managers (GPM) to conduct AB testing with minimal to no reliance on Partners, fostering experimentation and optimization. Partner is involved from a strategic point of view, understanding what experiments CG wants to run but not having to create them.

### Rapid Updates

XCE enables the continuous release of new features and updates to our protection panel without requiring technical support from Partners.

{% hint style="info" %}
XCE scripts use semantic versioning. Any major version release will be done together with Partner to adjust any potential integration breaking changes.
{% endhint %}

### Future Proof

XCE is future proof whereby new features we develop in the future for Partners can be seamlessly deployed with zero or minimal technical involvement from them.

{% hint style="warning" %}
XCE is designed to complement Cover Genius's existing XCover integration and does not replace it.
{% endhint %}

### Confirm Offer integration

XCover Elements handles the offer presentation to the customer. Once the customer has selected our protection product(s) the partner needs to handle confirm offer and other related booking management functions.

This process is documented under [API Integration](/xcover-elements/api-integration/summary).


# Installation

This page outlines the changes that Partners will be required to make in order to integrate with XCover Elements(XCE), including all necessary changes to the existing XCover API integration.

## Via CDN

XCE is initialized by loading a Javascript module via our CDN. Add the provided script to your head tag as follows:

{% code overflow="wrap" fullWidth="false" %}

```html
// production env
<script type="module" src="https://xce.xcover.com/{partner}/{version}/xcover-elements.js" async></script>


// sandbox(test) env
<script type="module" src="https://sandbox.xce.xcover.com/{partner}/{version}/xcover-elements.js" async></script>
```

{% endcode %}

{% hint style="danger" %}
Please make sure that the script tag is present on pages where elements are expected to be used.

`{partner}` and `{version}` will be supplied by our team.
{% endhint %}

After loading the script it will automatically load our BrightWrite (BW) client side dependency via CDN. This is used to facilitate AB Testing on our panel.

## Content Security Policy (CSP)

If your site uses a CSP, add the following origins to each directive so the integration can load scripts, reach its APIs, and display assets correctly.

#### script-src:

```
xce.xcover.com
cdn.brightwrite.com
```

#### connect-src:

```
api.xone.xcover.com
relay.xcover.com
cdn.brightwrite.com
brightwrite-data.com
```

#### image-src:

```
data:
xce.xcover.com
cdn.brightwrite.com
```

{% hint style="warning" %}
**Sandbox**: If you enforce CSP in your sandbox environment, replace `xce.xcover.com` with `sandbox.xce.xcover.com` in `script-src` and `img-src`. All other origins remain the same.
{% endhint %}


# Element Display

This page outlines how to get the XCE panel displayed on your web platform

Place a custom HTML element in the desired location in your HTML template. This is where the protection panel will be loaded by XCE.

<pre class="language-html"><code class="lang-html"><strong>&#x3C;!-- protection-offer example -->
</strong><strong>&#x3C;xce-protection-offer>&#x3C;/xce-protection-offer>
</strong></code></pre>

{% hint style="info" %}
The element name can change. The correct name will be provided to you during onboarding.
{% endhint %}

## Using custom attributes

XCE allows partners to use custom HTML attributes on the element to update the state such as UI, provide data for offer retrieval and more.\
\
**Custom attributes will be referenced in their specific integration guides.**

For example, in our protection-offer example we have the `selected` attribute that pre-selects one of the radio input options of the element.

{% hint style="warning" %}
The following custom attributes are just to showcase a scenario and might not be available on your integration.

Please refer to your CSE regarding the available custom attributes for your element.
{% endhint %}

<pre class="language-html"><code class="lang-html"><strong>&#x3C;!-- custom attributes example -->
</strong>&#x3C;!-- with 'yes protection' pre-selected -->
&#x3C;xce-protection-offer selected="option-1">&#x3C;/xce-protection-offer>

&#x3C;!-- with 'no protection' pre-selected -->
&#x3C;xce-protection-offer selected="reject">&#x3C;/xce-protection-offer>
</code></pre>


# Element Signals

Signals are how we communicate with the partner web platform

XCE provides a custom Javascript API called `signal layer` that gets added to the global namespace when our script is loaded. This is used as an abstraction layer for us to scale a performant integration.

There are three signal types available: `set` , `listen` and `update`

These are objects pushed to the signal layer by calling `signalLayer.push()` . Before calling the signal layer we first must initialize it like so:

```javascript
window.signalLayer = window.signalLayer || [];
```

Each signal object will be conformed by two main properties:

* `signal` - Type of signal(`set` , `listen` or `update`)
* `element` - The element tag name we want to publish to(`xce-protection-offer`)

Any additional properties will be depending on the signal we are working with, so please see the following guidelines on how to use set, listen and update signals and what their specific attributes are.

{% hint style="warning" %}
Each variable declared within the signal layer object will persist only as long as the visitor remains on the current page.
{% endhint %}

{% hint style="info" %}
See Element manipulation for instructions on passing state between pages to the element
{% endhint %}


# Set signal

This page details the requirements to integrate the set signal which is used to request the offers and display aligned currency formatting and order total values across the panel.

## Using `set` signal

The `set` signal is how a partner 1) creates an offer request for a customer and 2) formats the displayed currency in the element.

{% hint style="info" %}
For existing XCover partners, this replaces the create offer API request, with a similar field structure.
{% endhint %}

Call `signalLayer.push()` with `set` as the value for the `signal` property, add `onSet` and `data` as in the following example:

<pre class="language-javascript"><code class="lang-javascript">/* Travel xce-protection-offer example */
window.signalLayer.push({
  signal: 'set',
  element: 'xce-protection-offer',
  onSet: async (req) => {
    try {
      const response = await req
      if (!response) throw new Error('Empty response');
      // your disable checkout logic here..
    } catch (err) {
      console.error('XCE Request Error: ', err);
    }
  },
  data: {
    offer_request: {
      schema: 'demo-partner-travel:1',
      customer:{
        currency: 'AUD',
        country: 'AU',
        language: 'en',
      },
      context: {
<strong>        total_tickets_price: 344,
</strong>        departure_country: 'AU',
        destination_country: 'US',
        is_return: false,
        number_of_children: 0,
        number_of_adults: 1,
        number_of_infants: 0,
        trip_start_date: '2026-05-19T19:03:36.671Z',
        trip_end_date: '2026-05-19T19:02:21.444Z',
        flights: [
          {
            legs: [
              {
                departure_datetime: '2025-09-19T18:59:13.958Z',
                arrival_datetime: '2025-09-19T18:59:13.958Z',
                flight_number: 'SK1530',
                marketing_airline_iata_code: 'SK',
                marketing_airline_icao_code: 'SAS',
                operating_airline_iata_code: 'SK',
                operating_airline_icao_code: 'SAS',
                departure_airport: 'SYD',
                arrival_airport: 'JFK',
                departure_country: 'AU',
                arrival_country: 'US',
              },
            ],
            departure_datetime: '2025-09-19T18:59:13.958Z',
            arrival_datetime: '2025-09-19T18:59:13.958Z',
            departure_country: 'AU',
            departure_city: 'SYD',
            arrival_city: 'JFK',
          },
        ],
      },
    },
    currency_config: {
      trailingZeroDisplay: 'stripIfInteger'
    }
  }
});
</code></pre>

### onSet

The `onSet` property is a Promise function that will resolve with the quote response if successful, and the `data.offer_request` property is the create offer request body.

{% hint style="warning" %}
In order to get the offer response data for **confirm offer request** make sure to store the response from the `onSet` promise.

The resolved value contains the needed fields for **Confirm Offer** request, including the BrightWrite details object.
{% endhint %}

{% hint style="info" %}
See [Create Offer request fields](/xcover-elements/client-integration-examples/requests-and-responses) for a simplified reference to the data object
{% endhint %}

`onSet` may be invoked more than once

* Every `set` signal you push receives its own fresh promise, including integrations that reuse a single `onSet` handler function.
* Elements with in-element update actions (for example a coverage date change) invoke `onSet` again when the customer updates the offer. That promise resolves with the updated offer on success, or with the unchanged previous offer if the update fails; update promises never reject. Treat each resolution as the current offer, and store it for the Confirm Offer request.

{% hint style="info" %}
See [Checkout Enablement](/xcover-elements/client-integration/checkout-enablement) for the rejection codes and recommended handling.
{% endhint %}

### timeout

`timeout` is an optional circuit breaker on the Set signal's offers API call. If the API does not respond within the configured duration, Elements aborts the in-flight fetch and rejects the partner's `onSet` promise.

Partners opt in by adding a `timeout` property (milliseconds) to their Set signal push:

```javascript
window.signalLayer.push({
  signal: 'Set',
  element: 'xce-protection-offer',
  timeout: 2000,
  data: { offer_request: { ... } },
  onSet: (promise) => promise.catch((err) => { /* handle timeout or other errors */ })
});
```

When `timeout` is omitted or `undefined`, no timeout is enforced.

Valid range: **1001–10 000ms**.

{% hint style="info" %}
Any failed check logs a `console.warn` that includes the element's `tagName`&#x20;

i.e. "\[CG] The "timeout" value for \<xce-protection-offer/> must be greater than 1000ms."
{% endhint %}

#### Error shape

A timeout abort follows the same rejection path as any other API failure:

* `onSet` rejects with an `Error` whose `message` is `XCE_OFFER_REQUEST_FAILED` and whose `cause` is the `AbortError` from the aborted fetch.
* This is identical to how network failures and server errors surface. Handle timeouts with their existing `onSet` error path.
* The `AbortError` cause is distinguishable from other failures: its `message` contains the timeout duration and element tag name.
  * i.e. "Exceeded API timeout of 3000ms. Element \<xce-protection-offer/>"


# Listen signal

This page details the requirements to integrate the listen signal which is used to respond to user interaction with the panel and perform your application specific logic.

## Using `listen` signal

To determine when the user has selected an option for coverage you need to use the `listen` signal passing an `onChange` property that takes a function to handle the change event.

{% hint style="info" %}
This is similar to `addEventListener()` difference being we are using XCE Signals instead.
{% endhint %}

Call `signalLayer.push()` with `listen` as the value for the `signal` property and add `onChange` as in the following example:

```javascript
/* protection-offer example */
window.signalLayer.push({
  signal: "listen",
  element: "xce-protection-offer",
  onChange: (args) => {
    if(args.selectedOption !== "reject"){
      //Customer has selected a policy
      //List of selected policies available in args.selectedPolicies
    } else {
      //Customer has said no to a policy
    }
  },
});
```

### selectedOption

The `selectedOption` property is a `string` value returned in the callback arguments object will match the radio input value attribute that the customer selected.

The input value attribute varies depending on your integration.

* For option 'YES' the radio input value and the `selectedOption` property equals the option displayed to the user as in: `option-1`.
* For option 'NO' the radio input value and the `selectedOption` property equals `reject`.

When more than one product is displayed, the value will increase its last digit accordignly: `option-1` , `option-2` , etc.

{% hint style="info" %}
The 'NO' option of the panel will always match `reject`
{% endhint %}

### selectedProductIDs

The `selectedProductIDs` property is an array of strings returned in the callback arguments object that can have the selected products metadata.

* For option 'YES' the selected product ids will be appended to the `selectedProductIDs` array with the ones they wish to book.
* For option 'NO' the `selectedProductIDs` array will return empty.

Use the `selectedProductIDs` values to filter the products before confirming the offer.

Example:

Access the `args` object in the `onChange` callback function to access the `selectedProductIDs` array as in the following example:

```javascript
/* multiple policy offer example */
window.signalLayer.push({
  signal: "listen",
  element: "xce-protection-offer",
  onChange: (args) => {
    if (args.selectedProductIDs?.length) {
      // your data filtering logic here..
    }
    // your enable checkout logic here..
  },
});
```

### Modal element

When working with our modal element the `onSubmit` property will be expected as part of the object pushed to the signal layer array.

This handler function will be triggered every time the modal element is closed by the user and will return the same arguments object including `selectedOption`.

```javascript
/* protection-offer-modal example */
window.signalLayer.push({
  signal: "listen",
  element: "xce-protection-offer-modal",
  onChange: (args) => { // onChange runs on every input option change event
    if(args.selectedOption !== "reject"){
      //Customer has selected a product
      //List of selected products available in args.selectedProductIDs
    }
    // your enable checkout logic here..
  },
  onSubmit: (args) => { // onSubmit runs on modal close event
    if(args.selectedOption !== "reject"){
      //Customer has selected a product
      //List of selected products available in args.selectedProductIDs
    }
    // your enable checkout logic here..
  },
});
```

From here, you can perform whatever add-to-cart functionality is required and unblock the checkout journey that was preventing them from continuing until they selected an option.

{% hint style="warning" %}
The `onChange` and `onSubmit` handler function arguments will not include the native HTML Event object
{% endhint %}


# Update signal

XCE allows Partners to load the widget in a state other than the default with custom attributes or trigger events programmatically using the `update` signal.

This type of features work on an as needed basis for each element, which is explained below.

## Using `update` signal

The `update` signal allows you to programmatically trigger our element events.

This is useful for specific customer actions or contexts during their journey that kept them away from any direct element interaction and still being able to trigger the desired event.

#### isError

To programmatically set the element to an error state call `signalLayer.push()` with `update` as the value for the `signal` property and add the input value in the `isError` property as in the following example:

<pre class="language-javascript"><code class="lang-javascript">window.signalLayer.push({
  signal: "update",
  element: "xce-protection-offer",
  isError: true,
<strong>});
</strong></code></pre>

{% hint style="info" %}
This is similar to `dispatchEvent()` difference being we are using XCE Signals instead.
{% endhint %}


# Checkout Enablement

This page outlines the importance on how to maintain checkout enablement using XCE

{% hint style="info" %}
Not following these best practices may result in customers having an impacted experience if something goes wrong in XCE or a downstream dependancy.
{% endhint %}

Some partners may wish to prevent the user from continuing through the checkout journey until they have selected an option for XCover protection.

Because XCE is a third party dependency, we do not want to adversely affect the customer checkout journey. To that end, we strongly recommend that partners integrate our widget using the following practices:

* Use `onSet` promise in the set signal layer to wait for a response and control the user experience after.
* If `onSet` promise resolves then we can disable the Checkout Button to wait for users to select an insurance option from the widget.
* If `onSet` promise catches an error then we shouldn't disable the Checkout Button to avoid affecting the user checkout flow.\
  **Note**: Any time the request fails you can expect `onSet` to throw an error so you can catch it and react to it.
* If the `onSet` is never called that means there was an issue loading the script. As long as the Checkout Button is enabled by default this should not cause an issue.

### Rejection reasons

When the `onSet` promise rejects, `err.message` is one of the following stable codes, and `err.cause` carries the underlying error for diagnosis:

{% hint style="info" %}
Every `onSet` promise settles: it will always either resolve or reject, never remain pending indefinitely.
{% endhint %}

| Code                       | Meaning                                                                                   | `err.cause`                                           |
| -------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| `XCE_OFFER_REQUEST_FAILED` | The offer request failed and nothing was rendered                                         | The underlying error, e.g. the API validation message |
| `XCE_RENDER_FAILED`        | The offer request succeeded but the element failed to render                              | The render error                                      |
| `XCE_ONSET_SUPERSEDED`     | A newer `set` signal was pushed while this one was still loading; this promise is retired | none                                                  |

All rejections call for the same action: **do not disable the checkout button**. The codes and `err.cause` are diagnostic detail for your logging. For `XCE_ONSET_SUPERSEDED`, simply ignore that promise; your newer push's `onSet` carries the current outcome.


# Language

This page outlines how to set and update XCE content language

During partner onboarding, discuss the required languages with the CSE to ensure content is readily available in the platform. See the list of available languages below.

Once the content variations are created they will be made available through our element to our partners using [set signal](/xcover-elements/client-integration/element-signals/set-signal#using-set-signal). Here's how it works:

* **Initial language state:** To set the initial language state the element will refer to the `set` signal `data.offer_request` object property `customer_language`. The value will represent the preferred language for the element's content.
* **Updating language state:** To update the element's content language state we must update the `set` signal `data.offer_request` object with the new `customer_language` value and then call `signalLayer`. This will trigger a new offer request and update the element language state respectively.

Here's an snippet example of a callback function for a toggle component to dynamically update state:

{% code overflow="wrap" fullWidth="false" %}

```javascript
// Callback function to update language
const toggleLanguage = (lang) => {
  window.signalLayer({
    signal: 'set',
    element: 'xce-protection-offer',
    data: {
      offer_request: {
        // for this example, requestData is your offer request object defined
        ...requestData,
        customer: {
          language: lang,
        },
      }
    },
    onSet,
  });
};

```

{% endcode %}

Note: Any time the `customer_language` is updated, our built in currency formatter will use it as the `locale` value to align currency accordingly. Please go to [Currency Formatting Engine](/xcover-elements/client-integration/currency-formatting-engine) for more information on how it works.

{% hint style="warning" %}
Any time a language is not available our Language services will return `english` content as fallback.
{% endhint %}

### Language Codes

The languages supported by XCE are a combination of languages in ISO-639-1 and [RFC 5646](https://tools.ietf.org/html/rfc5646).

See the below table for the language codes we accept. Note that language content is available "as needed" to partners using XCE, discuss with your CSE for more information.

```
en	English
en-us	English (US)
ar	Arabic
az	Azerbaijani
be	Belarusian
bg	Bulgarian
ca	Catalan
zh-hans	Chinese Simplified
zh-hant	Chinese Traditional 
hr	Croatian
cs	Czech
da	Danish
nl	Dutch
et	Estonian
fil	Filipino (Philippines)
fi	Finnish
fr	French
ka	Georgian
de	German
el	Greek
he	Hebrew
hu	Hungarian
is	Iceland
id	Indonesian
it	Italian
ja	Japanese
ko	Korean
lv	Latvian
lt	Lithuanian
ms	Malay
mt	Maltese
no	Norwegian
pl	Polish
pt	Portuguese
pt-br	Portuguese (Brazilian)
ro	Romanian
ru	Russian
sr	Serbian
sk	Slovak
sl	Slovenian
es	Spanish
es-mx	Spanish (Mexico)
sw	Swahili
sv	Swedish
tl	Tagalog
th	Thai
tr	Turkish
uk	Ukrainian
vi	Vietnamese
```


# Currency Formatting Engine

This page outlines how to set and use the XCE Currency Formatting Engine (CFE)

## Overview

Our Currency Formatting Engine ensures a consistent and user-friendly experience for your customers by allowing you to configure how currency values are displayed within the XCE widget.

This ensures that your customers have a seamless experience across your platform and within our widget.

## Usage

Our currency formatting API is built on top of the [**Intl.NumberFormat** ECMAScript Internationalization API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) configuration options.

The currency configuration options are an object passed in to the `data` object of the [set signal](/xcover-elements/client-integration/element-signals/set-signal).

Here's an example of a `currency_config` object set to:

* Display currency as symbol
* No cents display when cents equals zero

```javascript
const currencyConfig = {
    currencyDisplay: 'symbol',
    trailingZeroDisplay: 'stripIfInteger'
};
```

Now, an example using currency configuration object together with our set signal.

{% code overflow="wrap" fullWidth="false" %}

```javascript
window.signalLayer.push({
  signal: 'set',
  element: 'xce-protection-offer',
  onSet: '{{onset_promise_function}}',
  data: {
    offer_rquest: '{{offer_request_body}}',
    currency_config: currencyConfig
  }
});
```

{% endcode %}

{% hint style="info" %}
Set signal is used to set the desired **currency** and **language**(**locale**) values for the currency formatting engine. This means that the currency locale equals the user's preferred language at all times, this is to always keep our widget content language and currency locale aligned.
{% endhint %}

In order to provide the desired currency format, when needed, we must update the currency configuration object every time a set signal is called. If no currency configuration object is passed, the element will render currency format using the defaults from Intl.NumberFormat API which could result in an undesired currency format.

### Custom options

Additionally to the default Intl.NumberFormat API options we have included a custom options property to override the currency symbol and/or placement of both the symbol and the amount:

* `marker` is used to replace in place the currency symbol or code with a custom value.
* `format` is used to format the placement of the currency symbol or code and the amount value. There's a special character assigned to both the symbol and the value:
  * `%m` stands for marker and represents the currency symbol or code.
  * `%v` stands for value and represents the number amount value.
  * You can also add or remove blank spaces, even include extra characters if needed.

Here are a couple of examples setting a custom symbol and placement using the marker and format properties:

```javascript
// & as marker and spaces
const currencyConfig = {
    currencyDisplay: 'symbol',
    trailingZeroDisplay: 'stripIfInteger',
    customOptions: {
        marker: '&',
        format: '%m%v', // renders: '&200'
    }
};

// & as marker and marker after value with spaces
const currencyConfig = {
    currencyDisplay: 'symbol',
    trailingZeroDisplay: 'stripIfInteger',
    customOptions: {
        marker: '&',
        format: '%v %m', // renders: '200 &'
    }
};
```

Custom options are independent from each other:

```javascript
// default symbol and no blank spaces
const currencyConfig = {
    currencyDisplay: 'symbol',
    trailingZeroDisplay: 'stripIfInteger',
    customOptions: {
        format: '%m%v', // renders: '$200'
    }
};

// & as symbol and no format
const currencyConfig = {
    currencyDisplay: 'symbol',
    trailingZeroDisplay: 'stripIfInteger',
    customOptions: {
        marker: '&', // renders: '& 200'
    }
};
```

{% hint style="danger" %}
Customer language values and currency values are critical for our currency formatting engine to provide the expected format. Be aware that mixing them can result in undesired formats. Please make sure to test your combinations before committing to the values.
{% endhint %}


# Element Theming

This page outlines how to implement theme overrides and how to set a color scheme(dark or light) to our XCover Elements

## Theme overrides

XCover Elements panels can be themed by adding predefined CSS custom properties and values to the root of the host website. The css custom properties are defined by XCE and are used to target specific pieces in the panel to be customized.

The following CSS custom properties can be used to customize the appearance of the panel:

<table data-full-width="true"><thead><tr><th>Variable</th><th>Description</th></tr></thead><tbody><tr><td><code>--xce-ext-heading-color</code></td><td>Text color of the panel heading</td></tr><tr><td><code>--xce-ext-heading-font-size</code></td><td>Font size of the panel heading</td></tr><tr><td><code>--xce-ext-heading-image-size</code></td><td>Icon size of the panel heading</td></tr><tr><td><code>--xce-ext-link-text-color</code></td><td>Text links color of the overall panel</td></tr><tr><td><code>--xce-ext-content-pill-background-color</code></td><td>Background color of the CTA pill</td></tr><tr><td><code>--xce-ext-content-pill-color</code></td><td>Text color of the CTA pill</td></tr><tr><td><code>--xce-ext-options-warning-panel-display</code></td><td>Display value of the Warning Panel when selecting Reject option</td></tr><tr><td><code>--xce-ext-options-selected-color</code></td><td>Color of the options border, radio input border and background when selecting an option</td></tr><tr><td><code>--xce-ext-options-error-color</code></td><td>Color of the options border, radio input border, background and the required message text when triggering error state</td></tr><tr><td><code>--xce-ext-options-radio-background-color</code></td><td>Background color of the options radio input on default state</td></tr><tr><td><code>--xce-ext-options-radio-error-background-color</code></td><td>Background color of the options radio input when triggering error state</td></tr><tr><td><code>--xce-ext-options-radio-border-color</code></td><td>Border color of the options radio input on default state</td></tr><tr><td><code>--xce-ext-options-radio-size</code></td><td>Size of the options radio input on any state</td></tr><tr><td><code>--xce-ext-options-radio-border-weight</code></td><td>Border weight of the options radio input on any state</td></tr></tbody></table>

The following example shows how to add custom CSS overrides:

<pre class="language-css"><code class="lang-css">:root {
<strong>    --xce-ext-heading-color: red;
</strong>    --xce-ext-heading-font-size: 24px;
    --xce-ext-heading-image-size: 32px;
    --xce-ext-link-text-color: blue;
    --xce-ext-content-pill-background-color: brown;
    --xce-ext-content-pill-color: yellow;
    --xce-ext-options-warning-panel-display: none;
}
</code></pre>

{% hint style="warning" %}
These theme variables **take priority over color schemes dark and light variables**. Make sure to consider aligning these variables overrides with your color scheme accordingly.
{% endhint %}

## Color schemes: Dark or Light

Our panels have the ability to switch between dark and light color scheme using the built in custom attribute `color-scheme`

To set a color scheme just pass in a string value to the `color-scheme` attribute with either `dark` or `light`

```html
<!-- custom attributes example -->
<!-- with 'dark' mode -->
<xce-protection-offer color-scheme="dark"></xce-protection-offer>

<!-- with 'light' mode -->
<xce-protection-offer color-scheme="light"></xce-protection-offer>
```

The default color scheme for our panels is set to light mode.

{% hint style="info" %}
To enable Color scheme, please refer to your CSE regarding the available custom attributes for your element.
{% endhint %}

{% hint style="warning" %}
Elements color scheme will **not change based on browser or user computer theme**.

In case you want to change color scheme based on browser or user computer the attribute would have to be added programmatically by the developer.
{% endhint %}


# Browser Compatibility

XCover Elements (XCE) requires modern browser features to deliver a robust web component experience. This page provides a comprehensive reference for browser compatibility requirements and supported platforms.

**Global Coverage:** 93% of worldwide browser usage is supported.

### Methodology & Sources

Browser compatibility data is derived from authoritative sources and feature-level checks:

* [**Can I use**](https://caniuse.com/) - Support tables for HTML5, CSS3, and modern web features
* [**MDN Web Docs**](https://developer.mozilla.org/) - Comprehensive browser compatibility documentation
* [**WebKit Release Notes**](https://webkit.org/) - Safari-specific feature tracking

Where possible, compatibility is determined through **feature-level checks** rather than browser versions alone. Key features monitored include:

* `fetch` API
* Custom Elements (Web Components)
* Shadow DOM
* CSS Nesting
* ES2022+ JavaScript features

### Required Browser Features

XCover Elements depends on the following modern web platform features:

| Feature                                     | Usage in XCE                                                             | Browsers Lacking Support                                          |
| ------------------------------------------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------- |
| **Custom Elements & Shadow DOM**            | Core architecture for encapsulated UI components and custom elements     | IE (all versions), Opera Mini, older Android browsers, UC Browser |
| **CSS Nesting**                             | CSS Modules with nested selectors for concise, modular component styling | Safari < 17, older Firefox versions, legacy mobile browsers       |
| **Numeric Separators & Logical Assignment** | Cleaner numeric literals and compact syntax (ES2022)                     | Browsers without ES2022 support                                   |
| **Optional Chaining & Nullish Coalescing**  | Helper functions and optional prop handling (ES2020)                     | Very old browsers pre-ES2020                                      |
| **CSS Container Queries**                   | Responsive component behavior without media query boilerplate            | Not fully supported in older browsers                             |
| **ES Modules Dynamic Import**               | Code splitting and lazy loading for optimized bundle sizes               | IE, legacy browsers                                               |

### Supported Browsers

#### Desktop Browsers

| Browser                | Minimum Version | Release Date   | Notes                   |
| ---------------------- | --------------- | -------------- | ----------------------- |
| **Chrome**             | 120+            | November 2023  | **Recommended browser** |
| **Mozilla Firefox**    | 117+            | August 2023    | Full feature support    |
| **Safari**             | 17+             | September 2023 | macOS and iOS           |
| **Microsoft Edge**     | 120+            | November 2023  | Chromium-based          |
| **Opera**              | 106+            | November 2023  | Chromium-based          |
| **Brave**              | 1.61+           | November 2023  | Chromium-based          |
| **Vivaldi**            | Chromium 120+   | 2023+          | Chromium-based          |
| **Arc Browser**        | Chromium 120+   | 2023+          | Chromium-based          |
| **DuckDuckGo Browser** | Chromium 120+   | 2023           | Chromium-based          |
| **Yandex Browser**     | Chromium 120+   | 2023+          | Chromium-based          |
| **SRWare Iron**        | Chromium 120+   | 2023+          | Chromium-based          |

#### Regional & Specialized Browsers

| Browser                  | Minimum Version | Release Date | Notes                      |
| ------------------------ | --------------- | ------------ | -------------------------- |
| **ChatGPT Atlas**        | Chromium 120+   | October 2025 | Chromium-based, macOS only |
| **Samsung Internet**     | Latest stable   | -            | Chromium-based             |
| **QQ Browser** (Tencent) | Chromium 120+   | -            | Chromium-based             |
| **Baidu Browser**        | Chromium 120+   | -            | Chromium-based             |

#### Mobile Browsers

| Platform    | Browser          | Minimum Version | Support Level |
| ----------- | ---------------- | --------------- | ------------- |
| **iOS**     | Safari           | 17+             | Full          |
| **iOS**     | Chrome           | 120+            | Full          |
| **iOS**     | DuckDuckGo       | Latest          | Full          |
| **Android** | Chrome           | 120+            | Full          |
| **Android** | Firefox          | 117+            | Full          |
| **Android** | Samsung Internet | Latest          | Full          |
| **Android** | DuckDuckGo       | Latest          | Full          |

***

### Unsupported Browsers

The following browsers **do not support** XCover Elements:

| Browser               | Status         | Reason                                                   |
| --------------------- | -------------- | -------------------------------------------------------- |
| **Internet Explorer** | ❌ All versions | End of Life; lacks Web Components, modern JS/CSS support |
| **Chrome**            | ❌ < 120        | Missing ES2022 support and modern APIs                   |
| **Firefox**           | ❌ < 117        | Missing modern CSS features and JS support               |
| **Safari**            | ❌ < 17         | Missing CSS nesting support and WebKit features          |
| **Edge Legacy**       | ❌ All versions | Replaced by Chromium-based Edge                          |
| **Opera**             | ❌ < 106        | Missing ES2022 support                                   |
| **Opera Mini**        | ❌ All versions | Does not support Web Components; outdated JS engine      |
| **UC Browser**        | ❌ < 2023       | Missing Web Components, CSS nesting, ES2022 support      |
| **KaiOS Browser**     | ❌ All versions | Missing ES2022 support                                   |


# HTML Script Demo

This is a demo of an integration and should not be copy/pasted for a production integration. This integration uses our "Demo partner" and can be used to demonstrate XCE functionality for a partner.

This HTML template showcases the following features:

1. **XCE Script Integration:** The template seamlessly integrates the XCE script into the page's `<head>` section, establishing a connection with the XCE platform.
2. **Standard Signal Utilization:** The template effectively employs standard XCE signals, namely `set` and `listen`, to interact with the XCE platform.
   1. **`set` signal:** The `set` signal is utilized to request an offer from the XCE platform and configure currency formatting. Upon successful offer retrieval, the template stores the offer response and element is rendered. In case of an error, it logs the error message to the developer console and element is hidden.
   2. **`listen` signal:** The `listen` signal keeps track of the selected option and logs the selected option and in case the option selected was the 'Yes' option it also logs the previously stored offer response to the developer console.
3. **Custom CTA for Error Handling:** The template showcases a custom CTA button that programmatically updates the element state to an error state if no option was previously selected, highlighting the importance of making a selection before proceeding.

To utilize this template, copy and paste it into your IDE, save it as an `.html` file, and open it in your web browser. Don't forget to open your DevTools!

### HTML Examples

Currently we have a script configured with two different elements: Travel demo and Ticketing demo. Each required their own specific body request.

Copy the desired HTML snippet bellow and paste on your sandbox for testing.

{% hint style="info" %}
Difference between snippets are: `offer_request` data and the element names: `xce-travel-demo` and `xce-ticket-demo` .
{% endhint %}

{% hint style="warning" %}
**These are Demo scripts.**

`xce-travel-demo` , `xce-ticket-demo` and the `offer_request` only work for Demo scripts. Partner scripts would have their own elements with different names as well as expect different request body.
{% endhint %}

{% tabs fullWidth="false" %}
{% tab title="Travel" %}

#### Travel: Comprehensive protection Offer

This is an example of what you should be seeing:

<div data-with-frame="true"><figure><img src="https://719583013-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwIXMQsGitXUADGsP8bzz%2Fuploads%2Fgit-blob-8be802798e5372bc9bd93154c15b2875acb79a24%2Fimage%20(1).png?alt=media" alt="XCE Ticketing Demo"><figcaption></figcaption></figure></div>

{% code overflow="wrap" lineNumbers="true" fullWidth="false" %}

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700&family=Roboto&display=swap"
      rel="stylesheet"
    />
    <title>XCE TRAVEL DEMO</title>
    <script type="module" src="https://sandbox.xce.xcover.com/offers-demo/v1/xcover-elements.js" async></script>
    <style>
      html {
        font-family: 'Roboto', sans-serif;
        font-size: 14px;
      }

      main {
        padding: 12px;
      }

      .offer-container {
        border: 1px solid rgba(0, 0, 0, 0.2);
        padding: 16px;
        border-radius: 5px;
      }

      .button {
        display: inline-block;
        padding: 8px 16px;
        margin-bottom: 22px;
        font-size: 12px;
        color: white;
        background-color: #04aa6d;
        border: 2px solid #04aa6d;
        border-radius: 30px;
        text-transform: uppercase;
        text-align: center;
        transition-duration: 0.4s;
      }

      .button:hover {
        background-color: white;
        color: black;
      }
    </style>
  </head>

  <body>
    <main>
      <h1 id="header">Hello World!</h1>
      <p id="description">This is an XCover Elements Travel demo.</p>
      <p>Before selecting an option, click on the following "Checkout" CTA to trigger the element error state</p>
      <button class="button" onclick="onCheckout()">Checkout</button>
      <div class="offer-container">
        <!-- XCover Element tag -->
        <xce-travel-demo></xce-travel-demo>
      </div>
    </main>
    <script>
      /** Define signalLayer in global scope */
      window.signalLayer = window.signalLayer || [];
      let responseData;
      let selectedOption;

      // Helper function to generate ISO date strings
      const getDateRange = (daysFromNow = 8) => {
        const now = new Date();
        const after5Seconds = new Date(now.getTime() + 5 * 1000);
        const endDate = new Date(now.getTime() + daysFromNow * 24 * 60 * 60 * 1000);
        return {
          startDate: after5Seconds.toISOString(),
          endDate: endDate.toISOString(),
        };
      };

      const { startDate, endDate } = getDateRange(8);

      /** Offer request body */
      const offer_request = {
        customer: {
          currency: 'AUD',
          country: 'AU',
          language: 'en',
          ip: '124.168.10.55',
        },
        schema: '',
        partner: {
          transaction_id: '4f3a9e1b-7c2d-4b8a-9e5f-1a2b3c4d5e6g',
          metadata: {
            device:
              'Browser: Mozilla Version: 0.0 Platform: MixAndMatchAU|Mozilla/5.0 (iPhone; CPU iPhone OS 17_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.3.1 Mobile/15E148 Safari/604.1',
            session_id: '1ebaf939-af73-4232-8ea5-7ce084d8f050',
          },
        },
        context: {
          insured: [
            {
              first_name: 'First',
              last_name: 'Last',
              country: 'AU',
            },
          ],
          total_tickets_price: 344,
          policy_start_date: startDate,
          policy_end_date: endDate,
          departure_country: 'AU',
          destination_country: 'US',
          is_return: false,
          flights: [
            {
              legs: [
                {
                  departure_datetime: startDate,
                  arrival_datetime: endDate,
                  flight_number: 'SK1530',
                  marketing_airline_iata_code: 'SK',
                  marketing_airline_icao_code: 'SAS',
                  operating_airline_iata_code: 'SK',
                  operating_airline_icao_code: 'SAS',
                  departure_airport: 'LHR',
                  arrival_airport: 'ARN',
                  departure_country: 'IT',
                  arrival_country: 'IT',
                },
              ],
            },
          ],
          number_of_children: 0,
          number_of_adults: 1,
          number_of_infants: 0,
          trip_start_date: startDate,
          trip_end_date: endDate,
        },
        extra_fields: ['tax'],
      };

      /** Set signal onSet promise function */
      const onSet = async (request) => {
        try {
          const res = await request;
          responseData = res;
        } catch (err) {
          console.error(err);
        }
      };

      /** Listen signal onChange function */
      const onChange = (args) => {
        if (args.selectedOption !== 'reject') {
          console.log('Insurance selected: ', args);
        } else {
          console.log('No insurance selected: ', args);
        }
        selectedOption = args.selectedOption;
      };

      const onCheckout = () => {
        if (selectedOption) {
          console.log('Valid selection - Checking Out 🎉');
          alert('Valid selection - Checking Out 🎉');
          return;
        }
        console.log('No protection option selected - Block checkout');

        /** Update signal to programatically set error state to true */
        window.signalLayer.push({
          signal: 'update',
          element: 'xce-travel-demo',
          isError: true,
        });
      };

      /** Set signal */
      window.signalLayer.push({
        signal: 'set',
        element: 'xce-travel-demo',
        data: {
          offer_request,
          currency_config: {
            trailingZeroDisplay: 'stripIfInteger',
            customOptions: {
              format: '$%v AUD',
            },
          },
        },
        onSet,
      });

      /** Listen signal */
      window.signalLayer.push({
        signal: 'listen',
        element: 'xce-travel-demo',
        onChange,
      });
    </script>
  </body>
</html>

```

{% endcode %}
{% endtab %}

{% tab title="Travel-Dual" %}

#### Travel: Comprehensive protection and trip cancellation Offer

This is an example of what you should be seeing:

<div data-with-frame="true"><figure><img src="https://719583013-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwIXMQsGitXUADGsP8bzz%2Fuploads%2Fgit-blob-ecae6cabef39b17b579ecd4205170c963834e9da%2Fimage%20(1)%20(1).png?alt=media" alt="XCE Travel Demo"><figcaption></figcaption></figure></div>

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700&family=Roboto&display=swap"
      rel="stylesheet"
    />
    <title>XCE TRAVEL DUAL DEMO</title>
    <script type="module" src="https://sandbox.xce.xcover.com/offers-demo/v2/xcover-elements.js" async></script>
    <style>
      html {
        font-family: 'Roboto', sans-serif;
        font-size: 14px;
      }

      main {
        padding: 12px;
      }

      .offer-container {
        border: 1px solid rgba(0, 0, 0, 0.2);
        padding: 16px;
        border-radius: 5px;
      }

      .button {
        display: inline-block;
        padding: 8px 16px;
        margin-bottom: 22px;
        font-size: 12px;
        color: white;
        background-color: #04aa6d;
        border: 2px solid #04aa6d;
        border-radius: 30px;
        text-transform: uppercase;
        text-align: center;
        transition-duration: 0.4s;
      }

      .button:hover {
        background-color: white;
        color: black;
      }
    </style>
  </head>

  <body>
    <main>
      <h1 id="header">Hello World!</h1>
      <p id="description">This is an XCover Elements Travel demo.</p>
      <p>Before selecting an option, click on the following "Checkout" CTA to trigger the element error state</p>
      <button class="button" onclick="onCheckout()">Checkout</button>
      <div class="offer-container">
        <xce-travel-dual-demo></xce-travel-dual-demo>
      </div>
    </main>
    <script>
      window.signalLayer = window.signalLayer || [];
      let responseData;
      let selectedOption;

      // Helper function to generate ISO date strings
      const getDateRange = (daysFromNow = 8) => {
        const now = new Date();
        const after5Seconds = new Date(now.getTime() + 5 * 1000);
        const endDate = new Date(now.getTime() + daysFromNow * 24 * 60 * 60 * 1000);
        return {
          startDate: after5Seconds.toISOString(),
          endDate: endDate.toISOString(),
        };
      };

      const { startDate, endDate } = getDateRange(8);

      const offer_request = {
        customer: {
          currency: 'AUD',
          country: 'AU',
          language: 'en',
          ip: '124.168.10.55',
        },
        schema: '',
        partner: {
          transaction_id: '4f3a9e1b-7c2d-4b8a-9e5f-1a2b3c4d5e6g',
          metadata: {
            device:
              'Browser: Mozilla Version: 0.0 Platform: MixAndMatchAU|Mozilla/5.0 (iPhone; CPU iPhone OS 17_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.3.1 Mobile/15E148 Safari/604.1',
            session_id: '1ebaf939-af73-4232-8ea5-7ce084d8f050',
          },
        },
        context: {
          offer_type: 'multiple',
          insured: [
            {
              first_name: 'First',
              last_name: 'Last',
              country: 'AU',
            },
          ],
          total_tickets_price: 344,
          policy_start_date: startDate,
          policy_end_date: endDate,
          departure_country: 'AU',
          destination_country: 'US',
          is_return: false,
          flights: [
            {
              legs: [
                {
                  departure_datetime: startDate,
                  arrival_datetime: endDate,
                  flight_number: 'SK1530',
                  marketing_airline_iata_code: 'SK',
                  marketing_airline_icao_code: 'SAS',
                  operating_airline_iata_code: 'SK',
                  operating_airline_icao_code: 'SAS',
                  departure_airport: 'LHR',
                  arrival_airport: 'ARN',
                  departure_country: 'IT',
                  arrival_country: 'IT',
                },
              ],
            },
          ],
          number_of_children: 0,
          number_of_adults: 1,
          number_of_infants: 0,
          trip_start_date: startDate,
          trip_end_date: endDate,
        },
        extra_fields: ['tax'],
      };

      const onSet = async (request) => {
        try {
          const res = await request;
          responseData = res;
        } catch (err) {
          console.error(err);
        }
      };

      const onChange = (args) => {
        if (args.selectedOption !== 'reject') {
          console.log('Insurance selected: ', args);
        } else {
          console.log('No insurance selected: ', args);
        }
        selectedOption = args.selectedOption;
      };

      const onCheckout = () => {
        if (selectedOption) {
          console.log('Valid selection - Checking Out 🎉');
          alert('Valid selection - Checking Out 🎉');
          return;
        }
        console.log('No protection option selected - Block checkout');
        window.signalLayer.push({
          signal: 'update',
          element: 'xce-travel-dual-demo',
          isError: true,
        });
      };

      window.signalLayer.push({
        signal: 'set',
        element: 'xce-travel-dual-demo',
        data: {
          offer_request,
          currency_config: {
            trailingZeroDisplay: 'stripIfInteger',
            customOptions: {
              format: '$%v AUD',
            },
          },
        },
        onSet,
      });

      window.signalLayer.push({
        signal: 'listen',
        element: 'xce-travel-dual-demo',
        onChange,
      });
    </script>
  </body>
</html>
```

{% endtab %}

{% tab title="Ticketing" %}

#### Ticketing: Event ticket protection Offer

This is an example of what you should be seeing:

<div data-with-frame="true"><figure><img src="https://719583013-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwIXMQsGitXUADGsP8bzz%2Fuploads%2Fgit-blob-ff3c35420254be94268ceccf0552ee91a55bdbaa%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure></div>

{% code overflow="wrap" lineNumbers="true" fullWidth="false" %}

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700&family=Roboto&display=swap"
      rel="stylesheet"
    />
    <title>XCE TICKET DEMO</title>
    <script type="module" src="https://sandbox.xce.xcover.com/offers-demo/v2/xcover-elements.js" async></script>
    <style>
      html {
        font-family: 'Roboto', sans-serif;
        font-size: 14px;
      }

      main {
        padding: 12px;
      }

      .offer-container {
        border: 1px solid rgba(0, 0, 0, 0.2);
        padding: 16px;
        border-radius: 5px;
      }

      .button {
        display: inline-block;
        padding: 8px 16px;
        margin-bottom: 8px;
        font-size: 12px;
        color: white;
        background-color: #04aa6d;
        border: 2px solid #04aa6d;
        border-radius: 30px;
        text-transform: uppercase;
        text-align: center;
        transition-duration: 0.4s;
      }

      .button:hover {
        background-color: white;
        color: black;
      }
    </style>
  </head>

  <body>
    <main>
      <h1 id="header">Hello World!</h1>
      <p id="description">This is an XCover Elements Ticket demo.</p>
      <p>Before selecting an option, click on the following "Checkout" CTA to trigger the element error state</p>
      <button class="button" onclick="onCheckout()">Checkout</button>
      <div class="offer-container">
        <xce-ticket-demo></xce-ticket-demo>
      </div>
    </main>
    <script>
      window.signalLayer = window.signalLayer || [];

      let responseData;
      let selectedOption;

      // Helper function to generate ISO date strings
      const getDateRange = (daysFromNow = 20) => {
        const now = new Date();
        const futureDate = new Date(now.getTime() + daysFromNow * 24 * 60 * 60 * 1000);
        return {
          startDate: now.toISOString(),
          endDate: futureDate.toISOString(),
        };
      };

      const { endDate } = getDateRange(20);
      // For multiple events
      const { endDate: endDate2 } = getDateRange(27);

      const offer_request = {
        customer: {
          currency: 'AUD',
          country: 'AU',
          language: 'en',
          region: 'NY',
          postcode: '10036',
        },
        schema: '',
        partner: {
          transaction_id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
          subsidiary: 'subsidiary',
          customer_id: '123456',
          metadata: {
            context_id: 'b2c3d4e5-f6a7-8901-bcde-f12345678901',
            event_id: 'c3d4e5f6-a7b8-9012-cdef-123456789012',
          },
        },
        context: {
          events: [
            {
              id: crypto.randomUUID(),
              start_date: endDate,
              name: 'Event name',
              venue: 'Premium Venue',
              country: 'AU',
              city: 'Sydney',
              ticket_count: 2,
              multiday_event: false,
              total_amount: 852,
              tickets: [
                {
                  price: 426,
                  type: 'GA',
                  status: 'purchased',
                  id: '459624186',
                  seat_info: 'Section A, Row 5, Seat 12',
                },
                {
                  price: 426,
                  type: 'GA',
                  status: 'purchased',
                  id: '459624187',
                  seat_info: 'Section A, Row 5, Seat 13',
                },
              ],
            },
            {
              id: crypto.randomUUID(),
              start_date: endDate2,
              name: 'Event 2 name',
              venue: 'Premium Venue',
              country: 'AU',
              city: 'Sydney',
              ticket_count: 2,
              multiday_event: false,
              total_amount: 900,
              tickets: [
                {
                  price: 450,
                  type: 'VIP',
                  status: 'purchased',
                  id: '459624188',
                  seat_info: 'VIP Section B, Row 2, Seat 8',
                },
                {
                  price: 450,
                  type: 'VIP',
                  status: 'purchased',
                  id: '459624189',
                  seat_info: 'VIP Section B, Row 2, Seat 9',
                },
              ],
            },
          ],
        },
      };

      const onSet = async (request) => {
        try {
          const res = await request;
          responseData = res;
        } catch (err) {
          console.error(err);
        }
      };

      const onChange = (args) => {
        if (args.selectedOption !== 'reject') {
          console.log('Insurance selected: ', args);
        } else {
          console.log('No insurance selected: ', args);
        }
        selectedOption = args.selectedOption;
      };

      const onCheckout = () => {
        if (selectedOption) {
          console.log('Valid selection - Checking Out 🎉');
          alert('Valid selection - Checking Out 🎉');
          return;
        }
        console.log('No protection option selected - Block checkout');
        window.signalLayer.push({
          signal: 'update',
          element: 'xce-ticket-demo',
          isError: true,
        });
      };

      window.signalLayer.push({
        signal: 'set',
        element: 'xce-ticket-demo',
        data: {
          offer_request,
          currency_config: {
            trailingZeroDisplay: 'stripIfInteger',
            customOptions: {
              format: '%m%v USD',
            },
          },
        },
        onSet,
      });

      window.signalLayer.push({
        signal: 'listen',
        element: 'xce-ticket-demo',
        onChange,
      });
    </script>
  </body>
</html>
```

{% endcode %}
{% endtab %}
{% endtabs %}


# Requests & Responses

Example payloads for requests to and responses from XCE

## Offer Request

The below is an example quote request to send to the XCE widget during initialization.

```json
{
  "schema": "demo-partner-travel:v1",
  "customer": {
    "currency": "EUR",
    "language": "en",
    "country": "NL"
  },
  "context": {
    "departure_country": "GB",
    "destination_country": "GB",
    "reservation_number": "aaca2167-3d55-4d12-a58d-cecf2657a7f4",
    "total_tickets_price": 265,
    "number_of_adults": 1,
    "number_of_children": 0,
    "number_of_infants": 0,
    "trip_start_date": "2025-11-08T09:25:00+11:00",
    "trip_end_date": "2025-11-17T15:45:00+11:00",
    "trips": [
      {
        "legs": [
          {
            "departure_datetime": "2025-11-08T09:25:00+11:00",
            "arrival_datetime": "2025-11-08T11:30:00+11:00",
            "trip_number": "ABC123",
            "departure_location": "Machester Piccadilly",
            "arrival_location": "London Kings Cross",
            "departure_country": "GB",
            "arrival_country": "GB",
            "departure_city": "Machester",
            "arrival_city": "London",
            "transport_mode": "train"
          }
        ]
      },
      {
        "legs": [
          {
            "departure_datetime": "2025-11-08T09:25:00+11:00",
            "arrival_datetime": "2025-11-08T11:30:00+11:00",
            "trip_number": "DEF456",
            "departure_location": "London Kings Cross",
            "arrival_location": "Piccadilly",
            "departure_country": "GB",
            "arrival_country": "GB",
            "departure_city": "London",
            "arrival_city": "Machester",
            "transport_mode": "train"
          }
        ]
      }
    ]
  }
}
```

## Offer Response

The below is an example response provided by XCE during the `onSet` function once an offer was successfully generated for a customer. This data is required to be stored for later consumption in the confirm offer request.

#### Finance and Benefits Response Fields

By default, the offer response includes these fields at the product level with null values:

* `tax` — tax amount for the product
* `surcharge` — surcharge amount
* `commission` — commission amount
* `benefits` — policy benefit details

The response contract is stable — these fields are always present. However, tax, surcharge, and commission will return `null` until your element is configured by your Client Solution Engineer (CSE) to request them. Once set up, the XCover engine populates them with their actual values. No changes are required on your side.

{% hint style="info" %}
To enable extra response fields, reach out to your CSE.
{% endhint %}

```json
{
    "id": "fe92ecc3-fe4c-408a-b678-a80e5a073c65",
    "offer_config_id": "409ae590-3302-4d56-9279-af956c1e2170",
    "products": [
        {
            "id": "1846ae80-bda8-4288-aeea-4ad130a4de6a",
            "product_config_id": "6e29bc7e-aca0-48d5-ba65-2c3eeb01ab08",
            "type": "insurance",
            "details": {
                "policy_version_id": "ab150d4d-38bb-4560-9901-fcea7ade5ede",
                "start_date": "2025-11-08T09:25:00+11:00",
                "end_date": "2025-11-22T09:25:00+11:00",
                "finance": {
                    "price": {
                        "total_amount": 18.61,
                        "total_amount_without_tax": null,
                        "total_amount_formatted": "€18.61",
                        "total_amount_without_tax_formatted": null
                    },
                    "tax": {
                        "total_amount": null,
                        "total_amount_formatted": null,
                        "breakdown": null,
                    },
                    "surcharge": {
                        "total_amount": null,
                        "total_amount_formatted": null
                    },
                    "commission": {
                        "total_amount": null,
                        "total_amount_formatted": null
                    }
                },
                "pds_url": "https://staging.xcover.com/en/pds/fe92ecc3-fe4c-408a-b678-a80e5a073c65?policy_type=travel_ticket_cover_v1",
                "files": [],
                "extra_fields": {},
                "experiment": {}
            }
        }
    ],
    "brightwrite_details": {
        "bw_device_id": "de506c6f-d65e-4abd-89f2-9daebb1b721a",
        "bw_experiment_id": null,
        "bw_variant_id": null
    }
}
```


# Summary

XCover Confirm offer and Opt out on XCover Elements integrations

XCover Elements handles the front-end presentation of offers to your customers. When a customer views protection products, XCover Elements creates offers automatically — no backend integration is needed for this step.

Once a customer has selected or declined a protection product, your backend server integrates directly with the **XCover API** to complete the transaction. This includes:

* **Confirming an offer** the customer has accepted
* **Opting out** of an offer the customer has declined

**Connecting frontend to backend:** The offer response from XCover Elements contains a `provider_reference` field. Use the IDs from `provider_reference` when making requests to the XCover API — these map the frontend offer to the corresponding XCover resource.

**Authentication:** The XCover API uses HMAC signature authentication for all server-to-server requests.

{% hint style="info" %}
More on Confirm Offer and Opt out API specs: [XCover API Reference](https://partner-docs.covergenius.com/xcover/api/reference)
{% endhint %}

You can use the HTML Demo under Client Integration Examples to display an example frontend widget, and the [Postman Collection](https://web.postman.co/workspace/%5BGitBook%5D-XCover-Elements-Demo~4aca8c38-22e6-4762-8cc7-0be5c3ed0ec7/collection/9582676-47676b6b-2078-40ce-82c7-7f269d1c2020) for the same demo partner to see example booking requests against the XCover API.

{% hint style="warning" %}
**Note: The Postman collection requires access. Please liase with your key account manager to request access.**
{% endhint %}




---

[Next Page](/llms-full.txt/1)

