Back to Blog
Product March 10, 2026 | 10 min read

Czech Litigation Monitoring: Courts, Insolvency, and Enforcement

Automated monitoring of Czech court proceedings, ISIR insolvency registry, enforcement tracking, and litigation outcome prediction

Tomas Korcak (korczis)

Prismatic Platform

Litigation history and active court proceedings are essential signals in due diligence. A company involved in significant litigation faces potential financial exposure, operational disruption, and reputational risk. In the Czech Republic, court data is distributed across multiple systems, each with its own access patterns and data structures. Prismatic integrates these systems into a unified litigation monitoring capability.


Czech Court System Data Sources


Three primary systems provide litigation data for Czech entities:


Justice.cz hosts the public court portal with access to proceedings across district, regional, and high courts. Data includes case numbers, parties, case type, filing dates, and published decisions. Access is public but requires structured querying.


ISIR (Insolvencni rejstrik) is the dedicated insolvency register, providing real-time data on insolvency petitions, proceedings, court decisions, creditor claims, and resolution plans. ISIR offers a SOAP API for automated access, making it the most machine-friendly Czech court data source.


CEDR and the Execution Registry track enforcement proceedings (exekuce), providing visibility into whether a company has unresolved debts being actively collected through court-ordered enforcement.


ISIR Integration


The ISIR adapter is Prismatic's most mature Czech court integration, leveraging the registry's structured SOAP API:



defmodule Prismatic.DD.Sources.ISIR do

@moduledoc """

Czech Insolvency Registry (ISIR) adapter.

Queries insolvency proceedings by ICO or name.

"""


@behaviour Prismatic.DD.Source


@isir_endpoint "https://isir.justice.cz/isir/ws/IsirWsService"


@impl true

def fetch(%{ico: ico}, opts) when is_binary(ico) do

timeout = Keyword.get(opts, :timeout, 15_000)


soap_body = build_query_by_ico(ico)


case send_soap_request(soap_body, timeout) do

{:ok, response} ->

proceedings = parse_insolvency_proceedings(response)


{:ok, %{

data: %{

proceedings: proceedings,

active_count: Enum.count(proceedings, & &1.is_active),

total_count: length(proceedings),

queried_at: DateTime.utc_now()

},

confidence: 0.95,

source: :isir

}}


{:error, reason} ->

{:error, {:isir_query_failed, reason}}

end

end


@impl true

def source_group, do: :court


@impl true

def rate_limit, do: {5, 60_000}


@impl true

def priority, do: 1


defp parse_insolvency_proceedings(response) do

response

|> SweetXml.xpath(~x"//insolvencniRizeni"l)

|> Enum.map(fn node ->

%{

case_number: SweetXml.xpath(node, ~x"./spisovaZnacka/text()"s),

court: SweetXml.xpath(node, ~x"./soud/text()"s),

filing_date: parse_date(SweetXml.xpath(node, ~x"./datumZalozeni/text()"s)),

status: map_status(SweetXml.xpath(node, ~x"./stav/text()"s)),

is_active: SweetXml.xpath(node, ~x"./stav/text()"s) not in ["KONC", "ZRUS"],

debtor_role: SweetXml.xpath(node, ~x"./roleSubjektu/text()"s),

proceedings_type: map_proceedings_type(

SweetXml.xpath(node, ~x"./druhRizeni/text()"s)

)

}

end)

end


defp map_status("NEVYR"), do: :pending

defp map_status("MORAT"), do: :moratorium

defp map_status("UPAD"), do: :bankruptcy_declared

defp map_status("ODDL"), do: :debt_relief

defp map_status("REOR"), do: :reorganization

defp map_status("KONK"), do: :liquidation

defp map_status("KONC"), do: :concluded

defp map_status("ZRUS"), do: :cancelled

defp map_status(other), do: {:unknown, other}

end


Litigation Event Processing


Raw court data requires processing to be useful for risk assessment. Prismatic normalizes litigation events into a standard structure and computes aggregate metrics:



defmodule Prismatic.DD.Litigation.Processor do

@moduledoc """

Litigation event normalization and aggregate risk computation.

"""


@type litigation_summary :: %{

total_cases: non_neg_integer(),

active_cases: non_neg_integer(),

as_plaintiff: non_neg_integer(),

as_defendant: non_neg_integer(),

total_exposure_czk: Decimal.t() | nil,

insolvency_history: boolean(),

active_enforcement: boolean(),

severity_distribution: %{atom() => non_neg_integer()}

}


@spec summarize(entity_id :: binary(), [map()]) :: litigation_summary()

def summarize(entity_id, raw_events) do

events = Enum.map(raw_events, &normalize_event/1)


%{

total_cases: length(events),

active_cases: Enum.count(events, & &1.is_active),

as_plaintiff: Enum.count(events, &(&1.entity_role == :plaintiff)),

as_defendant: Enum.count(events, &(&1.entity_role == :defendant)),

total_exposure_czk: compute_total_exposure(events),

insolvency_history: Enum.any?(events, &(&1.case_type == :insolvency)),

active_enforcement: Enum.any?(events, fn e ->

e.case_type == :enforcement and e.is_active

end),

severity_distribution: compute_severity_distribution(events),

timeline: build_timeline(events)

}

end


defp compute_total_exposure(events) do

events

|> Enum.filter(fn e -> e.is_active and e.entity_role == :defendant end)

|> Enum.map(& &1.claimed_amount)

|> Enum.reject(&is_nil/1)

|> case do

[] -> nil

amounts -> Enum.reduce(amounts, Decimal.new(0), &Decimal.add/2)

end

end


defp compute_severity_distribution(events) do

events

|> Enum.map(&classify_severity/1)

|> Enum.frequencies()

end


defp classify_severity(%{case_type: :insolvency, is_active: true}), do: :critical

defp classify_severity(%{case_type: :enforcement, is_active: true}), do: :high

defp classify_severity(%{claimed_amount: amt}) when not is_nil(amt) do

if Decimal.compare(amt, Decimal.new("10_000_000")) == :gt, do: :high, else: :medium

end

defp classify_severity(_event), do: :low

end


Continuous Monitoring


For entities under ongoing surveillance, Prismatic implements a polling-based monitoring system that checks for new court events at configurable intervals:



defmodule Prismatic.DD.Litigation.Monitor do

@moduledoc """

Continuous litigation monitoring with change detection.

"""


use GenServer

require Logger


@default_interval :timer.hours(6)


def start_link(opts) do

GenServer.start_link(__MODULE__, opts, name: __MODULE__)

end


@impl true

def init(opts) do

interval = Keyword.get(opts, :interval, @default_interval)

schedule_check(interval)

{:ok, %{interval: interval, watched_entities: MapSet.new()}}

end


@impl true

def handle_info(:check_updates, state) do

state.watched_entities

|> Enum.each(fn entity_id ->

check_entity_updates(entity_id)

end)


schedule_check(state.interval)

{:noreply, state}

end


defp check_entity_updates(entity_id) do

entity = Prismatic.DD.Entities.get!(entity_id)

last_check = entity.litigation_last_checked


case fetch_new_events(entity, last_check) do

{:ok, []} ->

:ok


{:ok, new_events} ->

Logger.info("Found #{length(new_events)} new litigation events for #{entity_id}")


Phoenix.PubSub.broadcast(

Prismatic.PubSub,

"dd:litigation:#{entity_id}",

{:new_litigation_events, entity_id, new_events}

)


Prismatic.DD.Entities.update_litigation_check(entity_id, DateTime.utc_now())


{:error, reason} ->

Logger.warning("Litigation check failed for #{entity_id}: #{inspect(reason)}")

end

end


defp schedule_check(interval) do

Process.send_after(self(), :check_updates, interval)

end

end


Outcome Analysis


Historical case outcomes provide context for assessing active cases. Prismatic tracks case dispositions and computes aggregate statistics per case type and court. For insolvency proceedings, the resolution rate, average duration, and creditor recovery percentages are all tracked. This data informs the risk scoring engine, allowing it to weight active cases not just by claimed amount but by the probability of an adverse outcome given historical patterns.


The litigation dimension contributes to the overall entity risk score with a default weight of 10%. However, for entities with active insolvency proceedings or enforcement actions, the scoring engine can escalate the litigation dimension dynamically, reflecting the outsized importance of these findings.


Integration Notes


All court data in the Czech Republic is public information, and automated access is permissible for legitimate purposes. However, rate limits must be respected. ISIR's API is reasonably reliable but has occasional downtime. Justice.cz is less structured and requires more robust error handling. The enforcement registry has the most limited programmatic access.


Prismatic handles source unavailability gracefully: if a court data source is down during a DD pipeline run, the investigation proceeds with available data and flags the missing source in the results. The analyst can trigger a targeted re-check once the source recovers.

Tags

litigation czech-courts insolvency isir enforcement monitoring

Related Glossary Terms