> ## Documentation Index
> Fetch the complete documentation index at: https://docs.playapi.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Vercel AI SDK integration

> Connect server-side Chat Completions through the OpenAI Compatible Provider.

## Prerequisites

This guide uses the generic `@ai-sdk/openai-compatible` adapter to connect AI SDK's `generateText` to this project's Chat Completions endpoint. Use Node.js 22.18+ or 24 LTS, an API key, and a model verified for Chat. Run the key and script only on a server or in a terminal.

The documentation directory pins `ai@7.0.141` and `@ai-sdk/openai-compatible@3.0.69`; install with `npm ci`. In your own Node project, install:

```sh theme={null}
npm install --save-exact ai@7.0.141 @ai-sdk/openai-compatible@3.0.69
```

SDK upgrades can change request and response normalization. Recheck outgoing paths and run contract tests. This example explicitly uses `provider.chatModel()` and does not automatically switch to Responses.

## Complete runnable example

Save as `examples/ai-sdk.mts`, then run:

```sh theme={null}
export API_BASE_URL='https://gateway.example.com/v1'
export API_KEY='YOUR_API_KEY'
export API_MODEL='YOUR_CHAT_MODEL_ID'
node examples/ai-sdk.mts
```

Preserve deployment path prefixes. Include `/v1` in the Base URL, excluding `/chat/completions`. This text example accepts one completed plain-text answer only. Refusal, tool calls, truncation, or empty text produce a nonzero exit without printing partial content as a successful result.

```typescript theme={null}
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
import { generateText } from 'ai';

try {
  const { API_BASE_URL, API_KEY, API_MODEL } = process.env;
  const base = new URL(API_BASE_URL || 'invalid:');
  if (!['http:', 'https:'].includes(base.protocol) || base.username || base.password
    || base.search || base.hash || !API_KEY?.trim() || !API_MODEL?.trim()) {
    throw new Error('Invalid configuration.');
  }
  const provider = createOpenAICompatible({
    name: 'api-gateway', baseURL: base.href.replace(/\/+$/, ''), apiKey: API_KEY,
    fetch: (input, init) => fetch(input, { ...init, redirect: 'error' }),
  });
  const result = await generateText({
    model: provider.chatModel(API_MODEL),
    prompt: 'Say hello in one short sentence.',
    maxRetries: 0,
    abortSignal: AbortSignal.timeout(60_000),
    include: { responseBody: true },
  });
  // Check the raw Chat response as well: adapters can normalize away refusal fields.
  const raw = result.response.body as {
    error?: unknown;
    choices?: Array<{ index?: number; finish_reason?: string; message?: {
      role?: string; content?: unknown; refusal?: unknown; tool_calls?: unknown;
      function_call?: unknown;
    } }>;
  } | undefined;
  const choice = raw?.choices?.[0];
  const message = choice?.message;
  if (raw?.error || raw?.choices?.length !== 1 || choice?.index !== 0
    || choice.finish_reason !== 'stop' || message?.role !== 'assistant'
    || message.refusal != null || message.tool_calls != null || message.function_call != null
    || typeof message.content !== 'string' || !message.content.trim()
    || result.finishReason !== 'stop' || result.toolCalls.length !== 0
    || result.text !== message.content) {
    throw new Error('Expected one completed text response.');
  }
  console.log(result.text);
} catch {
  console.error('AI SDK request failed or returned incomplete text. Check configuration and request logs. No automatic retry.');
  process.exitCode = 1;
}
```

## Key settings

| Setting | Reason |
| - | - |
| `chatModel(API_MODEL)` | Selects `/chat/completions` explicitly; the model comes from your deployment |
| `maxRetries: 0` | Disables AI SDK automatic retries to avoid multiplying gateway attempts |
| `AbortSignal.timeout(60_000)` | Bounds total waiting for this call; cancellation does not prove the upstream did no work |
| `redirect: 'error'` | Fails on redirects so you can correct the actual API address |
| `include.responseBody` | Retains the raw response in memory for validation; it is not written to logs |
| Completion and raw-response checks | Adapter normalization can hide fields such as refusals; the example also validates the raw Chat response |

## Enable extensions individually

This script verifies non-streaming text only. Streaming, tools, structured output, vision, and embeddings need separate configuration and model verification. Adapter options such as `includeUsage` and `supportsStructuredOutputs` cannot create upstream capabilities; enable them after confirming channel support. Browser `useChat`, framework route handlers, and SDK data-stream protocols also require a separate server implementation. Never pass the API key directly to the browser.

For protocol details, see [Chat API](/en/api-reference/chat-completions), [streaming](/en/guides/streaming), [tool calling](/en/guides/tool-calling), and [structured output](/en/guides/structured-output).

Local validation includes strict type checking of all `.mts` examples and real SDK requests against a local HTTP fixture for this script. It does not validate real models. References: [official adapter documentation](https://ai-sdk.dev/providers/openai-compatible-providers) and [generateText parameters](https://ai-sdk.dev/docs/reference/ai-sdk-core/generate-text).

[阅读中文](/zh/guides/ai-sdk)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.