Getting started

Brief description about platform's core functionality.

Initial setup

Before we can start using some of the platform core functionalities, we will need to setup a product. For showcase purposes we will be creating a mock company cyber insurance product that will have the following settings configured:

  • pricing logic

  • field definition

  • payment plan

The same product will be used in the sections below in order to hands-on explain how to use the platform.

Product creation

We will be creating a simple cyber insurance product with English language and TEST policy prefix. This product will not have sub products - all of the product settings will be configured on product level.

Pricing logic

For pricing logic, we will be using single payment pricing logic with the pricing file below:

And with the following validation rules under Validation Rules section:

{
	"quote": [
		{
			"name": "employee_number",
			"path": "data",
			"validation": "integer|required"
		},
		{
			"name": "yearly_turnover",
			"path": "data",
			"validation": "integer|required"
		},
		{
			"name": "company_backup",
			"path": "data",
			"validation": "string|required|in:weekly,monthly,quarterly,yearly,never"
		},
		{
			"name": "encryption",
			"path": "data",
			"validation": "boolean|required"
		},
		{
			"name": "deductible",
			"path": "data",
			"validation": "integer|required|in:100000,500000,1000000"
		},
		{
			"name": "insured_sum",
			"path": "data",
			"validation": "integer|required|in:10000000,30000000,50000000,100000000"
		},
		{
			"name": "online_revenue_percentage",
			"path": "data",
			"validation": "string|required|in:0_25,26_50,above_50"
		},
		{
			"name": "policy_start_date",
			"path": "data",
			"validation": "iso_date|required|after:today"
		},
		{
			"name": "third_party_coverage",
			"path": "data",
			"validation": "boolean|required"
		}
	],
	"quote_patch": [],
	"pricing_variables": []
}

Field definition

For field definition we will be using the configuration below:

{
	"version": "1.0",
	"definition": {
		"policy": [
			{
				"name": "first_name",
				"path": null,
				"validation": "string"
			},
			{
				"name": "last_name",
				"path": null,
				"validation": "string"
			},
			{
				"name": "email",
				"path": null,
				"validation": "string"
			},
			{
				"name": "company_name",
				"path": "data",
				"validation": "string|required"
			},
			{
				"name": "company_registered_date",
				"path": "data",
				"validation": "iso_date|required|before:today"
			},
			{
				"name": "optins",
				"path": "data",
				"validation": "boolean|required"
			},
			{
				"name": "street",
				"path": "data",
				"validation": "string|required"
			},
			{
				"name": "house_number",
				"path": "data",
				"validation": "string|required"
			},
			{
				"name": "postcode",
				"path": "data",
				"validation": "string|required"
			},
			{
				"name": "subsidiary",
				"path": "data",
				"validation": "integer|required|min:0|max:20"
			},
			{
				"name": "phone_number",
				"path": "data",
				"validation": "phone_number|required"
			},
			{
				"name": "city",
				"path": "data",
				"validation": "string|required"
			}
		]
	}
}

Payment plans

The product will have a single payment plan setup with an insurer payment method and invoice as the payment provider.

Integration

We will also need to create an integration. We can name it whatever we like, however since our mock product will be used through API only, we will toggle API Only Integrationon.

Policy creation flow

The core functionality of platform is the policy creation flow. In order to create a policy in KASKO, three steps must be completed:

  1. Quote generated;

  2. Offer created;

  3. Payment made;

This guide will be using the product created from Initial setup and will go through all of three steps above with request and response examples, explaining each of the steps in detail.

Quote generation

A "quote" refers to an estimate or proposal provided by the insurance product to a potential customer, outlining the cost and terms of an insurance policy.

The quote is calculated from the pricing logic file uploaded, given the user input.

In order to successfully construct the necessary payload, we will need to know:

  • product's payment plan id,

  • integration id and the,

  • public key.

Given the pricing logic and our hypothetical company we wish to insure, we construct the request below.

curl --location 'https://api.eu1.kaskocloud.com/quotes?key={{ public_key }}' \
--header 'Accept: application/vnd.kasko.v3+json' \
--header 'Content-Type: application/json' \
--data '{
  "data": {
    "employee_number": 11,
    "yearly_turnover": 1100000,
    "company_backup": "never",
    "encryption": true,
    "deductible": 100000,
    "insured_sum": 10000000,
    "online_revenue_percentage": "0_25",
    "policy_start_date": "2023-08-06",
    "third_party_coverage": false
  },
  "item_id": {{ integration_subproduct_id}},
  "subscription_plan_id": {{ payment_plan_id }},
  "integration_id": {{ integration_id }},
  "live_product": "false",
  "live_integration": "false"
}'

Pricing logic specific data must be passed within the data object and this data will be later passed to the pricing logic to perform the calculations.

As our product is not published, we set live_product & live_integration properties to "false" and for demonstration purposes we substituted product-specific variable values with curly braces (i.e. {{ integration_id }}).

If everything is setup correctly, expected response should look something like this:

{
    "token": "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",
    "gross_payment_amount": 275000,
    "extra_data": {
        "gross_premium": 275000,
        "premium_tax": 25000,
        "net_premium": 250000,
        "tax_rate": 0.1
    }
}

If one or more of the values fails either the defined validation rules within the product settings or the validation present within the pricing file itself, it will be noted to the end-user. An example of a failed validation response would look something like this:

{
    "status": "Bad Request",
    "message": "Data validation failed.",
    "errors": [
        {
            "code": "required",
            "field": "company_backup"
        }
    ]
}

Within the example we did not provide a value for company backup and the following response with a 400 status code was returned, as company_backup is defined as required in validation string.

Unpaid policy creation

Within the platform, an unpaid policy is considered an offer, so when an offer is created, technically platform is creating a policy that is waiting to be paid for.

Within the payload, the API expects data object. This is where we pass policy specific data. This data must align with the field definition configured (i.e. all the fields are present in the definition and they pass the validation rules). Given the mock product's field definition and the company we wish to insure, we construct the following payload:

curl --location 'https://api.eu1.kaskocloud.com/policies?key={{ public_key }}' \
--header 'Accept: application/vnd.kasko.v2+json' \
--header 'Content-Type: application/json' \
--data-raw '{
  "first_name": "Test",
  "last_name": "Test",
  "email": "test@test.io",
  "data": {
    "company_name": "Test",
    "company_registered_date": "2023-07-31",
    "optins": true,
    "street": "Tellplatz",
    "house_number": "52",
    "postcode": "4053",
    "subsidiary": 12,
    "phone_number": "+443333333333",
    "city": "Basel"
  },
    "quote_token": "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",
  "language": "en"
}'

Similar to the quote request, if any of the fields fail validation, a 400 HTTP status code response is returned with validation error response. For example, If subsidiary value is provided that exceeds the maximum of 20, following message is returned to the end-user:

{
    "status": "Bad Request",
    "message": "Data validation failed.",
    "errors": [
        {
            "path": "data",
            "code": "invalid_value",
            "field": "subsidiary",
            "rules": [
                "max"
            ]
        }
    ]
}

However, if everything is set correctly, the expected response from this request should look something like this:

{
    "id": "tpol_22433722923489f0268f95966b35",
    "insurer_policy_id": "TEST-TESTEXQK1KQD",
    "payment_token": "eyJpZCI6ImRyMSIsIml2IjoiTU5SRWJhS25EOEFLc2l5bXM5OGdjQT09IiwibWFjIjoiODU5NzIwZDEwNDQ5OTc3M2NiMmIyYjYzY2FjZjI1OWIwYzMyOWM1NThiZTc4ZDk3MmZiYTg2NTFiMzEyNmY0YiIsInZhbHVlIjoiS0lzNXV2TVNZbDI0NlBqU1wvdE92RXIzYUthdlNmZ1RKdWk1clpQXC9hVkJ0dks3R2N0TDdPXC9OMnkzZ3g4d01BSGJcL1dYVk95dHJIZHJ1SGVuV1kwdFZmRXkxYm90bnhPaDdmOE1ZYUVrbXRhRktcL2dla3Q4ajhnejRDcFlJWG9CK3REN3djalA5N1wvWGM2dHd0dUk5OExnPT0ifQ__",
    "_links": {
        "_self": {
            "href": "https://api.qa-u.eu1.kaskoqa.com/policies/tpol_22433722923489f0268f95966b35"
        },
        "assets": {
            "offer": {
                "href": "https://api.qa-u.eu1.kaskoqa.com/offers/tpol_22433722923489f0268f95966b35/assets?token=36fa3ebc626ea129c4328a2e9504ec9e2f93d34afb970ce09925cfc14047bc67af9e9b7ede96e44ad3cb89b46998ccdf1feb8aae7ca37c39369943452b567d1b"
            },
            "policy": {
                "href": "https://api.qa-u.eu1.kaskoqa.com/policies/tpol_22433722923489f0268f95966b35/assets?token=c73683200dbea8105645dc7ea8c012b6ee634a06b06a92ad4b16d012f8b37c762d1ffa3ae157a3314167267790beb536bb24cf63af96a946bf979b0a38ae5e59"
            }
        }
    }
}

On success, a payment token is generated (i.e. payment_token) and an unique 33 character offer ID (i.e. tpol_...) is returned.

Paying for policy

When constructing the payload for the request, provider and method properties must be set. These values depend on the product's configuration, however, since our mock product payment is setup to use invoice, we will use invoice for both of these properties.

The payment request should look something like this:

curl --location 'https://api.qa-u.eu1.kaskoqa.com/payments?key=pk_test_2jngq6d7GRmxQ58w0yVKW3PBrJXbEvoM' \
--header 'Accept: application/vnd.kasko.v2+json' \
--header 'Content-Type: application/json' \
--data '{
    "token": "eyJpZCI6ImRyMSIsIml2IjoiTU5SRWJhS25EOEFLc2l5bXM5OGdjQT09IiwibWFjIjoiODU5NzIwZDEwNDQ5OTc3M2NiMmIyYjYzY2FjZjI1OWIwYzMyOWM1NThiZTc4ZDk3MmZiYTg2NTFiMzEyNmY0YiIsInZhbHVlIjoiS0lzNXV2TVNZbDI0NlBqU1wvdE92RXIzYUthdlNmZ1RKdWk1clpQXC9hVkJ0dks3R2N0TDdPXC9OMnkzZ3g4d01BSGJcL1dYVk95dHJIZHJ1SGVuV1kwdFZmRXkxYm90bnhPaDdmOE1ZYUVrbXRhRktcL2dla3Q4ajhnejRDcFlJWG9CK3REN3djalA5N1wvWGM2dHd0dUk5OExnPT0ifQ__",
    "method": "invoice",
    "provider": "invoice",
    "policy_id": "tpol_22433722923489f0268f95966b35"
}'

The following request should return a response similar to this:

{
    "object": "payment",
    "id": "tcfbb8eec11b708606f69320b5c0a9795",
    "livemode": false,
    "provider": "invoice",
    "method": "invoice",
    "status": "ok",
    "transaction_metadata": [],
    "_links": {
        "_self": {
            "href": "https://api.eu1.kaskocloud.com/payments/tcfbb8eec11b708606f69320b5c0a9795"
        }
    }
}

This indicates that the payment has succeeded and a policy is created in KASKO platform.

  curl --location 'https://api.eu1.kaskocloud.com/policies/tpol_3a1d4c1e1d58fd04ad6b0de1b50c?key={{ public_key }}' \
--header 'Accept: application/vnd.kasko.v2+json'

The returned response from the request indicates that policy has been successfully created:

{
    "id": "tpol_3a1d4c1e1d58fd04ad6b0de1b50c",
    "insurer_policy_id": "TEST-TESTE76R4R7D",
    "insurer_external_policy_id": null,
    "status": "ready",
    "_links": {
        "_self": {
            "href": "https://api.eu1.kaskocloud.com/policies/tpol_3a1d4c1e1d58fd04ad6b0de1b50c"
        }
    }
}

To view more detailed information about the policy, other means of authorization must be used. The example above used a public key which restricts access to certain policy fields, thus only limited information can be fetched about the policy.

In this section we managed to undergo the policy creation flow and have successfully issued a policy for our mock product, exploring one of the core functionalities of the KASKO platform.

Last updated