# Models and credits

> List the AI models a Nodaro instance offers with client.models, read your credit balance, and look up the price of a model before you run it.

Source: https://nodaro.ai/docs/developers/sdk/models-and-credits

**`client.models`** returns the catalog of AI models a Nodaro instance offers, and **`client.credits`** returns your credit balance and the price of any model. Use them together to show users which models they can pick and what each run costs. The methods call the same endpoints as the [Credits REST API](https://nodaro.ai/docs/developers/api/credits). Prices and balances exist on Nodaro Cloud; self-hosted Community and Business installs have no credit system. See [Credits](https://nodaro.ai/docs/concepts/credits).

## Methods

| Method | What it does |
| --- | --- |
| [`models.list(opts?)`](#modelslistopts) | List the models, grouped by kind and maker |
| [`credits.balance()`](#creditsbalance) | Read your credit balance and tier |
| [`credits.modelCosts(ids)`](#creditsmodelcostsids) | Look up the credit price of up to 50 models or variants |

## client.models

### models.list(opts?)

Returns the model catalog (`GET /v1/models`), grouped by kind (image, video, audio) and by maker. Each model has its capabilities, its credit prices on Nodaro Cloud, and short prompt tips. The endpoint is public, and the server caches the answer for 5 minutes. The MCP `list_models` tool returns the same data.

```ts
list(opts?: {
kind?: "image" | "video" | "audio"
mode?: string
family?: string
featuredOnly?: boolean
}): Promise<ModelsListResult>
```

<TypeTable
type={{
kind: { type: '"image" | "video" | "audio"', description: "Only models of this kind." },
mode: { type: 'string', description: "Only models with this mode, such as t2i (text to image), t2v (text to video) or i2v (image to video)." },
family: { type: 'string', description: "Only models of this maker, such as Google." },
featuredOnly: { type: 'boolean', default: 'false', description: "Only the featured models." },
}}
/>

```ts
const catalog = await client.models.list({ kind: "video", mode: "i2v" })

for (const section of catalog.sections) {
for (const family of section.families) {
for (const model of family.models) {
console.log(family.family, model.id, model.durations, model.pricing?.[0]?.credits)
}
}
}
```

The result has `sections`, one per kind, each with `families` of models; `recommendations`, lists of model ids for common jobs; and `totalModels`. Each model has these fields:

| Field | Type | Description |
| --- | --- | --- |
| `id` | `string` | The model id, for the `provider` parameter of a node run. |
| `label`, `description` | `string` | The display name and a short description. |
| `modes` | `string[]` | What the model does, such as `t2i`, `i2i`, `t2v` or `i2v`. |
| `useCases` | `string[]` | Jobs the model suits. |
| `aspectRatios`, `resolutions`, `qualities`, `durations` | arrays | The values the model accepts, where they apply. |
| `features` | `string[]` | Extra capabilities. |
| `pricing` | `{ identifier, credits, note? }[]` | The credit price of each variant. Nodaro Cloud only. |
| `featured` | `boolean` | Whether the model is featured. |
| `promptTips` | `string[]` | Short prompting advice for the model. |
| `doctrineCovered` | `boolean` | `true` only when Nodaro has sourced prompting guidance for the model's family. Show a "maker guidance" badge only when it is `true`. |

The same catalog is on the [Models](https://nodaro.ai/docs/models) pages. For advice on which model to use, read [Choosing a model](https://nodaro.ai/docs/guides/choosing-models).

## client.credits

### credits.balance()

Returns your credit balance and tier (`GET /v1/user/credits`). Throws `UnauthorizedError` when no user is signed in.

```ts
balance(): Promise<UserBalance>
```

```ts
const balance = await client.credits.balance()
console.log(`${balance.total} credits (${balance.effectiveTier})`)
```

| Field | Type | Description |
| --- | --- | --- |
| `total` | `number` | The credits you can spend now. |
| `subscription` | `number` | Credits from the current subscription period. |
| `topup` | `number` | Credits you bought separately. |
| `dailySpent` | `number` | Credits spent today. |
| `dailyLimit` | `number \| null` | The daily spending limit, or `null` for none. |
| `monthlyAllocation` | `number` | Credits granted per billing period. |
| `tier` | `string` | The stored subscription tier, such as `"free"` or `"pro"`. |
| `effectiveTier` | `string` | The tier actually applied. `"payg"` means pay-as-you-go: no subscription, but bought credits, with every model, no watermark and no daily limit. |
| `features` | `Record<string, unknown>` | The features of the tier. |
| `periodEnd` | `string \| null` | The end of the billing period, as an ISO 8601 date. |
| `appCreditsAllowance` | `number` | Credits earned by running apps, on the free tier. |
| `externalWallet` | `{ available: number \| null }` | Present when the deployment uses a shared external wallet. `null` means the amount is unavailable. Do not show `total` in its place. See [External wallet](https://nodaro.ai/docs/developers/external-wallet). |

Prefer `effectiveTier` over `tier` when you decide what to show.

### credits.modelCosts(ids)

Looks up the credit price of models and their variants in one call (`POST /v1/credits/model-costs`). It checks up to the first 50 identifiers.

```ts
modelCosts(ids: string[]): Promise<{
data: Record<string, number>
missing: string[]
errors: string[]
}>
```

<TypeTable
type={{
ids: { type: 'string[]', required: true, description: "Price identifiers: a model id, such as nano-banana-pro, or a model id with its variant, such as nano-banana-pro:4K or seedance-2-fast:8s:720p." },
}}
/>

```ts
const { data, missing } = await client.credits.modelCosts([
"nano-banana-pro",
"nano-banana-pro:4K",
"seedance-2-fast:8s:720p",
])
console.log(data["nano-banana-pro:4K"])
if (missing.length) console.warn("No price for:", missing)
```

- **`data`** maps each priced identifier to its credit price.
- **`missing`** lists identifiers that have no price. Show a dash for them.
- **`errors`** lists identifiers whose lookup failed. The other prices still arrive.

The identifiers of each model are in the `pricing` field of [`models.list()`](#modelslistopts) and on each model's page. Settings such as quality, resolution and duration change the price, so name the variant the run will use. The price at run time is checked again when the run starts, so this call is a preview.

## Show models with their prices

Build a model picker for one node, with the price next to each model:

```ts
const { data: node } = await client.nodes.get("generate-video")
const { data: prices } = await client.credits.modelCosts(node.providers ?? [])

const options = (node.providers ?? []).map((id) => ({
id,
price: prices[id] ?? null, // null: no price on this instance
}))
```

Omit `provider` in a run to use the node's default model. When a user picks a model, send its id as `provider` to [`client.nodes.runAndWait()`](https://nodaro.ai/docs/developers/sdk/nodes).

## Frequently asked questions

### How do I list the models Nodaro offers from code?

Call client.models.list(). It returns every image, video and audio model grouped by kind and maker, with modes, aspect ratios, resolutions, durations and, on Nodaro Cloud, credit prices.

### How do I find the price of one model before running it?

Call client.credits.modelCosts with the model's price identifiers, such as nano-banana-pro or nano-banana-pro:4K. The data field maps each identifier to its credit price.

### How do I check my credit balance with the SDK?

Call client.credits.balance(). The total field is the number of credits available, split into subscription and top-up credits.

### Do self-hosted installs have credit prices?

No. Self-hosted Community and Business installs have no credit system, so model prices and credit costs are left out of their answers.
