Skip to content

Vercel AI SDK

Use HopBase from the Vercel AI SDK with the OpenAI-compatible provider, including streaming and tool calling.

The AI SDK by Vercel is a TypeScript toolkit for building AI applications. HopBase works with it through the official @ai-sdk/openai-compatible provider; Claude models use @ai-sdk/anthropic.

SettingValue
Package@ai-sdk/openai-compatible
baseURLhttps://api.hop-base.com/v1
apiKeyA key from the console, sent as Authorization: Bearer
Model IDThe exact ID returned by GET /v1/models for that key, such as deepseek-v4.1-flash-1017

Verified in production with ai 7.0 and @ai-sdk/openai-compatible 3.0: generateText, streamText, and tool calling with tool() all work, and usage is reported.

Pick the group that contains your model.

A HopBase key reaches only the models of the groups it includes. When you create the key in the console, select the group that serves the model you want — for example DeepSeek for deepseek-v4.1-flash-1017, DeepSeek Singapore Data Center for deepseek-v4.1-flash-1017-sg, or Gemini (all models, incl. image) for gemini-3.8-flash. A key without the model's group returns 404 model_not_found.

Install

npm i ai @ai-sdk/openai-compatible zod

Keep the key in an environment variable:

export HOPBASE_API_KEY=sk-your-key

Create the provider

import { createOpenAICompatible } from '@ai-sdk/openai-compatible';

export const hopbase = createOpenAICompatible({
  name: 'hopbase',
  baseURL: 'https://api.hop-base.com/v1',
  apiKey: process.env.HOPBASE_API_KEY,
  includeUsage: true, // report token usage on streamed responses
});

hopbase('<model ID>') returns a chat model. The ID must match GET /v1/models exactly.

Generate text

import { generateText } from 'ai';
import { hopbase } from './hopbase';

const { text } = await generateText({
  model: hopbase('deepseek-v4.1-flash-1017'),
  prompt: 'Reply with one word: hello.',
});
console.log(text);

Stream text

import { streamText } from 'ai';
import { hopbase } from './hopbase';

const result = streamText({
  model: hopbase('deepseek-v4.1-flash-1017'),
  prompt: 'Count from 1 to 5.',
});
for await (const delta of result.textStream) process.stdout.write(delta);

Call tools

import { generateText, tool, stepCountIs } from 'ai';
import { z } from 'zod';
import { hopbase } from './hopbase';

const { text } = await generateText({
  model: hopbase('deepseek-v4.1-flash-1017'),
  tools: {
    getWeather: tool({
      description: 'Get the weather for a city',
      inputSchema: z.object({ city: z.string() }),
      execute: async ({ city }) => ({ city, tempC: 21 }),
    }),
  },
  stopWhen: stepCountIs(3),
  prompt: 'What is the weather in Tokyo? Use the tool.',
});
console.log(text);

Switch models by changing only the ID, for example hopbase('gemini-3.8-flash') with a key that includes the Gemini (all models, incl. image) group.

Claude models

Claude models are served over the Anthropic Messages protocol. Use @ai-sdk/anthropic and keep /v1 in baseURL: the package appends /messages to it, so requests go to https://api.hop-base.com/v1/messages.

import { createAnthropic } from '@ai-sdk/anthropic';
import { generateText } from 'ai';

const hopbaseClaude = createAnthropic({
  baseURL: 'https://api.hop-base.com/v1',
  apiKey: process.env.HOPBASE_API_KEY,
});

const { text } = await generateText({
  model: hopbaseClaude('claude-sonnet-5-5'),
  prompt: 'Reply with one word: hello.',
});

The key must include a Claude group. This differs from the Anthropic SDKs and Claude Code, which take the bare host https://api.hop-base.com and add /v1/messages themselves.

Prices for every model are on the pricing page.

Troubleshooting

SymptomCause
401HOPBASE_API_KEY is unset in the process, or the key is disabled
404 model_not_foundThe key does not include the model's group, or the ID is shortened. Re-read GET /v1/models
Only the @ai-sdk/anthropic requests failbaseURL is missing /v1. The request URL must end in /v1/messages
route_not_foundThe key belongs to an image or video group with no chat endpoint

Next steps