---
title: AI calls
description: Call Claude, GPT, Gemini or an OpenAI-compatible model from an app with crow.ai, using a key you, your company or the app brings, with limits and costs you control.
---

# AI calls

`crow.ai` lets a page call an AI model without putting a key in the page. By default it uses **Crow Nest AI**: nothing to set up, no key to find. You can also bring your own key.

## Crow Nest AI

An app that turns AI on in `crow.json` works as soon as it's published. Crow Nest makes the call for you and adds what it used to your monthly bill, at cost plus 15%. The first $1 each month is included.

- **Who can use it.** A personal workspace needs a paid plan with a card (Flat or Pay as you go). An organization or company needs billing set up. Without that, calls answer `ai_needs_billing` and the app's owner is told to add a card.
- **The cap.** Each workspace has a monthly cap on AI spend, $25 unless you change it (Settings, or the organization's Billing page; 0 turns Crow Nest AI off). You get an email at 80% and at 100%. At 100%, calls answer `ai_cap_reached` until next month or a higher cap.
- **Models.** `anthropic/claude-haiku-5.5` (fast, the default), `anthropic/claude-sonnet-5.5` (balanced) and `anthropic/claude-opus-5.5` (strongest). The app's AI page lists them too. Pass one of their ids as `model`; any other id answers a 400 that names the allowed ones.
- **Organizations.** Admins can switch Crow Nest AI off for everyone in the Policy page.
- **Privacy.** Prompts and replies go to the model's maker and are never stored by Crow Nest. We keep counts and costs only.

Apps published before Crow Nest AI that had AI on but no key switch to it on their next publish, and the publish reply says so.

## Bring your own key

If you'd rather use your own account, add a key. Then the provider bills that key and Crow Nest adds nothing.

## 1. Add a key

Ask your AI to add an AI key. It uses the `ai_key` tool, which asks you for the key privately; never paste a key into the chat. You can also add one in the dashboard under Settings, AI keys. Crow Nest works out the provider from the key: Anthropic, OpenAI, Google, or an OpenAI-compatible service.

| Key scope | Belongs to | Who adds it |
| --- | --- | --- |
| Personal | You; used by apps you own | You |
| Company | Your organization or company | Admins |
| App | One app | The app's owner |

Keys are stored encrypted on the server and never shown again.

## 2. Choose which key the app uses

Ask your AI to set it (the `tool_ai` tool) or use the app's AI page in the dashboard: `crow` (Crow Nest AI, the default), `company`, `mine` (your personal key), `tool` (a key saved on the app) or `none`.

> **Important** Using your own key on an app other people can open means their calls are billed to you. Crow Nest asks you to accept that warning first, and shows the same warning when you later share the app more widely.

## 3. Turn it on in crow.json

```json
{ "ai": { "who": "viewers", "perViewerPerMinute": 10, "dailyLimit": 500 } }
```

`who` is `owner`, `viewers`, or `public` (public apps only). `perViewerPerMinute` and `dailyLimit` cap use.

## 4. Call it

```js
const r = await crow.ai.chat({
  messages: [{ role: "user", content: "Summarize this: ..." }],
  system: "You are concise.",      // optional
  model: "claude-sonnet-5-5",      // optional; the key's default model otherwise
  maxTokens: 1024,                 // optional, at most 8192
});
r.text;    // the answer
r.usage;   // { inputTokens, outputTokens }

try {
  for await (const chunk of crow.ai.stream({ messages })) out.textContent += chunk;   // streamed text
} catch (e) {
  // e.code "stream_interrupted": the answer was cut off part way. Keep what arrived and offer a Retry.
}
```

## Errors

`ai_not_enabled` (no `ai` in crow.json), `ai_no_key` (no key for this app), `ai_key_needs_ack` (the owner hasn't accepted the cost warning), `ai_needs_billing` (Crow Nest AI without a card or billing), `ai_cap_reached` (the monthly cap), `rate_limited`.

A stream can also stop part way: `stream_interrupted` when the connection drops, or `ai_provider_error` when the model's provider cuts the answer off. The pieces that arrived stay; the loop throws instead of ending, so an app can tell a cut-off answer from a finished one.

## Seeing costs

Settings and the organization's Billing page show what Crow Nest AI cost this month, what's included and the cap. The app's page in the dashboard shows AI calls, tokens and estimated cost per key. Company admins see the same for company keys.

## From server code

Server code calls the same models with `env.CROW.ai.chat(...)`, under the same key setting and limits. See [Server code](/server-code).
