> For the complete documentation index, see [llms.txt](https://dnotifier.gitbook.io/product-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dnotifier.gitbook.io/product-docs/ai/multi-models.md).

# Multi-model providers

![DNotifier as an AI orchestration layer between your app and LLM providers](https://3137823855-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzqWLtTQbwVjn3IbogO5j%2Fuploads%2Fgit-blob-3dbf28f1250cdbe2394d142e1e6446398be360c6%2Forchestration-layer.jpg?alt=media)

Most teams don't want to hardcode OpenAI forever. You might use Claude for long writing, Gemini for cheap classification, Bedrock in AWS accounts, or Ollama on a laptop.

In DNotifier the split is simple:

* **Portal** — wire up how DNotifier talks to each provider (your API key, a cloud account, an Ollama URL, or DNotifier-billed usage when that's on your plan).
* **SDK** — pick `provider` + `model` on `sendAI` (or bake defaults into an agent).

```
Projects → AI Studio → Providers → (OpenAI / Anthropic / …)
                │
                ▼
Your app: sendAI({ provider: "open_ai", model: "gpt-4o", … })
```

Don't put provider secrets in your repo. The SDK never needs them; it only names which portal connection and which model id to use.

## Keys vs DNotifier subscription

Two common setups:

1. **Your key** — you already have an OpenAI / Anthropic / etc. account. Paste the key (and endpoint bits if needed) under **Projects → AI Studio → Providers** in [app.dnotifier.com](https://app.dnotifier.com).
2. **DNotifier subscription** — for providers that support it, turn on usage through your DNotifier plan so you aren't managing that upstream key yourself.

Not every provider offers both options on every plan. Set up the connection first, then call the SDK.

## Provider strings

These are the `provider` values the SDK expects. Model ids are whatever that connection exposes (gpt-4o, a Claude snapshot id, a Bedrock id, an Ollama tag, …).

| Provider      | `provider`      | Docs                                                                                    |
| ------------- | --------------- | --------------------------------------------------------------------------------------- |
| OpenAI        | `open_ai`       | [OpenAI integration](/product-docs/ai/multi-models/open-ai-integration.md)              |
| Anthropic     | `anthropic`     | [Anthropic integration](/product-docs/ai/multi-models/anthropic-integration.md)         |
| Google Gemini | `google_gemini` | [Google Gemini integration](/product-docs/ai/multi-models/google-gemini-integration.md) |
| Hugging Face  | `hugging_face`  | [Hugging Face integration](/product-docs/ai/multi-models/hugging-face-integration.md)   |
| Perplexity    | `perplexity`    | [Perplexity integration](/product-docs/ai/multi-models/perplexity-integration.md)       |
| Azure AI      | `azure_ai`      | [Azure AI integration](/product-docs/ai/multi-models/azure-ai-integration.md)           |
| AWS Bedrock   | `aws_bedrock`   | [AWS Bedrock integration](/product-docs/ai/multi-models/aws-bedrock-integration.md)     |
| Ollama        | `ollama`        | [Ollama local integration](/product-docs/ai/multi-models/ollama-local-integration.md)   |

Spell the string exactly like the table. Typos fail at runtime.

Model names for each provider are listed under [LLM providers](/product-docs/integrations/llm-providers.md).

## Calling it from code

Skip `provider` / `model` and you get the project default from auth (`current_model`). Pass them when you want a specific stack.

{% tabs %}
{% tab title="JavaScript" %}

```js
await notifier.sendAI({
  senderId: USER_ID,
  provider: "open_ai",
  model: "gpt-4o",
  message: {
    useKnowledgeBase: false,
    messages: [{ role: "user", content: "Reply with one word: ok" }],
  },
  saveHistory: true,
});
```

{% endtab %}

{% tab title="Python" %}

```python
await notifier.send_ai(
    sender_id=user_id,
    provider="open_ai",
    model="gpt-4o",
    message={
        "useKnowledgeBase": False,
        "messages": [{"role": "user", "content": "Reply with one word: ok"}],
    },
    save_history=True,
)
```

{% endtab %}

{% tab title="Dart" %}

```dart
await notifier.sendAI(
  senderId: userId,
  provider: 'open_ai',
  model: 'gpt-4o',
  message: {
    'useKnowledgeBase': false,
    'messages': [
      {'role': 'user', 'content': 'Reply with one word: ok'},
    ],
  },
  saveHistory: true,
);
```

{% endtab %}
{% endtabs %}

If an agent always uses the same stack, set it once:

```js
const writer = DNotifier.defineAgent({
  name: "writer",
  provider: "anthropic",
  model: "claude-sonnet-4-20250514",
  async run(ctx) {
    // no provider/model here — inherits from the agent
    return ctx.sendAI({
      message: { text: ctx.input.prompt },
      saveHistory: false,
    });
  },
});
```

A later `ctx.sendAI({ provider, model })` still wins over the agent defaults.

Rough priority: **this call** → **agent** → **project default**.

## Getting unstuck

1. App exists in the portal; AI is on for the plan.
2. Provider connection saved under **Projects → AI Studio → Providers**.
3. Model id you pass actually exists for that connection.
4. `connect()` succeeded and `aiEnabled` is true.
5. Then hit `sendAI` with the right `provider` / `model`.

Step-by-step walks: [Tutorials](/product-docs/tutorials/tutorials.md).

Also useful: [Send a prompt](/product-docs/ai/send-prompt.md), [defineAgent](/product-docs/workflows-and-agents/define-agent.md), [observability](/product-docs/observability/ai-workflow-observability.md) (steps can show which model ran).
