Volver al blog

API y SDKGuía

Primera petición en Java con openai-java: URL base, clave, uso

Un programa Java 8+ ejecutable: openai-java apuntando a CheapTokens, una chat completion y la respuesta, finish_reason y uso de tokens impresos.

Por CheapTokens TeamPublicado el 5 min de lectura

Código Java que apunta openai-java a la API de CheapTokens
En esta página
  1. Añade la dependencia
  2. Configura la clave y la URL base fuera del código
  3. El programa
  4. Configura los valores explícitamente con el builder
  5. Tres errores que encontrarás primero
  6. Cuánto cuesta una petición

Para llamar a CheapTokens desde Java, conserva el SDK oficial openai-java y cambia tres cosas: la URL base (https://api.cheaptokens.dev/v1), la clave de API y el id del modelo, pasado como un String simple. El programa siguiente envía una chat completion e imprime la respuesta, el finish_reason y el uso de tokens. Necesita Java 8 o posterior.

Si tu equipo ya tiene un servicio Spring que habla con OpenAI, esta es toda la migración: ningún cliente nuevo, ninguna clase de petición nueva.

Añade la dependencia#

El README del SDK (github.com/openai/openai-java, consultado el 4 de noviembre de 2026) muestra la versión 4.99.0, grupo com.openai, artefacto openai-java. El README no indica una fecha de publicación, así que revisa el repositorio para ver la última versión antes de copiar esto.

Añade openai-java a tu build

Maven

xml
<dependency>
  <groupId>com.openai</groupId>
  <artifactId>openai-java</artifactId>
  <version>4.99.0</version>
</dependency>

Gradle

kotlin
implementation("com.openai:openai-java:4.99.0")

Los artefactos neutrales respecto al framework funcionan en Java 8+, así que un JDK corporativo antiguo no es un impedimento.

Configura la clave y la URL base fuera del código#

El SDK lee dos variables de entorno: OPENAI_API_KEY y OPENAI_BASE_URL. OpenAIOkHttpClient.fromEnv() recoge ambas, así que la clave nunca acaba en tus archivos fuente. (Las propiedades del sistema openai.apiKey y openai.baseUrl también funcionan y tienen prioridad sobre las variables).

bash
export OPENAI_API_KEY="your-cheaptokens-key"
export OPENAI_BASE_URL="https://api.cheaptokens.dev/v1"

La URL base por defecto del SDK es https://api.openai.com/v1. Omite la segunda línea y tu petición irá allí, con una clave de CheapTokens que no conoce. Esa es una forma de obtener un 401 en la primera ejecución. Para saber dónde guardar la clave y cómo mantenerla fuera de git, consulta guardar una clave de API de forma segura.

Las dos variables de entorno y un comando de ejecución en una terminal
La clave y la URL base vienen del entorno, no del archivo fuente

El programa#

Crea FirstRequest.java:

java
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()));
  }
}

Algunas líneas merecen una segunda mirada.

  • .model("deepseek-ai/DeepSeek-V4-Flash-0731"). Los ejemplos del README del SDK usan constantes tipadas como ChatModel.GPT_5_2, pero el builder también tiene una sobrecarga model(String), así que cualquier id sirve. Usa el id completo de la documentación de CheapTokens: el nombre corto deepseek-v4-flash-0731 es como se etiquetan los precios en el sitio; la API quiere el id completo con el prefijo deepseek-ai/. ¿No estás seguro de un id? Lista los modelos con GET /v1/models.
  • .maxCompletionTokens(300L). Un límite a la longitud de la respuesta, como un long. DeepSeek-V4-Flash permite hasta 32.768 tokens de salida por respuesta, así que 300 aquí es una elección para mantener la demo corta, no un límite del modelo.
  • content() es un Optional. Por eso el programa tiene orElse. Una respuesta compuesta solo de tool calls no tiene texto.
  • usage() también es un Optional. ifPresent lo imprime cuando el servidor lo envía.

Compílalo y ejecútalo como lo haga tu build (mvn compile exec:java -Dexec.mainClass=FirstRequest, o una tarea JavaExec en Gradle). Deberías obtener la explicación de un token, luego una línea finish_reason: … con stop en ella, y después una línea con los recuentos de tokens de entrada y salida. Si finish_reason dice length, la respuesta alcanzó tu tope de 300 tokens y se cortó: sube el número (por qué ocurre).

usage() devuelve los recuentos de tokens de prompt, completion y total (promptTokens(), completionTokens(), totalTokens()).

Configura los valores explícitamente con el builder#

Los tests, o un servicio con varios clientes, a veces necesitan valores explícitos. El mismo cliente, construido a mano:

java
OpenAIClient client = OpenAIOkHttpClient.builder()
    .apiKey(System.getenv("OPENAI_API_KEY"))
    .baseUrl("https://api.cheaptokens.dev/v1")
    .build();

Todo lo que sigue a esta línea, los params y la llamada create, se queda exactamente como arriba. Sigue leyendo la clave del entorno incluso aquí; un literal de cadena en un archivo .java acaba en tu repositorio.

Código Java, openai-java, el endpoint de CheapTokens y el modelo
Tu código habla con el SDK; solo la URL base decide quién responde

Tres errores que encontrarás primero#

Emparejar los pares

Relaciona el síntoma con la causa

  • 401 Unauthorizedla clave está vacía o es incorrecta, o la petición fue a api.openai.com porque OPENAI_BASE_URL no está configurada
  • 404 Not Founda la URL base le falta /v1, o el id del modelo no existe
  • finish_reason dice lengthmaxCompletionTokens es menor de lo que necesita la respuesta

Una variable de entorno vacía es fácil de pasar por alto en un IDE: una configuración de ejecución iniciada desde la barra de herramientas puede no heredar las variables que exportaste en la terminal. Si la clave "está configurada" pero sigues recibiendo 401, añade las variables a la configuración de ejecución. Más sobre estos códigos: API 401 o 404: clave, URL base, id del modelo.

Cuánto cuesta una petición#

Como imprimes usage, puedes calcular el precio de la petición antes de escalarla. Digamos que tu servicio envía unos 200 tokens de entrada y recibe 300. A los precios de hoy, esa petición cuesta $0.000033 en DeepSeek-V4-Flash. La entrada y la salida se facturan juntas, y en total eso es más barato que OpenRouter. La tabla lo repite para 1.000 peticiones en nuestros modelos:

Modelo Por solicitud 1000 solicitudes OpenRouter, 1000 solicitudes
GLM-5.3-Flash $0.000016 $0.016 $0.0316
DeepSeek-V4-Flash $0.000033 $0.033 $0.056
MiniMax-M2.7 $0.000055 $0.055 $0.66

200 tokens de entrada y 300 tokens de salida por solicitud. Los precios por 1M de tokens son actuales y cambian junto con nuestras tarifas; la columna de OpenRouter muestra precios de referencia para la misma carga de trabajo.

Ahora introduce tu propio tráfico. Mueve los deslizadores a los números de tu primera línea usage impresa:

Calculadora de costos

Un servicio de soporte con 2.000 peticiones al día

Tokens de entrada por solicitud: 200 · Tokens de salida por solicitud: 300 · Solicitudes por día: 2000

ModeloPor díaPor mes
GLM-5.3-Flash$0.032$0.96
DeepSeek-V4-Flash$0.066$1.98
MiniMax-M2.7$0.11$3.30

Para más espacio por respuesta o una forma de carga de trabajo distinta, DeepSeek-V4-Flash te da una ventana de contexto de 380K y un único precio a cualquier hora del día; GLM-5.3-Flash (zai-org/GLM-5.3-Flash) es un reemplazo directo en el mismo programa: cambia el id, nada más. Los precios actuales de todos los modelos están en la página de precios, y la documentación muestra la misma petición en otros lenguajes. ¿Lo haces en Go? Consulta la versión de openai-go.