External model connections v7

External models are API-based models hosted outside your Postgres instance. AIDB connects to them by registering a model with aidb.create_model(), supplying the provider name, a configuration object, and credentials such as an API key, if required.

Note

The examples on this page pass credentials inline as credentials => '{"api_key": "..."}'::JSONB for brevity. config itself can never contain an api_key or basic_auth key at any nesting depth — aidb.create_model() rejects it — so always pass credentials through the separate credentials argument. To avoid storing the secret in the database at all, pass credentials_env instead, naming an environment variable to read it from at connection time. See Credentials from environment variables.

Once registered, an external model is used exactly like a default local model — by name in any AIDB SQL function or pipeline step.

Validating a model at creation

By default, aidb.create_model() validates an external model as part of registration by sending a small probe request to the provider. This confirms the endpoint is reachable and the configuration and credentials are correct before the registration commits, surfacing problems like an invalid API key or wrong URL immediately instead of on first use. If the probe fails, the error is reported and no model is registered.

-- Validated by default: sends a test request to the provider now.
SELECT aidb.create_model(
    'my_openai_embedder',
    'openai_embeddings',
    config      => aidb.embeddings_config(model => 'text-embedding-3-small'),
    credentials => '{"api_key": "sk-..."}'::JSONB
);

Pass validate => false to skip the probe — for example, when the endpoint or credentials aren't available yet, or to avoid the request during scripted setup:

SELECT aidb.create_model(
    'my_openai_embedder',
    'openai_embeddings',
    config      => aidb.embeddings_config(model => 'text-embedding-3-small'),
    credentials => '{"api_key": "sk-..."}'::JSONB,
    validate    => false
);
Note

Validation sends a real request to the provider, so it requires network access from the Postgres host at creation time and may incur a small usage cost.

You can validate a model later — or re-check an existing one — with aidb.validate_model().

OpenAI-compatible endpoints

AIDB supports any embedding or chat/completions service that implements the OpenAI API. This includes OpenAI itself, self-hosted servers like Ollama, and any other compliant endpoint.

Embeddings

Use the openai_embeddings provider with aidb.embeddings_config(). Override the url parameter to redirect requests to any OpenAI-compatible server:

-- OpenAI
SELECT aidb.create_model(
    'my_openai_embedder',
    'openai_embeddings',
    config      => aidb.embeddings_config(
        model => 'text-embedding-3-small',
        url   => 'https://api.openai.com/v1'
    ),
    credentials => '{"api_key": "sk-..."}'::JSONB
);

-- Local Ollama server
SELECT aidb.create_model(
    'my_ollama_embedder',
    'openai_embeddings',
    config => aidb.embeddings_config(
        model => 'llama3.2',
        url   => 'http://llama.local:11434/v1/embeddings'
    )
);
ParameterTypeDefaultDescription
modelTEXTRequiredModel identifier as expected by the API.
api_keyTEXTNULLAPI key for authentication.
urlTEXTNULLAPI endpoint URL. Defaults to OpenAI's endpoint.
basic_authTEXTNULLBasic auth credentials (user:password).
max_concurrent_requestsINTEGERNULLMaximum concurrent requests to the endpoint.
max_batch_sizeINTEGERNULLMaximum number of inputs per batch request.
input_typeTEXTNULLInput type hint for encoding (provider-specific).
input_type_queryTEXTNULLInput type hint for query encoding (provider-specific).
is_hcp_modelBOOLEANNULLSet to true if referencing a model running on HCP.

Chat completions

Use the openai_completions provider with aidb.completions_config(). The url parameter works the same way — omit it for OpenAI, or override it for any other compliant server:

SELECT aidb.create_model(
    'my_openai_llm',
    'openai_completions',
    config      => aidb.completions_config(
        model       => 'gpt-4o',
        temperature => 0.2
    ),
    credentials => '{"api_key": "sk-..."}'::JSONB
);
ParameterTypeDefaultDescription
modelTEXTRequiredModel identifier.
api_keyTEXTNULLAPI key for authentication.
urlTEXTNULLAPI endpoint URL. Defaults to OpenAI's endpoint.
basic_authTEXTNULLBasic auth credentials (user:password).
temperatureDOUBLE PRECISIONNULLSampling temperature.
top_pDOUBLE PRECISIONNULLNucleus sampling threshold.
seedBIGINTNULLRandom seed for reproducible outputs.
system_promptTEXTNULLDefault system prompt prepended to every request.
max_tokensJSONBNULLMax tokens config (from aidb.max_tokens_config()).
thinkingBOOLEANNULLEnable extended reasoning (supported models only).
max_concurrent_requestsINTEGERNULLMaximum concurrent requests to the endpoint.
extra_argsJSONBNULLAdditional provider-specific arguments.
is_hcp_modelBOOLEANNULLSet to true if referencing a model running on HCP.
Note

When using pgvector indexing, be aware that pgvector limits indexed vectors to 2000 dimensions. If the model you choose produces more dimensions, use aidb.vector_index_disabled_config() in your pipeline step and manage the index manually.

OpenAI Responses API

AIDB has two providers for OpenAI models — both work with the same model identifiers (gpt-4o, gpt-5.x, and so on), so pick between them based on what you're doing, not which models you need:

ProviderAPIBest forTool calling
openai_completionsChat Completions (/v1/chat/completions)Simple, one-off text generation — aidb.generate_text(), summarization, pipeline steps.Rejects tools/tool_choice/response_format in aidb.generate_text()'s inference_config.
openai_responsesResponses API (/v1/responses)Agentic workloads — multi-step reasoning, reliable tool calling, structured output.Native — emits the API's real tools/tool_choice request fields and parses real tool-call responses back.

Both providers can also back an aidb.create_agent() agent — AIDB always gives the agent tool-calling ability, but how differs by provider. Backed by openai_responses, tool calls go over the wire as genuine Responses API tool calls. Backed by openai_completions (or almost any other provider), AIDB describes the available tools in the prompt text and parses a tool call back out of the model's plain-text reply — a simulation, not the model's own tool-calling behavior. openai_responses is the more reliable choice for agents; use openai_completions when you just need text out, not tool calling.

SELECT aidb.create_model(
    'my_gpt',
    'openai_responses',
    config      => aidb.openai_responses_config(model => 'gpt-5.1'),
    credentials => '{"api_key": "sk-..."}'::JSONB
);

Azure AI Foundry

Use openai_responses_azure for models hosted on Azure AI Foundry's unified Responses API surface. It's the same wire shape as direct OpenAI, but url is required since there's no universal default — point it at your resource's endpoint:

SELECT aidb.create_model(
    'my_gpt_azure',
    'openai_responses_azure',
    config      => aidb.openai_responses_config(
        model => 'gpt-5.1',
        url   => 'https://<resource>.openai.azure.com/openai/v1/responses'
    ),
    credentials => '{"api_key": "..."}'::JSONB
);

See aidb.openai_responses_config for the full parameter list, and Tool calling and structured output for using tools, tool_choice, and response_format with either provider.

Anthropic Messages API

The anthropic_messages provider connects to Anthropic's native Messages API (/v1/messages), with the same native tool-calling support as openai_responses: real tools/tool_choice request fields, real tool-call responses, and structured output via response_format.

SELECT aidb.create_model(
    'my_claude',
    'anthropic_messages',
    config      => aidb.anthropic_messages_config(model => 'claude-opus-4-6'),
    credentials => '{"api_key": "sk-ant-..."}'::JSONB
);

Azure AI Foundry and AWS Bedrock

Two more variants share the same config helper and wire body, differing only in auth and endpoint:

  • anthropic_messages_azure — Azure AI Foundry's native Anthropic Messages API surface. url is required (your resource's Messages endpoint).
  • anthropic_messages_bedrock — AWS Bedrock's InvokeModel API, authenticated with a Bedrock API key (bearer token, not AWS SigV4). url is required and should be the regional bedrock-runtime base endpoint — AIDB appends the model ID to the path automatically.
-- Azure AI Foundry
SELECT aidb.create_model(
    'my_claude_azure',
    'anthropic_messages_azure',
    config      => aidb.anthropic_messages_config(
        model => 'claude-opus-4-6',
        url   => 'https://<resource>.services.ai.azure.com/anthropic/v1/messages'
    ),
    credentials => '{"api_key": "..."}'::JSONB
);

-- AWS Bedrock
SELECT aidb.create_model(
    'my_claude_bedrock',
    'anthropic_messages_bedrock',
    config      => aidb.anthropic_messages_config(
        model => 'anthropic.claude-opus-4-6-v1:0',
        url   => 'https://bedrock-runtime.us-east-1.amazonaws.com'
    ),
    credentials => '{"api_key": "..."}'::JSONB
);
Note

Anthropic's Messages API has no native structured-output field. When you use response_format, AIDB translates it into a forced call to a synthetic tool internally — functionally equivalent, but it means response_format can't be combined with tools/tool_choice in the same call.

anthropic_messages is AIDB's only provider built specifically for Claude — there's no older anthropic_completions equivalent to openai_completions. If you'd rather reach Claude (or OpenAI, or other vendors) through a single unified gateway instead of a per-vendor provider, see OpenRouter below; the tradeoff is the same as openai_completions above — OpenRouter models get simulated (prompt-injected), not native, tool calling when backing an agent.

See aidb.anthropic_messages_config for the full parameter list.

NVIDIA NIM

AIDB supports NVIDIA NIM microservices hosted on build.nvidia.com as well as NIM instances running in your own environment.

Text generation (NIM completions)

Use the nim_completions provider with aidb.completions_config() — the same config helper openai_completions uses, since NIM's completions endpoint is OpenAI-compatible. See Chat completions above for the full parameter list.

SELECT aidb.create_model(
    'my_nim_llm',
    'nim_completions',
    config      => aidb.completions_config(
        model => 'meta/llama-3.3-70b-instruct'
    ),
    credentials => '{"api_key": "nvapi-..."}'::JSONB
);

To use a NIM instance running in your own environment, pass url to aidb.completions_config() pointing at your NIM endpoint.

After registering, run the model with aidb.generate_text():

SELECT aidb.generate_text('my_nim_llm', 'Tell me a short, one sentence story');
Output
                                       generate_text
----------------------------------------------------------------------------------
 As the clock struck midnight, a single tear fell from the porcelain doll's eye.
(1 row)

Multimodal embeddings (NIM CLIP)

Use the nim_clip provider with aidb.nim_clip_config() for joint text and image embeddings:

SELECT aidb.create_model(
    'my_nim_clip',
    'nim_clip',
    config      => aidb.nim_clip_config(
        model => 'nvidia/nvclip'
    ),
    credentials => '{"api_key": "nvapi-..."}'::JSONB
);

aidb.nim_clip_config() parameters:

ParameterTypeDefaultDescription
api_keyTEXTNULLAPI key for NIM authentication.
modelTEXTNULLNIM CLIP model identifier.
urlTEXTNULLNIM endpoint URL override.
basic_authTEXTNULLBasic auth credentials.
is_hcp_modelBOOLEANNULLSet to true if the model is running on HCP.

OCR (NIM OCR)

Use the nim_paddle_ocr provider with aidb.nim_ocr_config() to extract text from images:

SELECT aidb.create_model(
    'my_nim_ocr',
    'nim_paddle_ocr',
    config      => aidb.nim_ocr_config(),
    credentials => '{"api_key": "nvapi-..."}'::JSONB
);

aidb.nim_ocr_config() parameters:

ParameterTypeDefaultDescription
api_keyTEXTNULLAPI key for NIM authentication.
modelTEXTNULLNIM OCR model identifier.
urlTEXTNULLNIM endpoint URL override.
basic_authTEXTNULLBasic auth credentials.
is_hcp_modelBOOLEANNULLSet to true if the model is running on HCP.

Reranking (NIM reranking)

Use the nim_reranking provider with aidb.nim_reranking_config() to re-score search results by relevance. See Text reranking for usage with aidb.rerank_text():

SELECT aidb.create_model(
    'my_reranker',
    'nim_reranking',
    config      => aidb.nim_reranking_config(
        model => 'nvidia/nv-rerankqa-mistral-4b-v3'
    ),
    credentials => '{"api_key": "nvapi-..."}'::JSONB
);

aidb.nim_reranking_config() parameters:

ParameterTypeDefaultDescription
api_keyTEXTNULLAPI key for NIM authentication.
modelTEXTNULLNIM reranking model identifier.
urlTEXTNULLNIM endpoint URL override.
basic_authTEXTNULLBasic auth credentials.
is_hcp_modelBOOLEANNULLSet to true if the model is running on HCP.

To get a NIM API key, create an account at build.nvidia.com, select a model, and generate a key from the model's page.

Google Gemini

Use the gemini provider with aidb.gemini_config(). api_key is aidb.gemini_config()'s first parameter and has no default, but pass it as NULL and supply the real key through create_model()'s credentials argument instead — config can never contain an api_key field:

SELECT aidb.create_model(
    'my_gemini',
    'gemini',
    config      => aidb.gemini_config(
        api_key => NULL,
        model   => 'gemini-2.0-flash'
    ),
    credentials => '{"api_key": "AIza..."}'::JSONB
);

aidb.gemini_config() parameters:

ParameterTypeDefaultDescription
api_keyTEXTRequiredHas no default, but pass NULL and supply the real key via create_model()'s credentials argument instead — config can never contain api_key.
modelTEXTNULLGemini model identifier (for example, gemini-2.0-flash).
urlTEXTNULLAPI endpoint URL override.
max_concurrent_requestsINTEGERNULLMaximum concurrent requests to the API.
thinking_budgetINTEGERNULLExtended thinking token budget (Gemini 2.x models only).

OpenRouter

OpenRouter provides a unified API gateway to 200+ models from multiple providers. AIDB supports both chat completions and embeddings via OpenRouter.

Chat completions

SELECT aidb.create_model(
    'my_or_chat',
    'openrouter_chat',
    config      => aidb.openrouter_chat_config('anthropic/claude-3-5-haiku'),
    credentials => '{"api_key": "sk-or-..."}'::JSONB
);

aidb.openrouter_chat_config() parameters:

ParameterTypeDefaultDescription
modelTEXTRequiredOpenRouter model identifier.
api_keyTEXTNULLOpenRouter API key.
urlTEXTNULLAPI endpoint URL override.
max_concurrent_requestsINTEGERNULLMaximum concurrent requests.
max_tokensJSONBNULLMax tokens config (from aidb.max_tokens_config()).

Embeddings

SELECT aidb.create_model(
    'my_or_embedder',
    'openrouter_embeddings',
    config      => aidb.openrouter_embeddings_config('mistral/mistral-embed'),
    credentials => '{"api_key": "sk-or-..."}'::JSONB
);

aidb.openrouter_embeddings_config() parameters:

ParameterTypeDefaultDescription
modelTEXTRequiredOpenRouter embeddings model identifier.
api_keyTEXTNULLOpenRouter API key.
urlTEXTNULLAPI endpoint URL override.
max_concurrent_requestsINTEGERNULLMaximum concurrent requests.
max_batch_sizeINTEGERNULLMaximum inputs per batch request.

See the Models reference for full parameter details on all config helper functions.