---
title: "API Overview"
description: "The Nuabase API: the Nua.direct() constructor, the get() and list() methods, results, and errors."
canonical: "https://nuabase.com/docs/api/"
---

> Documentation index: https://nuabase.com/llms.txt

The Nuabase API has one constructor and two methods: `nua.get()` produces a single value, and `nua.list()` produces one value per row of an array.

## `Nua.direct(config)`

Creates a client. The config takes either `localAgent` or `providers`, not both:

```typescript
import { Nua, z } from 'nuabase';
import { findLocalAgent } from 'nuabase/local-agent';

// A coding agent CLI on this machine
const nua = Nua.direct({ localAgent: await findLocalAgent() });

// LLM provider APIs, with an optional default model
const nua = Nua.direct({
  providers: { openrouter: { apiKey: process.env.OPENROUTER_API_KEY! } },
  model: { alias: 'fast' },
});
```

| Option | Description |
|--------|-------------|
| `localAgent` | A `LocalAgent` from `localAgent()` or `findLocalAgent()` in `nuabase/local-agent`. See [Headless Coding Agent API](/docs/local-agent.md). |
| `providers` | API keys by provider: `{ groq?, cerebras?, gemini?, openrouter?, deepseek? }`, each `{ apiKey: string }`. See [LLM Provider APIs](/docs/direct.md). |
| `model` | Default model for a `providers` client: `{ alias }` or `{ provider, model }`. Defaults to `{ alias: 'fast' }`. A local agent's default model is set on the agent instead. |

## Methods

| Method | Returns | Description |
|--------|---------|-------------|
| [`nua.get(prompt)`](/docs/api/get.md) | `CastResult<string>` | A plain string answer. |
| [`nua.get(prompt, options)`](/docs/api/get.md) | `CastResult<z.infer<S>>` | A single value matching your schema. |
| [`nua.list(prompt, options)`](/docs/api/list.md) | `CastResult<Row[]>` | One value per input row, each tagged with its primary key. |

## Options

| Option | Used by | Description |
|--------|---------|-------------|
| `input` | `get`, `list` | Context data for `get` (any JSON-serializable value); an array of objects for `list`. |
| `output` | `get`, `list` | `{ name, schema }`: a name for the generated value and its Zod schema. |
| `primaryKey` | `list` | Name of a unique ID property on each input object. Each output row carries it. |
| `model` | `get`, `list` | Overrides the client's default model for this call: `{ alias }` or `{ provider, model }`. |

Keep `prompt` the same across calls and put what varies in `input`. Providers cache the start of a request, and Nuabase puts the prompt and schema first. See [prompt caching](/docs/how-it-works.md#prompt-caching).

## Results

Every call resolves to a `CastResult`, a union you narrow with `result.success`:

```typescript
const result = await nua.get('Extract the address', {
  input: 'Ship to 123 Main St, Springfield, IL 62701',
  output: { name: 'address', schema: AddressSchema },
});

if (result.success) {
  result.data;      // z.infer<typeof AddressSchema>
  result.usage;     // token counts
  result.model;     // "claude-code:haiku", "openrouter:z-ai/glm-5.3-flash", ...
  result.latencyMs; // wall-clock time including retries
  result.meta;      // engine, schemaEnforcement, provider or agent, model
} else {
  result.reason;    // why it failed, in the agent's or provider's words
  result.attempts;  // attempts made, 0 if none was
  result.error;     // a one-line summary for logs
  result.latencyMs;
}
```

| Field | Present when | Description |
|-------|--------------|-------------|
| `data` | `success: true` | The answer as parsed by your schema (or a `string`), with defaults filled in and transforms applied. |
| `usage` | `success: true` | `promptTokens`, `completionTokens`, `totalTokens`, plus `promptCacheReadTokens` and `promptCacheWriteTokens` when the provider reports them. |
| `model` | `success: true` | What answered: `provider:model` or `agent:model`. |
| `meta` | `success: true` | `engine` (`'http'` or `'local-agent'`), `schemaEnforcement` (`'native'` or `'in-prompt'`), `provider` or `agent`, `model`, and for agents `costUsdEstimate`. |
| `reason` | `success: false` | Why the last attempt failed, in the provider's or agent's own words where it gave any. When the answer didn't fit your schema, it starts with `Validation failed:` and includes the model's raw response. When no attempt was made, why not. |
| `attempts` | `success: false` | How many attempts were made: up to 3, or 0 when the call was refused before any. |
| `error` | `success: false` | A one-line summary for logs: the attempts made and why the last one failed. |
| `latencyMs` | Always | Total time in milliseconds, including retries. |
| `source` | Always | Always `'direct'`: every call runs in your process. |

See [Types](/docs/api/types.md) for the full type definitions.

## Errors

Nuabase separates failures of the LLM call from mistakes in your code.

**Returned as `success: false`.** These never throw:

- Network errors, agent timeouts, rate limits, and exhausted quota
- An invalid API key, or an agent that isn't logged in
- A model that can't run on the client: an alias with no configured provider, an unconfigured provider, or a provider model on a local agent
- Output your schema still rejects after retries
- For `list()`, an input row that isn't an object, or that lacks the `primaryKey` property

A model the client can't run and an invalid `list()` row are refused before any attempt, with `attempts: 0`.

**Thrown, before anything is sent:**

- An empty or non-string prompt
- A non-array `input` passed to `list()`
- An empty `primaryKey`
- A Zod schema with a type JSON Schema can't express, such as `z.date()` or `z.bigint()`

`localAgent()` also throws when the CLI isn't on `PATH`, and `findLocalAgent()` rejects when no agent is installed and logged in.
