# How to Configure a Custom OpenAI-Compatible Endpoint for AI Summaries in Meetily

> Configure a custom OpenAI-compatible endpoint for Meetily AI summaries by setting the customOpenAIEndpoint parameter in the builtin_ai_generate_summary Tauri command. Easily route to your preferred LLM service.

- Repository: [Zackriya Solutions/meetily](https://github.com/Zackriya-Solutions/meetily)
- Tags: how-to-guide
- Published: 2026-07-23

---

**You can route Meetily's AI summary generation to any OpenAI-compatible service by setting the `customOpenAIEndpoint` parameter in the `builtin_ai_generate_summary` Tauri command, which dynamically constructs the request URL in [`llm_client.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/llm_client.rs) rather than using a hard-coded constant.**

Meetily's architecture supports private or hosted Large Language Models (LLMs) through a flexible provider system that accepts custom endpoints at runtime. This allows you to integrate Azure OpenAI, private self-hosted models, or third-party proxies without modifying the Rust backend source code.

## Architecture Overview

Meetily's summary flow uses a three-stage pipeline to decouple the frontend from the specific LLM implementation:

1. **Frontend invocation** – React/TypeScript components call the Tauri runtime with configuration arguments
2. **Command routing** – `builtin_ai_generate_summary` in the Rust backend validates parameters and instantiates the LLM client
3. **Dynamic URL construction** – The `generate_summary` function in [`src-tauri/src/summary/llm_client.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src-tauri/src/summary/llm_client.rs) (lines 173-179) builds the final HTTP endpoint by appending `/chat/completions` to your custom base URL

When the `provider` argument resolves to `LLMProvider::CustomOpenAI`, the system expects a valid HTTP URL in the `custom_openai_endpoint` parameter. The backend trims trailing slashes and constructs the final request path automatically.

## Step-by-Step Implementation

### Frontend Configuration (TypeScript)

Your React components invoke the Tauri command through the `@tauri-apps/api` package. You must specify `'custom-openai'` as the provider string and include your endpoint URL:

```typescript
import { invoke } from '@tauri-apps/api/tauri';

/**
 * Generates a meeting summary using a private OpenAI-compatible API.
 */
async function summarizeWithCustomEndpoint(
  transcript: string,
  apiKey: string,
  endpoint: string = 'https://my-openai-proxy.example.com'
): Promise<string> {
  return await invoke<string>('builtin_ai_generate_summary', {
    provider: 'custom-openai',           // Maps to LLMProvider::CustomOpenAI
    modelName: 'gpt-4',
    apiKey: apiKey,
    systemPrompt: 'You are a concise meeting summary assistant.',
    userPrompt: transcript,
    customOpenAIEndpoint: endpoint,      // Your custom base URL
    maxTokens: 1024,
    temperature: 0.7,
    topP: 0.9,
  });
}

```

The `customOpenAIEndpoint` value is passed directly to the Rust backend as an optional string parameter.

### Tauri Command Routing

The `builtin_ai_generate_summary` command in [`src-tauri/src/summary/summary_engine/commands.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src-tauri/src/summary/summary_engine/commands.rs) acts as the bridge between the frontend and the LLM client. It accepts the optional endpoint and forwards it to the core generation logic:

```rust
#[tauri::command]
pub async fn builtin_ai_generate_summary(
    provider: String,
    model_name: String,
    api_key: String,
    system_prompt: String,
    user_prompt: String,
    custom_openai_endpoint: Option<String>,
    // ...additional optional parameters...
) -> Result<String, String> {
    let provider = LLMProvider::from_str(&provider)?;
    let client = reqwest::Client::new();

    summary::llm_client::generate_summary(
        &client,
        &provider,
        &model_name,
        &api_key,
        &system_prompt,
        &user_prompt,
        None,                       // ollama_endpoint (not used)
        custom_openai_endpoint.as_deref(),
        max_tokens,
        temperature,
        top_p,
        None,                       // app_data_dir
        None,                       // cancellation token
    )
    .await
}

```

This command handles the provider enum conversion and HTTP client instantiation before delegating to the summary generator.

### LLM Client URL Construction

The actual HTTP request construction occurs in [`src-tauri/src/summary/llm_client.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src-tauri/src/summary/llm_client.rs) at lines 173-179. When processing a `CustomOpenAI` provider, the code dynamically builds the API endpoint:

```rust
format!("{}/chat/completions", endpoint.trim_end_matches('/'))

```

This implementation ensures that whether you provide `https://api.example.com` or `https://api.example.com/`, the resulting URL correctly resolves to `https://api.example.com/chat/completions` without double slashes.

### Persisting Endpoint Configuration

To avoid hardcoding endpoints in your frontend components, Meetily stores user preferences in JSON format within the application's data directory (managed by [`src-tauri/src/config.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/src-tauri/src/config.rs)). A typical settings structure looks like:

```json
{
  "summary": {
    "customOpenAIEndpoint": "https://my-openai-proxy.example.com",
    "customOpenAIKey": "sk-..."
  }
}

```

Your settings UI should read this configuration on startup and pass the stored value as the `customOpenAIEndpoint` argument whenever calling `builtin_ai_generate_summary`.

## Key Source File References

The integration relies on three specific components:

- **[`frontend/src-tauri/src/summary/llm_client.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/summary/llm_client.rs)** – Contains the URL construction logic (lines 173-179) that appends `/chat/completions` to your custom base URL
- **[`frontend/src-tauri/src/summary/summary_engine/commands.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/summary/summary_engine/commands.rs)** – Houses the `builtin_ai_generate_summary` Tauri command that receives frontend requests
- **[`frontend/src-tauri/src/config.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/config.rs)** – Defines the app-data directory paths where persistent settings are stored

## Summary

- **Dynamic routing**: Meetily does not hard-code OpenAI URLs; the endpoint is supplied at runtime through the `custom_openai_endpoint` parameter
- **Provider selection**: You must use the provider string `'custom-openai'` (case-sensitive) to trigger the custom endpoint logic in [`llm_client.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/llm_client.rs)
- **URL construction**: The backend automatically handles trailing slashes and appends `/chat/completions` to your base URL
- **Persistence**: Store the endpoint in the app's JSON settings under the `summary.customOpenAIEndpoint` key to avoid repeated configuration

## Frequently Asked Questions

### What format should the custom endpoint URL use?

Provide the base URL without the `/chat/completions` suffix. For example, use `https://api.openai.com` or `https://my-azure-instance.openai.azure.com/openai/deployments/my-deployment`. The Rust code in [`llm_client.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/llm_client.rs) automatically appends `/chat/completions` and removes any trailing slashes from your input.

### Can I use Azure OpenAI Service with this configuration?

Yes. Azure OpenAI is compatible with this implementation as long as you provide the full deployment URL including the `/openai/deployments/{deployment-id}` path segment. Pass this as the `customOpenAIEndpoint` parameter along with your Azure API key in the `apiKey` field.

### Is the API key sent securely to the custom endpoint?

The API key is transmitted via HTTPS in the request headers to your specified endpoint, using the same `Authorization: Bearer {key}` format as standard OpenAI requests. Ensure your custom endpoint uses TLS/SSL, as the `reqwest` client in the Rust backend enforces HTTPS for security.

### How do I troubleshoot connection errors to my custom endpoint?

Check the Tauri backend logs for the constructed URL. The `generate_summary` function in [`llm_client.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/llm_client.rs) will fail at the HTTP request stage if the URL is malformed or unreachable. Verify that your endpoint responds to `POST /chat/completions` with a JSON body matching the OpenAI Chat Completions API schema.