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

> ## Agent Instructions
> To build and serve your own model, start at /deploy/development/quickstart and /deploy/development/overview. Deploying is the default path: reactor init scaffolds a workspace, reactor auth login authenticates, and reactor model deploy registers the model, publishes the release with the weights/ folder, and activates it on Reactor's GPUs, in one command from that workspace. Docker must be running, because the publish step builds the image locally. Bump model.version in reactor.yaml before redeploying a change, because a release that already has an image is reactivated as it is. Deployment access is granted per account, so contact team@reactor.inc if a deploy is refused. Every key in reactor.yaml is documented at /deploy/platform/reactor-yaml. Model code imports reactor_runtime; Python client code imports reactor_sdk. The runtime overview explains the model interface. Running the model on your own machine with reactor run is optional and needs a GPU you attach with --gpus; /deploy/development/local-testing covers that loop and pairs a complete brightness model with a Python client test in a separate brightness-test workspace.
> Reactor hosts multiple models, each with its own connect slug (modelName) and command/event schema. The catalog of every model — slug, typed SDK package, and links to its schema — is at /model-api-reference/overview. Some models expose one slug per experience (e.g. HappyOyster); always take the slug from the model's own pages, never guess it.
> Fastest path to a working app: `npx create-reactor-app my-app --model=<slug>` scaffolds a complete app with secure auth wired up. Typed TypeScript SDKs are published as @reactor-models/<model>; Python uses the base reactor-sdk package.
> Auth: exchange an API key (rk_...) for a JWT via POST https://api.reactor.inc/tokens from your server. Never put the API key in client-side code.
> Append .md to any docs URL for clean Markdown. Search these docs via the MCP server at https://docs.reactor.inc/mcp.

# Types

> Java SDK JSON values, replies, connection state, subscriptions, and errors

Public Java SDK types live in `inc.reactor.sdk`. These are the types used in the examples; the
[package Javadoc](https://javadoc.io/doc/inc.reactor/reactor-sdk/1.0.0/inc.reactor.sdk/inc/reactor/sdk/package-summary.html)
provides the complete reference.

## ConnectionStatus

Read `reactor.status()` or register `reactor.onStatus(handler)`.

| Value          | Meaning                                        |
| -------------- | ---------------------------------------------- |
| `DISCONNECTED` | No active connection                           |
| `CONNECTING`   | Establishing the session connection            |
| `WAITING`      | Connected, waiting for the model to be ready   |
| `READY`        | The model can answer commands and stream media |

## JsonValue

`JsonValue` represents JSON objects, arrays, strings, numbers, booleans, and null. Use it for
command arguments, schema results, and messages:

```java theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
import inc.reactor.sdk.JsonValue;

JsonValue arguments = JsonValue.object()
        .put("prompt", "a red bicycle")
        .build();
String json = arguments.toJsonString();
JsonValue parsed = JsonValue.parse(json);
if (parsed instanceof JsonValue.JsonObject object) {
    object.getString("prompt").ifPresent(System.out::println);
}
```

Use `JsonValue.of(...)` for strings, numbers, and booleans, `JsonValue.ofNull()` for JSON null, and
`JsonValue.array(List<JsonValue>)` for arrays. Object accessors such as `getString`, `getNumber`,
`getBoolean`, and `get` return optionals. An optional Jackson adapter is available separately; the
base SDK does not require Jackson.

## CommandReply

`sendCommand` resolves to `Optional<CommandReply>`. An empty optional is a successful acknowledgment
without a reply message. A present reply exposes:

| Accessor       | Result                                    |
| -------------- | ----------------------------------------- |
| `type()`       | `Optional<String>`: model message type    |
| `data()`       | `Optional<JsonValue>`: message payload    |
| `dataOrNull()` | Payload, or a JSON null value when absent |

## FileRef

`uploadFile` and `uploadBytes` return a `FileRef` with `uploadId()`, `name()`, `mimeType()`, and
`size()` in bytes. Pass it in the named upload map when sending a command. `toJsonValue()` supports
file references nested in a command's JSON arguments. See
[Upload files](/sdk-reference/java/reactor#upload-files).

## Clip and DownloadedClip

A `Clip` identifies media the platform is assembling. Its `playlistUrl()` points to the HLS
playlist; `sessionId()` identifies the session. The record also exposes `kind()`, `startMarker()`,
`endMarker()`, `nowMarker()`, and `predictedReadyAtMs()`.

A clip request completing does not mean its media is ready. Use `downloadClip` to wait and save it.
The resulting `DownloadedClip` contains `path()`, `bytes()`, and `segments()`. A `ClipProgress`
callback receives `(done, total)` segment counts on the download's thread.

## Subscription

Each event or frame registration returns a `Subscription`, which implements `AutoCloseable`. Call
`close()` to remove that handler; repeated calls are safe. Try-with-resources can limit a
subscription to a block. Keep the subscription somewhere accessible when it must be removed later.

## Errors

`ReactorException` is the unchecked base class for SDK failures, including errors delivered by
`onError`. Known codes have subclasses such as `UnauthorizedException`, `RateLimitedException`,
`DisconnectedException`, and `RequestTimeoutException`. Unknown codes remain available through
`code()` on the base exception.

| Accessor          | Meaning                                                |
| ----------------- | ------------------------------------------------------ |
| `code()`          | Stable code to match; prefer it to parsing the message |
| `getMessage()`    | Human-readable explanation                             |
| `isRecoverable()` | Whether the same operation could succeed later         |
| `status()`        | HTTP status, or `null`                                 |
| `operation()`     | Failed operation, or `null`                            |
| `retryAfterMs()`  | Suggested backoff in milliseconds, or `null`           |

An asynchronous SDK failure completes its future exceptionally. When using `join()`, inspect the
cause of `CompletionException`. Synchronous validation can throw `ReactorException` directly:

```java theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
try {
    reactor.sendCommand("set_prompt", JsonValue.object()
            .put("prompt", "a mountain landscape")
            .build()).join();
} catch (java.util.concurrent.CompletionException failure) {
    if (failure.getCause() instanceof inc.reactor.sdk.ReactorException error) {
        System.err.println(error.code() + ": " + error.getMessage());
    } else {
        throw failure;
    }
} catch (inc.reactor.sdk.ReactorException error) {
    System.err.println(error.code() + ": " + error.getMessage());
}
```

Check the error before retrying. For example, an expired token needs replacement, and a terminal
session needs a new session. See the
[ErrorCode Javadoc](https://javadoc.io/doc/inc.reactor/reactor-sdk/1.0.0/inc.reactor.sdk/inc/reactor/sdk/ErrorCode.html)
for the published codes and recovery classifications.
