Data Adapter queries
Use these examples to execute SQL queries using Data Adapter
Overview
Once you have successfully connected your preferred tool to Data Adapter, you should be able to execute your own SQL queries.
Amazon Athena supports a subset of the Data Definition Language (DDL) and Data Manipulation Language (DML) statements, functions, operators, and data types.
AWS Athena SQL reference
For more information on supported statements and caveats, please see the AWS SQL reference for Athena. This includes the full list of supported SQL functions.
This guide covers some common queries and functions to help get you started.
Data dictionary for navigating your Root data
To help you in navigate Root's data structure and tables, we have created a comprehensive data dictionary. It offers detailed information on data elements, their types, keys and interrelationships. It also provides hints on how you can use the data to extract meaningful insights for your business.
Click here to view the data dictionary. We hope it helps you maximise the value of the Data Adapter and streamline data analysis processes.
Working with JSON fields
Due to the highly configurable nature of the Root platform, many fields are represented as JSON objects or arrays that are returned as plain VARCHAR
strings. The Athena Querying JSON guide contains good examples of how to work with these fields.
Use the API reference to understand the shape of JSON data
Many of the JSON fields you will encounter when using Data Adapter are described in our API reference.
For example, if you want to understand the shape of the
created_by
JSON field on thepayments
table, go to the List policy payments endpoint and expand the200 Success
response to see a schema of thepayment
object.
Here are examples of how to extract data from a JSON field. These examples query the charges
JSON array on the policies
table. To understand which properties to expect on each charges
object, see the policy object on the API reference.
SELECT
policy_id,
-- first charge
JSON_EXTRACT_SCALAR(charges, '$[0].name')
AS "charge_0_name",
CAST(JSON_EXTRACT(charges, '$[0].amount') AS INTEGER)
AS "charge_0_amount",
-- second charge
JSON_EXTRACT_SCALAR(charges, '$[1].name')
AS "charge_1_name",
CAST(JSON_EXTRACT(charges, '$[1].amount') AS INTEGER)
AS "charge_1_amount",
-- last charge
JSON_ARRAY_GET(charges, -1)
AS "charges_last",
JSON_EXTRACT_SCALAR(JSON_ARRAY_GET(charges, -1), '$.name')
AS "charges_last_name",
CAST(JSON_EXTRACT(JSON_ARRAY_GET(charges, -1), '$.amount') AS INTEGER)
AS "charges_last_amount"
FROM
policies
LIMIT 100
;
Working with dates
You can find a good overview of working with dates in the PrestoDB documentation. Dates on the Root platform are generally represented as ISO 8601 strings in the UTC timezone.
All entities have a created_at
field, allowing to fetch entities from a certain timeframe, like how many policies were created in the last month:
SELECT
count(*)
FROM
policies
WHERE
-- specify dates relative to now (eg. not older than 1 month)
AND created_at > NOW() - INTERVAL '1' MONTH
Below are examples of converting date strings to timestamps. These examples query the schedule_versions
JSON array on the policies
table. To understand which properties to expect on each schedule version object, refer to the policy object on the API reference.
SELECT
policy_id,
JSON_ARRAY_GET(schedule_versions, -1)
AS "last_schedule_version",
-- parse string to ensure valid date
from_iso8601_timestamp(
JSON_EXTRACT_SCALAR(
JSON_ARRAY_GET(schedule_versions, -1),
'$.createdAt'
)
) AS "last_schedule_created",
-- cast to timestamp for further comparison
CAST (
from_iso8601_timestamp(
JSON_EXTRACT_SCALAR(
JSON_ARRAY_GET(schedule_versions, -1),
'$.createdAt'
)
)
AS timestamp
) AS "last_schedule_created_timestamp"
FROM
policies
LIMIT 100
If you want to work with dates in a particular timezone, please see Athena's list of supported timezones and available timezone functions. When using the format_datetime
function, also have a look at the available formatting options.
Below are examples of working with timezones. These examples convert the created_at
date on the policies
table to different timezones.
SELECT
policy_id,
created_at,
-- display timestamp in specific timezone
created_at AT TIME ZONE 'UTC' AS "created_at_utc",
created_at AT TIME ZONE 'Africa/Johannesburg' AS "created_at_jhb",
created_at AT TIME ZONE 'America/Los_Angeles' AS "created_at_la",
-- format timestamp
format_datetime(
created_at AT TIME ZONE 'Africa/Johannesburg',
'E, d MMMM y H:m:s Z'
) AS "created_at_format"
FROM
policies
WHERE
-- specify range in specific timezone
created_at
BETWEEN timestamp '2022-11-01 00:00:00 Africa/Johannesburg'
AND timestamp '2022-12-01 00:00:00 Africa/Johannesburg'
-- specify dates relative to now (eg. not older than 1 year)
AND created_at > NOW() - INTERVAL '1' YEAR
LIMIT 100
Creating views
To simplify analytical queries, you can make use of views
to extract data from complex fields.
Names of views must end with
_view
The name of any view created on the Root Data adapter must end with
_view
. For example,dinosure_policy_view
ormy_custom_event_view
.
In the example below, we start with aSELECT
query that extracts or combines the desired data from the policy_events
table:
- Extracting the
policy_id
from the persistence key and giving it an alias. - Extracting event
type
and with its own alias. - If the event was initiated by a user (and not via API or the system itself), we extract the UUID of that user with the alias
requested_by_user_id
.
The result of this query will make it easier to find and/or join events for specific policies, and perform further analysis.
SELECT
regexp_replace(
persistence_key,
'^.+-policy:',
''
) AS "policy_id",
created_at,
json_extract_scalar(data, '$.type') AS "type",
sequence,
version,
data,
CASE
json_extract_scalar(data, '$.metadata.requested_by.type')
WHEN 'user' THEN json_extract_scalar(
data,
'$.metadata.requested_by.id'
)
END AS "requested_by_user_id",
persistence_key
FROM
policy_events
LIMIT 100
Once we have confirmed that the query is returning the expected results, we can use the CREATE VIEW
query:
CREATE VIEW policy_events_view AS
SELECT
regexp_replace(
persistence_key,
'^.+-policy:',
''
) AS "policy_id",
created_at,
json_extract_scalar(data, '$.type') AS "type",
sequence,
version,
data,
CASE
json_extract_scalar(data, '$.metadata.requested_by.type')
WHEN 'user' THEN json_extract_scalar(data, '$.metadata.requested_by.id')
END AS "requested_by_user_id",
persistence_key
FROM
policy_events
Now, we can use this view in the same way as any other table in further queries. In this case, we are using the view to combine information from the policy_events
table with information from the policies
and users
tables.
SELECT
pol.policy_id,
ev.created_at AS "activated_at",
usr.email AS "activated_by"
FROM policies AS pol
LEFT JOIN policy_events_view AS ev
ON ev.policy_id = pol.policy_id
AND ev.type = 'policy_activated'
LEFT JOIN users AS usr
ON usr.id = ev.requested_by_user_id
LIMIT 100
If the view was created for temporary analyses, don't forget to DROP
the view when you are done:
DROP TABLE policy_events_view
Collections & billing operations
For background on these queries, see the Billing overview guide, as well as the other guides in the "Billing & payments" category.
SELECT
*
FROM
payments
WHERE
environment = 'production' -- Limits results to the production environment
AND finalized_at >= CURRENT_DATE - INTERVAL '1' month -- Limits results to where the finalized_at is within the last month
AND status = 'failed' -- Limits results to payments with a status of failed
ORDER BY
finalized_at; -- Orders the results from oldest to most recent finalized payment.
SELECT
policy_id,
payment_method_id,
collection_type,
payment_id,
description AS payment_description,
amount, -- In cents
currency,
status AS payment_status,
failure_code,
failure_reason,
json_extract_scalar(created_by, '$.type') AS created_by,
cast(billing_date AS date) AS billing_date,
cast(created_at AS date) AS payment_created_at,
cast(action_date AS date) AS action_date,
cast(submitted_at AS date) AS submitted_date,
cast(finalized_at AS date) AS finalized_at,
json_extract_scalar(finalized_by, '$.type') AS finalized_by,
json_extract_scalar(submitted_by, '$.type') AS submitted_by
FROM
payments
WHERE
environment = 'production' -- Limits results to the production environment.
AND status = 'failed' -- Limits results to only failed payments.
AND finalized_at >= CURRENT_DATE - INTERVAL '1' month -- Limits the results by only including a finalized_at date of within the last month.
ORDER BY finalized_at -- Orders the results from oldest to most recent finalized payment.
;
SELECT
pm.payment_method_id,
pm.type,
pm.banv_status,
pm.blocked_reason,
pm.updated_at,
pm.policyholder_id,
ph.policy_ids AS linked_policies,
pm.account_holder
FROM
payment_methods AS pm
LEFT JOIN policyholders AS ph ON ph.policyholder_id = pm.policyholder_id -- Linking the policyholders table to return linked data
WHERE
pm.environment = 'production' -- Limits results to the production environment.
AND pm.banv_status = 'blocked' -- Limits results to return payment methods with blocked status.
ORDER BY
pm.updated_at DESC; -- Orders the results from most recent to oldest updated payment method.
SELECT
id AS refund_id,
cast(created_at AS date) AS created_at,
json_extract_scalar(created_by, '$.type') AS created_by_type, -- Extracts the type from the created_by object.
json_extract_scalar(created_by, '$.id') AS created_by_id, -- Extracts the type from the created_by object.
status AS refund_status,
type,
amount AS refund_amount, -- Returns an amount in cents.
description,
json_extract_scalar(linked_entities, '$.policyId') AS policy_id, -- Extracts the policy_id from the linked_entities object.
-- finalised_at, -- Commented out because it will be a null value if status is pending.
-- json_extract_scalar(finalised_by, '$.type') AS finalized_by_type, -- Commented out because it will be a null value if status is pending.
-- json_extract_scalar(finalised_by, '$.id') AS finalized_by_id, -- Commented out because it will be a null value if status is pending.
-- rejection_reason, -- Commented out because it will be a null value if status is pending.
-- proof_of_payment_id, -- Commented out because it will be a null value if status is pending.
action_date,
payee AS payee_details
FROM
payout_requests
WHERE
type = 'policy_refund'
AND status = 'pending'
AND environment = 'prodcution' -- Limits results to the production environment.
ORDER BY
created_at -- Orders the results from oldest to most recent refund request.
;
WITH cte_ledger AS ( -- Creating a common table expression to simplify data in the main query.
SELECT
policy_id,
sum(amount) AS balance
FROM
policy_ledger
GROUP BY
policy_id
)
SELECT
pol.policy_number,
pol.policy_id,
pol.policyholder_id,
pol.product_module_id,
json_extract_scalar (pol.module, '$.type') AS module_type,
cast(pol.start_date AS date) AS policy_start_date,
cast(pol.end_date AS date) AS policy_end_date,
pol.status,
pol.billing_day,
pol.monthly_premium / 100.0 AS monthly_premium,
pl.balance / 100.0 AS ledger_balance
FROM
policies pol
LEFT JOIN cte_ledger pl ON pl.policy_id = pol.policy_id
WHERE
pol.environment = 'production' -- Limits results to the production environment.
AND pl.balance < 0 -- Limits data returned to policies with balances less than zero.
ORDER BY
pl.policy_id
;
WITH cte_ledger_balance AS ( -- Creating a common table expression to simplify data in the main query.
SELECT
pol.policy_id,
json_extract_scalar(module, '$.type') AS module_type, -- Returns the module type extracted from the module object.
pol.currency,
pol.monthly_premium,
sum(coalesce(pl.amount, 0)) AS balance,
CASE WHEN pol.monthly_premium = 0 THEN
0
ELSE
(sum(cast(coalesce(pl.amount, 0) AS double)) / cast(coalesce(monthly_premium, 0) AS double))
END AS arrears_num,
(sum(coalesce(pl.amount, 0)) / coalesce(monthly_premium, 0))
FROM
policies pol
LEFT JOIN policy_ledger pl ON pl.policy_id = pol.policy_id
WHERE
pol.environment = 'production' -- Limits results to the production environment.
AND pol.status = 'active' -- Limits results to active policies.
GROUP BY -- Group like cases together.
pol.policy_id,
json_extract_scalar (module, '$.type'),
pol.currency,
pol.monthly_premium
),
cte_aging AS ( -- Creating a common table expression to simplify data in the main query.
SELECT
module_type,
CASE WHEN arrears_num >= 0 THEN
'paidUp'
ELSE
concat(cast(cast(- floor(arrears_num) AS int) AS varchar), '_month')
END AS arrears_month,
count(policy_id) AS policy_count,
currency,
sum(balance) AS total_amount_cents
FROM
cte_ledger_balance AS lb
GROUP BY
module_type,
CASE WHEN arrears_num >= 0 THEN
'paidUp'
ELSE
concat(cast(cast(- floor(arrears_num) AS int) AS varchar), '_month')
END,
currency
)
SELECT -- Main query.
* -- Returns everything from the cte_aging expression.
FROM
cte_aging
ORDER BY -- Orders the data based of the below-mentioned columns.
module_type,
length(arrears_month),
arrears_month;
Payments overview
Use this query to get an overview of all payments (premium collections) for policies issued under your organisation. Limit results to a given date range or payment status.
Failed payments
Use this query to investigate and analyse failed premium collections.
Blocked payment methods
Use this query to investigate and analyse blocked payment methods.
Pending refunds
Use this query to get a view of pending premium refunds, for example due to policies cancelled within the cooling off period or refunds generated manually by your tem on the dashboard
Ledger balances
Use this query to get a view on whether policies in your organisation are paid up or whether there are arrears premiums outstanding.
Policy aging
Use this query for a different view on the buildup of arrears premiums across policies.
Claims
For background on these queries, see the Claims guide.
SELECT
*
FROM
claims
WHERE
environment = 'production' -- Limits results to the production environment
ORDER BY created_at; -- Orders the results from oldest to newest created claim
SELECT
id AS claim_id,
cast(created_at AS date) AS created_at,
json_extract_scalar(created_by, '$.type') AS created_by_type, -- Extracts the type from the created_by object.
json_extract_scalar(created_by, '$.id') AS created_by_id, -- Extracts the type from the created_by object.
status AS claim_status,
type,
amount AS claim_amount, -- Returns an amount in cents.
description,
json_extract_scalar(linked_entities, '$.policyId') AS policy_id, -- Extracts the policy_id from the linked_entities object.
-- finalised_at, -- Commented out because it will be a null value if status is pending.
-- json_extract_scalar(finalised_by, '$.type') AS finalized_by_type, -- Commented out because it will be a null value if status is pending.
-- json_extract_scalar(finalised_by, '$.id') AS finalized_by_id, -- Commented out because it will be a null value if status is pending.
-- rejection_reason, -- Commented out because it will be a null value if status is pending.
-- proof_of_payment_id, -- Commented out because it will be a null value if status is pending.
action_date,
payee AS payee_details
FROM
payout_requests
WHERE
type = 'claim_payout'
AND status = 'pending'
AND environment = 'sandbox' -- Limits results to the production environment.
ORDER BY
created_at -- Orders the results from oldest to most recent claim request.
;
Claims overview
Use this query to get an overview of claims submitted against policies under your organisation
Pending claims
Use this query to get more details on claims awaiting resolution.
Policies
For background on these queries, see the Managing policies guide.
SELECT
*
FROM
policies
WHERE
environment = 'production' -- Limits results to the production environment
AND status = 'active' -- Limits results to active policies
ORDER BY
created_at; -- Orders the results from oldest to newest created policy
SELECT
pol.policy_number,
pol.policy_id,
pol.policyholder_id,
pol.product_module_id,
pol.package_name,
cast(pol.created_at AS date) AS created_at,
cast(pol.start_date AS date) AS policy_start_date,
cast(pol.end_date AS date) AS policy_end_date,
cast(pol.status_updated_at AS date) AS status_updated_at,
status,
pol.billing_day,
pol.billing_frequency,
pol.sum_assured / 100.0 AS sum_assured,
pol.monthly_premium / 100.0 AS monthly_premium,
sum(pl.amount)/100.0 as ledger_balance
FROM
policies pol
LEFT JOIN policy_ledger pl ON pl.policy_id = pol.policy_id
WHERE
pol.environment = 'production' -- Limits results to the production environment.
AND cast(pol.status_updated_at as date) >= CURRENT_DATE - interval '1' day -- Limits the results by only including policies lapsed in the last day.
AND pol.status IN ('lapsed', 'not_taken_up') -- Limits results to statuses of lapsed and not_taken_up.
GROUP BY
pol.policy_number,
pol.policy_id,
pol.policyholder_id,
pol.product_module_id,
pol.package_name,
cast(pol.created_at AS date),
cast(pol.start_date AS date),
cast(pol.end_date AS date),
cast(pol.status_updated_at AS date),
status,
pol.billing_day,
pol.billing_frequency,
pol.sum_assured / 100.0,
pol.monthly_premium / 100.0
;
WITH cte_ledger AS (
SELECT
pol.policy_id,
pol.policy_number,
pol.status,
pol.billing_day,
pol.monthly_premium,
sum(pl.amount) AS balance
FROM
policy_ledger pl
LEFT JOIN policies pol ON pol.policy_id = pl.policy_id
WHERE
pol.environment = 'production'
AND pol.status = 'active' -- Include only active policies
AND pol.monthly_premium != 0 -- Exclude policies with a zero monthly premium
GROUP BY
pol.policy_id,
pol.policy_number,
pol.status,
pol.monthly_premium,
pol.billing_day
)
SELECT
*
FROM
cte_ledger
WHERE
date_diff ('day', CURRENT_DATE, date_add ('day', billing_day, date_trunc('month', CURRENT_DATE) - interval '1' day)) = 10 -- Limits results to the set amount of days until the policy should be billed
AND balance / monthly_premium <= -2 -- Limits results to the set amount of premiums in arreas
;
SELECT
sequence,
persistence_key,
regexp_replace(persistence_key, '^.+-policy:', '') AS policy_id,
substr(persistence_key, strpos(persistence_key, ':') + 1, strpos(persistence_key, '-pol') - 5) AS organization_id, -- Includes ""dev_"" in the front of the org_id if entry is in Sandbox.
from_unixtime (created_at / 1000) AS created_at,
version,
data
FROM
policy_events
WHERE
persistence_key NOT LIKE '%dev%'
ORDER BY
sequence;
SELECT
date_format(date(created_at), 'yyyy-mm') AS created_period,
json_extract_scalar(module, '$.type') AS module_type,
status,
currency,
round(cast(sum(monthly_premium / 100.0) AS double), 2) AS sum_of_premium,
round(cast(sum(sum_assured / 100.0) AS double), 2) AS total_sum_assured
FROM
policies
WHERE
environment = 'production'
GROUP BY
date_format(date(created_at), 'yyyy-mm'),
json_extract_scalar (module, '$.type'),
status,
currency
ORDER BY
date_format(date(created_at), 'yyyy-mm'),
json_extract_scalar(module, '$.type'),
status
Policies overview
Use this query to get an overview of all policies issued under your organisation. You can limit results by policy status.
Lapsed / NTU
Use this query to find policies that recently lapsed or were marked "not taken up" (due to the first collection failing).
Policies expected to lapse
Use this query to find all policies that are expected to lapse by their next collection date.
Policy events
Get a handle on the events that make up the policy history, including all policy updates.
Policyholders & notifications
SELECT
*
FROM
policyholders
WHERE
environment = 'production' -- Limits results to the production environment
AND element_at(split (replace(replace(policy_ids, '[', ''), ']',''), ','), 1) != '' -- Limits results to policyholders that have a policy linked to them.
ORDER BY created_at; -- Orders the results from oldest to newest created policyholder.
SELECT
notification_id,
cast(created_at AS date) AS created_at,
json_extract_scalar (created_by, '$.type') AS created_by_type, -- Extracts the type from the created_at object.
channel,
notification_type,
json_extract_scalar (linked_entities, '$.policyId') AS policy_id, -- Extracts the policy_id from the linked_entities object.
json_extract_scalar (linked_entities, '$.policyholderID') AS policyholder_id, -- Extracts the policyholder_id from the linked_entities object.
json_extract_scalar (linked_entities, '$.claimId') AS claim_id, -- Extracts the claim_id from the linked_entities object.
data,
status,
failed_at,
failure_reason
FROM
notifications
WHERE
environment = 'production' -- Limits results to the production environment.
ORDER BY
created_at; -- Orders the results from oldest to most recent notification.
-- Notification query for when a notification have been triggerred but was not successfull
WITH _policyholders AS (
-- has the policyholder had an unseccessful notification?
SELECT DISTINCT
json_extract_scalar (n.linked_entities, '$.policyholderId') AS "policyholder_id",
cast(n.created_at AS date) AS created_at,
n.environment,
n.notification_type,
n.notification_id,
n.organization_id
FROM
notifications AS n
WHERE
date_trunc('month', cast(n.created_at AS date)) = date('period') -- this needs to be adjusted to the period you wish to extract data for,example: '2024-06-01'
AND cast(n.created_at AS date) < now() - interval '24' hour
AND n.environment = 'production'
AND n.status IN ('queued', 'rejected', 'unknown_error')
),
_success_notifications AS (
-- has the policyholder received a successful notification for the same notification type within a days range
SELECT DISTINCT
succ.notification_id,
json_extract_scalar (succ.linked_entities, '$.policyholderId') AS policyholder_id,
succ.notification_type,
cast(succ.created_at AS date) AS created_at
FROM
notifications AS succ
JOIN _policyholders p ON cast(succ.created_at AS date) >= p.created_at - interval '1' day
AND cast(succ.created_at AS date) <= p.created_at + interval '1' day
AND succ.organization_id = p.organization_id
AND succ.environment = p.environment
AND succ.notification_type = p.notification_type
AND succ.status NOT IN ('queued', 'rejected', 'unknown_error')
AND json_extract_scalar (succ.linked_entities, '$.policyholderId') = p.policyholder_id
),
_main_notifications AS (
SELECT DISTINCT
p.policyholder_id,
p.notification_id,
p.notification_type
FROM
_policyholders p
WHERE
NOT EXISTS (
SELECT
1
FROM
_success_notifications s
WHERE
s.policyholder_id = p.policyholder_id
AND s.notification_type = p.notification_type
AND s.created_at = p.created_at))
SELECT
cast(date_trunc('month', n.created_at) AS date) AS period,
o.name,
json_extract_scalar (n.linked_entities, '$.policyholderId') AS "policyholder_id",
json_extract_scalar (n.linked_entities, '$.policyId') AS "policy_id",
n.created_at,
n.notification_id,
n.notification_type,
n.channel,
n.status,
json_extract_scalar (json_extract (n.status_updates, concat('$[', cast(json_array_length(json_parse (n.status_updates)) - 1 AS varchar), ']')), '$.description') AS "last_update",
n.updated_at,
external_reference
FROM
notifications AS n
LEFT JOIN organizations o ON o.organization_id = n.organization_id
WHERE
cast(date_trunc('month', n.created_at) AS date) = date('period') -- this needs to be adjusted to the period you wish to extract data for,example: '2024-06-01'
AND n.environment = 'production'
AND n.notification_id IN (
SELECT
notification_id
FROM
_main_notifications
ORDER BY
policyholder_id ASC)
AND n.status IN ('unknown_error', 'rejected', 'queued')
ORDER BY
cast(date_trunc('month', n.created_at) AS date),
n.notification_type,
n.channel,
n.status;
Policyholders
Get an overview of policyholders under your organisation, or segment policyholders by location or gender.
For further background, see the General settings guide and the Policyholders section of the API reference.
Notifications
Understand whether important notifications are reaching policyholders, and take action in the event of failed notifications.
For further background, see the Customer notifications overview guide and the Notifications section of the API reference.
Unsuccessful notifications
Identify policyholders who have notifications that were triggered but not successfully delivered. The query distinguishes between those who received at least one successful notification of the same type within a specific date range and those who did not. This helps pinpoint notification issues for corrective action.
Organisation set-up
SELECT
u.id AS user_id,
u.email,
u.state,
u.created_at,
our.organization_role_id,
orgr.name,
orgr.description
FROM
users u
LEFT JOIN organization_user_roles our ON our.user_id = u.id
LEFT JOIN organization_roles orgr ON orgr.organization_role_id = our.organization_role_id;
SELECT
product_module_definition_id,
product_module_id,
version_major,
version_minor,
created_at,
json_extract_scalar(created_by, '$.type') AS created_by_type, -- Extracts the type from the created_by object.
json_extract_scalar(created_by, '$.id') AS created_by_id, -- Extracts the type from the created_by object.
json_extract_scalar(published_by, '$.type') AS created_by_type, -- Extracts the type from the created_by object.
json_extract_scalar(published_by, '$.id') AS created_by_id, -- Extracts the type from the created_by object.
json_extract_scalar(json_extract(json_extract(settings, '$.billing'), '$.retries'), '$.retryFailedPayments') AS retryFailedPayments,
json_extract_scalar(json_extract(json_extract(settings, '$.billing'), '$.retries'), '$.daysBetweenFailedPaymentRetries') AS daysBetweenFailedPaymentRetries,
json_extract_scalar(json_extract(settings, '$.billing'), '$.currency') AS billing_currency,
json_extract_scalar(json_extract(settings, '$.billing'), '$.premiumType') AS billing_frequency,
json_extract(json_extract(settings, '$.billing'), '$.paymentMethodTypes') AS paymentMethodTypes,
json_extract_scalar(json_extract(json_extract(settings, '$.billing'), '$.primaryMethod'), '$.type') AS primaryMethodType,
json_extract_scalar(json_extract(settings, '$.billing'), '$.proRataMinimum') AS proRataMinimum,
json_extract_scalar(json_extract(settings, '$.billing'), '$.billBeforeWeekend') AS billBeforeWeekend,
json_extract_scalar(json_extract(settings, '$.billing'), '$.allowStartDateChange') AS allowStartDateChange,
json_extract_scalar(json_extract(settings, '$.billing'), '$.naedoArrearsPolicies') AS naedoArrearsPolicies,
json_extract_scalar(json_extract(settings, '$.billing'), '$.proRataBillingOnIssue') AS proRataBillingOnIssue,
json_extract_scalar(json_extract(settings, '$.billing'), '$.enableBillingOnSandbox') AS enableBillingOnSandbox,
json_extract_scalar(json_extract(settings, '$.billing'), '$.proRataBillingDisabled') AS proRataBillingDisabled,
json_extract_scalar(json_extract(settings, '$.billing'), '$.paymentSubmissionLeadTime') AS paymentSubmissionLeadTime,
json_extract_scalar(json_extract(settings, '$.billing'), '$.shouldCreateExternalPayments') AS shouldCreateExternalPayments,
json_extract_scalar(json_extract(settings, '$.billing'), '$.consecutiveFailedPaymentsAllowed') AS consecutiveFailedPaymentsAllowed
FROM
product_module_definitions
-- WHERE product_module_id = 'enter product_module_id here' -- Can be included to only extract the billing settings from a single product module.
ORDER BY
product_module_id,
version_major,
version_minor
;
SELECT
pmc.payment_method_config_id,
pmc.payment_method_type,
pmc.provider_id,
pmp.name AS provider_name,
pmp.description AS provider_description,
pmp.provider_type,
pmc.payment_method_config_key,
pmc.is_default,
pmp.is_default_for_new_orgs,
cast(pmc.created_at AS date) AS created_at,
cast(pmc.updated_at AS date) AS updated_at,
pmc.product_module_id,
pmc.billing_strategy_settings,
pmc.config AS payment_method_configuration,
pmp.config AS provider_configuration
FROM
payment_method_configs AS pmc
LEFT JOIN payment_method_providers AS pmp ON pmp.payment_method_provider_id = pmc.provider_id -- Joining an additional table to include more relevant data.
WHERE
pmc.environment = 'production' -- Limits results to the production environment.
ORDER BY
pmp.provider_type -- Orders the results from alphabetically using the provider type.
;
Users
Understand which users operate on Root on behalf of your organisation together with their roles and permissions. For further background, see the User management section of the help centre.
Billing settings
Get the billing configs that apply to collections for different product modules. For more details see the Billing settings guide and the Billing & payments guides.
Payment provider config
Get the config for different payment providers enabled for your organisation. For further background see the Billing & payments section.
Regulatory
SELECT
pol.policy_number,
pol.status AS policy_status,
pay.action_date AS payment_date,
pay.finalized_at AS finalized_date,
pay.status AS payment_status,
cast(pol.start_date AS date) AS policy_start_date,
date_diff('year', pol.start_date, CURRENT_DATE) AS policy_age,
json_extract_scalar(pol.module, '$.type') AS module_type,
date_diff('year', ph.date_of_birth, CURRENT_DATE) AS policyholder_age,
pay.description AS payment_description,
pol.monthly_premium / 100.0 AS monthly_premium, -- Returns an amount that has been converted from cents.
pay.amount / 100.0 AS amount_collected -- Returns an amount that has been converted from cents.
FROM
payments pay
LEFT JOIN policies pol ON pay.policy_id = pol.policy_id
LEFT JOIN policyholders ph ON pol.policyholder_id = ph.policyholder_id
WHERE
pay.environment = 'production' -- Limits results to the production environment.
AND pay.status = 'successful' -- Limits results to only successful payments.
AND pay.finalized_at >= CURRENT_DATE - INTERVAL '1' month -- Limits the results by only including a finalized_at date of within the last month.
;
SELECT
c.claim_number,
c.claim_id,
cast(c.created_at AS date) AS claim_created_at,
cast(c.updated_at AS date) AS claim_updated_at,
c.status AS claim_status,
c.approval_status,
c.policyholder_id,
c.policy_id,
json_extract_scalar (pol.module, '$.type') AS module_type,
pol.policy_number,
pol.status AS policy_status,
cast(pol.start_date AS date) AS policy_start_date,
date_diff ('year', pol.start_date, c.created_at) AS policy_age_at_claim_creation,
date_diff ('year', ph.date_of_birth, c.created_at) AS policyholder_age_at_claim_creation,
max(cast(pay.payment_date AS timestamp)) FILTER (WHERE pay.status = 'successful') AS last_successful_payment,
c.claimant AS claimant_details,
c.incident_date,
c.incident_type,
c.incident_cause,
c.requested_amount / 100.0 AS requested_amount,
c.granted_amount / 100.0 AS granted_amount,
c.rejection_reason
FROM
claims c
LEFT JOIN policies pol ON c.policy_id = pol.policy_id
LEFT JOIN policyholders ph ON c.policyholder_id = ph.policyholder_id
LEFT JOIN payments pay ON pay.policy_id = c.policy_id
WHERE
c.environment = 'production' -- Limits results to the production environment.
GROUP BY
c.claim_number,
c.claim_id,
cast(c.created_at AS date),
cast(c.updated_at AS date),
c.status,
c.approval_status,
c.policyholder_id,
c.policy_id,
json_extract_scalar (pol.module, '$.type'),
pol.policy_number,
pol.status,
cast(pol.start_date AS date),
date_diff ('year', pol.start_date, c.created_at),
date_diff ('year', ph.date_of_birth, c.created_at),
c.claimant,
c.incident_date,
c.incident_type,
c.incident_cause,
c.requested_amount,
c.granted_amount,
c.rejection_reason;
Payments bordereaux
Captures premium collection and policy status data for submission to regulators and re-insurers.
Claims bordereaux
Captures claims data for submission to regulators and re-insurers.
Updated 5 months ago