API и SDKИнструкция
Первый запрос на Java через openai-java: base URL, ключ, usage
Рабочая программа на Java 8+: openai-java с адресом CheapTokens, один chat completion и вывод ответа, finish_reason и расхода токенов.

Содержание
Чтобы обратиться к CheapTokens из Java, оставьте официальный SDK openai-java и поменяйте три вещи: base URL (https:/), ключ API и id модели, который передаётся обычной строкой String. Программа ниже отправляет один chat completion и печатает ответ, finish_reason и расход токенов. Нужна Java 8 или новее.
Если у вас уже есть сервис на Spring, который ходит в OpenAI, миграция — это всё: новый клиент и новые классы запроса не нужны.
Добавьте зависимость#
В README SDK (github.com/openai/openai-java, проверено 4 ноября 2026) указана версия 4.99.0, группа com.openai, артефакт openai-java. Дату релиза README не приводит, так что перед копированием загляните в репозиторий за свежей версией.
Подключите openai-java к сборке
Maven
<dependency>
<groupId>com.openai</groupId>
<artifactId>openai-java</artifactId>
<version>4.99.0</version>
</dependency>Gradle
implementation("com.openai:openai-java:4.99.0")Нейтральные к фреймворкам артефакты работают на Java 8+, так что старый корпоративный JDK не помеха.
Ключ и base URL — вне кода#
SDK читает две переменные окружения: OPENAI_API_KEY и OPENAI_BASE_URL. OpenAIOkHttpClient. подхватывает обе, поэтому ключ не попадает в исходники. (Системные свойства openai.apiKey и openai.baseUrl тоже работают и приоритетнее переменных.)
export OPENAI_API_KEY="your-cheaptokens-key"
export OPENAI_BASE_URL="https://api.cheaptokens.dev/v1"Адрес SDK по умолчанию — https:/. Пропустите вторую строку, и запрос уйдёт туда с ключом CheapTokens, которого там не знают. Так можно получить 401 при первом запуске. Где хранить ключ и как не отдать его git, читайте в статье как безопасно хранить API-ключ.

Программа#
Создайте FirstRequest.:
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.chat.completions.ChatCompletion;
import com.openai.models.chat.completions.ChatCompletionCreateParams;
public class FirstRequest {
public static void main(String[] args) {
OpenAIClient client = OpenAIOkHttpClient.fromEnv();
ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.model("deepseek-ai/DeepSeek-V4-Flash-0731")
.addUserMessage("Explain in two sentences what a token is.")
.maxCompletionTokens(300L)
.build();
ChatCompletion completion = client.chat().completions().create(params);
ChatCompletion.Choice choice = completion.choices().get(0);
System.out.println(choice.message().content().orElse("(no text)"));
System.out.println("finish_reason: " + choice.finishReason());
completion.usage().ifPresent(u ->
System.out.println("input " + u.promptTokens()
+ ", output " + u.completionTokens()));
}
}На несколько строк стоит посмотреть внимательнее.
.. В примерах README SDK — типизированные константы вродеmodel("deepseek- ai/ DeepSeek- V4- Flash- 0731") ChatModel., но у билдера есть и перегрузкаGPT_ 5_ 2 model(String), так что подойдёт любой id. Берите полный id из документации CheapTokens: короткоеdeepseek-— так подписаны цены на сайте; API ждёт полный id с префиксомv4- flash- 0731 deepseek-ai/. Не уверены в id? Получите список моделей через GET /v1/models... Потолок длины ответа, типmaxCompletionTokens(300L) long. DeepSeek-V4-Flash отдаёт до 32 768 токенов за ответ, так что 300 — выбор ради короткой демонстрации, а не предел модели.content()— этоOptional. Поэтому в программеorElse. У ответа, состоящего только из вызовов инструментов, текста нет.usage()тожеOptional.ifPresentпечатает его, когда сервер его прислал.
Соберите и запустите так, как это делает ваша сборка (mvn compile exec:java - или задача JavaExec в Gradle). Вы получите объяснение токена, затем строку finish_reason: … со словом stop, затем строку с числом входных и выходных токенов. Если в finish_reason стоит length, ответ упёрся в ваш лимит 300 токенов и был обрезан: увеличьте число (почему так бывает).
usage() возвращает число токенов промпта, ответа и общее (promptTokens(), completionTokens(), totalTokens()).
Явные значения через билдер#
Тестам или сервису с несколькими клиентами иногда нужны явные значения. Тот же клиент, собранный вручную:
OpenAIClient client = OpenAIOkHttpClient.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.baseUrl("https://api.cheaptokens.dev/v1")
.build();Всё после этой строки, параметры и вызов create, остаётся как выше. Ключ и здесь читайте из окружения: строка в .java-файле окажется в репозитории.

Три ошибки, которые встретятся первыми#
Найдите пары
Сопоставьте симптом и причину
Нажмите на элемент слева, затем на его пару
- 401 Unauthorizedключ пуст или неверен, либо запрос ушёл на api.openai.com, потому что
OPENAI_BASE_URLне задан - 404 Not Foundв base URL нет
/v1или такого id модели не существует - finish_reason равен length
maxCompletionTokensменьше, чем нужно ответу
Пустую переменную окружения легко проглядеть в IDE: конфигурация запуска из панели может не наследовать переменные, которые вы экспортировали в терминале. Если ключ «задан», а 401 всё равно приходит, добавьте переменные прямо в конфигурацию запуска. Подробнее об этих кодах: ошибка 401 или 404: ключ, base URL, id модели.
Сколько стоит один запрос#
Раз вы печатаете usage, запрос можно оценить в деньгах до масштабирования. Допустим, ваш сервис отправляет около 200 входных токенов и получает 300 обратно. По сегодняшним ценам такой запрос на DeepSeek-V4-Flash стоит $0.000033. Вход и выход оплачиваются вместе, и в сумме это дешевле, чем на OpenRouter. Таблица повторяет расчёт для 1 000 запросов по нашим моделям:
| Модель | Вход $/1M | Выход $/1M | За запрос | 1 000 запросов | OpenRouter, 1 000 запросов |
|---|---|---|---|---|---|
| GLM-5.3-Flash | $0.02 | $0.04 | $0.000016 | $0.016 | $0.0316 |
| DeepSeek-V4-Flash | $0.015 | $0.10 | $0.000033 | $0.033 | $0.056 |
| MiniMax-M2.7 | $0.05 | $0.15 | $0.000055 | $0.055 | $0.66 |
200 входных и 300 выходных токенов на запрос. Цены за 1M токенов актуальны и меняются вместе с нашими тарифами; столбец OpenRouter показывает справочные цены для той же нагрузки.
Теперь подставьте свой трафик. Подвиньте ползунки к числам из вашей первой напечатанной строки usage:
Калькулятор стоимости
Сервис поддержки: 2 000 запросов в день
Входные токены на запрос: 200 · Выходные токены на запрос: 300 · Запросов в день: 2 000
| Модель | В день | В месяц |
|---|---|---|
| GLM-5.3-Flash$0.02$0.04 | $0.032 | $0.96 |
| DeepSeek-V4-Flash$0.015$0.10 | $0.066 | $1.98 |
| MiniMax-M2.7$0.05$0.15 | $0.11 | $3.30 |
Если нужен длинный ответ или другая нагрузка: у DeepSeek-V4-Flash контекст 380K и одна цена в любое время суток; GLM-5.3-Flash (zai-) встаёт в ту же программу вместо неё — меняете id, и всё. Актуальные цены всех моделей — на странице цен, а тот же запрос на других языках — в документации. Пишете на Go? Смотрите версию для openai-go.



