# How OpenClaude Handles OpenAI-Compatible APIs: A Deep Dive into Provider Profiles and Request Routing

> Discover how OpenClaude manages OpenAI-compatible APIs using provider profiles. Learn about seamless integration with services like OpenRouter, Groq, and custom endpoints.

- Repository: [Gitlawb/openclaude](https://github.com/Gitlawb/openclaude)
- Tags: deep-dive
- Published: 2026-09-08

---

**OpenClaude treats every OpenAI-compatible service as a *provider profile* discovered at startup and injected into the request pipeline, enabling seamless integration with OpenRouter, Groq, DeepSeek, and custom self-hosted endpoints.**

OpenClaude's architecture for OpenAI-compatible API support centers on a flexible **provider profile system** that abstracts transport differences while preserving full compatibility with the OpenAI chat/completions format. This design allows the tool to route requests to any service implementing the standard OpenAI API shape—from commercial providers to private infrastructure—without code changes.

## What Are Provider Profiles?

Provider profiles are the fundamental abstraction in [`src/utils/providerProfiles.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/providerProfiles.ts). At startup, this module scans the user's configuration (or built-in defaults) and builds a registry of available endpoints. Each profile discovered through `parseOpenAICompatibleApiFormat` contains three essential components:

- **Base URL**: The root endpoint for the compatible API
- **Optional API key**: Authentication credentials for the service
- **Model catalog**: Available models exposed by that provider

This profile system decouples endpoint configuration from request execution, letting OpenClaude treat diverse backends uniformly.

## Credential Validation and Fallback Behavior

Before any request leaves the system, [`src/utils/providerValidation.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/providerValidation.ts) determines which credentials to use. The validation logic follows a priority scheme controlled by environment variables.

If `CLAUDE_CODE_USE_OPENAI=1` is set, validation falls back to generic OpenAI credentials via `hasUsableOpenAICredential`. Otherwise, each profile's own credentials are verified independently. This dual-path approach supports both "vanilla OpenAI mode" and multi-provider deployments.

```bash

# Force generic OpenAI profile globally

export CLAUDE_CODE_USE_OPENAI=1
export OPENAI_API_KEY=sk-...
openclaude run --model gpt-4o "Explain quantum entanglement"

```

Without this flag, OpenClaude validates profile-specific keys, enabling secure multi-tenant setups where different workloads use different providers.

## Schema Sanitization for Function Calling

OpenAI-compatible endpoints impose strict constraints on JSON Schema structure for tool use. The `sanitizeSchemaForOpenAICompat` function in [`src/utils/schemaSanitizer.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/schemaSanitizer.ts) rewrites user-provided schemas to match these expectations.

This sanitization handles:

- Structural transformations for function-calling payloads
- Constraint adjustments that vary between provider implementations
- Preservation of semantic meaning while meeting format requirements

When you pass tools to `createProviderClient`, the schema automatically undergoes this transformation before transmission:

```ts
const client = await createProviderClient({
  profileId: 'openrouter',
  model: 'meta-llama/Meta-Llama-3.1-8B-Instruct',
  tools: [{
    type: 'function',
    function: {
      name: 'get_weather',
      parameters: {
        type: 'object',
        properties: { city: { type: 'string' } },
        required: ['city']
      }
    }
  }],
});

const result = await client.chatCompletion({
  messages: [{ role: 'user', content: 'What is the weather in Paris?' }],
});

```

## Security: Redaction and URL Sanitization

Before any credential enters logs or UI displays, [`src/utils/redaction.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/redaction.ts) performs aggressive masking. The module recognizes multiple OpenAI key patterns:

- `sk-…` — standard API keys
- `sk-proj-…` — project-scoped keys

The `buildAPIProviderProperties` function additionally strips sensitive components from displayed base URLs, ensuring that provider endpoints don't leak infrastructure details in error messages or status reports.

## Routing and Transport Labeling

The internal routing layer, validated in [`src/utils/status.routes.test.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/status.routes.test.ts), assigns human-readable labels to each transport. These labels serve two purposes:

1. **UI display**: Users see "OpenAI", "OpenRouter", or "Groq" rather than raw URLs
2. **Cost tracking**: The label determines which pricing model applies

Routes marked as *OpenAI-compatible API* receive consistent handling regardless of underlying provider identity. This abstraction enables the same request pipeline to service both first-party OpenAI calls and third-party compatible endpoints.

## Cost Tracking and Rate Limiting

OpenClaude applies uniform cost accounting to all OpenAI-compatible calls through [`src/cost-tracker.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/cost-tracker.ts). The system treats these calls identically to native OpenAI for pricing purposes, drawing rate limit definitions from [`src/constants/apiLimits.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/constants/apiLimits.ts).

This design ensures that:

- Token consumption is accurately measured across providers
- Budget controls apply consistently regardless of backend
- Usage reports aggregate comparable metrics

## Configuring Custom OpenAI-Compatible Providers

Adding a self-hosted or niche provider requires only CLI configuration:

```bash

# Define a custom provider profile

openclaude config set providerProfiles.0.id=myselfhosted
openclaude config set providerProfiles.0.apiFormat="openai://myselfhosted.example.com/v1"
openclaude config set providerProfiles.0.apiKey=$MY_SELF_HOSTED_KEY

```

Programmatic access uses the same profile ID:

```ts
import { createProviderClient } from 'openclaude';

const client = await createProviderClient({
  profileId: 'myselfhosted',
  model: 'gpt-4o-mini',
  messages: [{ role: 'user', content: 'Hi!' }],
});

const response = await client.chatCompletion();
console.log(response.choices[0].message.content);

```

## Key Files in the OpenAI-Compatible Pipeline

| File | Responsibility |
|------|--------------|
| [`src/utils/providerProfiles.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/providerProfiles.ts) | Parses and constructs provider definitions from configuration |
| [`src/utils/providerValidation.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/providerValidation.ts) | Validates credentials and implements OpenAI-mode fallback |
| [`src/utils/schemaSanitizer.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/schemaSanitizer.ts) | Transforms JSON Schemas for OpenAI-compatible consumption |
| [`src/utils/redaction.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/redaction.ts) | Masks API keys and sanitizes URL displays |
| [`src/utils/status.routes.test.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/status.routes.test.ts) | Tests transport labeling and routing decisions |
| [`src/cost-tracker.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/cost-tracker.ts) | Applies pricing to OpenAI-compatible calls |
| [`src/constants/apiLimits.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/constants/apiLimits.ts) | Defines token and rate limits for compatible services |

## Summary

- **Provider profiles** in [`src/utils/providerProfiles.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/providerProfiles.ts) abstract OpenAI-compatible endpoints into uniform configuration objects
- **Credential validation** supports both generic OpenAI mode (`CLAUDE_CODE_USE_OPENAI`) and per-profile authentication
- **Schema sanitization** ensures function-calling payloads conform to provider expectations
- **Redaction** protects API keys through pattern-based masking before any log or display operation
- **Routing labels** enable consistent UI presentation and cost tracking across diverse backends
- The architecture supports **self-hosted, commercial, and shimmed providers** without code changes

## Frequently Asked Questions

### What providers besides OpenAI does OpenClaude support?

OpenClaude works with any service implementing the OpenAI chat/completions endpoint format. Verified integrations include **OpenRouter**, **Groq**, **DeepSeek**, and **Anthropic** (via compatibility shims), plus custom self-hosted servers using projects like **vLLM** or **llama.cpp**.

### How do I switch between OpenAI and a compatible provider in the same session?

Set `CLAUDE_CODE_USE_OPENAI=1` to force the generic OpenAI profile, or omit it to use profile-specific credentials. For per-request control, specify the `profileId` parameter in `createProviderClient` calls rather than relying on environment defaults.

### Why does my function calling fail with some OpenAI-compatible providers?

Incompatible JSON Schema structures are the most common cause. OpenClaude's `sanitizeSchemaForOpenAICompat` in [`src/utils/schemaSanitizer.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/schemaSanitizer.ts) handles most transformations automatically, but some providers impose additional constraints beyond the OpenAI specification. Check provider documentation for supported schema features.

### Are API keys safe in OpenClaude's logs and error messages?

Yes. The [`redaction.ts`](https://github.com/Gitlawb/openclaude/blob/main/redaction.ts) module masks all recognized OpenAI key patterns (`sk-…`, `sk-proj-…`) before any output. Base URLs are also sanitized through `buildAPIProviderProperties` to prevent infrastructure leakage.