> This is the Markdown version of the page. For the complete Lattice Developers documentation index, fetch https://developer.anduril.com/llms.txt. Append .md to any page URL for its clean Markdown.

# Changelog

## October 5, 2026

## Lattice SDK for Rust (REST)

You can now build Lattice REST integrations in Rust. The Lattice SDK for Rust is published to [crates.io](https://crates.io/crates/anduril-lattice-sdk) as
`anduril-lattice-sdk`, joining the existing Go, Java, Python,
and TypeScript REST SDKs. The Lattice SDK guides now carry REST-based Rust examples alongside every other language, including
[publishing entities](/guides/entities/publish).

> **Add the SDK to your project**
>
> Install the SDK with `cargo add anduril-lattice-sdk`, then add the
> [`tokio`](https://crates.io/crates/tokio) runtime it builds on with
> `cargo add tokio --features macros,rt-multi-thread`. The SDK enables a
> `rustls` TLS backend by default, so HTTPS requests work without any
> additional dependencies.

The entire API surface is available through a single `prelude`, so you import the client and every type you need in one line. The following example publishes a drone asset entity:

**`Rust (REST)`**

```rust title="Rust (REST)"
use anduril_lattice_sdk::prelude::*;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = ClientConfig {
        base_url: format!("https://{}", lattice_endpoint),
        token: Some(environment_token),
        ..Default::default()
    };
    let client = Lattice::new(config)?;

    let entity = Entity {
        entity_id: Some("drone-1".to_string()),
        is_live: Some(true),
        aliases: Some(Aliases {
            name: Some("Drone 1".to_string()),
            ..Default::default()
        }),
        ontology: Some(Ontology {
            template: Some(OntologyTemplate::TemplateAsset),
            platform_type: Some("UAV".to_string()),
            ..Default::default()
        }),
        mil_view: Some(MilView {
            disposition: Some(MilViewDisposition::DispositionFriendly),
            environment: Some(MilViewEnvironment::EnvironmentAir),
            ..Default::default()
        }),
        ..Default::default()
    };

    client.entities.publish_entity(&entity, None).await?;
    Ok(())
}
```

To get started, [install the SDK for REST](/guides/getting-started/set-up#get-the-sdk-for-rest) and follow the guides.

## September 17, 2026

## Faster schema updates in developer Sandboxes

Schema definitions published to the [Lattice Schema Registry](/guides/developer-tools/registry) (LSR) now automatically propagate to
your [Sandbox](/guides/developer-tools/sandboxes) environments within 15 minutes of pushing your schemas.

You no longer need to create a new environment to pick up schema definition updates. Existing Sandbox environments
register your published schemas automatically, so you can iterate on your Protobuf definitions from the
[Lattice Developer Console](https://dashboard.developer.anduril.com) without recreating an environment on every push.

See the updated [development loop](/guides/developer-tools/registry#development-loop) section in the Schema Registry guide
for details.

## September 9, 2026

## Stream live video into Lattice

The **Lattice Video API** is now available in `Preview`. Register a live video source, attach it to an
asset entity, and operators can watch the feed on the common operational picture (COP) right
alongside every other entity in the scene. A camera on a drone, a fixed tower sensor, or an
encoder behind a NAT gateway can all surface their video in Lattice through a single, consistent API.

The Video API manages the full lifecycle of a stream: register an ingress source, associate it with
an entity, list and inspect active streams, and stop a stream when its source goes offline. It is
available across the Lattice SDKs in **Python, Go, Java, and TypeScript (REST)** and in **gRPC**.

![Shows a live camera feed playing for a selected asset in Lattice.](/_fern-files/developer.anduril.com/anduril.docs.buildwithfern.com/2edb4fcc76cbbf5d6fd0e34191732654fc189aea27ff16cbecf388b1da322c55/assets/images/screenshots/lattice-ui-live-feed.gif)

### Supported protocols

Lattice ingests video over three transports:

* **RTSP**: provide a Real Time Streaming Protocol (`rtsp://`) URL and Lattice pulls frames from it.
  Use RTSP when your source can serve an RTSP endpoint, such as an IP camera or a
  [MediaMTX](https://github.com/bluenviron/mediamtx) relay.
* **SRT**: Lattice allocates a listener and returns the endpoint your producer pushes to, with an
  optional passphrase for AES encryption. Use SRT for low-latency, push-based delivery from
  encoders and devices behind a NAT gateway.
* **MPEG-TS**: Lattice supports MPEG-TS at the edge, for environments in closed networks. If you are connecting to Lattice
  over the public internet, you can't start an MPEG-TS stream, but you can you list or inspect the `IngressStream` object.

### Start an ingress stream

After publishing a camera asset entity, create an ingress stream and attach it to that entity so the
feed appears in the UI. The example below starts an RTSP stream. As shown, the Video API surfaces the same way
across every Lattice SDK:

**`Python (REST)`**

```python title="Python (REST)"
from anduril import Lattice, RtspSettings

client = Lattice(
    base_url=f"https://{lattice_endpoint}",
    token=environment_token,
)

stream = client.video.create_ingress_stream(
    title="pi-cam-01",
    rtsp=RtspSettings(url="rtsp://<rtsp-host>:<port>/cam"),
)
print(stream.ingress_id)
```

**`Go (REST)`**

```go title="Go (REST)"
package main

import (
    "context"
    "fmt"
    "os"

    Lattice "github.com/anduril/lattice-sdk-go/v5"
    "github.com/anduril/lattice-sdk-go/v5/client"
    "github.com/anduril/lattice-sdk-go/v5/option"
)

func main() {
    latticeEndpoint := os.Getenv("LATTICE_ENDPOINT")
    environmentToken := os.Getenv("ENVIRONMENT_TOKEN")

    c := client.NewClient(
        option.WithToken(environmentToken),
        option.WithBaseURL(fmt.Sprintf("https://%s", latticeEndpoint)),
    )

    stream, _ := c.Video.CreateIngressStream(context.TODO(), &Lattice.CreateIngressStreamRequest{
        Title: "pi-cam-01",
        Rtsp:  &Lattice.RtspSettings{URL: Lattice.String("rtsp://<rtsp-host>:<port>/cam")},
    })
    fmt.Println(stream.GetIngressID())
}
```

**`Java (REST)`**

```java title="Java (REST)"
import com.anduril.Lattice;
import com.anduril.resources.video.requests.CreateIngressStreamRequest;
import com.anduril.types.CreateIngressStreamResponse;
import com.anduril.types.RtspSettings;

Lattice client = Lattice.builder()
    .url(String.format("https://%s", latticeEndpoint))
    .token(environmentToken)
    .build();

CreateIngressStreamResponse stream = client.video().createIngressStream(
    CreateIngressStreamRequest.builder()
        .title("pi-cam-01")
        .rtsp(RtspSettings.builder().url("rtsp://<rtsp-host>:<port>/cam").build())
        .build());
System.out.println(stream.getIngressId());
```

**`TypeScript (REST)`**

```js title="TypeScript (REST)"
import { LatticeClient } from "@anduril-industries/lattice-sdk";

const client = new LatticeClient({
    baseUrl: `https://${latticeEndpoint}/api/v1`,
    token: environmentToken,
});

const stream = await client.video.createIngressStream({
    title: "pi-cam-01",
    rtsp: { url: "rtsp://<rtsp-host>:<port>/cam" },
});
console.log(stream.ingressId);
```

**`Rust (gRPC)`**

```rust title="Rust (gRPC)"
use anduril_lattice_sdk_community_neoeinstein_prost::anduril::videomanager::v1::{
    create_ingress_stream_request::Ingress, CreateIngressStreamRequest, RtspSettings,
};

let stream = client
    .create_ingress_stream(CreateIngressStreamRequest {
        title: "pi-cam-01".to_string(),
        ingress: Some(Ingress::Rtsp(RtspSettings {
            url: Some("rtsp://<rtsp-host>:<port>/cam".to_string()),
        })),
        ..Default::default()
    })
    .await?
    .into_inner();
println!("{}", stream.ingress_id);
```

Attach the returned `ingress_id` to your asset entity through the entity's `media` component, and the
live feed becomes selectable on the COP.

### Manage and re-publish streams

Once streams are live, the Video API lets you operate them:

* **List and inspect**: enumerate active ingress streams and retrieve a single stream's status,
  configuration, and associated egress identifiers.
* **Stop**: stopping a stream archives it. The record remains retrievable, but the stream transitions
  to `STREAM_STATUS_ARCHIVED` and no longer appears in listings.
* **Egress**: re-publish an active ingress stream to downstream consumers over RTSP or SRT. HTTP Live
  Streaming (HLS) egress is planned.

### Get started

See the following pages in the *Lattice SDK guide*:

* [Video overview](/guides/video/overview) reviews the API surface, the `IngressStream` object, and the stream lifecycle.
* [Stream a video](/guides/video/stream-a-video) walks through publishing a camera asset and starting an RTSP or SRT ingress stream.
* [Manage streams](/guides/video/manage-streams) covers listing, retrieving, stopping, and re-publishing streams.

If you are new to the Lattice SDK, [install the SDK](/guides/getting-started/set-up#get-the-sdk) in your
language of choice, then follow the video guides above.

## August 3, 2026

## Lattice SDK skills

Today, we're launching the official Lattice SDK skills. These teach coding agents how to create integrations using the latest best practices, so that you can get to a working integration as quickly as possible.

For installation instructions, more on how they work, and how we measure how well agents perform with these skills, see [Lattice SDK skills](/guides/developer-tools/skills).

## July 23, 2026

## Lattice Schema Registry

The Lattice Schema Registry (LSR) is now available at [https://schema-registry.developer.anduril.com](https://schema-registry.developer.anduril.com).

![The Lattice Schema Registry dashboard, showing published schema repositories and their versions.](/_fern-img/948813b683a8d8aae00d83c090fe6cde782a0c6d68119969aa1ddf7674ffa076.webp)

The LSR enables you to publish, share, and use schema definitions with the Protobuf Interface Definition Language. Log in with your
existing Lattice Developer single sign-on (SSO).

Your organization owns the lifecycle of the schemas you publish to the LSR, giving you more control over defining your integration's features in Lattice.
For example, if you're integrating a taskable agent, you can publish a task definition that expresses your platform's unique capabilities to operators, then
modify the schema as the integration evolves.

To get started, see the following pages in the *Lattice SDK guide*:

* [Define tasks](/guides/tasks/define-a-task) explains how to describe your platform's capabilities as a custom task definition.
* [Create tasks](/guides/tasks/command-and-operate#create-tasks) shows you how to issue tasks to your agent from those definitions.
* [Registry](/guides/developer-tools/registry) explains how to publish, version, and share your schemas in the LSR.

> **Repository visibility**
>
> * The Lattice Schema Registry is not rated for ITAR specifications, regardless of repository visibility.
>   Do not use the registry to store any classified specifications.

For an example of how to define and use custom tasks, see the [Auto reconnaissance sample app](https://github.com/anduril/sample-app-auto-reconnaissance).

> **Existing users**
>
> If you have used the Schema Registry in beta prior to today, we are making a change to how revisions work. Breaking changes are no longer allowed for
> `alpha`, `beta`, and `test` packages. To prevent breaking changes, you must publish a new version (for example, `v1alpha` to `v2alpha`).

## June 9, 2026

## Lattice Developer Console

The Lattice Developer Console gives you a consolidated view of your data in Lattice. Use it to inspect and debug entities, tasks, and objects. The Developer Console is now the default app on Lattice Sandboxes at `https://your_lattice_url.com/developer-console`, but you still have access to the operator view at `https://your_lattice_url.com/c2`.

### What's new

* **Entity Explorer**: Browse, filter, and search every entity in your sandbox. Open one to inspect its components and tasks, and validate it against provided schemas to confirm it's well-formed.

![Shows the Entity Explorer in the Lattice Developer Console.](/_fern-img/72c242c7f0277f5a308bd2efb784cfcd9675f4dab9d1790bd9b195c6df74c7d0.webp)![Shows an entity's detail page in the Lattice Developer Console.](/_fern-img/e4304bc543cec0b7c859c63328414b293bdd7403ad7eb26f3d07066afaa15951.webp)

* **Task Explorer**: Browse every task and inspect its status, lifecycle, and payload.

![Shows the Task Explorer in the Lattice Developer Console.](/_fern-img/cf4ac4c786cb0ede10df0be80e3fd0dcb59f3479af80ae66a65cff589ab814d4.webp)

* **Object Explorer**: Browse the objects stored in your sandbox.

![Shows the Object Explorer in the Lattice Developer Console.](/_fern-img/76d4bcb7f3e0b163fc527c2d43a7643e9ab6607a0bbea6e8cdffc5ea465b081b.webp)

The example C2 app remains available and is linked from the Developer Console as the **Example C2 App**.

To get started, see [Lattice Sandboxes](/guides/developer-tools/sandboxes) in the *Lattice SDK guide*.

## May 11, 2026

## Okta authentication for Lattice Sandboxes

The Lattice Sandboxes developer portal now uses Okta to manage access. The new sign-in experience replaces the previous email, password, and authenticator-app MFA flow with a passkey-based login at [https://login.developer.anduril.com](https://login.developer.anduril.com).

### What's new

* **Okta account activation**: New developers receive a welcome email from `no-reply@developer.anduril.com` with an **Activate Okta Account** link that expires seven days after it's sent.
* **Passkey-based MFA**: During activation, you register one of three passkey methods:
  * **Browser passkey**: Stored by your browser's password manager so that you can sign in from any device signed in to the same browser profile.
  * **Operating system biometrics**: Uses Touch ID, Face ID, Windows Hello, or another built-in platform authenticator bound to the current device.
  * **Physical FIDO or UBI key**: Uses a hardware token such as a YubiKey, which you can carry with you between devices.
* **New sign-in URL**: Sign in at [https://login.developer.anduril.com](https://login.developer.anduril.com). On success, Okta redirects you to the Lattice Sandboxes dashboard.
* **Self-service passkey management**: Manage your registered passkeys and password at [https://login.developer.anduril.com/account-settings/home](https://login.developer.anduril.com/account-settings/home). If you lose access to your passkey, email [lattice-developers@anduril.com](mailto:lattice-developers@anduril.com) for assistance.

> **Browser support**
>
> Use Chrome or a Chromium-based browser, such as Microsoft Edge or Brave, to access the Lattice Sandboxes developer portal. Firefox is not supported and will prevent you from completing the sign-in procedure.

For the full activation and sign-in procedures, see the [Sign in](/guides/developer-tools/sandboxes#sign-in) section of the Lattice Sandboxes guide.

## April 22, 2026

## StreamTasks gRPC support

The Lattice SDK now supports streaming task updates in real-time using the gRPC API:

* Added [`StreamTasks`](/reference/grpc/anduril-taskmanager-v-1/task-manager-api/anduril-taskmanager-v-1-stream-tasks) gRPC endpoint for establishing persistent connections to stream task events
* Implemented Go/gRPC example demonstrating how to connect and process task streams
* Updated documentation to include gRPC usage patterns alongside existing REST examples

## Key features

The `StreamTasks` gRPC API provides the same configurable parameters as the REST version:

* **`heartbeatIntervalMs`**: Configures how frequently the server sends heartbeat events to verify connection health.
* **`excludePreexistingTasks`**: Controls whether to stream only new tasks created after the connection is established or include existing tasks.
* **`taskType`**: Allows filtering the stream by task type prefix, reducing bandwidth usage and focusing on relevant task updates.

## Documentation updates

As a part of this release, the [Operate on tasks](/guides/tasks/command-and-operate) guide has been updated with a Go/gRPC code example.
The example demonstrates how to establish a task stream connection, process heartbeat events, and handle incoming task events using the gRPC protocol.

## April 14, 2026

## Cancel tasks API

The Lattice SDK now supports task cancellation through the [`CancelTask`](/reference/rest/tasks/cancel-task) API
available in both REST and gRPC. This API lets an operator request to cancel, giving you greater control over task lifecycle management.

The cancellation behavior depends on the task's current state:

* **Tasks not yet sent to an agent** cancel immediately and transition to a terminal state.
* **Tasks already sent to an agent** receive a cancellation request that the agent can accept or reject based on the task's execution state.

For more information on using the `CancelTask` API in your integration, see [Cancel tasks](/guides/tasks/command-and-operate#cancel-tasks)
in the Lattice SDK guide.

For API reference details, see [`CancelTask` (REST)](/reference/rest/tasks/cancel-task)
and [`CancelTask` (gRPC)](/reference/grpc/anduril-taskmanager-v-1/task-manager-api/anduril-taskmanager-v-1-cancel-task).

## February 5, 2026

## Server-sent events (SSE) for tasking

The Lattice SDK now supports two new APIs that use server-sent events (SSE) for real-time task monitoring in Lattice:

1. [**StreamTasks**](/reference/rest/tasks/stream-tasks) - For monitoring all tasks across your Lattice environment.
2. [**StreamAsAgent**](/reference/rest/tasks/stream-as-agent) - For receiving tasks assigned to specific agents.

These new features provide instant updates on task creation, status changes,
and completion without the need for polling, and replace the previous polling-based approach:

* **Filtering options**: Focus on specific tasks using type prefix filtering.
* **Heartbeat mechanism**: Verify connection health with configurable heartbeat intervals.
* **Comprehensive event data**: Access full task details including status, description, and metadata.
* **Efficient resource usage**: Reduce network traffic and server load compared to polling.

### StreamTasks

The `StreamTasks` API enables centralized monitoring of all tasks in your Lattice environment regardless of the assigned agent.

**`Golang`**

```go title="Golang"
// Create task stream request
request := &Lattice.TaskStreamRequest{
    HeartbeatIntervalMs:     Lattice.Int(10000),
    ExcludePreexistingTasks: Lattice.Bool(false),
    TaskType: &Lattice.TaskStreamRequestTaskType{
        TaskStreamRequestTaskTypeTaskTypePrefix: &Lattice.TaskStreamRequestTaskTypeTaskTypePrefix{
            TaskTypePrefix: "type.googleapis.com/<your-organization>.tasks",
        },
    },
}

// Start the task stream
stream, err := LatticeClient.Tasks.StreamTasks(ctx, request)
```

### StreamAsAgent

The `StreamAsAgent` API replaces the previous ListenAsAgent method, allowing agents to listen for tasks assigned specifically to them using server-sent events.

**`Golang`**

```go title="Golang"
// Create agent stream request
agentRequest := &Lattice.AgentStreamRequest{
    AgentSelector: &Lattice.EntityIdsSelector{
        EntityIds: []string{entityId},
    },
}

// Start streaming tasks for the agent
agentStream, err := LatticeClient.Tasks.StreamAsAgent(ctx, agentRequest)
```

**`Java`**

```java title="Java"
// Create agent selector
EntityIdsSelector agentSelector = EntityIdsSelector
    .builder()
    .entityIds(Arrays.asList(entityId))
    .build();

// Create agent stream request
AgentStreamRequest agentRequest = AgentStreamRequest
    .builder()
    .agentSelector(agentSelector)
    .build();

// Start streaming tasks for the agent
client.tasks().streamAsAgent(agentRequest)
```

For more information about monitoring tasks, see [Command and operate](/guides/tasks/command-and-operate) in the Lattice SDK guide.

## January 15, 2026

## OAuth 2.0 client credentials for Sandboxes

Lattice now supports machine-to-machine (M2M) authentication using the OAuth 2.0 client credentials flow. This gives you more control over permissions and improved security using short-lived tokens.

> **Existing users**
>
> We continue to support long-lived tokens for existing Lattice deployments while we roll out this new feature.
>
> If you have a pre-existing integration deployed to a production Lattice environment, we encourage you to work with your Anduril representative to determine a timeline for migrating to the OAuth 2.0 client credentials flow.
>
> If you are building a new integration within Lattice Sandboxes, we encourage you to start using the OAuth 2.0 client credentials flow.

### Use OAuth 2.0 client credentials

You can find your **Client ID** and **Client Secret** in the Sandboxes UI under the Resource Credentials section:

* **Lattice Client ID**: This is a unique, public identifier associated with your integration.
* **Lattice Client Secret**: This is the secure credential your integration will use to authenticate with the Lattice environment, proving its identity.

In your integration, use the **Lattice Client ID** and **Lattice Client Secret** to submit requests to the API.

**`Golang`**

```go title="Golang"
clientId := os.Getenv("LATTICE_CLIENT_ID")
clientSecret := os.Getenv("LATTICE_CLIENT_SECRET")

LatticeClient := client.NewClient(
    option.WithClientCredentials(clientID, clientSecret),
    option.WithBaseURL(fmt.Sprintf("https://%s", latticeEndpoint)),
    option.WithHTTPHeader(headers),
)
```

**`Java`**

```java title="Java"
String clientId = System.getenv("LATTICE_CLIENT_ID")
String clientSecret = System.getenv("LATTICE_CLIENT_SECRET");

Lattice client = Lattice.withCredentials(clientId, clientSecret)
    .url(endpoint)
    .addHeader("Anduril-Sandbox-Authorization", "Bearer " + sandboxesToken)
    .build();
```

**`Python`**

```python title="Python"
client_id = os.getenv('LATTICE_CLIENT_ID')
client_secret = os.getenv('LATTICE_CLIENT_SECRET')

client = Lattice(
    base_url=f"https://{lattice_endpoint}",
    client_id=client_id,
    client_secret=client_secret,
    headers={ "anduril-sandbox-authorization": f"Bearer {sandboxes_token}" }
)
```

**`TypeScript`**

```javascript title="TypeScript"
const client = new LatticeClient(
    const clientId = process.env.LATTICE_CLIENT_ID
    const clientSecret = process.env.LATTICE_CLIENT_SECRET

    {
        clientId: clientId,
        clientSecret: clientSecret,
        baseUrl: `https://${latticeEndpoint}`,
        headers: {  "Anduril-Sandbox-Authorization": `Bearer ${sandboxesToken}` }
    }
);
```

For more information about setting up your development environment, see [Set up](/guides/getting-started/set-up) in the *Lattice SDK guide*.

## December 12, 2025

## Updated SDKs

Today we have released new versions of the Lattice SDK in all four languages. This contains the following changes:

* ⚠️ **Breaking change** - This addresses an issue where the [`centerRayPose`](/reference/rest/entities/publish-entity#request.body.sensors.sensors.fieldsOfView.centerRayPose) component on the `Entity` was incorrectly modelled. If you were using this component, you will need to update your code to reference the new fields.
* Dependency updates and other bug fixes

#### SDKs

* [Lattice SDK for Go](https://github.com/anduril/lattice-sdk-go/releases/tag/v4.0.0)
* [Lattice SDK for Java](https://github.com/anduril/lattice-sdk-java/releases/tag/v5.0.0)
* [Lattice SDK for Javascript](https://github.com/anduril/lattice-sdk-java/releases/tag/v4.0.0)
* [Lattice SDK for Python](https://github.com/anduril/lattice-sdk-java/releases/tag/v4.0.0)

## October 27, 2025

## New SDK Versions

Today we have released new major versions of the Lattice SDK in all four languages:

* [Lattice SDK for Go](https://github.com/anduril/lattice-sdk-go/releases/tag/v3.0.0)
* [Lattice SDK for Java](https://github.com/anduril/lattice-sdk-java/releases/tag/v4.0.0)
* [Lattice SDK for JavaScript](https://github.com/anduril/lattice-sdk-java/releases/tag/v3.0.0)
* [Lattice SDK for Python](https://github.com/anduril/lattice-sdk-java/releases/tag/v3.0.0)

This addresses an issue where the [`status`](/reference/rest/entities/publish-entity#response.body.status)
component on the `Entity` was previously incorrectly modelled. If you were using this component, you will need to update your code to reference
the new fields on the message.

## October 3, 2025

## Java SDK v3

The [Lattice SDK for Java v3](https://github.com/anduril/lattice-sdk-java/releases/tag/v3.0.0)
introduces a number of changes:

* ⚠️ **Breaking change** - Alter how enum types are generated to support forward-compatible enums. These now follow a visitor pattern
* Fixes for SSE streaming

**`Before`**

```java title="Before"
switch (event.getEventType().get()) {
    case EVENT_TYPE_PREEXISTING:
        System.out.println("Received pre-existing entity event");
        break;
    default:
        System.out.println("Default case");
        break;
}
```

**`After`**

```java title="After"
event.getEventType().get().visit(new EntityEventEventType.Visitor<Optional<EntityEventEventType>>() {
    @Override
    public Optional<EntityEventEventType> visitEventTypePreexisting() {
        System.out.println("Received pre-existing entity event");
    }

    @Override
    public Optional<EntityEventEventType> visitUnknown(String unknownType) {
        System.out.println("Received pre-existing entity event");
    }
})
```

## September 5, 2025

Updated all Java examples to use the new `addHeader` method for adding authentication headers,
simplifying how Sandbox authentication headers are set in Java applications.

```diff title={"java-headers.diff"}
--- java-client-before.java	2025-09-05 10:00:00
+++ java-client-after.java	2025-09-05 10:30:00
@@ -1,19 +1,11 @@
 import com.anduril.Lattice;
-import okhttp3.OkHttpClient;
 
 public class LatticeClientExample {
     public static void main(String[] args) {
         String endpoint = System.getenv("LATTICE_ENDPOINT");
         String token = System.getenv("ENVIRONMENT_TOKEN");
         String sandboxesToken = System.getenv("SANDBOXES_TOKEN");
-        
-        // Create HTTP client with Sandbox authentication
-        OkHttpClient httpClient = new OkHttpClient.Builder()
-            .addInterceptor(chain -> {
-                return chain.proceed(chain.request().newBuilder()
-                    .header("Anduril-Sandbox-Authorization", "Bearer " + sandboxesToken)
-                    .build());
-            })
-            .build();
-        
+
+        // Create Lattice client with Sandbox authentication
         Lattice client = Lattice.builder()
             .url(endpoint)
             .token(token)
-            .httpClient(httpClient)
+            .addHeader("Anduril-Sandbox-Authorization", "Bearer " + sandboxesToken)
             .build();
     }
 }
```

## Java SDK Improvements

The [Lattice SDK for Java 2.3.0](https://github.com/anduril/lattice-sdk-java/releases/tag/v2.3.0)
introduces a simplified approach for adding authentication headers to API requests:

* Added new `addHeader` method to the Lattice client builder that eliminates the need to create custom `OkHttpClient` instances.
* Updated all Java examples to use this new approach, resulting in cleaner, more maintainable code.
* Removed boilerplate `OkHttpClient` interceptor configuration that was previously required.

## August 11, 2025

The Lattice SDK now supports streaming entity updates in real-time using the REST API across all supported languages:

* Added [`StreamEntities`](/reference/rest/entities/stream-entities) API for establishing persistent connections to stream entity events
* Implemented examples for streaming entities in Go, Java, Python, and TypeScript
* Updated documentation to demonstrate both basic streaming and component filtering

## New features

The new `StreamEntities` API provides several configurable parameters:

* **`preExistingOnly`**: Controls whether to stream only existing entities or include real-time updates.
* **`heartbeatIntervalMS`**: Configures how frequently the server sends heartbeat events.
* **`componentsToInclude`**: Allows filtering which entity components are streamed, reducing bandwidth usage and improving performance.

## Documentation updates

As a part of this release, [Watch entities](/guides/entities/watch) guide has been updated with code examples in all supported languages.
Each example demonstrates both basic entity streaming and filtering specific components, providing common patterns for integrating
real-time entity data into your Lattice apps.

## July 24, 2025

> **Existing developers**
>
> This major version update introduces breaking changes from SDK v1.
> If you are a current Lattice SDK developer, version v1 will continue to work but will no longer be maintained.
> We recommend upgrading to Lattice SDK v2.
>
> Lattice SDK v1 is built to natively support gRPC, while v2 uses OpenAPI to offer a
> more streamlined experience. To choose a migration path that works for you, see
> [migration guide](/reference/overview/versioning/migrating-to-v2).

## New REST SDKs

The Lattice SDK introduces improved access to the Lattice SDK with REST support. Simply
[install the Lattice SDK](/guides/getting-started/set-up#get-the-sdk) in a language of your choice to get started building with Lattice:

**`Go`**

```go title="Go"
package main

import (
    "os"
    "fmt"
    "github.com/anduril/lattice-sdk-go/v2/client"
    "github.com/anduril/lattice-sdk-go/v2/option"
)

func main() {
    latticeEndpoint := os.Getenv("LATTICE_ENDPOINT")
    environmentToken := os.Getenv("ENVIRONMENT_TOKEN")

    client := client.NewClient(
	    option.WithToken(environmentToken),
	    option.WithBaseURL(fmt.Sprintf("https://%s", latticeEndpoint)),
    )

    client.Entities.GetEntity(
	    context.TODO(),
	    "ENTITY_ID",
    )
}
```

**`Java`**

```java title="Java"
package com.example;

import com.anduril.Lattice;

public class Example {
    public static void main(String[] args) {
        Lattice client = Lattice.builder()
            .url(endpoint)
            .token(token)
            .httpClient(httpClient)
            .build();
        Entity entity = client.entities().getEntity(ENTITY_ID);
    }
}
```

**`Python`**

```python title="Python"
from anduril import Lattice

client = Lattice(
    base_url=f"https://{lattice_endpoint}",
    token=environment_token,
)

entity = client.entities.get_entity(
    entity_id=entity_id
)
```

**`TypeScript`**

```js title="TypeScript"
import { LatticeClient } from "@anduril-industries/lattice-sdk";

const client = new LatticeClient(
    {
        baseUrl: `https://${latticeEndpoint}/api/v1`,
        token: `${environmentToken}`,
    }
)
const entity = await client.entities.getEntityById(entityId);
```

## The Buf Schema registry

The Lattice Protobuf definitions are now published, and available from the
[Buf Schema registry](https://buf.build/anduril/lattice-sdk/).

![Shows the Buf schema registry.](/_fern-img/7cf7ebc2f433fec5e77a2b7061b720f89bc2932716d34c05a73360a24cef1943.webp)

Use the Lattice protos and a plugin of your choice, to generate SDK artifacts for your language of choice.
For more information, and to see an example in Go, see [Generate the Lattice SDK for gRPC](/guides/getting-started/set-up#generate-the-sdk-for-grpc).

## Objects API

Lattice now supporting a resilient, distributed binary object store, letting you efficiently
store binary data and relate them to entities in your environment. Some use cases include:

* Creating image thumbnails for tracks in the Lattice UI.
* Maintaining CSV data for entities for implementing vessel manifests, or other relevant entity metadata.

![Lattice UI object store.](/_fern-img/dc72382af2efe25a3f117a76ec39a7aaf531e7d501fadb6d805e24cdab27578b.webp)

The [Objects API](/reference/rest/objects/list-objects) lets you upload, retrieve, and delete objects across
the Lattice mesh. For more information, see [Objects](/guides/objects/overview) in the *Lattice SDK Guide*.