Short path: OpenAI-compatible API · Multi-model API · Cheap LLM API · Models
Last verified: August 3, 2026
To use an OpenAI-compatible API with the Vercel AI SDK, install @ai-sdk/openai-compatible, create a provider with createOpenAICompatible, and pass the provider's model object to generateText or streamText. For LumeAPI, set baseURL to https://api.lumeapi.site/v1, keep the key in LUMEAPI_API_KEY, and use an exact model ID from the live catalog.
This is the official AI SDK abstraction for providers that implement the OpenAI API. It is preferable to pretending a third-party gateway is the first-party OpenAI provider because the provider name, base URL and compatibility boundary remain explicit in code.
Install the packages
npm install ai @ai-sdk/openai-compatibleCreate .env.local for local development:
LUMEAPI_API_KEY=replace-with-your-inference-key
LUMEAPI_MODEL=gpt-5.6-terraNever prefix a client-side environment variable with NEXT_PUBLIC_. Model credentials belong on the server.
Create one provider module
// src/lib/lumeapi.ts
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
const apiKey = process.env.LUMEAPI_API_KEY;
if (!apiKey) {
throw new Error('LUMEAPI_API_KEY is required');
}
export const lumeapi = createOpenAICompatible({
name: 'lumeapi',
apiKey,
baseURL: 'https://api.lumeapi.site/v1',
includeUsage: true,
});Centralizing the provider prevents different routes from drifting to different URLs, headers or provider names. It also gives tests one module to replace with a mock.
Run a non-streaming smoke test
// scripts/lumeapi-smoke.ts
import { generateText } from 'ai';
import { lumeapi } from '../src/lib/lumeapi';
const modelId = process.env.LUMEAPI_MODEL ?? 'gpt-5.6-terra';
const result = await generateText({
model: lumeapi(modelId),
prompt: 'Reply with exactly: ai sdk connection ok',
temperature: 0,
});
console.log({
text: result.text,
usage: result.usage,
finishReason: result.finishReason,
});Run it with your project's TypeScript runner. The successful contract is simple: a non-empty text, a normal finish reason, and usage data when the upstream route provides it.
Stream text without buffering the whole answer
import { streamText } from 'ai';
import { lumeapi } from './src/lib/lumeapi';
const result = streamText({
model: lumeapi(process.env.LUMEAPI_MODEL ?? 'gpt-5.6-terra'),
prompt: 'Give three checks for an OpenAI-compatible endpoint.',
});
for await (const chunk of result.textStream) {
process.stdout.write(chunk);
}Streaming success does not follow automatically from non-streaming success. Reverse proxies can buffer chunks, timeouts can interrupt a stream after partial output, and some routes expose different usage timing. Test both paths through the same deployment network users will reach.
Provider configuration map
| AI SDK option | Purpose | LumeAPI setting |
|---|---|---|
name | Namespace used by AI SDK metadata and provider options | lumeapi |
apiKey | Adds Authorization: Bearer … | process.env.LUMEAPI_API_KEY |
baseURL | Prefix for compatible API calls | https://api.lumeapi.site/v1 |
includeUsage | Requests usage information in streaming responses when available | true |
model passed to lumeapi() | Upstream catalog ID | Exact value from /models |
Do not append /chat/completions to baseURL; the provider package adds the resource path. Do not add an openai/ prefix unless the LumeAPI catalog itself lists that exact string. Client-specific transport prefixes from other tools are not universal model IDs.
Compatibility boundaries to test
The package supports core OpenAI-compatible language-model behavior, but an endpoint may differ on optional features. Test each capability your application uses:
| Capability | Minimum test |
|---|---|
| Text generation | Fixed prompt with deterministic output |
| Streaming | First-byte time, incremental chunks and clean completion |
| Usage | Input/output counters appear where your billing code expects them |
| Tool calls | Tool name and JSON arguments round-trip without schema changes |
| Structured output | Valid schema result on the selected model route |
| Images or files | Explicit route/model test; do not infer support from chat success |
| Provider options | Inspect the actual request body and reject unsupported fields |
Set supportsStructuredOutputs only after testing the selected route. A compatible Chat Completions endpoint does not promise every first-party OpenAI feature.
Common errors
401 Unauthorized: confirm the server-only environment variable is loaded in the process handling the request. Restart the development server after changing .env.local.
404 Not Found: use the /v1 root as baseURL. A full /v1/chat/completions value causes the SDK to append another resource path.
Model not found: fetch the current catalog and use the exact ID. Do not assume a model shown in another provider's documentation exists on LumeAPI.
No usage in a stream: includeUsage asks for usage, but the route must return it. Treat missing usage as unknown, not zero.
Provider option ignored: the compatible package can pass provider-specific options, but the receiving endpoint must implement them. Keep an allowlist of tested options.
Production pattern
Use one provider module, one model allowlist and one request wrapper that attaches a request ID, deadline and normalized error type. Log the selected model, duration, token usage and outcome without logging sensitive prompt content by default. If you switch models to reduce spend, compare completed-task cost and quality through the cheap LLM API guide, not only per-token rates.
Sources and testing boundary
- Vercel AI SDK: OpenAI-compatible providers
- Vercel AI SDK: provider management
- LumeAPI developer documentation
- LumeAPI model catalog
The TypeScript blocks were syntax-reviewed against the public AI SDK documentation on August 3, 2026. Package APIs can change across major versions, and no customer inference key was available for a billable route test in this workspace.