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

# Manual tracking

> Track custom providers, tool calls, and multi-step workflows.

Use manual runs when you need explicit control or when the provider is not OpenAI or Anthropic.

For normal OpenAI or Anthropic calls, prefer `margovia.openai(client)` or `margovia.anthropic(client)`. Those tracked clients can read provider usage and report cost automatically. Use wrappers or explicit provider helpers when you need to migrate existing call sites.

## Start and complete a run

```ts theme={null}
import { Margovia } from "@margovia/sdk";

const margovia = new Margovia();

const run = await margovia.startRun({
  name: "generate_report",
  userId: "user_123",
  customerId: "workspace_123",
  customerName: "Acme Inc.",
  customerPlan: { name: "enterprise", monthlyUsd: 499 },
  properties: {
    reportType: "weekly_margin"
  }
});

await run.trackCost({
  provider: "serpapi",
  label: "search_tool",
  costUsd: 0.01,
  status: "success"
});

await run.complete({ outcome: "report_generated" });
```

Manual runs stay `running` until you explicitly call `run.complete(...)` or `run.fail(...)`. Cost events alone do not close the run.

## Track failures

```ts theme={null}
try {
  await doWork();
  await run.complete({ outcome: "done" });
} catch (error) {
  await run.fail({
    error: error instanceof Error ? error.message : "Unknown error"
  });
  throw error;
}
```

## Use `track` for workflow lifecycle

`track` wraps a function, opens a run, and completes or fails it automatically. It does not read provider token usage by itself.

```ts theme={null}
const result = await margovia.track({
  name: "generate_report",
  customerId: "workspace_123",
  outcome: "report_generated",
  fn: async () => generateReport()
});
```

`track` is the safest option for custom workflows because it automatically completes the run on success and fails it when `fn` throws.

If the function calls OpenAI or Anthropic, use wrapped clients inside:

```ts theme={null}
const openai = margovia.wrapOpenAI(new OpenAI());

await margovia.track({
  name: "generate_report",
  customerId: "workspace_123",
  outcome: "report_generated",
  fn: () => openai.chat.completions.create({ model: "gpt-5-mini", messages })
});
```

Do not use `track` around a raw provider client unless you also report cost manually.

## Track multiple provider calls

Use one manual run when several calls belong to the same user-facing workflow.

```ts theme={null}
const run = await margovia.startRun({
  name: "research_report",
  customerId: `workspace_${workspace.id}`,
  customerName: workspace.name,
  customerPlan: { name: workspace.plan, monthlyUsd: workspace.planMonthlyUsd }
});

try {
  await run.step("outline", () => createOutline());
  await run.step("source_search", () => searchSources());
  await run.step("final_draft", () => draftReport());

  await run.complete({ outcome: "report_generated" });
} catch (error) {
  await run.fail({
    error: error instanceof Error ? error.message : "Unknown error"
  });
  throw error;
}
```

`run.step(...)` attaches wrapped provider calls to the existing run instead of creating separate runs.

## Customer IDs

Send a stable, namespaced customer ID:

```ts theme={null}
customerId: `workspace_${workspace.id}`
customerId: `org_${organization.id}`
customerId: `stripe_${stripeCustomer.id}`
```

Avoid raw IDs like `"1"` unless that is the stable ID you use across your whole system. Margovia will not rewrite the value.
