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

# Execution

> Call a Flow from your app, threading traces, feedback, and signals by correlation id

The execution surface is what your app calls to actually **run a Flow**. Authentication is the **trigger secret** for the Flow you're calling — no PAT needed here.

## `flows.run`

```ts theme={null}
const r = await nora.flows.run("support", "How does coverage work?", {
  variables: { plan: "pro" },   // {{plan}} override
  model: "gpt-4o",              // optional agent model override
  idempotencyKey: "req_123",    // optional
});

r.traceId;   // always present — even when the run fails
r.status;    // "ok" | "partial" | "needs_review" | "failed" | string (extensible for new server-side states)
r.outputs;   // populated even on partial
r.notices;   // things that constrained the run but weren't failures (e.g. tool-call cap hit)
r.failure;   // present only when status === "failed": { code, message, retryable, at }
```

Options:

* `variables` — override Flow variables per call. Same shape as the trigger `variables` field.
* `model` — override the agent model for this run only (respects your workspace routing / BYOK).
* `idempotencyKey` — send the same key twice and the server returns the first execution instead of running again.

**Run-result failures don't throw.** The SDK gives you back a `traceId` and any partial outputs so you can log, retry, or degrade — always inspect `.status` and `.failure` on the return value. Transport / auth / request errors do throw; see [Errors](/sdk/errors).

## `newTraceRef`

Weave traces, signals, and feedback through your own logs with a correlation id you can assert before the trace exists.

```ts theme={null}
const ref = nora.newTraceRef();
myLogger.info({ ref, event: "flow.about-to-run" });

const r = await nora.flows.run("support", input, { /* ... */ });
myLogger.info({ ref, traceId: r.traceId, status: r.status });
```

Use this when you want the ref in your application logs (or a Slack message) before you have the `traceId` from the server response.

## Common patterns

### Degrade on partial

```ts theme={null}
const r = await nora.flows.run("support", input);

if (r.status === "failed") {
  return { text: fallbackAnswer, traceId: r.traceId, failure: r.failure };
}
if (r.status === "needs_review") {
  await queueForReview(r.traceId);
  return { text: r.outputs.answer, review: true };
}
return { text: r.outputs.answer };
```

### Idempotent retries

If you're retrying at the HTTP layer (e.g. because your handler timed out but the server may already be processing), pass the same `idempotencyKey` on the retry. The server returns the original execution's `traceId` instead of starting a new run.

```ts theme={null}
const key = `req_${requestId}`;
try {
  return await nora.flows.run("support", input, { idempotencyKey: key });
} catch (e) {
  if (isTransient(e)) return await nora.flows.run("support", input, { idempotencyKey: key });
  throw e;
}
```

### Surface notices, not failures

`notices[]` are things that shaped the run but aren't failures (tool-call cap hit, retrieval returned nothing, output truncated). Log them or show them to your admin UI, but don't surface as errors to end users.

## MCP / CLI equivalents

While the SDK is [pre-publish](/sdk/overview), the same operation is available via MCP and the CLI:

```bash theme={null}
# MCP tool — authenticated by PAT / session, no trigger secret needed
run_flow { slug, input, variables?, model?, threadId?, userId?, test? }

# CLI
nora flows run <slug> --input "How does coverage work?" \
  [--variables '{"plan":"pro"}'] [--model gpt-4o] [--test]
```

Both return the same envelope as `flows.run` — `traceId` · `status` · `outputs` · `notices` · `failure`.
