# Standalone Nexus Operations - .NET SDK

> Execute Nexus Operations independently without a Workflow using the Temporal .NET SDK.

> **Pre-release**
> Requires .NET SDK `1.16.0` or above. All APIs are experimental and may be subject to backwards-incompatible changes.

[Standalone Nexus Operations](/standalone-nexus-operation) let you run Nexus Operation Executions independently, without
being orchestrated by a Workflow. Instead of calling a Nexus Operation from within a Workflow Definition using
`Workflow.CreateNexusWorkflowClient<TService>()`, you execute a Standalone Nexus Operation directly from a Nexus Client
created using `ITemporalClient.CreateNexusClient<TService>()`.

Standalone Nexus Operations use the same Nexus Service contract, Operation handlers, and Worker setup as
Workflow-driven Operations — only the execution path differs. See the [Nexus feature guide](/develop/dotnet/nexus/feature-guide)
for details on
[defining a Service contract](/develop/dotnet/nexus/feature-guide#define-nexus-service-contract),
[developing Operation handlers](/develop/dotnet/nexus/feature-guide#develop-nexus-service-operation-handlers), and
[registering a Service in a Worker](/develop/dotnet/nexus/feature-guide#register-a-nexus-service-in-a-worker).

This page focuses on the client-side APIs that are unique to Standalone Nexus Operations:

- [Execute a Standalone Nexus Operation](#execute-operation)
- [Get the result of a Standalone Nexus Operation](#get-operation-result)
- [List Standalone Nexus Operations](#list-operations)
- [Count Standalone Nexus Operations](#count-operations)
- [Run Standalone Nexus Operations with Temporal Cloud](#run-standalone-nexus-operations-temporal-cloud)

> **📝 Note:**
> This documentation uses source code from the
> [.NET Nexus Standalone sample](https://github.com/temporalio/samples-dotnet/tree/main/src/NexusStandaloneOperations).
>

## Prerequisites 

Standalone Nexus Operations are at Pre-release and require a special Temporal CLI build.

### 1. Install and verify the Pre-release Temporal CLI 

The `temporal nexus operation` commands require a Pre-release build of the Temporal CLI. See
[Temporal CLI support](/standalone-nexus-operation#temporal-cli-support) for the platform downloads,
then verify:

```bash
./temporal --version
# temporal version 1.7.4-standalone-nexus-operations
```

Run it as `./temporal` from the directory where you extracted it. The standard `brew install temporal`
build does not include Standalone Nexus Operation support during Pre-release.

### 2. Start a local dev server 

The Pre-release dev server enables Standalone Nexus Operations by default — no dynamic config is
required. Start it with the caller and handler Namespaces pre-created:

```bash
./temporal server start-dev \
  --namespace my-caller-namespace \
  --namespace my-handler-namespace
```

The starter and Worker connect to two different Namespaces (a caller Namespace and a handler
Namespace), mirroring how Nexus crosses Namespace boundaries.

To run the examples on this page against the [.NET sample](https://github.com/temporalio/samples-dotnet/tree/main/src/NexusStandaloneOperations),
create a Nexus Endpoint that routes to the handler Namespace and the Worker's Task Queue:

```bash
./temporal operator nexus endpoint create \
  --name my-nexus-endpoint \
  --target-namespace my-handler-namespace \
  --target-task-queue nexus-handler-queue
```

Start the sample Worker in the handler Namespace:

```bash
TEMPORAL_NAMESPACE=my-handler-namespace dotnet run worker
```

Run the starter in the caller Namespace (from a separate terminal):

```bash
TEMPORAL_NAMESPACE=my-caller-namespace dotnet run starter
```

## Execute a Standalone Nexus Operation 

To execute a Standalone Nexus Operation, first create a
[`NexusClient`](https://dotnet.temporal.io/api/Temporalio.Client.NexusClient.html) using
`ITemporalClient.CreateNexusClient<TService>()`, bound to a specific Nexus Endpoint and Service. The endpoint must be
pre-created on the server. Then call `ExecuteNexusOperationAsync()` from application code (for example, a starter
program), not from inside a Workflow Definition.

`ExecuteNexusOperationAsync` is a shortcut that starts the Operation and waits for the result. If you need a handle to
the Operation while it runs, call `StartNexusOperationAsync` instead — it returns a
[`NexusOperationHandle`](https://dotnet.temporal.io/api/Temporalio.Client.NexusOperationHandle.html) that you can use to
get the result, describe, cancel, or terminate the Operation. `Id` is required on
[`NexusOperationOptions`](https://dotnet.temporal.io/api/Temporalio.Client.NexusOperationOptions.html);
`ScheduleToCloseTimeout` is optional and defaults to the maximum allowed by the Temporal server.

```csharp
var nexusClient = client.CreateNexusClient<IHelloService>("my-nexus-endpoint");

var result = await nexusClient.ExecuteNexusOperationAsync(
    svc => svc.Echo(new("Nexus Echo 👋")),
    new("unique-operation-id")
    {
        ScheduleToCloseTimeout = TimeSpan.FromSeconds(10),
    });
```

You can also use the untyped overload that takes the Operation name as a string:

```csharp
var nexusClient = client.CreateNexusClient("my-nexus-endpoint", "HelloService");

var handle = await nexusClient.StartNexusOperationAsync<IHelloService.EchoOutput>(
    "Echo",
    new IHelloService.EchoInput("Nexus Echo 👋"),
    new("unique-operation-id")
    {
        ScheduleToCloseTimeout = TimeSpan.FromSeconds(10),
    });
```

Or use the Temporal CLI to execute a Standalone Nexus Operation:

```bash
./temporal nexus operation execute \
  --namespace my-caller-namespace \
  --endpoint my-nexus-endpoint \
  --service HelloService \
  --operation Echo \
  --operation-id my-echo-op \
  --input '{"Message":"hello"}'
```

## Get the result of a Standalone Nexus Operation 

Use `NexusOperationHandle<TResult>.GetResultAsync()` to await the Operation's completion and retrieve its result. This
works for both synchronous and asynchronous (Workflow-backed) Operations.

```csharp
var output = await handle.GetResultAsync();
logger.LogInformation("Operation result: {Message}", output.Message);
```

If the Operation completed successfully, the result is deserialized into the handle's result type. If the Operation
failed, a `NexusOperationFailedException` is thrown.

You can also recover a handle for an already-started Operation using `GetNexusOperationHandle<TResult>()` on the
Temporal Client:

```csharp
var handle = client.GetNexusOperationHandle<IHelloService.EchoOutput>("unique-operation-id");
var output = await handle.GetResultAsync();
```

Or use the Temporal CLI to wait for a result by Operation ID:

```bash
./temporal nexus operation result --namespace my-caller-namespace --operation-id my-echo-op
```

## List Standalone Nexus Operations 

Use [`ITemporalClient.ListNexusOperationsAsync()`](https://dotnet.temporal.io/api/Temporalio.Client.ITemporalClient.html#Temporalio_Client_ITemporalClient_ListNexusOperationsAsync_System_String_Temporalio_Client_NexusOperationListOptions_)
to list Standalone Nexus Operation Executions that match a [List Filter](/list-filter) query. The call returns an
`IAsyncEnumerable<NexusOperationExecution>` that you can iterate with `await foreach`.

Note that `ListNexusOperationsAsync` is called on the base `ITemporalClient`, not on the `NexusClient`.

```csharp
await foreach (var execution in client.ListNexusOperationsAsync(
    "Endpoint = 'my-nexus-endpoint'"))
{
    logger.LogInformation(
        "OperationID: {Id}, Operation: {Operation}, Status: {Status}",
        execution.OperationId, execution.Operation, execution.Status);
}
```

The query string accepts [List Filter](/list-filter) syntax. For example,
`"Endpoint = 'my-endpoint' AND Status = 'Running'"`.

Or use the Temporal CLI:

```bash
./temporal nexus operation list --namespace my-caller-namespace --query 'Endpoint = "my-nexus-endpoint"'
```

## Count Standalone Nexus Operations 

Use [`ITemporalClient.CountNexusOperationsAsync()`](https://dotnet.temporal.io/api/Temporalio.Client.ITemporalClient.html#Temporalio_Client_ITemporalClient_CountNexusOperationsAsync_System_String_Temporalio_Client_NexusOperationCountOptions_)
to count Standalone Nexus Operation Executions that match a [List Filter](/list-filter) query.

Note that `CountNexusOperationsAsync` is called on the base `ITemporalClient`, not on the `NexusClient`.

```csharp
var count = await client.CountNexusOperationsAsync(
    "Endpoint = 'my-nexus-endpoint'");
logger.LogInformation("Total Nexus operations: {Count}", count.Count);
```

Or use the Temporal CLI:

```bash
./temporal nexus operation count --namespace my-caller-namespace --query 'Endpoint = "my-nexus-endpoint"'
```

## Run Standalone Nexus Operations with Temporal Cloud 

Standalone Nexus Operations work against Temporal Cloud with the same code — only the client connection options change.
For full details on connecting to Temporal Cloud, including Namespace creation, Nexus Endpoint setup, certificate
generation, and authentication options, see
[Make Nexus calls across Namespaces in Temporal Cloud](/develop/dotnet/nexus/feature-guide#nexus-calls-across-namespaces-temporal-cloud)
and [Connect to Temporal Cloud](/develop/dotnet/client/temporal-client#connect-to-temporal-cloud).
