> ## Documentation Index
>
> Fetch the complete documentation index at: https://lithi.ai/llms.txt
>
> Use this file to discover all available pages before exploring further.

---
title: Use a Java or Kotlin client
description: >-
  What decides whether a Java or Kotlin client is released, how to read its tested
  surface instead of generator output, and what to build against until one is listed.
route: /docs/compute/clients/jvm
page_id: docs-compute-clients-jvm
page_type: howTo
content_layer: guided documentation
surface_profile: guided_docs
audience: Java and Kotlin developers integrating Compute
voice: D
reader_question: Can I rely on a Java or Kotlin client today, and how do I check?
primary_action: Check the compatibility matrix for a tested JVM surface
source_locale: en-US
source_status: APPROVED
source_version: docs-compute-clients-jvm-en-us-2026-09-05-v1
last_updated: '2026-09-05'
robots: index
claim_registry_pinned: true
claim_registry_resync: "npm run governed:tsx -- scripts/build-compute-public-claim-registry.ts --write"
---

## What decides whether a JVM client is released

Two independent gates decide it, and both must pass.

The generator output must compile and pass conformance against the contract release it claims. The official runtime must then pass the same conformance suite on the exact Java or Kotlin versions being claimed.

A client is listed on the compatibility matrix only when both pass. Nothing else counts as a release, including a build that compiles cleanly.

## Read the tested surface, not the generator output

An OpenAPI generator will emit a Java or Kotlin client from the description you download. It will emit method names for every operation, whether or not any of them was exercised.

That output is yours. It proves a generator ran, and it proves nothing about behavior under refusal, cancellation, streaming or partial completion.

The matrix names the tested surface exactly: client version, protocol version, the features exercised, and the known gaps. Read a method list as a shape, and read the matrix as the claim.

## Check the matrix before you write against it

Find your Java or Kotlin version in the matrix. If no row lists a tested JVM surface for it, that version is unsupported, and the matrix states that rather than leaving it blank.

An unsupported client may still return responses. That is not evidence it handles the cases you care about, and it is not something to build a production path on.

## Build against REST in the meantime

Everything a JVM client would do is available over REST today, using the description you download for paths, headers and schemas.

You send the same seven request objects: `workflow`, `input`, `parameters`, `quality`, `policy`, `output` and `limits`. You read the same envelope back, carrying `request_id`, the operation, the contract release, a typed state, an evidence class, `observed_at`, `valid_until` and a `next_action`.

Your base URL and current API version appear in the portal under developer settings, and in the API description you download.

## The rules do not change with the language

Whatever you build against, four things hold.

- A quote never authorizes work. It carries `non_authorizing = true`, an expiry and a signature, and you approve separately.
- Terminal job states are `SUCCEEDED`, `PARTIAL`, `FAILED` and `CANCELLED`.
- Every operation carries its own generated `error_schema`, so there is no one error table to import.
- `result-manifest.json` is written last and is the only complete-bundle marker.

Keep `EDGE_ABUSE_LIMITED`, `CANONICAL_ADMISSION_LIMITED`, `CANONICAL_BUDGET_EXHAUSTED` and `CELL_CAPACITY_UNAVAILABLE` in separate branches. Two of them describe authority, and retrying those changes nothing.

Read [the tested rows on the compatibility matrix](/docs/compute/clients/compatibility), then [submit work over REST](/docs/compute/clients/rest) while you wait for a JVM row you can rely on.
