# How the Open Notebook Connection Tester Validates Provider Credentials

> Learn how the Open Notebook connection tester validates provider credentials by sending HTTP requests to provider endpoints and analyzing responses for authentication.

- Repository: [Luis Novo/open-notebook](https://github.com/lfnovo/open-notebook)
- Tags: how-to-guide
- Published: 2026-06-07

---

**The connection tester validates provider credentials by executing lightweight HTTP requests to provider-specific endpoints like `/models` or `/api/tags`, analyzing HTTP status codes and JSON payloads to confirm authentication while mapping technical errors to user-friendly messages.**

The `lfnovo/open-notebook` repository implements a robust credential validation system in [`open_notebook/ai/connection_tester.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/connection_tester.py) that verifies AI provider connectivity before expensive operations begin. This module distinguishes between managed cloud endpoints, local instances, and generic providers through targeted validation strategies that minimize costs while ensuring reliable authentication checks.

## Provider-Specific Validation Workflows

The connection tester implements distinct validation logic for different provider categories based on their API architectures and endpoint capabilities.

### Azure OpenAI Validation

For Azure OpenAI deployments, the system uses `_test_azure_connection` to send a GET request to `{endpoint}/openai/models?api-version={version}` with the `api-key` header. A successful HTTP 200 response containing any model list—even an empty array—indicates functional credentials. The function parses the response to count available models and report specific deployment names to the user.

### Ollama Local Instance Checks

Local Ollama servers are validated via `_test_ollama_connection`, which queries `{base_url}/api/tags`. The tester confirms connectivity when the response contains a `models` array, returning the exact count of available local models. This approach requires no API key authentication and works exclusively with self-hosted infrastructure.

### OpenAI-Compatible Endpoints

Generic OpenAI-compatible providers use `_test_openai_compatible_connection` to send GET requests to `{base_url}/models`, optionally including an `Authorization: Bearer` header when API keys are configured. Success requires an HTTP 200 status and a JSON response containing a `data` array listing available models.

### Generic Cloud Provider Testing

For providers like Anthropic, Google, Groq, Mistral, DeepSeek, XAI, OpenRouter, Voyage, ElevenLabs, and Deepgram, the tester cannot rely on model listing endpoints. Instead, it uses the `test_individual_model` function to call the provider's cheapest model endpoint—defined in the internal `TEST_MODELS` configuration—with minimal payloads. Language models receive a simple `"Hi!"` prompt, while embedding models process short text lists, ensuring the authentication test costs fractions of a cent.

## Error Normalization and User Feedback

All validation errors funnel through `_normalize_error_message`, which converts technical HTTP failures into actionable feedback. The function maps **401 Unauthorized** responses to "Invalid API key", **403 Forbidden** to "API key lacks required permissions", and network timeouts to "Connection error – check network/endpoint". Notably, rate limit errors (429) return "Rate limited – but connection works", treating throttling as successful authentication since the credentials are demonstrably valid.

## The Primary Validation Function: test_individual_model

The public API exposed to both the UI and CLI is `test_individual_model(model)`, defined in [`open_notebook/ai/connection_tester.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/connection_tester.py). This asynchronous function returns a `(bool success, str message)` tuple and performs three critical operations:

1. Instantiates the appropriate provider through `ModelManager` from [`open_notebook/ai/models.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/models.py)
2. Executes the minimal test request based on provider type—either a listing endpoint or a cheap model call
3. Interprets the response through the error normalization layer to generate human-readable status messages

When testing generic providers, the function automatically selects the most economical model available to minimize API costs during the verification process.

## Practical Implementation Examples

Use these patterns to validate credentials programmatically in your own Open Notebook extensions or scripts:

```python

# Validate Azure OpenAI credentials directly

import asyncio
from open_notebook.ai.connection_tester import _test_azure_connection

success, message = asyncio.run(_test_azure_connection(
    endpoint="https://my-resource.openai.azure.com",
    api_key="your-api-key",
    api_version="2024-10-21"
))
print(f"Connected: {success}, Details: {message}")

```

```python

# Test a generic cloud provider using its cheapest model

from open_notebook.ai.connection_tester import test_individual_model
from open_notebook.ai.models import Model

model = Model(
    id="anthropic:claude-3-haiku-20240307",
    provider="anthropic",
    type="language",
    api_key="sk-ant-api03-..."
)

success, message = await test_individual_model(model)
print(f"Validation: {'Success' if success else 'Failed'} - {message}")

```

```python

# Check local Ollama server health

from open_notebook.ai.connection_tester import _test_ollama_connection

success, message = await _test_ollama_connection("http://localhost:11434")
print(message)  # Returns: "Connected. 12 models available: llama2, mistral, ..."

```

## Core Source Files

The validation logic spans several critical files in the repository:

- [`open_notebook/ai/connection_tester.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/connection_tester.py) - Implements credential checks, provider-specific helpers, and `_normalize_error_message`
- [`open_notebook/ai/models.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/models.py) - Defines the Pydantic `Model` schema and `ModelManager` used during testing
- [`open_notebook/ai/__init__.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/__init__.py) - Exports connection utilities for UI and CLI consumption
- [`docs/6-TROUBLESHOOTING/connection-issues.md`](https://github.com/lfnovo/open-notebook/blob/main/docs/6-TROUBLESHOOTING/connection-issues.md) - User-facing documentation explaining common validation failures and resolutions

## Summary

- The connection tester validates credentials through provider-specific HTTP requests to listing endpoints where available, falling back to cheap model calls for generic providers.
- Azure uses the `/openai/models` endpoint, Ollama uses `/api/tags`, and OpenAI-compatible providers use `/models` for lightweight authentication verification.
- Generic providers are validated by calling their cheapest model endpoint with minimal payloads to keep costs negligible.
- All errors normalize through `_normalize_error_message` to provide actionable feedback like "Invalid API key" or "Rate limited".
- The `test_individual_model` function serves as the unified entry point for both UI and programmatic credential validation across all supported AI backends.

## Frequently Asked Questions

### What HTTP status codes indicate successful credential validation?

HTTP 200 responses indicate successful validation across all provider types. For Azure OpenAI, Ollama, and OpenAI-compatible endpoints, the response must also contain valid JSON with model lists or tags. Rate limit responses (429) are treated as successful connections since they prove the credentials are valid, though the returned message indicates throttling rather than a functional error.

### How does the connection tester minimize costs when validating generic providers?

Rather than invoking expensive frontier models, the `test_individual_model` function selects the cheapest available model defined in the internal `TEST_MODELS` mapping. It sends minimal payloads—such as "Hi!" for language models or single-word lists for embeddings—ensuring the API call costs fractions of a cent while still verifying that authentication headers and endpoint configurations work correctly.

### Can the connection tester validate local AI servers like Ollama without API keys?

Yes. The `_test_ollama_connection` function specifically handles local Ollama instances by querying the `/api/tags` endpoint at the provided base URL. This validation requires no API key authentication and returns the count of available local models, making it ideal for verifying self-hosted infrastructure before notebook operations begin.

### Where does the connection tester map technical errors to user-friendly messages?

All validation errors funnel through the `_normalize_error_message` helper function in [`open_notebook/ai/connection_tester.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/connection_tester.py). This centralized error handling maps HTTP 401 to "Invalid API key", HTTP 403 to permission errors, rate limiting to connection success with warnings, and network failures to connection troubleshooting suggestions, ensuring consistent messaging across the web interface and command-line tools.