API & SDK가이드
openai-java로 Java에서 첫 요청: base URL, 키, 사용량
실행 가능한 Java 8+ 프로그램: CheapTokens를 가리키는 openai-java, 채팅 완성 한 번, 그리고 답변, finish_reason, 토큰 사용량 출력.

Java에서 CheapTokens를 호출하려면 공식 openai-java SDK를 유지하고 세 가지만 바꾸면 됩니다: base URL(https:/), API 키, 그리고 일반 String로 전달하는 모델 id입니다. 아래 프로그램은 채팅 완성을 한 번 보내고 답변, finish_reason, 토큰 사용량을 출력합니다. Java 8 이상이 필요합니다.
팀에 이미 OpenAI와 통신하는 Spring 서비스가 있다면, 이것이 마이그레이션의 전부입니다: 새 클라이언트도, 새 요청 클래스도 필요 없습니다.
의존성 추가#
SDK의 README(github.com/openai/openai-java, 2026년 11월 4일 확인)에는 버전 4.99.0, group com.openai, artifact 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의 기본 base URL은 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()));
}
}몇 줄은 다시 볼 가치가 있습니다.
.. SDK의 README 예제는model("deepseek- ai/ DeepSeek- V4- Flash- 0731") ChatModel.같은 타입 상수를 사용하지만, 빌더에는GPT_ 5_ 2 model(String)오버로드도 있으므로 어떤 id든 작동합니다. CheapTokens 문서의 전체 id를 사용하세요: 짧은 이름deepseek-는 사이트에서 가격이 표시되는 방식이고, API는v4- flash- 0731 deepseek-ai/접두사가 붙은 전체 id를 원합니다. id가 확실하지 않나요? GET /v1/models로 모델 목록 조회... 답변 길이의 상한으로,maxCompletionTokens(300L) long입니다. DeepSeek-V4-Flash는 답변당 최대 32,768 출력 토큰을 허용하므로, 여기서 300은 데모를 짧게 유지하기 위한 선택이지 모델의 한계가 아닙니다.content()는Optional입니다. 그래서 프로그램에orElse이 있습니다. 도구 호출로만 이루어진 응답에는 텍스트가 없습니다.usage()도Optional입니다.ifPresent는 서버가 보낼 때 이를 출력합니다.
빌드 방식대로 컴파일하고 실행하세요(mvn compile exec:java -, 또는 Gradle의 JavaExec 태스크). 토큰에 대한 설명이 나오고, 그다음 stop이 포함된 finish_reason: … 줄, 그다음 입력 및 출력 토큰 수가 있는 줄이 나와야 합니다. 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();이 줄 이후의 모든 것, 즉 params와 create 호출은 위와 정확히 동일하게 유지됩니다. 여기서도 키는 환경에서 읽으세요; .java 파일의 문자열 리터럴은 결국 저장소에 남습니다.

가장 먼저 만나게 될 세 가지 오류#
짝 맞추기
증상을 원인과 연결하세요
왼쪽 항목을 탭한 다음 짝을 탭하세요
- 401 Unauthorized키가 비어 있거나 잘못되었거나,
OPENAI_BASE_URL가 설정되지 않아 요청이 api.openai.com으로 간 경우 - 404 Not Foundbase URL에
/v1가 없거나, 모델 id가 존재하지 않음 - finish_reason이 length를 나타냄
maxCompletionTokens이 답변에 필요한 것보다 낮음
빈 환경 변수는 IDE에서 놓치기 쉽습니다: 툴바에서 시작한 실행 구성은 터미널에서 export한 변수를 상속하지 않을 수 있습니다. 키가 "설정되어" 있는데도 여전히 401이 나오면, 실행 구성에 변수를 추가하세요. 이 코드들에 대한 자세한 내용: API 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개 토큰입니다. 100만 토큰당 가격은 현재 기준이며 당사 요금제에 따라 함께 변경됩니다. 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 버전을 참고하세요.



